¨4.0.1¨

This commit is contained in:
¨NW¨
2023-12-03 14:07:47 +00:00
parent c08b36d1b6
commit f35052522d
1112 changed files with 43019 additions and 24987 deletions

View File

@@ -5,12 +5,20 @@ namespace FleetCart\Http\Controllers;
use Exception;
use FleetCart\Install\App;
use FleetCart\Install\Store;
use Illuminate\Http\Response;
use FleetCart\Install\Database;
use FleetCart\Install\Permission;
use Illuminate\Http\JsonResponse;
use FleetCart\Install\Requirement;
use Illuminate\Routing\Controller;
use Illuminate\Contracts\View\View;
use FleetCart\Install\AdminAccount;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Artisan;
use FleetCart\Http\Requests\InstallRequest;
use Jackiedo\DotenvEditor\Facades\DotenvEditor;
use Illuminate\Contracts\Foundation\Application;
use FleetCart\Http\Middleware\RedirectIfInstalled;
class InstallController extends Controller
@@ -20,50 +28,56 @@ class InstallController extends Controller
$this->middleware(RedirectIfInstalled::class);
}
public function preInstallation(Requirement $requirement)
public function installation(Requirement $requirement, Permission $permission): Factory|View|Application
{
return view('install.pre_installation', compact('requirement'));
return view('install.install', compact('requirement', 'permission'));
}
public function getConfiguration(Requirement $requirement)
{
if (! $requirement->satisfied()) {
return redirect()->route('install.pre_installation');
}
return view('install.configuration', compact('requirement'));
}
public function postConfiguration(
public function install(
InstallRequest $request,
Database $database,
AdminAccount $admin,
Store $store,
App $app
) {
Database $database,
AdminAccount $admin,
Store $store,
App $app
): JsonResponse
{
@set_time_limit(0);
try {
$database->setup($request->db);
$admin->setup($request->admin);
$store->setup($request->store);
Artisan::call('optimize:clear');
$database->setup($request);
$admin->setup($request);
$store->setup($request);
$app->setup();
DotenvEditor::setKey('APP_INSTALLED', 'true')->save();
Artisan::call('key:generate', ['--force' => true]);
$success = true;
$message = "Congratulations! FleetCart installed successfully";
} catch (Exception $e) {
return back()->withInput()
->with('error', $e->getMessage());
$success = false;
$message = $e->getMessage();
try {
if (Schema::hasTable('migrations')) {
Artisan::call('migrate:rollback', ['--force' => true]);
}
} catch (Exception $e) {
$message .= '<br><br>' . $e->getMessage();
}
} finally {
return response()->json(
[
'success' => $success,
'message' => $message,
],
$success ? Response::HTTP_OK : Response::HTTP_INTERNAL_SERVER_ERROR
);
}
return redirect('install/complete');
}
public function complete()
{
if (config('app.installed')) {
return redirect()->route('home');
}
DotenvEditor::setKey('APP_INSTALLED', 'true')->save();
return view('install.complete');
}
}

View File

