Merge branch 'branch-jagad' into 'main'
Branch jagad See merge request fiqhpratama1/xpendify!1
This commit is contained in:
@@ -67,3 +67,7 @@ AWS_BUCKET=
|
|||||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
VITE_APP_NAME="${APP_NAME}"
|
VITE_APP_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
NEXT_CLOUD_URL=https://mkt.tunggal-pharma.com/
|
||||||
|
NEXT_CLOUD_USERNAME=user_dev
|
||||||
|
NEXT_CLOUD_PASSWORD=userdev12345
|
||||||
|
|||||||
@@ -64,3 +64,7 @@ AWS_BUCKET=
|
|||||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
VITE_APP_NAME="${APP_NAME}"
|
VITE_APP_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
NEXT_CLOUD_URL=
|
||||||
|
NEXT_CLOUD_USERNAME=
|
||||||
|
NEXT_CLOUD_PASSWORD=
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Helpers;
|
||||||
|
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use GuzzleHttp\Exception\RequestException;
|
||||||
|
|
||||||
|
class NextCloudHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a folder in Nextcloud.
|
||||||
|
*
|
||||||
|
* @param string $baseUrl Nextcloud Base URL
|
||||||
|
* @param string $username Nextcloud Username
|
||||||
|
* @param string $password Nextcloud Password
|
||||||
|
* @param string $folderPath Folder Path to Create
|
||||||
|
* @return array Response Data
|
||||||
|
*/
|
||||||
|
public static function createFolder($baseUrl, $username, $password, $folderPath)
|
||||||
|
{
|
||||||
|
$client = new Client();
|
||||||
|
$url = rtrim($baseUrl, '/') . "/remote.php/dav/files/{$username}/" . ltrim($folderPath, '/');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $client->request('MKCOL', $url, [
|
||||||
|
'auth' => [$username, $password]
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'status' => $response->getStatusCode(),
|
||||||
|
'message' => 'Folder created successfully.'
|
||||||
|
];
|
||||||
|
} catch (RequestException $e) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'status' => $e->getCode(),
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a user in Nextcloud.
|
||||||
|
*
|
||||||
|
* @param string $baseUrl Nextcloud Base URL
|
||||||
|
* @param string $adminUsername Admin Username
|
||||||
|
* @param string $adminPassword Admin Password
|
||||||
|
* @param string $userId New User ID
|
||||||
|
* @param string $password New User Password
|
||||||
|
* @param string $displayName New User Display Name
|
||||||
|
* @param string $email New User Email
|
||||||
|
* @return array Response Data
|
||||||
|
*/
|
||||||
|
public static function createUser($baseUrl, $adminUsername, $adminPassword, $userId, $password, $displayName, $email)
|
||||||
|
{
|
||||||
|
$client = new Client();
|
||||||
|
$url = rtrim($baseUrl, '/') . "/mktia/ocs/v1.php/cloud/users";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $client->request('POST', $url, [
|
||||||
|
'auth' => [$adminUsername, $adminPassword],
|
||||||
|
'headers' => [
|
||||||
|
'OCS-APIRequest' => 'true',
|
||||||
|
],
|
||||||
|
'form_params' => [
|
||||||
|
'userid' => $userId,
|
||||||
|
'password' => $password,
|
||||||
|
'displayName' => $displayName,
|
||||||
|
'email' => $email
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'status' => $response->getStatusCode(),
|
||||||
|
'message' => 'User created successfully.'
|
||||||
|
];
|
||||||
|
} catch (RequestException $e) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'status' => $e->getCode(),
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a user to a group in Nextcloud.
|
||||||
|
*
|
||||||
|
* @param string $baseUrl Nextcloud Base URL
|
||||||
|
* @param string $adminUsername Admin Username
|
||||||
|
* @param string $adminPassword Admin Password
|
||||||
|
* @param string $userId New User ID
|
||||||
|
* @param string $groupName Group Name
|
||||||
|
* @return array Response Data
|
||||||
|
*/
|
||||||
|
public static function addUserToGroup($baseUrl, $adminUsername, $adminPassword, $userId, $groupName)
|
||||||
|
{
|
||||||
|
$client = new Client();
|
||||||
|
$url = rtrim($baseUrl, '/') . "/mktia/ocs/v1.php/cloud/groups/{$groupName}";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $client->request('POST', $url, [
|
||||||
|
'auth' => [$adminUsername, $adminPassword],
|
||||||
|
'headers' => [
|
||||||
|
'OCS-APIRequest' => 'true',
|
||||||
|
],
|
||||||
|
'form_params' => [
|
||||||
|
'userid' => $userId
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'status' => $response->getStatusCode(),
|
||||||
|
'message' => 'User added to group successfully.'
|
||||||
|
];
|
||||||
|
} catch (RequestException $e) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'status' => $e->getCode(),
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ use Illuminate\Contracts\Support\Renderable;
|
|||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Spatie\Permission\Models\Role;
|
use Spatie\Permission\Models\Role;
|
||||||
|
use App\Helpers\NextcloudHelper;
|
||||||
|
|
||||||
class AdminsController extends Controller
|
class AdminsController extends Controller
|
||||||
{
|
{
|
||||||
@@ -56,14 +57,23 @@ class AdminsController extends Controller
|
|||||||
$admin->password = Hash::make($request->password);
|
$admin->password = Hash::make($request->password);
|
||||||
$admin->username = $request->username;
|
$admin->username = $request->username;
|
||||||
$admin->email = $request->email;
|
$admin->email = $request->email;
|
||||||
|
$admin->phone = $request->phone;
|
||||||
$admin->save();
|
$admin->save();
|
||||||
|
|
||||||
if ($request->roles) {
|
if ($request->roles) {
|
||||||
$admin->assignRole($request->roles);
|
$admin->assignRole($request->roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
session()->flash('success', __('Admin has been created.'));
|
// Create a folder in Nextcloud
|
||||||
return redirect()->route('admin.admins.index');
|
$response = NextcloudHelper::createUser(env('NEXT_CLOUD_URL'), env('NEXT_CLOUD_USERNAME'), env('NEXT_CLOUD_PASSWORD'), $request->username, $request->password, $request->name, $request->email);
|
||||||
|
|
||||||
|
if ($response['success']) {
|
||||||
|
session()->flash('success', __('Admin has been created.'));
|
||||||
|
return redirect()->route('admin.admins.index');
|
||||||
|
} else {
|
||||||
|
session()->flash('error', $response['message']);
|
||||||
|
return redirect()->route('admin.admins.index');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(int $id): Renderable
|
public function edit(int $id): Renderable
|
||||||
@@ -93,6 +103,7 @@ class AdminsController extends Controller
|
|||||||
$admin->name = $request->name;
|
$admin->name = $request->name;
|
||||||
$admin->email = $request->email;
|
$admin->email = $request->email;
|
||||||
$admin->username = $request->username;
|
$admin->username = $request->username;
|
||||||
|
$admin->phone = $request->phone;
|
||||||
|
|
||||||
if ($request->password) {
|
if ($request->password) {
|
||||||
$admin->password = Hash::make($request->password);
|
$admin->password = Hash::make($request->password);
|
||||||
@@ -104,7 +115,7 @@ class AdminsController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
session()->flash('success', 'Admin has been updated.');
|
session()->flash('success', 'Admin has been updated.');
|
||||||
return back();
|
return redirect()->route('admin.admins.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy(int $id): RedirectResponse
|
public function destroy(int $id): RedirectResponse
|
||||||
@@ -114,6 +125,6 @@ class AdminsController extends Controller
|
|||||||
$admin = Admin::findOrFail($id);
|
$admin = Admin::findOrFail($id);
|
||||||
$admin->delete();
|
$admin->delete();
|
||||||
session()->flash('success', 'Admin has been deleted.');
|
session()->flash('success', 'Admin has been deleted.');
|
||||||
return back();
|
return redirect()->route('admin.admins.index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ class RolesController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
session()->flash('success', 'Role has been updated.');
|
session()->flash('success', 'Role has been updated.');
|
||||||
return back();
|
return redirect()->route('admin.roles.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy(int $id): RedirectResponse
|
public function destroy(int $id): RedirectResponse
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Forms;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\FormUpCountry;
|
||||||
|
use App\Models\Rayon;
|
||||||
|
|
||||||
|
class FormUpCountryController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('backend.pages.forms.upcountry.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('backend.pages.forms.upcountry.create', [
|
||||||
|
'rayons' => Rayon::all()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
return view('backend.pages.forms.upcountry.edit', [
|
||||||
|
'rayons' => Rayon::all()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Master;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Kategori;
|
||||||
|
|
||||||
|
class CategoryController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['category.view']);
|
||||||
|
return view('backend.pages.master.category.index', [
|
||||||
|
'categories' => Kategori::all()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['category.create']);
|
||||||
|
return view('backend.pages.master.category.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['category.create']);
|
||||||
|
$request->validate([
|
||||||
|
'name' => 'required|unique:kategori,name',
|
||||||
|
'account_number' => 'required|unique:kategori,account_number'
|
||||||
|
]);
|
||||||
|
|
||||||
|
Kategori::create([
|
||||||
|
'name' => $request->name,
|
||||||
|
'account_number' => $request->account_number
|
||||||
|
]);
|
||||||
|
|
||||||
|
session()->flash('success', 'Category has been created.');
|
||||||
|
return redirect()->route('admin.category.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['category.edit']);
|
||||||
|
return view('backend.pages.master.category.edit', [
|
||||||
|
'category' => Kategori::findOrfail($id)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['category.edit']);
|
||||||
|
$request->validate([
|
||||||
|
'name' => 'required|unique:kategori,name,' . $id . ',id',
|
||||||
|
'account_number' => 'required|unique:kategori,account_number,' . $id . ',id'
|
||||||
|
]);
|
||||||
|
|
||||||
|
Kategori::findOrfail($id)->update([
|
||||||
|
'name' => $request->name,
|
||||||
|
'account_number' => $request->account_number
|
||||||
|
]);
|
||||||
|
|
||||||
|
session()->flash('success', 'Category has been updated.');
|
||||||
|
return redirect()->route('admin.category.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['category.delete']);
|
||||||
|
Kategori::findOrfail($id)->delete();
|
||||||
|
|
||||||
|
session()->flash('success', 'Category has been deleted.');
|
||||||
|
return redirect()->route('admin.category.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Master;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\CostCentre;
|
||||||
|
|
||||||
|
class CostCentreController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['cost.view']);
|
||||||
|
return view('backend.pages.master.cost.index', [
|
||||||
|
'costs' => CostCentre::all()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['cost.create']);
|
||||||
|
return view('backend.pages.master.cost.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['cost.create']);
|
||||||
|
$request->validate([
|
||||||
|
'code' => 'required|unique:cost_centre,code',
|
||||||
|
'name' => 'required|unique:cost_centre,name'
|
||||||
|
]);
|
||||||
|
|
||||||
|
CostCentre::create([
|
||||||
|
'code' => $request->code,
|
||||||
|
'name' => $request->name
|
||||||
|
]);
|
||||||
|
|
||||||
|
session()->flash('success', 'Cost Centre has been created.');
|
||||||
|
return redirect()->route('admin.cost.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['cost.edit']);
|
||||||
|
return view('backend.pages.master.cost.edit', [
|
||||||
|
'cost' => CostCentre::findOrfail($id)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['cost.edit']);
|
||||||
|
$request->validate([
|
||||||
|
'code' => 'required|unique:cost_centre,code,' . $id . ',id',
|
||||||
|
'name' => 'required|unique:cost_centre,name,' . $id . ',id'
|
||||||
|
]);
|
||||||
|
|
||||||
|
CostCentre::findOrfail($id)->update([
|
||||||
|
'code' => $request->code,
|
||||||
|
'name' => $request->name
|
||||||
|
]);
|
||||||
|
|
||||||
|
session()->flash('success', 'Cost has been updated.');
|
||||||
|
return redirect()->route('admin.cost.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['cost.delete']);
|
||||||
|
CostCentre::findOrfail($id)->delete();
|
||||||
|
|
||||||
|
session()->flash('success', 'Cost has been deleted.');
|
||||||
|
return redirect()->route('admin.cost.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Master;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Rayon;
|
||||||
|
|
||||||
|
class RayonController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['rayon.view']);
|
||||||
|
return view('backend.pages.master.rayon.index', [
|
||||||
|
'rayons' => Rayon::all()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['rayon.create']);
|
||||||
|
return view('backend.pages.master.rayon.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['rayon.create']);
|
||||||
|
$request->validate([
|
||||||
|
'code' => 'required|unique:rayon,code',
|
||||||
|
'name' => 'required|unique:rayon,name'
|
||||||
|
]);
|
||||||
|
|
||||||
|
Rayon::create([
|
||||||
|
'code' => $request->code,
|
||||||
|
'name' => $request->name
|
||||||
|
]);
|
||||||
|
|
||||||
|
session()->flash('success', 'Rayon has been created.');
|
||||||
|
return redirect()->route('admin.rayon.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['rayon.edit']);
|
||||||
|
return view('backend.pages.master.rayon.edit', [
|
||||||
|
'rayon' => Rayon::findOrfail($id)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['rayon.edit']);
|
||||||
|
$request->validate([
|
||||||
|
'code' => 'required|unique:rayon,code,' . $id . ',id',
|
||||||
|
'name' => 'required|unique:rayon,name,' . $id . ',id'
|
||||||
|
]);
|
||||||
|
|
||||||
|
Rayon::findOrfail($id)->update([
|
||||||
|
'code' => $request->code,
|
||||||
|
'name' => $request->name
|
||||||
|
]);
|
||||||
|
|
||||||
|
session()->flash('success', 'Rayon has been updated.');
|
||||||
|
return redirect()->route('admin.rayon.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$this->checkAuthorization(auth()->user(), ['rayon.delete']);
|
||||||
|
Rayon::findOrfail($id)->delete();
|
||||||
|
|
||||||
|
session()->flash('success', 'Rayon has been deleted.');
|
||||||
|
return redirect()->route('admin.rayon.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ use Spatie\Menu\Laravel\Facades\Menu;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
|
||||||
class MenuMiddleware
|
class MenuMiddleware
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -42,9 +41,7 @@ class MenuMiddleware
|
|||||||
WHERE m.parent_id IS NULL AND rm.role_id = '".$currentRoleId."'
|
WHERE m.parent_id IS NULL AND rm.role_id = '".$currentRoleId."'
|
||||||
ORDER BY m.id
|
ORDER BY m.id
|
||||||
");
|
");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach ($menus as $item) {
|
foreach ($menus as $item) {
|
||||||
// Ambil submenu jika ada
|
// Ambil submenu jika ada
|
||||||
$children = DB::select("
|
$children = DB::select("
|
||||||
@@ -77,7 +74,7 @@ class MenuMiddleware
|
|||||||
'<li class="nav-item">' .
|
'<li class="nav-item">' .
|
||||||
'<a href="#" class="nav-link">' .
|
'<a href="#" class="nav-link">' .
|
||||||
'<i class="nav-icon ' . $item->icon . '"></i>' .
|
'<i class="nav-icon ' . $item->icon . '"></i>' .
|
||||||
'<p>' . $item->title . '<i class="fas fa-angle-left right"></i></p>' .
|
'<p>' . $item->title . '<i class="fas fa-angle-left right mt-1"></i></p>' .
|
||||||
'</a>' .
|
'</a>' .
|
||||||
$submenu->render() .
|
$submenu->render() .
|
||||||
'</li>'
|
'</li>'
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class AdminRequest extends FormRequest
|
|||||||
'email' => 'required|max:100|email|unique:admins,email,' . $adminId,
|
'email' => 'required|max:100|email|unique:admins,email,' . $adminId,
|
||||||
'username' => 'required|max:100|unique:admins,username,' . $adminId,
|
'username' => 'required|max:100|unique:admins,username,' . $adminId,
|
||||||
'password' => $adminId ? 'nullable|confirmed' : 'confirmed',
|
'password' => $adminId ? 'nullable|confirmed' : 'confirmed',
|
||||||
|
'phone' => 'required|max:15|unique:admins,phone,' . $adminId,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@@ -11,6 +12,7 @@ use Spatie\Permission\Traits\HasRoles;
|
|||||||
class Admin extends Authenticatable
|
class Admin extends Authenticatable
|
||||||
{
|
{
|
||||||
use Notifiable, HasRoles;
|
use Notifiable, HasRoles;
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the default guard for this model.
|
* Set the default guard for this model.
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class AuditTrail extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'audit_trail';
|
||||||
|
protected $fillable = [
|
||||||
|
'user_id',
|
||||||
|
'ip_address',
|
||||||
|
'activity',
|
||||||
|
'action',
|
||||||
|
'user_agent',
|
||||||
|
'browser',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Cabang extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'cabang';
|
||||||
|
protected $fillable = [
|
||||||
|
'region_id',
|
||||||
|
'cost_id',
|
||||||
|
'code',
|
||||||
|
'name',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class CostCentre extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'cost_centre';
|
||||||
|
protected $fillable = [
|
||||||
|
'code',
|
||||||
|
'name',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class FormEntertaimentPresentation extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'form_entertainment_presentation';
|
||||||
|
protected $fillable = [
|
||||||
|
'expense_number',
|
||||||
|
'user_id',
|
||||||
|
'tanggal',
|
||||||
|
'jenis',
|
||||||
|
'keterangan',
|
||||||
|
'total',
|
||||||
|
'name',
|
||||||
|
'alamat',
|
||||||
|
'nik_or_npwp',
|
||||||
|
'bukti1',
|
||||||
|
'bukti2',
|
||||||
|
'bukti3',
|
||||||
|
'account_number',
|
||||||
|
'status',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class FormMeetingSeminar extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'form_meeting_seminar';
|
||||||
|
protected $fillable = [
|
||||||
|
'expense_number',
|
||||||
|
'user_id',
|
||||||
|
'allowance',
|
||||||
|
'transport_ankot',
|
||||||
|
'hotel',
|
||||||
|
'total',
|
||||||
|
'bukti1',
|
||||||
|
'bukti2',
|
||||||
|
'bukti3',
|
||||||
|
'account_number',
|
||||||
|
'status',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class FormOthers extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'form_others';
|
||||||
|
protected $fillable = [
|
||||||
|
'expense_number',
|
||||||
|
'user_id',
|
||||||
|
'kategori_id',
|
||||||
|
'tanggal',
|
||||||
|
'keterangan',
|
||||||
|
'total',
|
||||||
|
'bukti1',
|
||||||
|
'bukti2',
|
||||||
|
'bukti3',
|
||||||
|
'status',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class FormUpCountry extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'form_up_country';
|
||||||
|
protected $fillable = [
|
||||||
|
'expense_number',
|
||||||
|
'user_id',
|
||||||
|
'rayon_id',
|
||||||
|
'tanggal',
|
||||||
|
'tujuan',
|
||||||
|
'jarak',
|
||||||
|
'allowance',
|
||||||
|
'transport_dalkot',
|
||||||
|
'transport_ankot',
|
||||||
|
'hotel',
|
||||||
|
'total',
|
||||||
|
'bukti1',
|
||||||
|
'bukti2',
|
||||||
|
'bukti3',
|
||||||
|
'account_number',
|
||||||
|
'status',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class FormVehicleRunningCost extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'form_vehicle_running_cost';
|
||||||
|
protected $fillable = [
|
||||||
|
'expense_number',
|
||||||
|
'user_id',
|
||||||
|
'tanggal',
|
||||||
|
'liter',
|
||||||
|
'harga',
|
||||||
|
'jarak',
|
||||||
|
'tipe_bensin',
|
||||||
|
'nopol',
|
||||||
|
'keterangan',
|
||||||
|
'bukti1',
|
||||||
|
'bukti2',
|
||||||
|
'bukti3',
|
||||||
|
'account_number',
|
||||||
|
'status',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Kategori extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'kategori';
|
||||||
|
protected $fillable = [
|
||||||
|
'name',
|
||||||
|
'account_number',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Rayon extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'rayon';
|
||||||
|
protected $fillable = ['code', 'name'];
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Region extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'region';
|
||||||
|
protected $fillable = [
|
||||||
|
'code',
|
||||||
|
'name',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -6,11 +6,13 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||||
use HasFactory, Notifiable;
|
use HasFactory, Notifiable;
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -20,7 +22,9 @@ class User extends Authenticatable
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'name',
|
||||||
'email',
|
'email',
|
||||||
|
'username',
|
||||||
'password',
|
'password',
|
||||||
|
'phone',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class UserHasCabang extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'user_has_cabang';
|
||||||
|
protected $fillable = [
|
||||||
|
'user_id',
|
||||||
|
'cabang_id',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
"laravel/tinker": "^2.9",
|
"laravel/tinker": "^2.9",
|
||||||
"laravel/ui": "^4.6",
|
"laravel/ui": "^4.6",
|
||||||
"laravolt/avatar": "^6.0",
|
"laravolt/avatar": "^6.0",
|
||||||
|
"nino/laravel-nextcloud-fs": "^2.0",
|
||||||
"phpoffice/phpspreadsheet": "^3.5",
|
"phpoffice/phpspreadsheet": "^3.5",
|
||||||
"spatie/laravel-html": "^3.11",
|
"spatie/laravel-html": "^3.11",
|
||||||
"spatie/laravel-menu": "^4.2",
|
"spatie/laravel-menu": "^4.2",
|
||||||
|
|||||||
Generated
+907
-129
File diff suppressed because it is too large
Load Diff
@@ -57,6 +57,14 @@ return [
|
|||||||
'throw' => false,
|
'throw' => false,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'nextcloud' => [
|
||||||
|
'driver' => 'nextcloud',
|
||||||
|
'baseUri' => env('NEXT_CLOUD_URL'),
|
||||||
|
'userName' => env('NEXT_CLOUD_USERNAME'),
|
||||||
|
'password' => env('NEXT_CLOUD_PASSWORD'),
|
||||||
|
'directory' => '',
|
||||||
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ class CreateUsersTable extends Migration
|
|||||||
$table->string('username')->unique();
|
$table->string('username')->unique();
|
||||||
$table->timestamp('email_verified_at')->nullable();
|
$table->timestamp('email_verified_at')->nullable();
|
||||||
$table->string('password');
|
$table->string('password');
|
||||||
|
$table->string('phone');
|
||||||
$table->rememberToken();
|
$table->rememberToken();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ class CreateAdminsTable extends Migration
|
|||||||
$table->string('username')->unique();
|
$table->string('username')->unique();
|
||||||
$table->timestamp('email_verified_at')->nullable();
|
$table->timestamp('email_verified_at')->nullable();
|
||||||
$table->string('password');
|
$table->string('password');
|
||||||
|
$table->string('phone');
|
||||||
$table->rememberToken();
|
$table->rememberToken();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ return new class extends Migration
|
|||||||
|
|
||||||
// Foreign key
|
// Foreign key
|
||||||
$table->foreign('user_id')->references('id')->on('admins')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('admins')->onDelete('cascade');
|
||||||
|
$table->softDeletes();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -11,9 +11,11 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('{{ table }}', function (Blueprint $table) {
|
Schema::create('rayon', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
|
$table->string('name');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,6 +24,6 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('{{ table }}');
|
Schema::dropIfExists('rayon');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('form_up_country', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('expense_number')->unique();
|
||||||
|
$table->foreignId('user_id')->constrained('admins')->cascadeOnDelete();
|
||||||
|
$table->foreignId('rayon_id')->constrained('rayon')->cascadeOnDelete();
|
||||||
|
$table->date('tanggal');
|
||||||
|
$table->string('tujuan');
|
||||||
|
$table->integer('jarak');
|
||||||
|
$table->integer('allowance');
|
||||||
|
$table->integer('transport_dalkot');
|
||||||
|
$table->integer('transport_ankot');
|
||||||
|
$table->integer('hotel');
|
||||||
|
$table->integer('total');
|
||||||
|
$table->string('bukti1')->nullable();
|
||||||
|
$table->string('bukti2')->nullable();
|
||||||
|
$table->string('bukti3')->nullable();
|
||||||
|
$table->string('account_number');
|
||||||
|
$table->string('status');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('form_up_country');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('form_vehicle_running_cost', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('expense_number')->unique();
|
||||||
|
$table->foreignId('user_id')->constrained('admins')->cascadeOnDelete();
|
||||||
|
$table->dateTime('tanggal');
|
||||||
|
$table->integer('liter');
|
||||||
|
$table->integer('harga');
|
||||||
|
$table->integer('jarak');
|
||||||
|
$table->string('tipe_bensin');
|
||||||
|
$table->string('nopol');
|
||||||
|
$table->text('keterangan');
|
||||||
|
$table->string('bukti1')->nullable();
|
||||||
|
$table->string('bukti2')->nullable();
|
||||||
|
$table->string('bukti3')->nullable();
|
||||||
|
$table->string('account_number');
|
||||||
|
$table->string('status');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('form_vehicle_running_cost');
|
||||||
|
}
|
||||||
|
};
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('form_entertainment_presentation', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('expense_number')->unique();
|
||||||
|
$table->foreignId('user_id')->constrained('admins')->cascadeOnDelete();
|
||||||
|
$table->date('tanggal');
|
||||||
|
$table->string('jenis');
|
||||||
|
$table->text('keterangan');
|
||||||
|
$table->integer('total');
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('alamat');
|
||||||
|
$table->string('nik_or_npwp');
|
||||||
|
$table->string('bukti1')->nullable();
|
||||||
|
$table->string('bukti2')->nullable();
|
||||||
|
$table->string('bukti3')->nullable();
|
||||||
|
$table->string('account_number');
|
||||||
|
$table->string('status');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('form_entertainment_presentation');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('form_meeting_seminar', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('expense_number')->unique();
|
||||||
|
$table->foreignId('user_id')->constrained('admins')->cascadeOnDelete();
|
||||||
|
$table->integer('allowance');
|
||||||
|
$table->integer('transport_ankot');
|
||||||
|
$table->integer('hotel');
|
||||||
|
$table->integer('total');
|
||||||
|
$table->string('bukti1')->nullable();
|
||||||
|
$table->string('bukti2')->nullable();
|
||||||
|
$table->string('bukti3')->nullable();
|
||||||
|
$table->string('account_number');
|
||||||
|
$table->string('status');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('form_meeting_seminar');
|
||||||
|
}
|
||||||
|
};
|
||||||
+6
-7
@@ -11,13 +11,12 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('notifications', function (Blueprint $table) {
|
Schema::create('kategori', function (Blueprint $table) {
|
||||||
$table->uuid('id')->primary();
|
$table->id();
|
||||||
$table->string('type');
|
$table->string('name');
|
||||||
$table->morphs('notifiable');
|
$table->string('account_number');
|
||||||
$table->text('data');
|
|
||||||
$table->timestamp('read_at')->nullable();
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +25,6 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('notifications');
|
Schema::dropIfExists('kategori');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('form_others', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('expense_number')->unique();
|
||||||
|
$table->foreignId('user_id')->constrained('admins')->cascadeOnDelete();
|
||||||
|
$table->foreignId('kategori_id')->constrained('kategori')->cascadeOnDelete();
|
||||||
|
$table->date('tanggal');
|
||||||
|
$table->text('keterangan');
|
||||||
|
$table->integer('total');
|
||||||
|
$table->string('bukti1')->nullable();
|
||||||
|
$table->string('bukti2')->nullable();
|
||||||
|
$table->string('bukti3')->nullable();
|
||||||
|
$table->string('status')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('form_others');
|
||||||
|
}
|
||||||
|
};
|
||||||
+8
-2
@@ -11,7 +11,13 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
//
|
Schema::create('region', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('code');
|
||||||
|
$table->string('name');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,6 +25,6 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
//
|
Schema::dropIfExists('region');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('cost_centre', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('code');
|
||||||
|
$table->string('name');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('cost_centre');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('cabang', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('region_id')->constrained('region')->onDelete('cascade');
|
||||||
|
$table->foreignId('cost_id')->constrained('cost_centre')->onDelete('cascade');
|
||||||
|
$table->string('code');
|
||||||
|
$table->string('name');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('cabang');
|
||||||
|
}
|
||||||
|
};
|
||||||
+6
-8
@@ -11,14 +11,12 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('{{table}}', function (Blueprint $table) {
|
Schema::create('user_has_cabang', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->string('uuid')->unique();
|
$table->foreignId('user_id')->constrained('admins')->cascadeOnDelete();
|
||||||
$table->text('connection');
|
$table->foreignId('cabang_id')->constrained('cabang')->cascadeOnDelete();
|
||||||
$table->text('queue');
|
$table->timestamps();
|
||||||
$table->longText('payload');
|
$table->softDeletes();
|
||||||
$table->longText('exception');
|
|
||||||
$table->timestamp('failed_at')->useCurrent();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,6 +25,6 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('{{table}}');
|
Schema::dropIfExists('user_has_cabang');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('audit_trail', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('user_id')->constrained('admins')->cascadeOnDelete();
|
||||||
|
$table->string('ip_address');
|
||||||
|
$table->string('activity')->nullable();
|
||||||
|
$table->string('action')->nullable();
|
||||||
|
$table->text('user_agent')->nullable();
|
||||||
|
$table->string('browser')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('audit_trail');
|
||||||
|
}
|
||||||
|
};
|
||||||
+4
-4
@@ -11,8 +11,8 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::table('{{ table }}', function (Blueprint $table) {
|
Schema::table('rayon', function (Blueprint $table) {
|
||||||
//
|
$table->string('code')->after('id')->nullable()->unique();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::table('{{ table }}', function (Blueprint $table) {
|
Schema::table('rayon', function (Blueprint $table) {
|
||||||
//
|
$table->dropColumn('code');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeds;
|
||||||
|
|
||||||
use App\Models\Admin;
|
use App\Models\Admin;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@@ -21,6 +23,7 @@ class AdminSeeder extends Seeder
|
|||||||
$admin->email = "superadmin@email.com";
|
$admin->email = "superadmin@email.com";
|
||||||
$admin->username = "superadmin";
|
$admin->username = "superadmin";
|
||||||
$admin->password = Hash::make('12345678');
|
$admin->password = Hash::make('12345678');
|
||||||
|
$admin->phone = "085112345622";
|
||||||
$admin->save();
|
$admin->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
use Database\Seeds\UserSeeder;
|
||||||
|
use Database\Seeds\AdminSeeder;
|
||||||
|
use Database\Seeds\RolePermissionSeeder;
|
||||||
|
use Database\Seeds\MenuSeeder;
|
||||||
|
use Database\Seeds\RayonSeeder;
|
||||||
|
use Database\Seeds\RolePermissionSeeder2;
|
||||||
|
|
||||||
class DatabaseSeeder extends Seeder
|
class DatabaseSeeder extends Seeder
|
||||||
{
|
{
|
||||||
@@ -14,6 +20,8 @@ class DatabaseSeeder extends Seeder
|
|||||||
$this->call(UserSeeder::class);
|
$this->call(UserSeeder::class);
|
||||||
$this->call(AdminSeeder::class);
|
$this->call(AdminSeeder::class);
|
||||||
$this->call(RolePermissionSeeder::class);
|
$this->call(RolePermissionSeeder::class);
|
||||||
$this->call(MenusTableSeeder::class);
|
$this->call(MenuSeeder::class);
|
||||||
|
$this->call(RayonSeeder::class);
|
||||||
|
$this->call(RolePermissionSeeder2::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeds;
|
||||||
|
|
||||||
|
use App\Models\Admin;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
class MenusTableSeeder extends Seeder
|
class MenuSeeder extends Seeder
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Run the database seeds.
|
* Run the database seeds.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run()
|
||||||
{
|
{
|
||||||
DB::table('menus')->insert([
|
DB::table('menus')->insert([
|
||||||
[
|
[
|
||||||
@@ -45,5 +49,27 @@ class MenusTableSeeder extends Seeder
|
|||||||
'updated_at' => Carbon::now(),
|
'updated_at' => Carbon::now(),
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
DB::table('role_menu')->insert([
|
||||||
|
[
|
||||||
|
'role_id' => 1,
|
||||||
|
'menu_id' => 61,
|
||||||
|
'created_at' => Carbon::now(),
|
||||||
|
'updated_at' => Carbon::now(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'role_id' => 1,
|
||||||
|
'menu_id' => 62,
|
||||||
|
'created_at' => Carbon::now(),
|
||||||
|
'updated_at' => Carbon::now(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'role_id' => 1,
|
||||||
|
'menu_id' => 63,
|
||||||
|
'created_at' => Carbon::now(),
|
||||||
|
'updated_at' => Carbon::now(),
|
||||||
|
]
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeds;
|
||||||
|
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use App\Models\Rayon;
|
||||||
|
|
||||||
|
class RayonSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
Rayon::create([
|
||||||
|
'code' => 'R1',
|
||||||
|
'name' => 'Rayon 1',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Rayon::create([
|
||||||
|
'code' => 'R2',
|
||||||
|
'name' => 'Rayon 2',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Rayon::create([
|
||||||
|
'code' => 'R3',
|
||||||
|
'name' => 'Rayon 3',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeds;
|
||||||
|
|
||||||
use App\Models\Admin;
|
use App\Models\Admin;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Spatie\Permission\Models\Role;
|
use Spatie\Permission\Models\Role;
|
||||||
@@ -36,7 +38,6 @@ class RolePermissionSeeder extends Seeder
|
|||||||
|
|
||||||
// Permission List as array
|
// Permission List as array
|
||||||
$permissions = [
|
$permissions = [
|
||||||
|
|
||||||
[
|
[
|
||||||
'group_name' => 'dashboard',
|
'group_name' => 'dashboard',
|
||||||
'permissions' => [
|
'permissions' => [
|
||||||
@@ -78,9 +79,6 @@ class RolePermissionSeeder extends Seeder
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Do same for the admin guard for tutorial purposes.
|
// Do same for the admin guard for tutorial purposes.
|
||||||
$admin = Admin::where('username', 'superadmin')->first();
|
$admin = Admin::where('username', 'superadmin')->first();
|
||||||
$roleSuperAdmin = $this->maybeCreateSuperAdminRole($admin);
|
$roleSuperAdmin = $this->maybeCreateSuperAdminRole($admin);
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeds;
|
||||||
|
|
||||||
|
use App\Models\Admin;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
use Spatie\Permission\Models\Permission;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RolePermissionSeeder.
|
||||||
|
*
|
||||||
|
* @see https://spatie.be/docs/laravel-permission/v5/basic-usage/multiple-guards
|
||||||
|
*
|
||||||
|
* @package App\Database\Seeds
|
||||||
|
*/
|
||||||
|
class RolePermissionSeeder2 extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Enable these options if you need same role and other permission for User Model
|
||||||
|
* Else, please follow the below steps for admin guard
|
||||||
|
*/
|
||||||
|
$permissions = [
|
||||||
|
[
|
||||||
|
'group_name' => 'rayon',
|
||||||
|
'permissions' => [
|
||||||
|
'rayon.view',
|
||||||
|
'rayon.edit',
|
||||||
|
'rayon.create',
|
||||||
|
'rayon.delete',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'group_name' => 'cost',
|
||||||
|
'permissions' => [
|
||||||
|
'cost.view',
|
||||||
|
'cost.edit',
|
||||||
|
'cost.create',
|
||||||
|
'cost.delete',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'group_name' => 'category',
|
||||||
|
'permissions' => [
|
||||||
|
'category.view',
|
||||||
|
'category.edit',
|
||||||
|
'category.create',
|
||||||
|
'category.delete',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Do same for the admin guard for tutorial purposes.
|
||||||
|
$admin = Admin::where('username', 'superadmin')->first();
|
||||||
|
$roleSuperAdmin = $this->maybeCreateSuperAdminRole($admin);
|
||||||
|
|
||||||
|
// Create and Assign Permissions
|
||||||
|
for ($i = 0; $i < count($permissions); $i++) {
|
||||||
|
$permissionGroup = $permissions[$i]['group_name'];
|
||||||
|
for ($j = 0; $j < count($permissions[$i]['permissions']); $j++) {
|
||||||
|
$permissionExist = Permission::where('name', $permissions[$i]['permissions'][$j])->first();
|
||||||
|
if (is_null($permissionExist)) {
|
||||||
|
$permission = Permission::create(
|
||||||
|
[
|
||||||
|
'name' => $permissions[$i]['permissions'][$j],
|
||||||
|
'group_name' => $permissionGroup,
|
||||||
|
'guard_name' => 'admin'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$roleSuperAdmin->givePermissionTo($permission);
|
||||||
|
$permission->assignRole($roleSuperAdmin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign super admin role permission to superadmin user
|
||||||
|
if ($admin) {
|
||||||
|
$admin->assignRole($roleSuperAdmin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function maybeCreateSuperAdminRole($admin): Role
|
||||||
|
{
|
||||||
|
if (is_null($admin)) {
|
||||||
|
$roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']);
|
||||||
|
} else {
|
||||||
|
$roleSuperAdmin = Role::where('name', 'superadmin')->where('guard_name', 'admin')->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($roleSuperAdmin)) {
|
||||||
|
$roleSuperAdmin = Role::create(['name' => 'superadmin', 'guard_name' => 'admin']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $roleSuperAdmin;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeds;
|
||||||
|
|
||||||
use App\User;
|
use App\User;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@@ -20,6 +22,7 @@ class UserSeeder extends Seeder
|
|||||||
$user->username = "user1";
|
$user->username = "user1";
|
||||||
$user->email = "user1@gmail.com";
|
$user->email = "user1@gmail.com";
|
||||||
$user->password = Hash::make('12345678');
|
$user->password = Hash::make('12345678');
|
||||||
|
$user->phone = "085112345678";
|
||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
@if (Session::has('success'))
|
@if (Session::has('success'))
|
||||||
<script>
|
<script>
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<div class="col-12 mt-5">
|
<div class="col-12 mt-5">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h4 class="header-title">{{ $pageInfo['title'] }}</h4>
|
<h4 class="header-title mb-4">{{ $pageInfo['title'] }}</h4>
|
||||||
@include('backend.layouts.partials.messages')
|
@include('backend.layouts.partials.messages')
|
||||||
|
|
||||||
<form action="{{ route('admin.admins.store') }}" method="POST">
|
<form action="{{ route('admin.admins.store') }}" method="POST">
|
||||||
@@ -84,7 +84,11 @@
|
|||||||
placeholder="Enter Username" required value="{{ old('username') }}">
|
placeholder="Enter Username" required value="{{ old('username') }}">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-md-6 col-sm-6">
|
||||||
|
<label for="phone">Phone</label>
|
||||||
|
<input type="text" class="form-control" id="phone" name="phone"
|
||||||
|
placeholder="Enter phone number" required value="{{ old('phone') }}">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,12 @@
|
|||||||
placeholder="Enter Username" required value="{{ $admin->username }}">
|
placeholder="Enter Username" required value="{{ $admin->username }}">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-md-6 col-sm-6">
|
||||||
|
<label for="phone">Phone</label>
|
||||||
|
<input type="text" class="form-control" id="phone" name="phone"
|
||||||
|
placeholder="Enter phone number" required value="{{ $admin->phone }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
Dashboard
|
Dashboard
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
|
||||||
@section('admin-content')
|
@section('admin-content')
|
||||||
<section class="content-header">
|
<section class="content-header">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Tambahkan Expense Up Country Baru</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<form>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Pilih Rayon</label>
|
||||||
|
<select class="form-control form-control-md">
|
||||||
|
<option value="">Pilih Rayon</option>
|
||||||
|
@foreach ($rayons as $rayon)
|
||||||
|
<option value="{{ $rayon->id }}">{{ $rayon->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tanggal</label>
|
||||||
|
<input type="date" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tujuan</label>
|
||||||
|
<input type="text" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Jarak</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Allowance</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Transport Dalam Kota</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Transport Antar Kota</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Hotel</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Total</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bukti 1</label>
|
||||||
|
<input type="file" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bukti 2</label>
|
||||||
|
<input type="file" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bukti 3</label>
|
||||||
|
<input type="file" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary ml-2">Submit</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Edit Expense Up Country</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<form>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Pilih Rayon</label>
|
||||||
|
<select class="form-control form-control-md">
|
||||||
|
<option value="">Pilih Rayon</option>
|
||||||
|
@foreach ($rayons as $rayon)
|
||||||
|
<option value="{{ $rayon->id }}">{{ $rayon->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tanggal</label>
|
||||||
|
<input type="date" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Tujuan</label>
|
||||||
|
<input type="text" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Jarak</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Allowance</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Transport Dalam Kota</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Transport Antar Kota</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Hotel</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Total</label>
|
||||||
|
<input type="number" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bukti 1</label>
|
||||||
|
<input type="file" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bukti 2</label>
|
||||||
|
<input type="file" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Bukti 3</label>
|
||||||
|
<input type="file" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary ml-2">Submit</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Forms Up Country</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="header-title float-left">List Data Forms Up Country Anda</h4>
|
||||||
|
<p class="float-right mb-2">
|
||||||
|
<a class="btn btn-primary text-white" href="">
|
||||||
|
Add New Expense Up Country
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<div class="dataTables_wrapper dt-bootstrap4 mt-2">
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<table id="dataTable"
|
||||||
|
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline"
|
||||||
|
style="width:100%">
|
||||||
|
<thead class="bg-light text-capitalize">
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Nama</th>
|
||||||
|
<th>Rayon</th>
|
||||||
|
<th>Tanggal</th>
|
||||||
|
<th>Tujuan</th>
|
||||||
|
<th>Jarak</th>
|
||||||
|
<th>Allowance</th>
|
||||||
|
<th>Transport Dalkot</th>
|
||||||
|
<th>Transport Ankot</th>
|
||||||
|
<th>Hotel</th>
|
||||||
|
<th>Bukti 1</th>
|
||||||
|
<th>Bukti 2</th>
|
||||||
|
<th>Bukti 3</th>
|
||||||
|
<th>Account Number</th>
|
||||||
|
<th>Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>1</td>
|
||||||
|
<td>John Doe</td>
|
||||||
|
<td>Rayon 1</td>
|
||||||
|
<td>2021-09-01</td>
|
||||||
|
<td>Surabaya</td>
|
||||||
|
<td>100</td>
|
||||||
|
<td>100000</td>
|
||||||
|
<td>10000</td>
|
||||||
|
<td>5000</td>
|
||||||
|
<td>50000</td>
|
||||||
|
<td>file1.jpg</td>
|
||||||
|
<td>file2.jpg</td>
|
||||||
|
<td>file3.jpg</td>
|
||||||
|
<td>1234567890</td>
|
||||||
|
<td>
|
||||||
|
<a href="" class="btn btn-warning btn-sm">
|
||||||
|
<i class="fas fa-edit text-white"></i>
|
||||||
|
</a>
|
||||||
|
<a href="" class="btn btn-danger btn-sm">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Tambahkan Category Baru</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" action="{{ route('admin.category.store') }}">
|
||||||
|
@csrf
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Nama</label>
|
||||||
|
<input type="text" class="form-control" name="name">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Account Number</label>
|
||||||
|
<input type="text" class="form-control" name="account_number">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Edit Category</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" action="{{ route('admin.category.update', $category->id) }}">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Nama</label>
|
||||||
|
<input type="text" class="form-control" name="name" value="{{ $category->name }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Account Number</label>
|
||||||
|
<input type="text" class="form-control" name="account_number" value="{{ $category->account_number }}">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Data Master Category</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="header-title float-left">List Data Category</h4>
|
||||||
|
<p class="float-right mb-2">
|
||||||
|
@if (Auth::user()->can('category.create'))
|
||||||
|
<a class="btn btn-primary text-white" href="{{ route('admin.category.create') }}">
|
||||||
|
Add New Category
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<div class="dataTables_wrapper dt-bootstrap4 mt-2">
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<table id="dataTable"
|
||||||
|
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline"
|
||||||
|
style="width:100%">
|
||||||
|
<thead class="bg-light text-capitalize">
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Nama</th>
|
||||||
|
<th>Account Number</th>
|
||||||
|
<th>Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($categories as $category)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $loop->index + 1 }}</td>
|
||||||
|
<td>{{ $category->name }}</td>
|
||||||
|
<td>{{ $category->account_number }}</td>
|
||||||
|
<td>
|
||||||
|
@if (auth()->user()->can('admin.edit'))
|
||||||
|
<a class="btn btn-success btn-sm text-white" href="{{ route('admin.category.edit', $category->id) }}">Edit</a>
|
||||||
|
@endif
|
||||||
|
@if (auth()->user()->can('admin.delete'))
|
||||||
|
<a class="btn btn-danger text-white btn-sm" href="javascript:void(0);"
|
||||||
|
onclick="event.preventDefault(); if(confirm('Are you sure you want to delete?')) { document.getElementById('delete-form-{{ $category->id }}').submit(); }">
|
||||||
|
{{ __('Delete') }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<form id="delete-form-{{ $category->id }}"
|
||||||
|
action="{{ route('admin.category.destroy', $category->id) }}"
|
||||||
|
method="POST" style="display: none;">
|
||||||
|
@method('DELETE')
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('scripts')
|
||||||
|
<script>
|
||||||
|
if ($('#dataTable').length) {
|
||||||
|
$('#dataTable').DataTable({
|
||||||
|
responsive: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Tambahkan Cost Centre Baru</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" action="{{ route('admin.cost.store') }}">
|
||||||
|
@csrf
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Code Cost Centre</label>
|
||||||
|
<input type="text" class="form-control" name="code">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Nama Cost Centre</label>
|
||||||
|
<input type="text" class="form-control" name="name">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Edit Cost Centre</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" action="{{ route('admin.cost.update', $cost->id) }}">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Code Cost Centre</label>
|
||||||
|
<input type="text" class="form-control" name="code" value="{{ $cost->code }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Nama Cost Centre</label>
|
||||||
|
<input type="text" class="form-control" name="name" value="{{ $cost->name }}">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Data Master Cost Centre</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="header-title float-left">List Data Cost Centre</h4>
|
||||||
|
<p class="float-right mb-2">
|
||||||
|
@if (Auth::user()->can('cost.create'))
|
||||||
|
<a class="btn btn-primary text-white" href="{{ route('admin.cost.create') }}">
|
||||||
|
Add New Cost Centre
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<div class="dataTables_wrapper dt-bootstrap4 mt-2">
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<table id="dataTable"
|
||||||
|
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline"
|
||||||
|
style="width:100%">
|
||||||
|
<thead class="bg-light text-capitalize">
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Code</th>
|
||||||
|
<th>Nama</th>
|
||||||
|
<th>Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($costs as $cost)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $loop->index + 1 }}</td>
|
||||||
|
<td>{{ $cost->code }}</td>
|
||||||
|
<td>{{ $cost->name }}</td>
|
||||||
|
<td>
|
||||||
|
@if (auth()->user()->can('admin.edit'))
|
||||||
|
<a class="btn btn-success btn-sm text-white" href="{{ route('admin.cost.edit', $cost->id) }}">Edit</a>
|
||||||
|
@endif
|
||||||
|
@if (auth()->user()->can('admin.delete'))
|
||||||
|
<a class="btn btn-danger text-white btn-sm" href="javascript:void(0);"
|
||||||
|
onclick="event.preventDefault(); if(confirm('Are you sure you want to delete?')) { document.getElementById('delete-form-{{ $cost->id }}').submit(); }">
|
||||||
|
{{ __('Delete') }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<form id="delete-form-{{ $cost->id }}"
|
||||||
|
action="{{ route('admin.cost.destroy', $cost->id) }}"
|
||||||
|
method="POST" style="display: none;">
|
||||||
|
@method('DELETE')
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('scripts')
|
||||||
|
<script>
|
||||||
|
if ($('#dataTable').length) {
|
||||||
|
$('#dataTable').DataTable({
|
||||||
|
responsive: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Tambahkan Rayon Baru</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" action="{{ route('admin.rayon.store') }}">
|
||||||
|
@csrf
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Code Rayon</label>
|
||||||
|
<input type="text" class="form-control" name="code">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Nama Rayon</label>
|
||||||
|
<input type="text" class="form-control" name="name">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Edit Rayon</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" action="{{ route('admin.rayon.update', $rayon->id) }}">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Code Rayon</label>
|
||||||
|
<input type="text" class="form-control" name="code" value="{{ $rayon->code }}">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Nama Rayon</label>
|
||||||
|
<input type="text" class="form-control" name="name" value="{{ $rayon->name }}">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Dashboard
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('admin-content')
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>Data Master Rayon</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="{{ route('dashboard.index') }}">Dashboard</a></li>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="card card-primary card-outline">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="header-title float-left">List Data Rayon</h4>
|
||||||
|
<p class="float-right mb-2">
|
||||||
|
@if (Auth::user()->can('rayon.create'))
|
||||||
|
<a class="btn btn-primary text-white" href="{{ route('admin.rayon.create') }}">
|
||||||
|
Add New Rayon
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<div class="dataTables_wrapper dt-bootstrap4 mt-2">
|
||||||
|
@include('backend.layouts.partials.messages')
|
||||||
|
<table id="dataTable"
|
||||||
|
class="table table-bordered table-striped table-head-fixed dataTable dtr-inline"
|
||||||
|
style="width:100%">
|
||||||
|
<thead class="bg-light text-capitalize">
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Code</th>
|
||||||
|
<th>Nama</th>
|
||||||
|
<th>Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($rayons as $rayon)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $loop->index + 1 }}</td>
|
||||||
|
<td>{{ $rayon->code }}</td>
|
||||||
|
<td>{{ $rayon->name }}</td>
|
||||||
|
<td>
|
||||||
|
@if (auth()->user()->can('admin.edit'))
|
||||||
|
<a class="btn btn-success btn-sm text-white" href="{{ route('admin.rayon.edit', $rayon->id) }}">Edit</a>
|
||||||
|
@endif
|
||||||
|
@if (auth()->user()->can('admin.delete'))
|
||||||
|
<a class="btn btn-danger text-white btn-sm" href="javascript:void(0);"
|
||||||
|
onclick="event.preventDefault(); if(confirm('Are you sure you want to delete?')) { document.getElementById('delete-form-{{ $rayon->id }}').submit(); }">
|
||||||
|
{{ __('Delete') }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<form id="delete-form-{{ $rayon->id }}"
|
||||||
|
action="{{ route('admin.rayon.destroy', $rayon->id) }}"
|
||||||
|
method="POST" style="display: none;">
|
||||||
|
@method('DELETE')
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('scripts')
|
||||||
|
<script>
|
||||||
|
if ($('#dataTable').length) {
|
||||||
|
$('#dataTable').DataTable({
|
||||||
|
responsive: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
@endsection
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
{{ $pageInfo['title'] }}
|
{{ $pageInfo['title'] }}
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
|
||||||
@section('admin-content')
|
@section('admin-content')
|
||||||
<section class="content-header">
|
<section class="content-header">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
@@ -63,10 +62,23 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@if (auth::user()->can('admin.edit'))
|
@if (auth()->user()->can('admin.edit'))
|
||||||
<a class="btn btn-success btn-sm text-white"
|
<a class="btn btn-success btn-sm text-white"
|
||||||
href="{{ route('admin.roles.edit', $role->id) }}">Edit</a>
|
href="{{ route('admin.roles.edit', $role->id) }}">Edit</a>
|
||||||
@endif
|
@endif
|
||||||
|
@if (auth()->user()->can('admin.delete'))
|
||||||
|
<a class="btn btn-danger text-white btn-sm" href="javascript:void(0);"
|
||||||
|
onclick="event.preventDefault(); if(confirm('Are you sure you want to delete?')) { document.getElementById('delete-form-{{ $role->id }}').submit(); }">
|
||||||
|
{{ __('Delete') }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<form id="delete-form-{{ $role->id }}"
|
||||||
|
action="{{ route('admin.roles.destroy', $role->id) }}"
|
||||||
|
method="POST" style="display: none;">
|
||||||
|
@method('DELETE')
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
<a class="btn btn-primary btn-sm text-white"
|
<a class="btn btn-primary btn-sm text-white"
|
||||||
href="{{ route('auth.menurole.index', $role->id) }}">Assign
|
href="{{ route('auth.menurole.index', $role->id) }}">Assign
|
||||||
Menus</a>
|
Menus</a>
|
||||||
|
|||||||
@@ -29,5 +29,4 @@
|
|||||||
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="{{ asset('js/global.function.js') }}"></script>
|
<script src="{{ asset('js/global.function.js') }}"></script>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<!-- sidebar menu area start -->
|
<!-- sidebar menu area start -->
|
||||||
@php
|
@php
|
||||||
$usr = Auth::guard('admin')->user();
|
$usr = Auth::guard('admin')->user();
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<nav class="mt-2">
|
<nav class="mt-2">
|
||||||
{!! $menu !!}
|
{!! $menu !!}
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
+41
-4
@@ -8,11 +8,13 @@ use App\Http\Controllers\GenerateDataMasterController;
|
|||||||
use App\Http\Controllers\Backend\DashboardController;
|
use App\Http\Controllers\Backend\DashboardController;
|
||||||
use App\Http\Controllers\Backend\RolesController;
|
use App\Http\Controllers\Backend\RolesController;
|
||||||
use App\Http\Controllers\Backend\MenuRoleController;
|
use App\Http\Controllers\Backend\MenuRoleController;
|
||||||
|
use App\Http\Controllers\Forms\FormUpCountryController;
|
||||||
|
use App\Http\Controllers\Master\RayonController;
|
||||||
|
use App\Http\Controllers\Master\CostCentreController;
|
||||||
|
use App\Http\Controllers\Master\CategoryController;
|
||||||
|
|
||||||
Auth::routes();
|
Auth::routes();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
|
Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
|
||||||
// Login Routes.
|
// Login Routes.
|
||||||
Route::post('/login/submit', [LoginController::class, 'login'])->name('login.submit');
|
Route::post('/login/submit', [LoginController::class, 'login'])->name('login.submit');
|
||||||
@@ -22,8 +24,6 @@ Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin routes
|
* Admin routes
|
||||||
*/
|
*/
|
||||||
@@ -31,10 +31,47 @@ Route::group(['prefix' => 'admin', 'as' => 'admin.', 'middleware' => ['auth:admi
|
|||||||
Route::resource('admins', AdminsController::class);
|
Route::resource('admins', AdminsController::class);
|
||||||
Route::resource('roles', RolesController::class);
|
Route::resource('roles', RolesController::class);
|
||||||
Route::get('/admin', [DashboardController::class, 'index'])->name('dashboard');
|
Route::get('/admin', [DashboardController::class, 'index'])->name('dashboard');
|
||||||
|
|
||||||
|
// Rayon
|
||||||
|
Route::get('/rayon', [RayonController::class, 'index'])->name('rayon.index');
|
||||||
|
Route::get('/rayon/create', [RayonController::class, 'create'])->name('rayon.create');
|
||||||
|
Route::post('/rayon/store', [RayonController::class, 'store'])->name('rayon.store');
|
||||||
|
Route::get('/rayon/edit/{id}', [RayonController::class, 'edit'])->name('rayon.edit');
|
||||||
|
Route::put('/rayon/update/{id}', [RayonController::class, 'update'])->name('rayon.update');
|
||||||
|
Route::delete('/rayon/destroy/{id}', [RayonController::class, 'destroy'])->name('rayon.destroy');
|
||||||
|
|
||||||
|
// Cost Centre
|
||||||
|
Route::get('/cost', [CostCentreController::class, 'index'])->name('cost.index');
|
||||||
|
Route::get('/cost/create', [CostCentreController::class, 'create'])->name('cost.create');
|
||||||
|
Route::post('/cost/store', [CostCentreController::class, 'store'])->name('cost.store');
|
||||||
|
Route::get('/cost/edit/{id}', [CostCentreController::class, 'edit'])->name('cost.edit');
|
||||||
|
Route::put('/cost/update/{id}', [CostCentreController::class, 'update'])->name('cost.update');
|
||||||
|
Route::delete('/cost/destroy/{id}', [CostCentreController::class, 'destroy'])->name('cost.destroy');
|
||||||
|
|
||||||
|
// Category
|
||||||
|
Route::get('/category', [CategoryController::class, 'index'])->name('category.index');
|
||||||
|
Route::get('/category/create', [CategoryController::class, 'create'])->name('category.create');
|
||||||
|
Route::post('/category/store', [CategoryController::class, 'store'])->name('category.store');
|
||||||
|
Route::get('/category/edit/{id}', [CategoryController::class, 'edit'])->name('category.edit');
|
||||||
|
Route::put('/category/update/{id}', [CategoryController::class, 'update'])->name('category.update');
|
||||||
|
Route::delete('/category/destroy/{id}', [CategoryController::class, 'destroy'])->name('category.destroy');
|
||||||
|
|
||||||
})->middleware(['auth:admin']);
|
})->middleware(['auth:admin']);
|
||||||
|
|
||||||
Route::middleware(['auth:admin', 'menu'])->group(function () {
|
Route::middleware(['auth:admin', 'menu'])->group(function () {
|
||||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard.index');
|
Route::get('/', [DashboardController::class, 'index'])->name('dashboard.index');
|
||||||
|
|
||||||
|
// Forms
|
||||||
|
Route::prefix('forms')->group(function () {
|
||||||
|
// Up Country
|
||||||
|
Route::get('/up-country', [FormUpCountryController::class, 'index'])->name('forms.up-country');
|
||||||
|
Route::get('/up-country/create', [FormUpCountryController::class, 'create'])->name('forms.up-country.create');
|
||||||
|
Route::post('/up-country/store', [FormUpCountryController::class, 'store'])->name('forms.up-country.store');
|
||||||
|
Route::get('/up-country/edit/{id}', [FormUpCountryController::class, 'edit'])->name('forms.up-country.edit');
|
||||||
|
Route::put('/up-country/update/{id}', [FormUpCountryController::class, 'update'])->name('forms.up-country.update');
|
||||||
|
Route::delete('/up-country/destroy/{id}', [FormUpCountryController::class, 'destroy'])->name('forms.up-country.destroy');
|
||||||
|
});
|
||||||
|
|
||||||
//Menu Role
|
//Menu Role
|
||||||
Route::get('/auth/menu-tree/{id}', [MenuRoleController::class, 'index'])->name('auth.menurole.index');
|
Route::get('/auth/menu-tree/{id}', [MenuRoleController::class, 'index'])->name('auth.menurole.index');
|
||||||
Route::post('/auth/menu-tree/submit', [MenuRoleController::class, 'saveMenu'])->name('auth.menurole.submit');
|
Route::post('/auth/menu-tree/submit', [MenuRoleController::class, 'saveMenu'])->name('auth.menurole.submit');
|
||||||
|
|||||||
Vendored
-25
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload.php @generated by Composer
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 50600) {
|
|
||||||
if (!headers_sent()) {
|
|
||||||
header('HTTP/1.1 500 Internal Server Error');
|
|
||||||
}
|
|
||||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
|
||||||
if (!ini_get('display_errors')) {
|
|
||||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
|
||||||
fwrite(STDERR, $err);
|
|
||||||
} elseif (!headers_sent()) {
|
|
||||||
echo $err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trigger_error(
|
|
||||||
$err,
|
|
||||||
E_USER_ERROR
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once __DIR__ . '/composer/autoload_real.php';
|
|
||||||
|
|
||||||
return ComposerAutoloaderInit626b9e7ddd47fb7eff9aaa53cce0c9ad::getLoader();
|
|
||||||
Vendored
-119
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../nesbot/carbon/bin/carbon)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = $this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/nesbot/carbon/bin/carbon');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/nesbot/carbon/bin/carbon';
|
|
||||||
Vendored
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/carbon
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
php "%BIN_TARGET%" %*
|
|
||||||
Vendored
-119
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../symfony/error-handler/Resources/bin/patch-type-declarations)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = $this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/error-handler/Resources/bin/patch-type-declarations');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/symfony/error-handler/Resources/bin/patch-type-declarations';
|
|
||||||
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/patch-type-declarations
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
php "%BIN_TARGET%" %*
|
|
||||||
Vendored
-119
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../nikic/php-parser/bin/php-parse)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = $this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse';
|
|
||||||
Vendored
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/php-parse
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
php "%BIN_TARGET%" %*
|
|
||||||
Vendored
-122
@@ -1,122 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../phpunit/phpunit/phpunit)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
$GLOBALS['__PHPUNIT_ISOLATION_EXCLUDE_LIST'] = $GLOBALS['__PHPUNIT_ISOLATION_BLACKLIST'] = array(realpath(__DIR__ . '/..'.'/phpunit/phpunit/phpunit'));
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = 'phpvfscomposer://'.$this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
$data = str_replace('__DIR__', var_export(dirname($this->realpath), true), $data);
|
|
||||||
$data = str_replace('__FILE__', var_export($this->realpath, true), $data);
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/phpunit/phpunit/phpunit');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/phpunit/phpunit/phpunit';
|
|
||||||
Vendored
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/phpunit
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
php "%BIN_TARGET%" %*
|
|
||||||
Vendored
-119
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../laravel/pint/builds/pint)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = $this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/laravel/pint/builds/pint');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/laravel/pint/builds/pint';
|
|
||||||
Vendored
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/pint
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
php "%BIN_TARGET%" %*
|
|
||||||
Vendored
-119
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../psy/psysh/bin/psysh)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = $this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/psy/psysh/bin/psysh');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/psy/psysh/bin/psysh';
|
|
||||||
Vendored
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/psysh
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
php "%BIN_TARGET%" %*
|
|
||||||
Vendored
-37
@@ -1,37 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
# Support bash to support `source` with fallback on $0 if this does not run with bash
|
|
||||||
# https://stackoverflow.com/a/35006505/6512
|
|
||||||
selfArg="$BASH_SOURCE"
|
|
||||||
if [ -z "$selfArg" ]; then
|
|
||||||
selfArg="$0"
|
|
||||||
fi
|
|
||||||
|
|
||||||
self=$(realpath $selfArg 2> /dev/null)
|
|
||||||
if [ -z "$self" ]; then
|
|
||||||
self="$selfArg"
|
|
||||||
fi
|
|
||||||
|
|
||||||
dir=$(cd "${self%[/\\]*}" > /dev/null; cd ../laravel/sail/bin && pwd)
|
|
||||||
|
|
||||||
if [ -d /proc/cygdrive ]; then
|
|
||||||
case $(which php) in
|
|
||||||
$(readlink -n /proc/cygdrive)/*)
|
|
||||||
# We are in Cygwin using Windows php, so the path must be translated
|
|
||||||
dir=$(cygpath -m "$dir");
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
export COMPOSER_RUNTIME_BIN_DIR="$(cd "${self%[/\\]*}" > /dev/null; pwd)"
|
|
||||||
|
|
||||||
# If bash is sourcing this file, we have to source the target as well
|
|
||||||
bashSource="$BASH_SOURCE"
|
|
||||||
if [ -n "$bashSource" ]; then
|
|
||||||
if [ "$bashSource" != "$0" ]; then
|
|
||||||
source "${dir}/sail" "$@"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
"${dir}/sail" "$@"
|
|
||||||
Vendored
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/../laravel/sail/bin/sail
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
bash "%BIN_TARGET%" %*
|
|
||||||
Vendored
-119
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../symfony/var-dumper/Resources/bin/var-dump-server)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = $this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server';
|
|
||||||
Vendored
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/var-dump-server
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
php "%BIN_TARGET%" %*
|
|
||||||
Vendored
-119
@@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../symfony/yaml/Resources/bin/yaml-lint)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = $this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint';
|
|
||||||
Vendored
-5
@@ -1,5 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
setlocal DISABLEDELAYEDEXPANSION
|
|
||||||
SET BIN_TARGET=%~dp0/yaml-lint
|
|
||||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
|
||||||
php "%BIN_TARGET%" %*
|
|
||||||
Vendored
-463
@@ -1,463 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
|
|
||||||
## [0.12.1](https://github.com/brick/math/releases/tag/0.12.1) - 2023-11-29
|
|
||||||
|
|
||||||
⚡️ **Performance improvements**
|
|
||||||
|
|
||||||
- `BigNumber::of()` is now faster, thanks to [@SebastienDug](https://github.com/SebastienDug) in [#77](https://github.com/brick/math/pull/77).
|
|
||||||
|
|
||||||
## [0.12.0](https://github.com/brick/math/releases/tag/0.12.0) - 2023-11-26
|
|
||||||
|
|
||||||
💥 **Breaking changes**
|
|
||||||
|
|
||||||
- Minimum PHP version is now 8.1
|
|
||||||
- `RoundingMode` is now an `enum`; if you're type-hinting rounding modes, you need to type-hint against `RoundingMode` instead of `int` now
|
|
||||||
- `BigNumber` classes do not implement the `Serializable` interface anymore (they use the [new custom object serialization mechanism](https://wiki.php.net/rfc/custom_object_serialization))
|
|
||||||
- The following breaking changes only affect you if you're creating your own `BigNumber` subclasses:
|
|
||||||
- the return type of `BigNumber::of()` is now `static`
|
|
||||||
- `BigNumber` has a new abstract method `from()`
|
|
||||||
- all `public` and `protected` functions of `BigNumber` are now `final`
|
|
||||||
|
|
||||||
## [0.11.0](https://github.com/brick/math/releases/tag/0.11.0) - 2023-01-16
|
|
||||||
|
|
||||||
💥 **Breaking changes**
|
|
||||||
|
|
||||||
- Minimum PHP version is now 8.0
|
|
||||||
- Methods accepting a union of types are now strongly typed<sup>*</sup>
|
|
||||||
- `MathException` now extends `Exception` instead of `RuntimeException`
|
|
||||||
|
|
||||||
<sup>* You may now run into type errors if you were passing `Stringable` objects to `of()` or any of the methods
|
|
||||||
internally calling `of()`, with `strict_types` enabled. You can fix this by casting `Stringable` objects to `string`
|
|
||||||
first.</sup>
|
|
||||||
|
|
||||||
## [0.10.2](https://github.com/brick/math/releases/tag/0.10.2) - 2022-08-11
|
|
||||||
|
|
||||||
👌 **Improvements**
|
|
||||||
|
|
||||||
- `BigRational::toFloat()` now simplifies the fraction before performing division (#73) thanks to @olsavmic
|
|
||||||
|
|
||||||
## [0.10.1](https://github.com/brick/math/releases/tag/0.10.1) - 2022-08-02
|
|
||||||
|
|
||||||
✨ **New features**
|
|
||||||
|
|
||||||
- `BigInteger::gcdMultiple()` returns the GCD of multiple `BigInteger` numbers
|
|
||||||
|
|
||||||
## [0.10.0](https://github.com/brick/math/releases/tag/0.10.0) - 2022-06-18
|
|
||||||
|
|
||||||
💥 **Breaking changes**
|
|
||||||
|
|
||||||
- Minimum PHP version is now 7.4
|
|
||||||
|
|
||||||
## [0.9.3](https://github.com/brick/math/releases/tag/0.9.3) - 2021-08-15
|
|
||||||
|
|
||||||
🚀 **Compatibility with PHP 8.1**
|
|
||||||
|
|
||||||
- Support for custom object serialization; this removes a warning on PHP 8.1 due to the `Serializable` interface being deprecated (#60) thanks @TRowbotham
|
|
||||||
|
|
||||||
## [0.9.2](https://github.com/brick/math/releases/tag/0.9.2) - 2021-01-20
|
|
||||||
|
|
||||||
🐛 **Bug fix**
|
|
||||||
|
|
||||||
- Incorrect results could be returned when using the BCMath calculator, with a default scale set with `bcscale()`, on PHP >= 7.2 (#55).
|
|
||||||
|
|
||||||
## [0.9.1](https://github.com/brick/math/releases/tag/0.9.1) - 2020-08-19
|
|
||||||
|
|
||||||
✨ **New features**
|
|
||||||
|
|
||||||
- `BigInteger::not()` returns the bitwise `NOT` value
|
|
||||||
|
|
||||||
🐛 **Bug fixes**
|
|
||||||
|
|
||||||
- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers
|
|
||||||
- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available
|
|
||||||
|
|
||||||
## [0.9.0](https://github.com/brick/math/releases/tag/0.9.0) - 2020-08-18
|
|
||||||
|
|
||||||
👌 **Improvements**
|
|
||||||
|
|
||||||
- `BigNumber::of()` now accepts `.123` and `123.` formats, both of which return a `BigDecimal`
|
|
||||||
|
|
||||||
💥 **Breaking changes**
|
|
||||||
|
|
||||||
- Deprecated method `BigInteger::powerMod()` has been removed - use `modPow()` instead
|
|
||||||
- Deprecated method `BigInteger::parse()` has been removed - use `fromBase()` instead
|
|
||||||
|
|
||||||
## [0.8.17](https://github.com/brick/math/releases/tag/0.8.17) - 2020-08-19
|
|
||||||
|
|
||||||
🐛 **Bug fix**
|
|
||||||
|
|
||||||
- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers
|
|
||||||
- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available
|
|
||||||
|
|
||||||
## [0.8.16](https://github.com/brick/math/releases/tag/0.8.16) - 2020-08-18
|
|
||||||
|
|
||||||
🚑 **Critical fix**
|
|
||||||
|
|
||||||
- This version reintroduces the deprecated `BigInteger::parse()` method, that has been removed by mistake in version `0.8.9` and should have lasted for the whole `0.8` release cycle.
|
|
||||||
|
|
||||||
✨ **New features**
|
|
||||||
|
|
||||||
- `BigInteger::modInverse()` calculates a modular multiplicative inverse
|
|
||||||
- `BigInteger::fromBytes()` creates a `BigInteger` from a byte string
|
|
||||||
- `BigInteger::toBytes()` converts a `BigInteger` to a byte string
|
|
||||||
- `BigInteger::randomBits()` creates a pseudo-random `BigInteger` of a given bit length
|
|
||||||
- `BigInteger::randomRange()` creates a pseudo-random `BigInteger` between two bounds
|
|
||||||
|
|
||||||
💩 **Deprecations**
|
|
||||||
|
|
||||||
- `BigInteger::powerMod()` is now deprecated in favour of `modPow()`
|
|
||||||
|
|
||||||
## [0.8.15](https://github.com/brick/math/releases/tag/0.8.15) - 2020-04-15
|
|
||||||
|
|
||||||
🐛 **Fixes**
|
|
||||||
|
|
||||||
- added missing `ext-json` requirement, due to `BigNumber` implementing `JsonSerializable`
|
|
||||||
|
|
||||||
⚡️ **Optimizations**
|
|
||||||
|
|
||||||
- additional optimization in `BigInteger::remainder()`
|
|
||||||
|
|
||||||
## [0.8.14](https://github.com/brick/math/releases/tag/0.8.14) - 2020-02-18
|
|
||||||
|
|
||||||
✨ **New features**
|
|
||||||
|
|
||||||
- `BigInteger::getLowestSetBit()` returns the index of the rightmost one bit
|
|
||||||
|
|
||||||
## [0.8.13](https://github.com/brick/math/releases/tag/0.8.13) - 2020-02-16
|
|
||||||
|
|
||||||
✨ **New features**
|
|
||||||
|
|
||||||
- `BigInteger::isEven()` tests whether the number is even
|
|
||||||
- `BigInteger::isOdd()` tests whether the number is odd
|
|
||||||
- `BigInteger::testBit()` tests if a bit is set
|
|
||||||
- `BigInteger::getBitLength()` returns the number of bits in the minimal representation of the number
|
|
||||||
|
|
||||||
## [0.8.12](https://github.com/brick/math/releases/tag/0.8.12) - 2020-02-03
|
|
||||||
|
|
||||||
🛠️ **Maintenance release**
|
|
||||||
|
|
||||||
Classes are now annotated for better static analysis with [psalm](https://psalm.dev/).
|
|
||||||
|
|
||||||
This is a maintenance release: no bug fixes, no new features, no breaking changes.
|
|
||||||
|
|
||||||
## [0.8.11](https://github.com/brick/math/releases/tag/0.8.11) - 2020-01-23
|
|
||||||
|
|
||||||
✨ **New feature**
|
|
||||||
|
|
||||||
`BigInteger::powerMod()` performs a power-with-modulo operation. Useful for crypto.
|
|
||||||
|
|
||||||
## [0.8.10](https://github.com/brick/math/releases/tag/0.8.10) - 2020-01-21
|
|
||||||
|
|
||||||
✨ **New feature**
|
|
||||||
|
|
||||||
`BigInteger::mod()` returns the **modulo** of two numbers. The *modulo* differs from the *remainder* when the signs of the operands are different.
|
|
||||||
|
|
||||||
## [0.8.9](https://github.com/brick/math/releases/tag/0.8.9) - 2020-01-08
|
|
||||||
|
|
||||||
⚡️ **Performance improvements**
|
|
||||||
|
|
||||||
A few additional optimizations in `BigInteger` and `BigDecimal` when one of the operands can be returned as is. Thanks to @tomtomsen in #24.
|
|
||||||
|
|
||||||
## [0.8.8](https://github.com/brick/math/releases/tag/0.8.8) - 2019-04-25
|
|
||||||
|
|
||||||
🐛 **Bug fixes**
|
|
||||||
|
|
||||||
- `BigInteger::toBase()` could return an empty string for zero values (BCMath & Native calculators only, GMP calculator unaffected)
|
|
||||||
|
|
||||||
✨ **New features**
|
|
||||||
|
|
||||||
- `BigInteger::toArbitraryBase()` converts a number to an arbitrary base, using a custom alphabet
|
|
||||||
- `BigInteger::fromArbitraryBase()` converts a string in an arbitrary base, using a custom alphabet, back to a number
|
|
||||||
|
|
||||||
These methods can be used as the foundation to convert strings between different bases/alphabets, using BigInteger as an intermediate representation.
|
|
||||||
|
|
||||||
💩 **Deprecations**
|
|
||||||
|
|
||||||
- `BigInteger::parse()` is now deprecated in favour of `fromBase()`
|
|
||||||
|
|
||||||
`BigInteger::fromBase()` works the same way as `parse()`, with 2 minor differences:
|
|
||||||
|
|
||||||
- the `$base` parameter is required, it does not default to `10`
|
|
||||||
- it throws a `NumberFormatException` instead of an `InvalidArgumentException` when the number is malformed
|
|
||||||
|
|
||||||
## [0.8.7](https://github.com/brick/math/releases/tag/0.8.7) - 2019-04-20
|
|
||||||
|
|
||||||
**Improvements**
|
|
||||||
|
|
||||||
- Safer conversion from `float` when using custom locales
|
|
||||||
- **Much faster** `NativeCalculator` implementation 🚀
|
|
||||||
|
|
||||||
You can expect **at least a 3x performance improvement** for common arithmetic operations when using the library on systems without GMP or BCMath; it gets exponentially faster on multiplications with a high number of digits. This is due to calculations now being performed on whole blocks of digits (the block size depending on the platform, 32-bit or 64-bit) instead of digit-by-digit as before.
|
|
||||||
|
|
||||||
## [0.8.6](https://github.com/brick/math/releases/tag/0.8.6) - 2019-04-11
|
|
||||||
|
|
||||||
**New method**
|
|
||||||
|
|
||||||
`BigNumber::sum()` returns the sum of one or more numbers.
|
|
||||||
|
|
||||||
## [0.8.5](https://github.com/brick/math/releases/tag/0.8.5) - 2019-02-12
|
|
||||||
|
|
||||||
**Bug fix**: `of()` factory methods could fail when passing a `float` in environments using a `LC_NUMERIC` locale with a decimal separator other than `'.'` (#20).
|
|
||||||
|
|
||||||
Thanks @manowark 👍
|
|
||||||
|
|
||||||
## [0.8.4](https://github.com/brick/math/releases/tag/0.8.4) - 2018-12-07
|
|
||||||
|
|
||||||
**New method**
|
|
||||||
|
|
||||||
`BigDecimal::sqrt()` calculates the square root of a decimal number, to a given scale.
|
|
||||||
|
|
||||||
## [0.8.3](https://github.com/brick/math/releases/tag/0.8.3) - 2018-12-06
|
|
||||||
|
|
||||||
**New method**
|
|
||||||
|
|
||||||
`BigInteger::sqrt()` calculates the square root of a number (thanks @peter279k).
|
|
||||||
|
|
||||||
**New exception**
|
|
||||||
|
|
||||||
`NegativeNumberException` is thrown when calling `sqrt()` on a negative number.
|
|
||||||
|
|
||||||
## [0.8.2](https://github.com/brick/math/releases/tag/0.8.2) - 2018-11-08
|
|
||||||
|
|
||||||
**Performance update**
|
|
||||||
|
|
||||||
- Further improvement of `toInt()` performance
|
|
||||||
- `NativeCalculator` can now perform some multiplications more efficiently
|
|
||||||
|
|
||||||
## [0.8.1](https://github.com/brick/math/releases/tag/0.8.1) - 2018-11-07
|
|
||||||
|
|
||||||
Performance optimization of `toInt()` methods.
|
|
||||||
|
|
||||||
## [0.8.0](https://github.com/brick/math/releases/tag/0.8.0) - 2018-10-13
|
|
||||||
|
|
||||||
**Breaking changes**
|
|
||||||
|
|
||||||
The following deprecated methods have been removed. Use the new method name instead:
|
|
||||||
|
|
||||||
| Method removed | Replacement method |
|
|
||||||
| --- | --- |
|
|
||||||
| `BigDecimal::getIntegral()` | `BigDecimal::getIntegralPart()` |
|
|
||||||
| `BigDecimal::getFraction()` | `BigDecimal::getFractionalPart()` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**New features**
|
|
||||||
|
|
||||||
`BigInteger` has been augmented with 5 new methods for bitwise operations:
|
|
||||||
|
|
||||||
| New method | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `and()` | performs a bitwise `AND` operation on two numbers |
|
|
||||||
| `or()` | performs a bitwise `OR` operation on two numbers |
|
|
||||||
| `xor()` | performs a bitwise `XOR` operation on two numbers |
|
|
||||||
| `shiftedLeft()` | returns the number shifted left by a number of bits |
|
|
||||||
| `shiftedRight()` | returns the number shifted right by a number of bits |
|
|
||||||
|
|
||||||
Thanks to @DASPRiD 👍
|
|
||||||
|
|
||||||
## [0.7.3](https://github.com/brick/math/releases/tag/0.7.3) - 2018-08-20
|
|
||||||
|
|
||||||
**New method:** `BigDecimal::hasNonZeroFractionalPart()`
|
|
||||||
|
|
||||||
**Renamed/deprecated methods:**
|
|
||||||
|
|
||||||
- `BigDecimal::getIntegral()` has been renamed to `getIntegralPart()` and is now deprecated
|
|
||||||
- `BigDecimal::getFraction()` has been renamed to `getFractionalPart()` and is now deprecated
|
|
||||||
|
|
||||||
## [0.7.2](https://github.com/brick/math/releases/tag/0.7.2) - 2018-07-21
|
|
||||||
|
|
||||||
**Performance update**
|
|
||||||
|
|
||||||
`BigInteger::parse()` and `toBase()` now use GMP's built-in base conversion features when available.
|
|
||||||
|
|
||||||
## [0.7.1](https://github.com/brick/math/releases/tag/0.7.1) - 2018-03-01
|
|
||||||
|
|
||||||
This is a maintenance release, no code has been changed.
|
|
||||||
|
|
||||||
- When installed with `--no-dev`, the autoloader does not autoload tests anymore
|
|
||||||
- Tests and other files unnecessary for production are excluded from the dist package
|
|
||||||
|
|
||||||
This will help make installations more compact.
|
|
||||||
|
|
||||||
## [0.7.0](https://github.com/brick/math/releases/tag/0.7.0) - 2017-10-02
|
|
||||||
|
|
||||||
Methods renamed:
|
|
||||||
|
|
||||||
- `BigNumber:sign()` has been renamed to `getSign()`
|
|
||||||
- `BigDecimal::unscaledValue()` has been renamed to `getUnscaledValue()`
|
|
||||||
- `BigDecimal::scale()` has been renamed to `getScale()`
|
|
||||||
- `BigDecimal::integral()` has been renamed to `getIntegral()`
|
|
||||||
- `BigDecimal::fraction()` has been renamed to `getFraction()`
|
|
||||||
- `BigRational::numerator()` has been renamed to `getNumerator()`
|
|
||||||
- `BigRational::denominator()` has been renamed to `getDenominator()`
|
|
||||||
|
|
||||||
Classes renamed:
|
|
||||||
|
|
||||||
- `ArithmeticException` has been renamed to `MathException`
|
|
||||||
|
|
||||||
## [0.6.2](https://github.com/brick/math/releases/tag/0.6.2) - 2017-10-02
|
|
||||||
|
|
||||||
The base class for all exceptions is now `MathException`.
|
|
||||||
`ArithmeticException` has been deprecated, and will be removed in 0.7.0.
|
|
||||||
|
|
||||||
## [0.6.1](https://github.com/brick/math/releases/tag/0.6.1) - 2017-10-02
|
|
||||||
|
|
||||||
A number of methods have been renamed:
|
|
||||||
|
|
||||||
- `BigNumber:sign()` is deprecated; use `getSign()` instead
|
|
||||||
- `BigDecimal::unscaledValue()` is deprecated; use `getUnscaledValue()` instead
|
|
||||||
- `BigDecimal::scale()` is deprecated; use `getScale()` instead
|
|
||||||
- `BigDecimal::integral()` is deprecated; use `getIntegral()` instead
|
|
||||||
- `BigDecimal::fraction()` is deprecated; use `getFraction()` instead
|
|
||||||
- `BigRational::numerator()` is deprecated; use `getNumerator()` instead
|
|
||||||
- `BigRational::denominator()` is deprecated; use `getDenominator()` instead
|
|
||||||
|
|
||||||
The old methods will be removed in version 0.7.0.
|
|
||||||
|
|
||||||
## [0.6.0](https://github.com/brick/math/releases/tag/0.6.0) - 2017-08-25
|
|
||||||
|
|
||||||
- Minimum PHP version is now [7.1](https://gophp71.org/); for PHP 5.6 and PHP 7.0 support, use version `0.5`
|
|
||||||
- Deprecated method `BigDecimal::withScale()` has been removed; use `toScale()` instead
|
|
||||||
- Method `BigNumber::toInteger()` has been renamed to `toInt()`
|
|
||||||
|
|
||||||
## [0.5.4](https://github.com/brick/math/releases/tag/0.5.4) - 2016-10-17
|
|
||||||
|
|
||||||
`BigNumber` classes now implement [JsonSerializable](http://php.net/manual/en/class.jsonserializable.php).
|
|
||||||
The JSON output is always a string.
|
|
||||||
|
|
||||||
## [0.5.3](https://github.com/brick/math/releases/tag/0.5.3) - 2016-03-31
|
|
||||||
|
|
||||||
This is a bugfix release. Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
|
||||||
|
|
||||||
## [0.5.2](https://github.com/brick/math/releases/tag/0.5.2) - 2015-08-06
|
|
||||||
|
|
||||||
The `$scale` parameter of `BigDecimal::dividedBy()` is now optional again.
|
|
||||||
|
|
||||||
## [0.5.1](https://github.com/brick/math/releases/tag/0.5.1) - 2015-07-05
|
|
||||||
|
|
||||||
**New method: `BigNumber::toScale()`**
|
|
||||||
|
|
||||||
This allows to convert any `BigNumber` to a `BigDecimal` with a given scale, using rounding if necessary.
|
|
||||||
|
|
||||||
## [0.5.0](https://github.com/brick/math/releases/tag/0.5.0) - 2015-07-04
|
|
||||||
|
|
||||||
**New features**
|
|
||||||
- Common `BigNumber` interface for all classes, with the following methods:
|
|
||||||
- `sign()` and derived methods (`isZero()`, `isPositive()`, ...)
|
|
||||||
- `compareTo()` and derived methods (`isEqualTo()`, `isGreaterThan()`, ...) that work across different `BigNumber` types
|
|
||||||
- `toBigInteger()`, `toBigDecimal()`, `toBigRational`() conversion methods
|
|
||||||
- `toInteger()` and `toFloat()` conversion methods to native types
|
|
||||||
- Unified `of()` behaviour: every class now accepts any type of number, provided that it can be safely converted to the current type
|
|
||||||
- New method: `BigDecimal::exactlyDividedBy()`; this method automatically computes the scale of the result, provided that the division yields a finite number of digits
|
|
||||||
- New methods: `BigRational::quotient()` and `remainder()`
|
|
||||||
- Fine-grained exceptions: `DivisionByZeroException`, `RoundingNecessaryException`, `NumberFormatException`
|
|
||||||
- Factory methods `zero()`, `one()` and `ten()` available in all classes
|
|
||||||
- Rounding mode reintroduced in `BigInteger::dividedBy()`
|
|
||||||
|
|
||||||
This release also comes with many performance improvements.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Breaking changes**
|
|
||||||
- `BigInteger`:
|
|
||||||
- `getSign()` is renamed to `sign()`
|
|
||||||
- `toString()` is renamed to `toBase()`
|
|
||||||
- `BigInteger::dividedBy()` now throws an exception by default if the remainder is not zero; use `quotient()` to get the previous behaviour
|
|
||||||
- `BigDecimal`:
|
|
||||||
- `getSign()` is renamed to `sign()`
|
|
||||||
- `getUnscaledValue()` is renamed to `unscaledValue()`
|
|
||||||
- `getScale()` is renamed to `scale()`
|
|
||||||
- `getIntegral()` is renamed to `integral()`
|
|
||||||
- `getFraction()` is renamed to `fraction()`
|
|
||||||
- `divideAndRemainder()` is renamed to `quotientAndRemainder()`
|
|
||||||
- `dividedBy()` now takes a **mandatory** `$scale` parameter **before** the rounding mode
|
|
||||||
- `toBigInteger()` does not accept a `$roundingMode` parameter anymore
|
|
||||||
- `toBigRational()` does not simplify the fraction anymore; explicitly add `->simplified()` to get the previous behaviour
|
|
||||||
- `BigRational`:
|
|
||||||
- `getSign()` is renamed to `sign()`
|
|
||||||
- `getNumerator()` is renamed to `numerator()`
|
|
||||||
- `getDenominator()` is renamed to `denominator()`
|
|
||||||
- `of()` is renamed to `nd()`, while `parse()` is renamed to `of()`
|
|
||||||
- Miscellaneous:
|
|
||||||
- `ArithmeticException` is moved to an `Exception\` sub-namespace
|
|
||||||
- `of()` factory methods now throw `NumberFormatException` instead of `InvalidArgumentException`
|
|
||||||
|
|
||||||
## [0.4.3](https://github.com/brick/math/releases/tag/0.4.3) - 2016-03-31
|
|
||||||
|
|
||||||
Backport of two bug fixes from the 0.5 branch:
|
|
||||||
- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected
|
|
||||||
- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
|
||||||
|
|
||||||
## [0.4.2](https://github.com/brick/math/releases/tag/0.4.2) - 2015-06-16
|
|
||||||
|
|
||||||
New method: `BigDecimal::stripTrailingZeros()`
|
|
||||||
|
|
||||||
## [0.4.1](https://github.com/brick/math/releases/tag/0.4.1) - 2015-06-12
|
|
||||||
|
|
||||||
Introducing a `BigRational` class, to perform calculations on fractions of any size.
|
|
||||||
|
|
||||||
## [0.4.0](https://github.com/brick/math/releases/tag/0.4.0) - 2015-06-12
|
|
||||||
|
|
||||||
Rounding modes have been removed from `BigInteger`, and are now a concept specific to `BigDecimal`.
|
|
||||||
|
|
||||||
`BigInteger::dividedBy()` now always returns the quotient of the division.
|
|
||||||
|
|
||||||
## [0.3.5](https://github.com/brick/math/releases/tag/0.3.5) - 2016-03-31
|
|
||||||
|
|
||||||
Backport of two bug fixes from the 0.5 branch:
|
|
||||||
|
|
||||||
- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected
|
|
||||||
- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
|
||||||
|
|
||||||
## [0.3.4](https://github.com/brick/math/releases/tag/0.3.4) - 2015-06-11
|
|
||||||
|
|
||||||
New methods:
|
|
||||||
- `BigInteger::remainder()` returns the remainder of a division only
|
|
||||||
- `BigInteger::gcd()` returns the greatest common divisor of two numbers
|
|
||||||
|
|
||||||
## [0.3.3](https://github.com/brick/math/releases/tag/0.3.3) - 2015-06-07
|
|
||||||
|
|
||||||
Fix `toString()` not handling negative numbers.
|
|
||||||
|
|
||||||
## [0.3.2](https://github.com/brick/math/releases/tag/0.3.2) - 2015-06-07
|
|
||||||
|
|
||||||
`BigInteger` and `BigDecimal` now have a `getSign()` method that returns:
|
|
||||||
- `-1` if the number is negative
|
|
||||||
- `0` if the number is zero
|
|
||||||
- `1` if the number is positive
|
|
||||||
|
|
||||||
## [0.3.1](https://github.com/brick/math/releases/tag/0.3.1) - 2015-06-05
|
|
||||||
|
|
||||||
Minor performance improvements
|
|
||||||
|
|
||||||
## [0.3.0](https://github.com/brick/math/releases/tag/0.3.0) - 2015-06-04
|
|
||||||
|
|
||||||
The `$roundingMode` and `$scale` parameters have been swapped in `BigDecimal::dividedBy()`.
|
|
||||||
|
|
||||||
## [0.2.2](https://github.com/brick/math/releases/tag/0.2.2) - 2015-06-04
|
|
||||||
|
|
||||||
Stronger immutability guarantee for `BigInteger` and `BigDecimal`.
|
|
||||||
|
|
||||||
So far, it would have been possible to break immutability of these classes by calling the `unserialize()` internal function. This release fixes that.
|
|
||||||
|
|
||||||
## [0.2.1](https://github.com/brick/math/releases/tag/0.2.1) - 2015-06-02
|
|
||||||
|
|
||||||
Added `BigDecimal::divideAndRemainder()`
|
|
||||||
|
|
||||||
## [0.2.0](https://github.com/brick/math/releases/tag/0.2.0) - 2015-05-22
|
|
||||||
|
|
||||||
- `min()` and `max()` do not accept an `array` anymore, but a variable number of parameters
|
|
||||||
- **minimum PHP version is now 5.6**
|
|
||||||
- continuous integration with PHP 7
|
|
||||||
|
|
||||||
## [0.1.1](https://github.com/brick/math/releases/tag/0.1.1) - 2014-09-01
|
|
||||||
|
|
||||||
- Added `BigInteger::power()`
|
|
||||||
- Added HHVM support
|
|
||||||
|
|
||||||
## [0.1.0](https://github.com/brick/math/releases/tag/0.1.0) - 2014-08-31
|
|
||||||
|
|
||||||
First beta release.
|
|
||||||
|
|
||||||
Vendored
-20
@@ -1,20 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2013-present Benjamin Morel
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
Vendored
-39
@@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "brick/math",
|
|
||||||
"description": "Arbitrary-precision arithmetic library",
|
|
||||||
"type": "library",
|
|
||||||
"keywords": [
|
|
||||||
"Brick",
|
|
||||||
"Math",
|
|
||||||
"Mathematics",
|
|
||||||
"Arbitrary-precision",
|
|
||||||
"Arithmetic",
|
|
||||||
"BigInteger",
|
|
||||||
"BigDecimal",
|
|
||||||
"BigRational",
|
|
||||||
"BigNumber",
|
|
||||||
"Bignum",
|
|
||||||
"Decimal",
|
|
||||||
"Rational",
|
|
||||||
"Integer"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"require": {
|
|
||||||
"php": "^8.1"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^10.1",
|
|
||||||
"php-coveralls/php-coveralls": "^2.2",
|
|
||||||
"vimeo/psalm": "5.16.0"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Brick\\Math\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload-dev": {
|
|
||||||
"psr-4": {
|
|
||||||
"Brick\\Math\\Tests\\": "tests/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-754
@@ -1,754 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Brick\Math;
|
|
||||||
|
|
||||||
use Brick\Math\Exception\DivisionByZeroException;
|
|
||||||
use Brick\Math\Exception\MathException;
|
|
||||||
use Brick\Math\Exception\NegativeNumberException;
|
|
||||||
use Brick\Math\Internal\Calculator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Immutable, arbitrary-precision signed decimal numbers.
|
|
||||||
*
|
|
||||||
* @psalm-immutable
|
|
||||||
*/
|
|
||||||
final class BigDecimal extends BigNumber
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The unscaled value of this decimal number.
|
|
||||||
*
|
|
||||||
* This is a string of digits with an optional leading minus sign.
|
|
||||||
* No leading zero must be present.
|
|
||||||
* No leading minus sign must be present if the value is 0.
|
|
||||||
*/
|
|
||||||
private readonly string $value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The scale (number of digits after the decimal point) of this decimal number.
|
|
||||||
*
|
|
||||||
* This must be zero or more.
|
|
||||||
*/
|
|
||||||
private readonly int $scale;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Protected constructor. Use a factory method to obtain an instance.
|
|
||||||
*
|
|
||||||
* @param string $value The unscaled value, validated.
|
|
||||||
* @param int $scale The scale, validated.
|
|
||||||
*/
|
|
||||||
protected function __construct(string $value, int $scale = 0)
|
|
||||||
{
|
|
||||||
$this->value = $value;
|
|
||||||
$this->scale = $scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
protected static function from(BigNumber $number): static
|
|
||||||
{
|
|
||||||
return $number->toBigDecimal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a BigDecimal from an unscaled value and a scale.
|
|
||||||
*
|
|
||||||
* Example: `(12345, 3)` will result in the BigDecimal `12.345`.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $value The unscaled value. Must be convertible to a BigInteger.
|
|
||||||
* @param int $scale The scale of the number, positive or zero.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException If the scale is negative.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function ofUnscaledValue(BigNumber|int|float|string $value, int $scale = 0) : BigDecimal
|
|
||||||
{
|
|
||||||
if ($scale < 0) {
|
|
||||||
throw new \InvalidArgumentException('The scale cannot be negative.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigDecimal((string) BigInteger::of($value), $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a BigDecimal representing zero, with a scale of zero.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function zero() : BigDecimal
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-suppress ImpureStaticVariable
|
|
||||||
* @var BigDecimal|null $zero
|
|
||||||
*/
|
|
||||||
static $zero;
|
|
||||||
|
|
||||||
if ($zero === null) {
|
|
||||||
$zero = new BigDecimal('0');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a BigDecimal representing one, with a scale of zero.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function one() : BigDecimal
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-suppress ImpureStaticVariable
|
|
||||||
* @var BigDecimal|null $one
|
|
||||||
*/
|
|
||||||
static $one;
|
|
||||||
|
|
||||||
if ($one === null) {
|
|
||||||
$one = new BigDecimal('1');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $one;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a BigDecimal representing ten, with a scale of zero.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function ten() : BigDecimal
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-suppress ImpureStaticVariable
|
|
||||||
* @var BigDecimal|null $ten
|
|
||||||
*/
|
|
||||||
static $ten;
|
|
||||||
|
|
||||||
if ($ten === null) {
|
|
||||||
$ten = new BigDecimal('10');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ten;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the sum of this number and the given one.
|
|
||||||
*
|
|
||||||
* The result has a scale of `max($this->scale, $that->scale)`.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigDecimal.
|
|
||||||
*
|
|
||||||
* @throws MathException If the number is not valid, or is not convertible to a BigDecimal.
|
|
||||||
*/
|
|
||||||
public function plus(BigNumber|int|float|string $that) : BigDecimal
|
|
||||||
{
|
|
||||||
$that = BigDecimal::of($that);
|
|
||||||
|
|
||||||
if ($that->value === '0' && $that->scale <= $this->scale) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->value === '0' && $this->scale <= $that->scale) {
|
|
||||||
return $that;
|
|
||||||
}
|
|
||||||
|
|
||||||
[$a, $b] = $this->scaleValues($this, $that);
|
|
||||||
|
|
||||||
$value = Calculator::get()->add($a, $b);
|
|
||||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
|
||||||
|
|
||||||
return new BigDecimal($value, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the difference of this number and the given one.
|
|
||||||
*
|
|
||||||
* The result has a scale of `max($this->scale, $that->scale)`.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigDecimal.
|
|
||||||
*
|
|
||||||
* @throws MathException If the number is not valid, or is not convertible to a BigDecimal.
|
|
||||||
*/
|
|
||||||
public function minus(BigNumber|int|float|string $that) : BigDecimal
|
|
||||||
{
|
|
||||||
$that = BigDecimal::of($that);
|
|
||||||
|
|
||||||
if ($that->value === '0' && $that->scale <= $this->scale) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
[$a, $b] = $this->scaleValues($this, $that);
|
|
||||||
|
|
||||||
$value = Calculator::get()->sub($a, $b);
|
|
||||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
|
||||||
|
|
||||||
return new BigDecimal($value, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the product of this number and the given one.
|
|
||||||
*
|
|
||||||
* The result has a scale of `$this->scale + $that->scale`.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigDecimal.
|
|
||||||
*
|
|
||||||
* @throws MathException If the multiplier is not a valid number, or is not convertible to a BigDecimal.
|
|
||||||
*/
|
|
||||||
public function multipliedBy(BigNumber|int|float|string $that) : BigDecimal
|
|
||||||
{
|
|
||||||
$that = BigDecimal::of($that);
|
|
||||||
|
|
||||||
if ($that->value === '1' && $that->scale === 0) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->value === '1' && $this->scale === 0) {
|
|
||||||
return $that;
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = Calculator::get()->mul($this->value, $that->value);
|
|
||||||
$scale = $this->scale + $that->scale;
|
|
||||||
|
|
||||||
return new BigDecimal($value, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the result of the division of this number by the given one, at the given scale.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The divisor.
|
|
||||||
* @param int|null $scale The desired scale, or null to use the scale of this number.
|
|
||||||
* @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException If the scale or rounding mode is invalid.
|
|
||||||
* @throws MathException If the number is invalid, is zero, or rounding was necessary.
|
|
||||||
*/
|
|
||||||
public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
|
||||||
{
|
|
||||||
$that = BigDecimal::of($that);
|
|
||||||
|
|
||||||
if ($that->isZero()) {
|
|
||||||
throw DivisionByZeroException::divisionByZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($scale === null) {
|
|
||||||
$scale = $this->scale;
|
|
||||||
} elseif ($scale < 0) {
|
|
||||||
throw new \InvalidArgumentException('Scale cannot be negative.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($that->value === '1' && $that->scale === 0 && $scale === $this->scale) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$p = $this->valueWithMinScale($that->scale + $scale);
|
|
||||||
$q = $that->valueWithMinScale($this->scale - $scale);
|
|
||||||
|
|
||||||
$result = Calculator::get()->divRound($p, $q, $roundingMode);
|
|
||||||
|
|
||||||
return new BigDecimal($result, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the exact result of the division of this number by the given one.
|
|
||||||
*
|
|
||||||
* The scale of the result is automatically calculated to fit all the fraction digits.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
|
||||||
*
|
|
||||||
* @throws MathException If the divisor is not a valid number, is not convertible to a BigDecimal, is zero,
|
|
||||||
* or the result yields an infinite number of digits.
|
|
||||||
*/
|
|
||||||
public function exactlyDividedBy(BigNumber|int|float|string $that) : BigDecimal
|
|
||||||
{
|
|
||||||
$that = BigDecimal::of($that);
|
|
||||||
|
|
||||||
if ($that->value === '0') {
|
|
||||||
throw DivisionByZeroException::divisionByZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
[, $b] = $this->scaleValues($this, $that);
|
|
||||||
|
|
||||||
$d = \rtrim($b, '0');
|
|
||||||
$scale = \strlen($b) - \strlen($d);
|
|
||||||
|
|
||||||
$calculator = Calculator::get();
|
|
||||||
|
|
||||||
foreach ([5, 2] as $prime) {
|
|
||||||
for (;;) {
|
|
||||||
$lastDigit = (int) $d[-1];
|
|
||||||
|
|
||||||
if ($lastDigit % $prime !== 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$d = $calculator->divQ($d, (string) $prime);
|
|
||||||
$scale++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->dividedBy($that, $scale)->stripTrailingZeros();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns this number exponentiated to the given value.
|
|
||||||
*
|
|
||||||
* The result has a scale of `$this->scale * $exponent`.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
|
|
||||||
*/
|
|
||||||
public function power(int $exponent) : BigDecimal
|
|
||||||
{
|
|
||||||
if ($exponent === 0) {
|
|
||||||
return BigDecimal::one();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($exponent === 1) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($exponent < 0 || $exponent > Calculator::MAX_POWER) {
|
|
||||||
throw new \InvalidArgumentException(\sprintf(
|
|
||||||
'The exponent %d is not in the range 0 to %d.',
|
|
||||||
$exponent,
|
|
||||||
Calculator::MAX_POWER
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigDecimal(Calculator::get()->pow($this->value, $exponent), $this->scale * $exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the quotient of the division of this number by the given one.
|
|
||||||
*
|
|
||||||
* The quotient has a scale of `0`.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
|
||||||
*
|
|
||||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
|
||||||
*/
|
|
||||||
public function quotient(BigNumber|int|float|string $that) : BigDecimal
|
|
||||||
{
|
|
||||||
$that = BigDecimal::of($that);
|
|
||||||
|
|
||||||
if ($that->isZero()) {
|
|
||||||
throw DivisionByZeroException::divisionByZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
$p = $this->valueWithMinScale($that->scale);
|
|
||||||
$q = $that->valueWithMinScale($this->scale);
|
|
||||||
|
|
||||||
$quotient = Calculator::get()->divQ($p, $q);
|
|
||||||
|
|
||||||
return new BigDecimal($quotient, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the remainder of the division of this number by the given one.
|
|
||||||
*
|
|
||||||
* The remainder has a scale of `max($this->scale, $that->scale)`.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
|
||||||
*
|
|
||||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
|
||||||
*/
|
|
||||||
public function remainder(BigNumber|int|float|string $that) : BigDecimal
|
|
||||||
{
|
|
||||||
$that = BigDecimal::of($that);
|
|
||||||
|
|
||||||
if ($that->isZero()) {
|
|
||||||
throw DivisionByZeroException::divisionByZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
$p = $this->valueWithMinScale($that->scale);
|
|
||||||
$q = $that->valueWithMinScale($this->scale);
|
|
||||||
|
|
||||||
$remainder = Calculator::get()->divR($p, $q);
|
|
||||||
|
|
||||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
|
||||||
|
|
||||||
return new BigDecimal($remainder, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the quotient and remainder of the division of this number by the given one.
|
|
||||||
*
|
|
||||||
* The quotient has a scale of `0`, and the remainder has a scale of `max($this->scale, $that->scale)`.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
|
||||||
*
|
|
||||||
* @return BigDecimal[] An array containing the quotient and the remainder.
|
|
||||||
*
|
|
||||||
* @psalm-return array{BigDecimal, BigDecimal}
|
|
||||||
*
|
|
||||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
|
||||||
*/
|
|
||||||
public function quotientAndRemainder(BigNumber|int|float|string $that) : array
|
|
||||||
{
|
|
||||||
$that = BigDecimal::of($that);
|
|
||||||
|
|
||||||
if ($that->isZero()) {
|
|
||||||
throw DivisionByZeroException::divisionByZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
$p = $this->valueWithMinScale($that->scale);
|
|
||||||
$q = $that->valueWithMinScale($this->scale);
|
|
||||||
|
|
||||||
[$quotient, $remainder] = Calculator::get()->divQR($p, $q);
|
|
||||||
|
|
||||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
|
||||||
|
|
||||||
$quotient = new BigDecimal($quotient, 0);
|
|
||||||
$remainder = new BigDecimal($remainder, $scale);
|
|
||||||
|
|
||||||
return [$quotient, $remainder];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the square root of this number, rounded down to the given number of decimals.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException If the scale is negative.
|
|
||||||
* @throws NegativeNumberException If this number is negative.
|
|
||||||
*/
|
|
||||||
public function sqrt(int $scale) : BigDecimal
|
|
||||||
{
|
|
||||||
if ($scale < 0) {
|
|
||||||
throw new \InvalidArgumentException('Scale cannot be negative.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->value === '0') {
|
|
||||||
return new BigDecimal('0', $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->value[0] === '-') {
|
|
||||||
throw new NegativeNumberException('Cannot calculate the square root of a negative number.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = $this->value;
|
|
||||||
$addDigits = 2 * $scale - $this->scale;
|
|
||||||
|
|
||||||
if ($addDigits > 0) {
|
|
||||||
// add zeros
|
|
||||||
$value .= \str_repeat('0', $addDigits);
|
|
||||||
} elseif ($addDigits < 0) {
|
|
||||||
// trim digits
|
|
||||||
if (-$addDigits >= \strlen($this->value)) {
|
|
||||||
// requesting a scale too low, will always yield a zero result
|
|
||||||
return new BigDecimal('0', $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = \substr($value, 0, $addDigits);
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = Calculator::get()->sqrt($value);
|
|
||||||
|
|
||||||
return new BigDecimal($value, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a copy of this BigDecimal with the decimal point moved $n places to the left.
|
|
||||||
*/
|
|
||||||
public function withPointMovedLeft(int $n) : BigDecimal
|
|
||||||
{
|
|
||||||
if ($n === 0) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($n < 0) {
|
|
||||||
return $this->withPointMovedRight(-$n);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigDecimal($this->value, $this->scale + $n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a copy of this BigDecimal with the decimal point moved $n places to the right.
|
|
||||||
*/
|
|
||||||
public function withPointMovedRight(int $n) : BigDecimal
|
|
||||||
{
|
|
||||||
if ($n === 0) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($n < 0) {
|
|
||||||
return $this->withPointMovedLeft(-$n);
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = $this->value;
|
|
||||||
$scale = $this->scale - $n;
|
|
||||||
|
|
||||||
if ($scale < 0) {
|
|
||||||
if ($value !== '0') {
|
|
||||||
$value .= \str_repeat('0', -$scale);
|
|
||||||
}
|
|
||||||
$scale = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigDecimal($value, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a copy of this BigDecimal with any trailing zeros removed from the fractional part.
|
|
||||||
*/
|
|
||||||
public function stripTrailingZeros() : BigDecimal
|
|
||||||
{
|
|
||||||
if ($this->scale === 0) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$trimmedValue = \rtrim($this->value, '0');
|
|
||||||
|
|
||||||
if ($trimmedValue === '') {
|
|
||||||
return BigDecimal::zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
$trimmableZeros = \strlen($this->value) - \strlen($trimmedValue);
|
|
||||||
|
|
||||||
if ($trimmableZeros === 0) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($trimmableZeros > $this->scale) {
|
|
||||||
$trimmableZeros = $this->scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = \substr($this->value, 0, -$trimmableZeros);
|
|
||||||
$scale = $this->scale - $trimmableZeros;
|
|
||||||
|
|
||||||
return new BigDecimal($value, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the absolute value of this number.
|
|
||||||
*/
|
|
||||||
public function abs() : BigDecimal
|
|
||||||
{
|
|
||||||
return $this->isNegative() ? $this->negated() : $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the negated value of this number.
|
|
||||||
*/
|
|
||||||
public function negated() : BigDecimal
|
|
||||||
{
|
|
||||||
return new BigDecimal(Calculator::get()->neg($this->value), $this->scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function compareTo(BigNumber|int|float|string $that) : int
|
|
||||||
{
|
|
||||||
$that = BigNumber::of($that);
|
|
||||||
|
|
||||||
if ($that instanceof BigInteger) {
|
|
||||||
$that = $that->toBigDecimal();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($that instanceof BigDecimal) {
|
|
||||||
[$a, $b] = $this->scaleValues($this, $that);
|
|
||||||
|
|
||||||
return Calculator::get()->cmp($a, $b);
|
|
||||||
}
|
|
||||||
|
|
||||||
return - $that->compareTo($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSign() : int
|
|
||||||
{
|
|
||||||
return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUnscaledValue() : BigInteger
|
|
||||||
{
|
|
||||||
return self::newBigInteger($this->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getScale() : int
|
|
||||||
{
|
|
||||||
return $this->scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string representing the integral part of this decimal number.
|
|
||||||
*
|
|
||||||
* Example: `-123.456` => `-123`.
|
|
||||||
*/
|
|
||||||
public function getIntegralPart() : string
|
|
||||||
{
|
|
||||||
if ($this->scale === 0) {
|
|
||||||
return $this->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
|
||||||
|
|
||||||
return \substr($value, 0, -$this->scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string representing the fractional part of this decimal number.
|
|
||||||
*
|
|
||||||
* If the scale is zero, an empty string is returned.
|
|
||||||
*
|
|
||||||
* Examples: `-123.456` => '456', `123` => ''.
|
|
||||||
*/
|
|
||||||
public function getFractionalPart() : string
|
|
||||||
{
|
|
||||||
if ($this->scale === 0) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
|
||||||
|
|
||||||
return \substr($value, -$this->scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether this decimal number has a non-zero fractional part.
|
|
||||||
*/
|
|
||||||
public function hasNonZeroFractionalPart() : bool
|
|
||||||
{
|
|
||||||
return $this->getFractionalPart() !== \str_repeat('0', $this->scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toBigInteger() : BigInteger
|
|
||||||
{
|
|
||||||
$zeroScaleDecimal = $this->scale === 0 ? $this : $this->dividedBy(1, 0);
|
|
||||||
|
|
||||||
return self::newBigInteger($zeroScaleDecimal->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toBigDecimal() : BigDecimal
|
|
||||||
{
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toBigRational() : BigRational
|
|
||||||
{
|
|
||||||
$numerator = self::newBigInteger($this->value);
|
|
||||||
$denominator = self::newBigInteger('1' . \str_repeat('0', $this->scale));
|
|
||||||
|
|
||||||
return self::newBigRational($numerator, $denominator, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
|
||||||
{
|
|
||||||
if ($scale === $this->scale) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toInt() : int
|
|
||||||
{
|
|
||||||
return $this->toBigInteger()->toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toFloat() : float
|
|
||||||
{
|
|
||||||
return (float) (string) $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __toString() : string
|
|
||||||
{
|
|
||||||
if ($this->scale === 0) {
|
|
||||||
return $this->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
|
||||||
|
|
||||||
return \substr($value, 0, -$this->scale) . '.' . \substr($value, -$this->scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is required for serializing the object and SHOULD NOT be accessed directly.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @return array{value: string, scale: int}
|
|
||||||
*/
|
|
||||||
public function __serialize(): array
|
|
||||||
{
|
|
||||||
return ['value' => $this->value, 'scale' => $this->scale];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is only here to allow unserializing the object and cannot be accessed directly.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* @psalm-suppress RedundantPropertyInitializationCheck
|
|
||||||
*
|
|
||||||
* @param array{value: string, scale: int} $data
|
|
||||||
*
|
|
||||||
* @throws \LogicException
|
|
||||||
*/
|
|
||||||
public function __unserialize(array $data): void
|
|
||||||
{
|
|
||||||
if (isset($this->value)) {
|
|
||||||
throw new \LogicException('__unserialize() is an internal function, it must not be called directly.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->value = $data['value'];
|
|
||||||
$this->scale = $data['scale'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Puts the internal values of the given decimal numbers on the same scale.
|
|
||||||
*
|
|
||||||
* @return array{string, string} The scaled integer values of $x and $y.
|
|
||||||
*/
|
|
||||||
private function scaleValues(BigDecimal $x, BigDecimal $y) : array
|
|
||||||
{
|
|
||||||
$a = $x->value;
|
|
||||||
$b = $y->value;
|
|
||||||
|
|
||||||
if ($b !== '0' && $x->scale > $y->scale) {
|
|
||||||
$b .= \str_repeat('0', $x->scale - $y->scale);
|
|
||||||
} elseif ($a !== '0' && $x->scale < $y->scale) {
|
|
||||||
$a .= \str_repeat('0', $y->scale - $x->scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [$a, $b];
|
|
||||||
}
|
|
||||||
|
|
||||||
private function valueWithMinScale(int $scale) : string
|
|
||||||
{
|
|
||||||
$value = $this->value;
|
|
||||||
|
|
||||||
if ($this->value !== '0' && $scale > $this->scale) {
|
|
||||||
$value .= \str_repeat('0', $scale - $this->scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds leading zeros if necessary to the unscaled value to represent the full decimal number.
|
|
||||||
*/
|
|
||||||
private function getUnscaledValueWithLeadingZeros() : string
|
|
||||||
{
|
|
||||||
$value = $this->value;
|
|
||||||
$targetLength = $this->scale + 1;
|
|
||||||
$negative = ($value[0] === '-');
|
|
||||||
$length = \strlen($value);
|
|
||||||
|
|
||||||
if ($negative) {
|
|
||||||
$length--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($length >= $targetLength) {
|
|
||||||
return $this->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($negative) {
|
|
||||||
$value = \substr($value, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$value = \str_pad($value, $targetLength, '0', STR_PAD_LEFT);
|
|
||||||
|
|
||||||
if ($negative) {
|
|
||||||
$value = '-' . $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-1051
File diff suppressed because it is too large
Load Diff
Vendored
-509
@@ -1,509 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Brick\Math;
|
|
||||||
|
|
||||||
use Brick\Math\Exception\DivisionByZeroException;
|
|
||||||
use Brick\Math\Exception\MathException;
|
|
||||||
use Brick\Math\Exception\NumberFormatException;
|
|
||||||
use Brick\Math\Exception\RoundingNecessaryException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common interface for arbitrary-precision rational numbers.
|
|
||||||
*
|
|
||||||
* @psalm-immutable
|
|
||||||
*/
|
|
||||||
abstract class BigNumber implements \JsonSerializable
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The regular expression used to parse integer or decimal numbers.
|
|
||||||
*/
|
|
||||||
private const PARSE_REGEXP_NUMERICAL =
|
|
||||||
'/^' .
|
|
||||||
'(?<sign>[\-\+])?' .
|
|
||||||
'(?<integral>[0-9]+)?' .
|
|
||||||
'(?<point>\.)?' .
|
|
||||||
'(?<fractional>[0-9]+)?' .
|
|
||||||
'(?:[eE](?<exponent>[\-\+]?[0-9]+))?' .
|
|
||||||
'$/';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The regular expression used to parse rational numbers.
|
|
||||||
*/
|
|
||||||
private const PARSE_REGEXP_RATIONAL =
|
|
||||||
'/^' .
|
|
||||||
'(?<sign>[\-\+])?' .
|
|
||||||
'(?<numerator>[0-9]+)' .
|
|
||||||
'\/?' .
|
|
||||||
'(?<denominator>[0-9]+)' .
|
|
||||||
'$/';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a BigNumber of the given value.
|
|
||||||
*
|
|
||||||
* The concrete return type is dependent on the given value, with the following rules:
|
|
||||||
*
|
|
||||||
* - BigNumber instances are returned as is
|
|
||||||
* - integer numbers are returned as BigInteger
|
|
||||||
* - floating point numbers are converted to a string then parsed as such
|
|
||||||
* - strings containing a `/` character are returned as BigRational
|
|
||||||
* - strings containing a `.` character or using an exponential notation are returned as BigDecimal
|
|
||||||
* - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger
|
|
||||||
*
|
|
||||||
* @throws NumberFormatException If the format of the number is not valid.
|
|
||||||
* @throws DivisionByZeroException If the value represents a rational number with a denominator of zero.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
final public static function of(BigNumber|int|float|string $value) : static
|
|
||||||
{
|
|
||||||
$value = self::_of($value);
|
|
||||||
|
|
||||||
if (static::class === BigNumber::class) {
|
|
||||||
// https://github.com/vimeo/psalm/issues/10309
|
|
||||||
assert($value instanceof static);
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return static::from($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
private static function _of(BigNumber|int|float|string $value) : BigNumber
|
|
||||||
{
|
|
||||||
if ($value instanceof BigNumber) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\is_int($value)) {
|
|
||||||
return new BigInteger((string) $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_float($value)) {
|
|
||||||
$value = (string) $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str_contains($value, '/')) {
|
|
||||||
// Rational number
|
|
||||||
if (\preg_match(self::PARSE_REGEXP_RATIONAL, $value, $matches, PREG_UNMATCHED_AS_NULL) !== 1) {
|
|
||||||
throw NumberFormatException::invalidFormat($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sign = $matches['sign'];
|
|
||||||
$numerator = $matches['numerator'];
|
|
||||||
$denominator = $matches['denominator'];
|
|
||||||
|
|
||||||
assert($numerator !== null);
|
|
||||||
assert($denominator !== null);
|
|
||||||
|
|
||||||
$numerator = self::cleanUp($sign, $numerator);
|
|
||||||
$denominator = self::cleanUp(null, $denominator);
|
|
||||||
|
|
||||||
if ($denominator === '0') {
|
|
||||||
throw DivisionByZeroException::denominatorMustNotBeZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigRational(
|
|
||||||
new BigInteger($numerator),
|
|
||||||
new BigInteger($denominator),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Integer or decimal number
|
|
||||||
if (\preg_match(self::PARSE_REGEXP_NUMERICAL, $value, $matches, PREG_UNMATCHED_AS_NULL) !== 1) {
|
|
||||||
throw NumberFormatException::invalidFormat($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sign = $matches['sign'];
|
|
||||||
$point = $matches['point'];
|
|
||||||
$integral = $matches['integral'];
|
|
||||||
$fractional = $matches['fractional'];
|
|
||||||
$exponent = $matches['exponent'];
|
|
||||||
|
|
||||||
if ($integral === null && $fractional === null) {
|
|
||||||
throw NumberFormatException::invalidFormat($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($integral === null) {
|
|
||||||
$integral = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($point !== null || $exponent !== null) {
|
|
||||||
$fractional = ($fractional ?? '');
|
|
||||||
$exponent = ($exponent !== null) ? (int)$exponent : 0;
|
|
||||||
|
|
||||||
if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) {
|
|
||||||
throw new NumberFormatException('Exponent too large.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$unscaledValue = self::cleanUp($sign, $integral . $fractional);
|
|
||||||
|
|
||||||
$scale = \strlen($fractional) - $exponent;
|
|
||||||
|
|
||||||
if ($scale < 0) {
|
|
||||||
if ($unscaledValue !== '0') {
|
|
||||||
$unscaledValue .= \str_repeat('0', -$scale);
|
|
||||||
}
|
|
||||||
$scale = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigDecimal($unscaledValue, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
$integral = self::cleanUp($sign, $integral);
|
|
||||||
|
|
||||||
return new BigInteger($integral);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overridden by subclasses to convert a BigNumber to an instance of the subclass.
|
|
||||||
*
|
|
||||||
* @throws MathException If the value cannot be converted.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
abstract protected static function from(BigNumber $number): static;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy method to access BigInteger's protected constructor from sibling classes.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
final protected function newBigInteger(string $value) : BigInteger
|
|
||||||
{
|
|
||||||
return new BigInteger($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy method to access BigDecimal's protected constructor from sibling classes.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
final protected function newBigDecimal(string $value, int $scale = 0) : BigDecimal
|
|
||||||
{
|
|
||||||
return new BigDecimal($value, $scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy method to access BigRational's protected constructor from sibling classes.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
final protected function newBigRational(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator) : BigRational
|
|
||||||
{
|
|
||||||
return new BigRational($numerator, $denominator, $checkDenominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the minimum of the given values.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible
|
|
||||||
* to an instance of the class this method is called on.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException If no values are given.
|
|
||||||
* @throws MathException If an argument is not valid.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
final public static function min(BigNumber|int|float|string ...$values) : static
|
|
||||||
{
|
|
||||||
$min = null;
|
|
||||||
|
|
||||||
foreach ($values as $value) {
|
|
||||||
$value = static::of($value);
|
|
||||||
|
|
||||||
if ($min === null || $value->isLessThan($min)) {
|
|
||||||
$min = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($min === null) {
|
|
||||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $min;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the maximum of the given values.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible
|
|
||||||
* to an instance of the class this method is called on.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException If no values are given.
|
|
||||||
* @throws MathException If an argument is not valid.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
final public static function max(BigNumber|int|float|string ...$values) : static
|
|
||||||
{
|
|
||||||
$max = null;
|
|
||||||
|
|
||||||
foreach ($values as $value) {
|
|
||||||
$value = static::of($value);
|
|
||||||
|
|
||||||
if ($max === null || $value->isGreaterThan($max)) {
|
|
||||||
$max = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($max === null) {
|
|
||||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the sum of the given values.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string ...$values The numbers to add. All the numbers need to be convertible
|
|
||||||
* to an instance of the class this method is called on.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException If no values are given.
|
|
||||||
* @throws MathException If an argument is not valid.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
final public static function sum(BigNumber|int|float|string ...$values) : static
|
|
||||||
{
|
|
||||||
/** @var static|null $sum */
|
|
||||||
$sum = null;
|
|
||||||
|
|
||||||
foreach ($values as $value) {
|
|
||||||
$value = static::of($value);
|
|
||||||
|
|
||||||
$sum = $sum === null ? $value : self::add($sum, $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($sum === null) {
|
|
||||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds two BigNumber instances in the correct order to avoid a RoundingNecessaryException.
|
|
||||||
*
|
|
||||||
* @todo This could be better resolved by creating an abstract protected method in BigNumber, and leaving to
|
|
||||||
* concrete classes the responsibility to perform the addition themselves or delegate it to the given number,
|
|
||||||
* depending on their ability to perform the operation. This will also require a version bump because we're
|
|
||||||
* potentially breaking custom BigNumber implementations (if any...)
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
private static function add(BigNumber $a, BigNumber $b) : BigNumber
|
|
||||||
{
|
|
||||||
if ($a instanceof BigRational) {
|
|
||||||
return $a->plus($b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($b instanceof BigRational) {
|
|
||||||
return $b->plus($a);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($a instanceof BigDecimal) {
|
|
||||||
return $a->plus($b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($b instanceof BigDecimal) {
|
|
||||||
return $b->plus($a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var BigInteger $a */
|
|
||||||
|
|
||||||
return $a->plus($b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes optional leading zeros and applies sign.
|
|
||||||
*
|
|
||||||
* @param string|null $sign The sign, '+' or '-', optional. Null is allowed for convenience and treated as '+'.
|
|
||||||
* @param string $number The number, validated as a non-empty string of digits.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
private static function cleanUp(string|null $sign, string $number) : string
|
|
||||||
{
|
|
||||||
$number = \ltrim($number, '0');
|
|
||||||
|
|
||||||
if ($number === '') {
|
|
||||||
return '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $sign === '-' ? '-' . $number : $number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is equal to the given one.
|
|
||||||
*/
|
|
||||||
final public function isEqualTo(BigNumber|int|float|string $that) : bool
|
|
||||||
{
|
|
||||||
return $this->compareTo($that) === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is strictly lower than the given one.
|
|
||||||
*/
|
|
||||||
final public function isLessThan(BigNumber|int|float|string $that) : bool
|
|
||||||
{
|
|
||||||
return $this->compareTo($that) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is lower than or equal to the given one.
|
|
||||||
*/
|
|
||||||
final public function isLessThanOrEqualTo(BigNumber|int|float|string $that) : bool
|
|
||||||
{
|
|
||||||
return $this->compareTo($that) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is strictly greater than the given one.
|
|
||||||
*/
|
|
||||||
final public function isGreaterThan(BigNumber|int|float|string $that) : bool
|
|
||||||
{
|
|
||||||
return $this->compareTo($that) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is greater than or equal to the given one.
|
|
||||||
*/
|
|
||||||
final public function isGreaterThanOrEqualTo(BigNumber|int|float|string $that) : bool
|
|
||||||
{
|
|
||||||
return $this->compareTo($that) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number equals zero.
|
|
||||||
*/
|
|
||||||
final public function isZero() : bool
|
|
||||||
{
|
|
||||||
return $this->getSign() === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is strictly negative.
|
|
||||||
*/
|
|
||||||
final public function isNegative() : bool
|
|
||||||
{
|
|
||||||
return $this->getSign() < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is negative or zero.
|
|
||||||
*/
|
|
||||||
final public function isNegativeOrZero() : bool
|
|
||||||
{
|
|
||||||
return $this->getSign() <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is strictly positive.
|
|
||||||
*/
|
|
||||||
final public function isPositive() : bool
|
|
||||||
{
|
|
||||||
return $this->getSign() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this number is positive or zero.
|
|
||||||
*/
|
|
||||||
final public function isPositiveOrZero() : bool
|
|
||||||
{
|
|
||||||
return $this->getSign() >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the sign of this number.
|
|
||||||
*
|
|
||||||
* @psalm-return -1|0|1
|
|
||||||
*
|
|
||||||
* @return int -1 if the number is negative, 0 if zero, 1 if positive.
|
|
||||||
*/
|
|
||||||
abstract public function getSign() : int;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares this number to the given one.
|
|
||||||
*
|
|
||||||
* @psalm-return -1|0|1
|
|
||||||
*
|
|
||||||
* @return int -1 if `$this` is lower than, 0 if equal to, 1 if greater than `$that`.
|
|
||||||
*
|
|
||||||
* @throws MathException If the number is not valid.
|
|
||||||
*/
|
|
||||||
abstract public function compareTo(BigNumber|int|float|string $that) : int;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts this number to a BigInteger.
|
|
||||||
*
|
|
||||||
* @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding.
|
|
||||||
*/
|
|
||||||
abstract public function toBigInteger() : BigInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts this number to a BigDecimal.
|
|
||||||
*
|
|
||||||
* @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding.
|
|
||||||
*/
|
|
||||||
abstract public function toBigDecimal() : BigDecimal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts this number to a BigRational.
|
|
||||||
*/
|
|
||||||
abstract public function toBigRational() : BigRational;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts this number to a BigDecimal with the given scale, using rounding if necessary.
|
|
||||||
*
|
|
||||||
* @param int $scale The scale of the resulting `BigDecimal`.
|
|
||||||
* @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY.
|
|
||||||
*
|
|
||||||
* @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding.
|
|
||||||
* This only applies when RoundingMode::UNNECESSARY is used.
|
|
||||||
*/
|
|
||||||
abstract public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the exact value of this number as a native integer.
|
|
||||||
*
|
|
||||||
* If this number cannot be converted to a native integer without losing precision, an exception is thrown.
|
|
||||||
* Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit.
|
|
||||||
*
|
|
||||||
* @throws MathException If this number cannot be exactly converted to a native integer.
|
|
||||||
*/
|
|
||||||
abstract public function toInt() : int;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an approximation of this number as a floating-point value.
|
|
||||||
*
|
|
||||||
* Note that this method can discard information as the precision of a floating-point value
|
|
||||||
* is inherently limited.
|
|
||||||
*
|
|
||||||
* If the number is greater than the largest representable floating point number, positive infinity is returned.
|
|
||||||
* If the number is less than the smallest representable floating point number, negative infinity is returned.
|
|
||||||
*/
|
|
||||||
abstract public function toFloat() : float;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string representation of this number.
|
|
||||||
*
|
|
||||||
* The output of this method can be parsed by the `of()` factory method;
|
|
||||||
* this will yield an object equal to this one, without any information loss.
|
|
||||||
*/
|
|
||||||
abstract public function __toString() : string;
|
|
||||||
|
|
||||||
final public function jsonSerialize() : string
|
|
||||||
{
|
|
||||||
return $this->__toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-413
@@ -1,413 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Brick\Math;
|
|
||||||
|
|
||||||
use Brick\Math\Exception\DivisionByZeroException;
|
|
||||||
use Brick\Math\Exception\MathException;
|
|
||||||
use Brick\Math\Exception\NumberFormatException;
|
|
||||||
use Brick\Math\Exception\RoundingNecessaryException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An arbitrarily large rational number.
|
|
||||||
*
|
|
||||||
* This class is immutable.
|
|
||||||
*
|
|
||||||
* @psalm-immutable
|
|
||||||
*/
|
|
||||||
final class BigRational extends BigNumber
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The numerator.
|
|
||||||
*/
|
|
||||||
private readonly BigInteger $numerator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The denominator. Always strictly positive.
|
|
||||||
*/
|
|
||||||
private readonly BigInteger $denominator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Protected constructor. Use a factory method to obtain an instance.
|
|
||||||
*
|
|
||||||
* @param BigInteger $numerator The numerator.
|
|
||||||
* @param BigInteger $denominator The denominator.
|
|
||||||
* @param bool $checkDenominator Whether to check the denominator for negative and zero.
|
|
||||||
*
|
|
||||||
* @throws DivisionByZeroException If the denominator is zero.
|
|
||||||
*/
|
|
||||||
protected function __construct(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator)
|
|
||||||
{
|
|
||||||
if ($checkDenominator) {
|
|
||||||
if ($denominator->isZero()) {
|
|
||||||
throw DivisionByZeroException::denominatorMustNotBeZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($denominator->isNegative()) {
|
|
||||||
$numerator = $numerator->negated();
|
|
||||||
$denominator = $denominator->negated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->numerator = $numerator;
|
|
||||||
$this->denominator = $denominator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
protected static function from(BigNumber $number): static
|
|
||||||
{
|
|
||||||
return $number->toBigRational();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a BigRational out of a numerator and a denominator.
|
|
||||||
*
|
|
||||||
* If the denominator is negative, the signs of both the numerator and the denominator
|
|
||||||
* will be inverted to ensure that the denominator is always positive.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $numerator The numerator. Must be convertible to a BigInteger.
|
|
||||||
* @param BigNumber|int|float|string $denominator The denominator. Must be convertible to a BigInteger.
|
|
||||||
*
|
|
||||||
* @throws NumberFormatException If an argument does not represent a valid number.
|
|
||||||
* @throws RoundingNecessaryException If an argument represents a non-integer number.
|
|
||||||
* @throws DivisionByZeroException If the denominator is zero.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function nd(
|
|
||||||
BigNumber|int|float|string $numerator,
|
|
||||||
BigNumber|int|float|string $denominator,
|
|
||||||
) : BigRational {
|
|
||||||
$numerator = BigInteger::of($numerator);
|
|
||||||
$denominator = BigInteger::of($denominator);
|
|
||||||
|
|
||||||
return new BigRational($numerator, $denominator, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a BigRational representing zero.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function zero() : BigRational
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-suppress ImpureStaticVariable
|
|
||||||
* @var BigRational|null $zero
|
|
||||||
*/
|
|
||||||
static $zero;
|
|
||||||
|
|
||||||
if ($zero === null) {
|
|
||||||
$zero = new BigRational(BigInteger::zero(), BigInteger::one(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a BigRational representing one.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function one() : BigRational
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-suppress ImpureStaticVariable
|
|
||||||
* @var BigRational|null $one
|
|
||||||
*/
|
|
||||||
static $one;
|
|
||||||
|
|
||||||
if ($one === null) {
|
|
||||||
$one = new BigRational(BigInteger::one(), BigInteger::one(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $one;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a BigRational representing ten.
|
|
||||||
*
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function ten() : BigRational
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-suppress ImpureStaticVariable
|
|
||||||
* @var BigRational|null $ten
|
|
||||||
*/
|
|
||||||
static $ten;
|
|
||||||
|
|
||||||
if ($ten === null) {
|
|
||||||
$ten = new BigRational(BigInteger::ten(), BigInteger::one(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ten;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNumerator() : BigInteger
|
|
||||||
{
|
|
||||||
return $this->numerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDenominator() : BigInteger
|
|
||||||
{
|
|
||||||
return $this->denominator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the quotient of the division of the numerator by the denominator.
|
|
||||||
*/
|
|
||||||
public function quotient() : BigInteger
|
|
||||||
{
|
|
||||||
return $this->numerator->quotient($this->denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the remainder of the division of the numerator by the denominator.
|
|
||||||
*/
|
|
||||||
public function remainder() : BigInteger
|
|
||||||
{
|
|
||||||
return $this->numerator->remainder($this->denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the quotient and remainder of the division of the numerator by the denominator.
|
|
||||||
*
|
|
||||||
* @return BigInteger[]
|
|
||||||
*
|
|
||||||
* @psalm-return array{BigInteger, BigInteger}
|
|
||||||
*/
|
|
||||||
public function quotientAndRemainder() : array
|
|
||||||
{
|
|
||||||
return $this->numerator->quotientAndRemainder($this->denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the sum of this number and the given one.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The number to add.
|
|
||||||
*
|
|
||||||
* @throws MathException If the number is not valid.
|
|
||||||
*/
|
|
||||||
public function plus(BigNumber|int|float|string $that) : BigRational
|
|
||||||
{
|
|
||||||
$that = BigRational::of($that);
|
|
||||||
|
|
||||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
|
||||||
$numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator));
|
|
||||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
|
||||||
|
|
||||||
return new BigRational($numerator, $denominator, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the difference of this number and the given one.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The number to subtract.
|
|
||||||
*
|
|
||||||
* @throws MathException If the number is not valid.
|
|
||||||
*/
|
|
||||||
public function minus(BigNumber|int|float|string $that) : BigRational
|
|
||||||
{
|
|
||||||
$that = BigRational::of($that);
|
|
||||||
|
|
||||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
|
||||||
$numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator));
|
|
||||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
|
||||||
|
|
||||||
return new BigRational($numerator, $denominator, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the product of this number and the given one.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The multiplier.
|
|
||||||
*
|
|
||||||
* @throws MathException If the multiplier is not a valid number.
|
|
||||||
*/
|
|
||||||
public function multipliedBy(BigNumber|int|float|string $that) : BigRational
|
|
||||||
{
|
|
||||||
$that = BigRational::of($that);
|
|
||||||
|
|
||||||
$numerator = $this->numerator->multipliedBy($that->numerator);
|
|
||||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
|
||||||
|
|
||||||
return new BigRational($numerator, $denominator, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the result of the division of this number by the given one.
|
|
||||||
*
|
|
||||||
* @param BigNumber|int|float|string $that The divisor.
|
|
||||||
*
|
|
||||||
* @throws MathException If the divisor is not a valid number, or is zero.
|
|
||||||
*/
|
|
||||||
public function dividedBy(BigNumber|int|float|string $that) : BigRational
|
|
||||||
{
|
|
||||||
$that = BigRational::of($that);
|
|
||||||
|
|
||||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
|
||||||
$denominator = $this->denominator->multipliedBy($that->numerator);
|
|
||||||
|
|
||||||
return new BigRational($numerator, $denominator, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns this number exponentiated to the given value.
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
|
|
||||||
*/
|
|
||||||
public function power(int $exponent) : BigRational
|
|
||||||
{
|
|
||||||
if ($exponent === 0) {
|
|
||||||
$one = BigInteger::one();
|
|
||||||
|
|
||||||
return new BigRational($one, $one, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($exponent === 1) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigRational(
|
|
||||||
$this->numerator->power($exponent),
|
|
||||||
$this->denominator->power($exponent),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the reciprocal of this BigRational.
|
|
||||||
*
|
|
||||||
* The reciprocal has the numerator and denominator swapped.
|
|
||||||
*
|
|
||||||
* @throws DivisionByZeroException If the numerator is zero.
|
|
||||||
*/
|
|
||||||
public function reciprocal() : BigRational
|
|
||||||
{
|
|
||||||
return new BigRational($this->denominator, $this->numerator, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the absolute value of this BigRational.
|
|
||||||
*/
|
|
||||||
public function abs() : BigRational
|
|
||||||
{
|
|
||||||
return new BigRational($this->numerator->abs(), $this->denominator, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the negated value of this BigRational.
|
|
||||||
*/
|
|
||||||
public function negated() : BigRational
|
|
||||||
{
|
|
||||||
return new BigRational($this->numerator->negated(), $this->denominator, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the simplified value of this BigRational.
|
|
||||||
*/
|
|
||||||
public function simplified() : BigRational
|
|
||||||
{
|
|
||||||
$gcd = $this->numerator->gcd($this->denominator);
|
|
||||||
|
|
||||||
$numerator = $this->numerator->quotient($gcd);
|
|
||||||
$denominator = $this->denominator->quotient($gcd);
|
|
||||||
|
|
||||||
return new BigRational($numerator, $denominator, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function compareTo(BigNumber|int|float|string $that) : int
|
|
||||||
{
|
|
||||||
return $this->minus($that)->getSign();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSign() : int
|
|
||||||
{
|
|
||||||
return $this->numerator->getSign();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toBigInteger() : BigInteger
|
|
||||||
{
|
|
||||||
$simplified = $this->simplified();
|
|
||||||
|
|
||||||
if (! $simplified->denominator->isEqualTo(1)) {
|
|
||||||
throw new RoundingNecessaryException('This rational number cannot be represented as an integer value without rounding.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $simplified->numerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toBigDecimal() : BigDecimal
|
|
||||||
{
|
|
||||||
return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toBigRational() : BigRational
|
|
||||||
{
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
|
||||||
{
|
|
||||||
return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toInt() : int
|
|
||||||
{
|
|
||||||
return $this->toBigInteger()->toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toFloat() : float
|
|
||||||
{
|
|
||||||
$simplified = $this->simplified();
|
|
||||||
return $simplified->numerator->toFloat() / $simplified->denominator->toFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __toString() : string
|
|
||||||
{
|
|
||||||
$numerator = (string) $this->numerator;
|
|
||||||
$denominator = (string) $this->denominator;
|
|
||||||
|
|
||||||
if ($denominator === '1') {
|
|
||||||
return $numerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->numerator . '/' . $this->denominator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is required for serializing the object and SHOULD NOT be accessed directly.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @return array{numerator: BigInteger, denominator: BigInteger}
|
|
||||||
*/
|
|
||||||
public function __serialize(): array
|
|
||||||
{
|
|
||||||
return ['numerator' => $this->numerator, 'denominator' => $this->denominator];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is only here to allow unserializing the object and cannot be accessed directly.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
* @psalm-suppress RedundantPropertyInitializationCheck
|
|
||||||
*
|
|
||||||
* @param array{numerator: BigInteger, denominator: BigInteger} $data
|
|
||||||
*
|
|
||||||
* @throws \LogicException
|
|
||||||
*/
|
|
||||||
public function __unserialize(array $data): void
|
|
||||||
{
|
|
||||||
if (isset($this->numerator)) {
|
|
||||||
throw new \LogicException('__unserialize() is an internal function, it must not be called directly.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->numerator = $data['numerator'];
|
|
||||||
$this->denominator = $data['denominator'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Brick\Math\Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown when a division by zero occurs.
|
|
||||||
*/
|
|
||||||
class DivisionByZeroException extends MathException
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function divisionByZero() : DivisionByZeroException
|
|
||||||
{
|
|
||||||
return new self('Division by zero.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function modulusMustNotBeZero() : DivisionByZeroException
|
|
||||||
{
|
|
||||||
return new self('The modulus must not be zero.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function denominatorMustNotBeZero() : DivisionByZeroException
|
|
||||||
{
|
|
||||||
return new self('The denominator of a rational number cannot be zero.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Brick\Math\Exception;
|
|
||||||
|
|
||||||
use Brick\Math\BigInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown when an integer overflow occurs.
|
|
||||||
*/
|
|
||||||
class IntegerOverflowException extends MathException
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-pure
|
|
||||||
*/
|
|
||||||
public static function toIntOverflow(BigInteger $value) : IntegerOverflowException
|
|
||||||
{
|
|
||||||
$message = '%s is out of range %d to %d and cannot be represented as an integer.';
|
|
||||||
|
|
||||||
return new self(\sprintf($message, (string) $value, PHP_INT_MIN, PHP_INT_MAX));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Brick\Math\Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all math exceptions.
|
|
||||||
*/
|
|
||||||
class MathException extends \Exception
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user