@@ -4,6 +4,10 @@ namespace FleetCart\Http\Controllers;
use FleetCart\License;
use Illuminate\Routing\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\Foundation\Application;
use FleetCart\Http\Middleware\RedirectIfShouldNotCreateLicense;
class LicenseController extends Controller
@@ -13,18 +17,23 @@ class LicenseController extends Controller
$this->middleware(RedirectIfShouldNotCreateLicense::class);
}
public function create()
public function create(): Factory|View|Application
{
return view('license.create');
}
public function store(License $license)
public function store(License $license): RedirectResponse
{
request()->validate([
'purchase_code' => 'required',
], [
'required' => 'The purchase code field is required.',
]);
request()->validate(
[
'purchase_code' => 'required',
],
[
'required' => 'The purchase code field is required.',
]
);
$license->activate(request('purchase_code'));

View File

@@ -2,7 +2,26 @@
namespace FleetCart\Http;
use FleetCart\Http\Middleware\RunUpdater;
use FleetCart\Http\Middleware\TrimStrings;
use FleetCart\Http\Middleware\TrustProxies;
use FleetCart\Http\Middleware\EncryptCookies;
use FleetCart\Http\Middleware\VerifyCsrfToken;
use Illuminate\Auth\Middleware\RequirePassword;
use Illuminate\Http\Middleware\SetCacheHeaders;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Routing\Middleware\ValidateSignature;
use FleetCart\Http\Middleware\ConvertStringBooleans;
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use FleetCart\Http\Middleware\CheckForMaintenanceMode;
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use FleetCart\Http\Middleware\RedirectToInstallerIfNotInstalled;
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
class Kernel extends HttpKernel
{
@@ -14,16 +33,16 @@ class Kernel extends HttpKernel
* @var array
*/
protected $middleware = [
\FleetCart\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
\FleetCart\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\FleetCart\Http\Middleware\TrimStrings::class,
\FleetCart\Http\Middleware\ConvertStringBooleans::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\FleetCart\Http\Middleware\TrustProxies::class,
\FleetCart\Http\Middleware\RedirectToInstallerIfNotInstalled::class,
\FleetCart\Http\Middleware\RunUpdater::class,
EncryptCookies::class,
StartSession::class,
CheckForMaintenanceMode::class,
ValidatePostSize::class,
TrimStrings::class,
ConvertStringBooleans::class,
ConvertEmptyStringsToNull::class,
TrustProxies::class,
RedirectToInstallerIfNotInstalled::class,
RunUpdater::class,
];
/**
@@ -33,10 +52,10 @@ class Kernel extends HttpKernel
*/
protected $middlewareGroups = [
'web' => [
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\FleetCart\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
AddQueuedCookiesToResponse::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
@@ -52,11 +71,11 @@ class Kernel extends HttpKernel
* @var array
*/
protected $routeMiddleware = [
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'bindings' => SubstituteBindings::class,
'cache.headers' => SetCacheHeaders::class,
'password.confirm' => RequirePassword::class,
'signed' => ValidateSignature::class,
'throttle' => ThrottleRequests::class,
'verified' => EnsureEmailIsVerified::class,
];
}

View File

@@ -3,6 +3,9 @@
namespace FleetCart\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Http\Exceptions\MaintenanceModeException;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as BaseCheckForMaintenanceMode;
class CheckForMaintenanceMode extends BaseCheckForMaintenanceMode
@@ -16,17 +19,19 @@ class CheckForMaintenanceMode extends BaseCheckForMaintenanceMode
'*/admin*',
];
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param Request $request
* @param Closure $next
*
* @return mixed
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* @throws \Illuminate\Foundation\Http\Exceptions\MaintenanceModeException
* @throws HttpException
* @throws MaintenanceModeException
*/
public function handle($request, Closure $next)
public function handle($request, Closure $next): mixed
{
if (
config('app.installed')

View File

@@ -9,11 +9,12 @@ class ConvertStringBooleans extends TransformsRequest
/**
* Transform the given value.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param $key
* @param $value
*
* @return mixed
*/
protected function transform($key, $value)
protected function transform($key, $value): mixed
{
if ($value === 'true' || $value === 'TRUE') {
return true;

View File

@@ -0,0 +1,29 @@
<?php
namespace FleetCart\Http\Middleware;
use Closure;
use FleetCart\License;
class LicenseChecker
{
private $license;
public function __construct(License $license)
{
$this->license = $license;
}
public function handle($request, Closure $next)
{
if ($this->license->shouldRecheck()) {
$this->license->recheck();
} else if ($this->license->shouldCreateLicense()) {
return redirect()->route('license.create');
}
return $next($request);
}
}

View File

@@ -3,17 +3,19 @@
namespace FleetCart\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class RedirectIfInstalled
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param Request $request
* @param Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
public function handle($request, Closure $next): mixed
{
if (config('app.installed')) {
return redirect()->route('home');

View File

@@ -4,26 +4,30 @@ namespace FleetCart\Http\Middleware;
use Closure;
use FleetCart\License;
use Illuminate\Http\Request;
class RedirectIfShouldNotCreateLicense
{
private $license;
public function __construct(License $license)
{
$this->license = $license;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param Request $request
* @param Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
public function handle($request, Closure $next): mixed
{
if ($this->license->valid() || ! $this->license->shouldCreateLicense()) {
if ($this->license->valid() || !$this->license->shouldCreateLicense()) {
return redirect()->intended('/admin');
}

View File

@@ -3,20 +3,22 @@
namespace FleetCart\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class RedirectToInstallerIfNotInstalled
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param Request $request
* @param Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
public function handle($request, Closure $next): mixed
{
if (! config('app.installed') && ! $request->is('install/*')) {
return redirect()->route('install.pre_installation');
if (!config('app.installed') && !$request->is('install')) {
return redirect()->route('install.show');
}
return $next($request);

View File

@@ -4,17 +4,19 @@ namespace FleetCart\Http\Middleware;
use Closure;
use FleetCart\Updater;
use Illuminate\Http\Request;
class RunUpdater
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param Request $request
* @param Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
public function handle(Request $request, Closure $next): mixed
{
if (config('app.installed') && file_exists(storage_path('app/update'))) {
Updater::run();

View File

@@ -12,66 +12,68 @@ class InstallRequest extends Request
*
* @return bool
*/
public function authorize()
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
public function rules(): array
{
return [
'db.host' => 'required',
'db.port' => 'required',
'db.username' => 'required',
'db.password' => 'nullable',
'db.database' => 'required',
'admin.first_name' => 'required',
'admin.last_name' => 'required',
'admin.email' => 'required|email',
'admin.phone' => 'required',
'admin.password' => 'required|confirmed|min:6',
'store.store_name' => 'required',
'store.store_email' => 'required|email',
'store.store_phone' => 'required',
'store.search_engine' => ['required', Rule::in(['mysql', 'algolia', 'meilisearch'])],
'store.algolia_app_id' => 'required_if:store.search_engine,algolia',
'store.algolia_secret' => 'required_if:store.search_engine,algolia',
'store.meilisearch_host' => 'required_if:store.search_engine,meilisearch',
'store.meilisearch_key' => 'required_if:store.search_engine,meilisearch',
'db_host' => 'required',
'db_port' => 'required',
'db_username' => 'required',
'db_password' => 'nullable',
'db_database' => 'required',
'admin_first_name' => 'required',
'admin_last_name' => 'required',
'admin_email' => 'required|email',
'admin_phone' => 'required',
'admin_password' => 'required|confirmed|min:6',
'store_name' => 'required',
'store_email' => 'required|email',
'store_phone' => 'required',
'store_search_engine' => ['required', Rule::in(['mysql', 'algolia', 'meilisearch'])],
'algolia_app_id' => 'required_if:store_search_engine,algolia',
'algolia_secret' => 'required_if:store_search_engine,algolia',
'meilisearch_host' => 'required_if:store_search_engine,meilisearch',
'meilisearch_key' => 'required_if:store_search_engine,meilisearch',
];
}
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes()
public function attributes(): array
{
return [
'db.host' => 'host',
'db.port' => 'port',
'db.username' => 'username',
'db.password' => 'password',
'db.database' => 'datbase',
'admin.first_name' => 'first name',
'admin.last_name' => 'last name',
'admin.email' => 'email',
'admin.phone' => 'phone',
'admin.password' => 'password',
'store.store_name' => 'store name',
'store.store_email' => 'store email',
'store.store_phone' => 'store phone',
'store.search_engine' => 'search engine',
'store.algolia_app_id' => 'algolia application id',
'store.algolia_secret' => 'algolia admin api key',
'store.meilisearch_host' => 'meilisearch host',
'store.meilisearch_key' => 'meilisearch key',
'db_host' => 'host',
'db_port' => 'port',
'db_username' => 'username',
'db_password' => 'password',
'db_database' => 'datbase',
'admin_first_name' => 'first name',
'admin_last_name' => 'last name',
'admin_email' => 'email',
'admin_phone' => 'phone',
'admin_password' => 'password',
'store_name' => 'store name',
'store_email' => 'store email',
'store_phone' => 'store phone',
'store_search_engine' => 'search engine',
'algolia_app_id' => 'algolia application id',
'algolia_secret' => 'algolia admin api key',
'meilisearch_host' => 'meilisearch host',
'meilisearch_key' => 'meilisearch key',
];
}
}