first upload all files

This commit is contained in:
NW
2023-06-11 13:14:03 +01:00
parent f14dbc52b5
commit c08b36d1b6
1705 changed files with 106852 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
<?php
return [
'core_modules' => [
'core',
'support',
'admin',
'dashboard',
'meta',
'user',
'workshop',
'setting',
'media',
'meta',
'page',
'product',
'translation',
],
];

View File

@@ -0,0 +1,52 @@
<?php
namespace Modules\Core\Events;
use Modules\Core\Foundation\Asset\Pipeline\AssetPipeline;
class CollectingAssets
{
/**
* Asset pipeline instance.
*
* @var \Modules\Core\Foundation\Asset\Pipeline\AssetPipeline
*/
private $assetPipeline;
/**
* Create a new event instance.
*
* @param \Modules\Core\Foundation\Asset\Pipeline\AssetPipeline $assetPipeline
*/
public function __construct(AssetPipeline $assetPipeline)
{
$this->assetPipeline = $assetPipeline;
}
/**
* Determine if the current route name is any of the given routes.
*
* @param array $routes
* @return bool
*/
public function onRoutes(array $routes)
{
foreach ($routes as $route) {
if (preg_match("/{$route}/", request()->route()->getName())) {
return true;
}
}
return false;
}
/**
* Require assets to the asset pipeline.
*
* @param array $assets
*/
public function requireAssets(array $assets)
{
return $this->assetPipeline->requireAssets($assets);
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Modules\Core\Foundation\Asset;
use Exception;
class AssetNotFoundException extends Exception
{
public static function make($asset)
{
return new static("Asset [$asset] not found.");
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Modules\Core\Foundation\Asset\Manager;
interface AssetManager
{
/**
* Add a new asset.
*
* @param string $dependency
* @param string $path
* @return void
*/
public function addAsset($asset, $path);
/**
* Get all css files.
*
* @return \Illuminate\Support\Collection
*/
public function allCss();
/**
* Get all js files.
*
* @return \Illuminate\Support\Collection
*/
public function allJs();
/**
* Get css file for the given dependency.
*
* @param string $dependency
* @return string
*
* @throws \Modules\Core\Foundation\Asset\AssetNotFoundException
*/
public function getJs($dependency);
/**
* Get js file for the given dependency.
*
* @param string $dependency
* @return string
*
* @throws \Modules\Core\Foundation\Asset\AssetNotFoundException
*/
public function getCss($dependency);
}

View File

@@ -0,0 +1,104 @@
<?php
namespace Modules\Core\Foundation\Asset\Manager;
use Illuminate\Support\Collection;
use Modules\Core\Foundation\Asset\AssetNotFoundException;
class FleetCartAssetManager implements AssetManager
{
/**
* @var array
*/
protected $css = [];
/**
* @var array
*/
protected $js = [];
/**
* Create new instance of FleetCartAssetManager.
*
* @return void
*/
public function __construct()
{
$this->css = new Collection;
$this->js = new Collection;
}
/**
* Add a new asset.
*
* @param string $dependency
* @param string $path
* @return void
*/
public function addAsset($asset, $path)
{
$extension = pathinfo($path, PATHINFO_EXTENSION);
if ($extension === 'css') {
$collection = $this->css;
} elseif ($extension === 'js') {
$collection = $this->js;
}
$collection->put($asset, $path);
}
/**
* Get all css files.
*
* @return \Illuminate\Support\Collection
*/
public function allCss()
{
return $this->css;
}
/**
* Get all js files.
*
* @return \Illuminate\Support\Collection
*/
public function allJs()
{
return $this->js;
}
/**
* Get css file for the given dependency.
*
* @param string $dependency
* @return string
*
* @throws \Modules\Core\Foundation\Asset\AssetNotFoundException
*/
public function getCss($dependency)
{
return tap($this->css->get($dependency), function ($asset) use ($dependency) {
if (is_null($asset)) {
throw AssetNotFoundException::make($dependency);
}
});
}
/**
* Get js file for the given dependency.
*
* @param string $dependency
* @return string
*
* @throws \Modules\Core\Foundation\Asset\AssetNotFoundException
*/
public function getJs($dependency)
{
return tap($this->js->get($dependency), function ($asset) use ($dependency) {
if (is_null($asset)) {
throw AssetNotFoundException::make($dependency);
}
});
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Modules\Core\Foundation\Asset\Pipeline;
interface AssetPipeline
{
/**
* Return all css files to include.
*
* @return \Illuminate\Support\Collection
*/
public function allCss();
/**
* Return all js files to include.
*
* @return \Illuminate\Support\Collection
*/
public function allJs();
/**
* Add a javascript dependency on the view.
*
* @param string|array $assets
* @return $this
*/
public function requireAssets($assets);
/**
* Add an asset after another one.
*
* @param string $asset
* @return void
*/
public function after($asset);
/**
* Add an asset before another one.
*
* @param string $asset
* @return void
*/
public function before($asset);
}

View File

@@ -0,0 +1,178 @@
<?php
namespace Modules\Core\Foundation\Asset\Pipeline;
use Illuminate\Support\Collection;
use Modules\Core\Foundation\Asset\Manager\AssetManager;
class FleetCartAssetPipeline implements AssetPipeline
{
/**
* @var \Illuminate\Support\Collection
*/
protected $css;
/**
* @var \Illuminate\Support\Collection
*/
protected $js;
/**
* Create a new instance of FleetCartAssetPipeline.
*
* @param \Modules\Core\Foundation\Asset\Manager\AssetManager $assetManager
*/
public function __construct(AssetManager $assetManager)
{
$this->css = new Collection;
$this->js = new Collection;
$this->assetManager = $assetManager;
}
/**
* Return all css files to include.
*
* @return \Illuminate\Support\Collection
*/
public function allCss()
{
return $this->css;
}
/**
* Return all js files to include.
*
* @return \Illuminate\Support\Collection
*/
public function allJs()
{
return $this->js;
}
/**
* Require assets for the view.
*
* @param string|array $assets
* @return $this
*/
public function requireAssets($assets)
{
$assets = is_array($assets) ? $assets : func_get_args();
foreach ($assets as $asset) {
$this->addAsset($asset);
}
return $this;
}
/**
* Add asset to css/js collection.
*
* @param string $asset
* @return void
*/
private function addAsset($asset)
{
$extension = pathinfo($asset, PATHINFO_EXTENSION);
if ($extension === 'css') {
$collection = $this->css;
$assetPath = $this->assetManager->getCss($asset);
} elseif ($extension === 'js') {
$collection = $this->js;
$assetPath = $this->assetManager->getJs($asset);
}
$collection->put($asset, $assetPath);
}
/**
* Add an asset before another one.
*
* @param string $asset
* @return void
*/
public function before($asset)
{
$this->insert($asset, 'before');
}
/**
* Add an asset after another one.
*
* @param string $asset
* @return void
*/
public function after($asset)
{
$this->insert($asset, 'after');
}
/**
* Insert an asset in right order.
*
* @param string $asset
* @param string $offset
*/
private function insert($asset, $offset = 'before')
{
$offset = $offset === 'before' ? 0 : 1;
list($assets, $collection) = $this->findDependenciesForKey($asset);
list($key, $value) = $this->getLastKeyAndValueOf($assets);
$pos = $this->getPositionInArray($asset, $assets);
$assets = array_merge(
array_slice($assets, 0, $pos + $offset, true),
[$key => $value],
array_slice($assets, $pos, count($assets) - 1, true)
);
$this->$collection = new Collection($assets);
}
/**
* Find in which collection the given asset exists.
*
* @param string $asset
* @return array
*/
private function findDependenciesForKey($asset)
{
if ($this->css->get($asset)) {
return [$this->css->all(), 'css'];
}
return [$this->js->all(), 'js'];
}
/**
* Get the last key and value the given array.
*
* @param array $assets
* @return array
*/
private function getLastKeyAndValueOf(array $assets)
{
$value = end($assets);
$key = key($assets);
reset($assets);
return [$key, $value];
}
/**
* Return the position in the array of the given key.
*
* @param string $asset
* @param array $assets
* @return int
*/
private function getPositionInArray($asset, array $assets)
{
return array_search($asset, array_keys($assets), true);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Modules\Core\Foundation\Asset\Types;
use Illuminate\Support\Facades\File;
abstract class Asset
{
protected function asset($url)
{
list($dirname, $name, $extension) = $this->parse($url);
$url = "{$dirname}/{$name}";
if ($extension === 'css' && is_rtl()) {
$url .= '.rtl';
}
return "{$url}.{$extension}";
}
private function parse($url)
{
return [
File::dirname($url),
File::name($url),
File::extension($url),
];
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Modules\Core\Foundation\Asset\Types;
interface AssetType
{
/**
* Get the URL.
*
* @return string
*/
public function url();
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Core\Foundation\Asset\Types;
use InvalidArgumentException;
class AssetTypeFactory
{
/**
* @param $asset
* @return \Modules\Core\Foundation\Asset\Types\AssetType
*
* @throws \InvalidArgumentException
*/
public function make($asset)
{
$typeClass = 'Modules\Core\Foundation\Asset\Types\\' . ucfirst(key($asset)) . 'Asset';
if (! class_exists($typeClass)) {
throw new InvalidArgumentException("Asset Type Class [{$typeClass}] not found");
}
return new $typeClass(
$asset[key($asset)]
);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Modules\Core\Foundation\Asset\Types;
class CdnAsset implements AssetType
{
private $path;
public function __construct($path)
{
$this->path = $path;
}
public function url()
{
return $this->path;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Modules\Core\Foundation\Asset\Types;
use Nwidart\Modules\Facades\Module;
class ModuleAsset extends Asset implements AssetType
{
private $path;
public function __construct($path)
{
$this->path = $path;
}
public function url()
{
return $this->asset(
Module::asset($this->path)
);
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Modules\Core\Foundation\Asset\Types;
use Theme;
class ThemeAsset extends Asset implements AssetType
{
private $path;
public function __construct($path)
{
$this->path = $path;
}
public function url()
{
return $this->asset(
Theme::url($this->path)
);
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Modules\Core\Http\Middleware;
use Closure;
class AdminMiddleware
{
/**
* The routes that should be excluded from verification.
*
* @var array
*/
protected $except = [
'admin.login.*',
'admin.reset.*',
];
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, Closure $next)
{
if (auth()->check() && auth()->user()->isCustomer()) {
return redirect()->route('account.dashboard.index');
}
if ($this->inExceptArray($request) || auth()->check()) {
return $next($request);
}
return redirect()->guest(route('admin.login'));
}
/**
* Determine if the request URI is in except array.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function inExceptArray($request)
{
foreach ($this->except as $except) {
$routeName = optional($request->route())->getName();
if (preg_match("/{$except}/", $routeName)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Modules\Core\Http\Middleware;
use Closure;
class Authenticate
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle($request, Closure $next)
{
if (auth()->check()) {
return $next($request);
}
$url = url()->full();
if (! $request->isMethod('get')) {
$url = url()->previous();
}
session()->put('url.intended', $url);
if ($request->ajax()) {
abort(403, 'Unauthenticated.');
}
return redirect()->route('login');
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Modules\Core\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class Authorization
{
/**
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $permission
* @param string $to
* @return \Illuminate\Http\Response
*/
public function handle(Request $request, Closure $next, $permission, $to = '')
{
if (! auth()->user()->hasAccess($permission)) {
return $this->handleUnauthorizedRequest($request, $permission);
}
return $next($request);
}
/**
* @param \Illuminate\Http\Request $request
* @param string $permission
* @return \Illuminate\Http\Response
*/
private function handleUnauthorizedRequest(Request $request, $permission)
{
if ($request->ajax()) {
abort(401, 'Unauthorized.');
}
return back()->withError(trans('admin::messages.permission_denied', ['permission' => $permission]));
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Core\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class GuestMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Illuminate\Http\Response
*/
public function handle(Request $request, Closure $next)
{
if (auth()->check()) {
$route = app('inAdminPanel') ? 'admin.dashboard.index' : 'account.dashboard.index';
return redirect()->route($route);
}
return $next($request);
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace Modules\Core\Http\Requests;
use Closure;
use Illuminate\Foundation\Http\FormRequest;
abstract class Request extends FormRequest
{
/**
* Available attributes.
*
* @var string
*/
protected $availableAttributes = '';
/**
* Current processed locale.
*
* @var string
*/
protected $localeKey;
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [];
}
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes()
{
$attributes = trans($this->availableAttributes) ?: [];
if (! is_array($attributes)) {
return [];
}
return array_map('mb_strtolower', array_dot($attributes));
}
/**
* Get custom messages for validator errors.
*
* @return array
*/
public function messages()
{
$attributesAndRules = $this->parseRules($this->rules());
$messages = [];
foreach ($attributesAndRules as $attributeAndRule) {
$rule = last(explode('.', $attributeAndRule));
$messages[$attributeAndRule] = trans("core::validation.{$rule}");
}
return $messages;
}
/**
* Parse rules for the given attributes.
*
* Gives
* [
* 'name' => 'required|size:60',
* ]
*
* Returns
* [
* 'name.required',
* 'name.size',
* ]
*
* @param array $rules
* @return array
*/
protected function parseRules(array $rules)
{
$attributesAndRules = [];
foreach ($rules as $attribute => $rulesList) {
if (! is_array($rulesList)) {
$rulesList = explode('|', $rulesList);
}
foreach ($rulesList as $rule) {
if ($rule instanceof Closure) {
continue;
}
if (strpos($rule, ':') !== false) {
list($rule) = explode(':', $rule, 2);
}
$attributesAndRules[] = "{$attribute}.{$rule}";
}
}
return $attributesAndRules;
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace Modules\Core\Providers;
use Illuminate\Support\ServiceProvider;
use Modules\Core\Foundation\Asset\Manager\AssetManager;
use Modules\Core\Foundation\Asset\Pipeline\AssetPipeline;
use Modules\Core\Foundation\Asset\Manager\FleetCartAssetManager;
use Modules\Core\Foundation\Asset\Pipeline\FleetCartAssetPipeline;
use Modules\Core\Foundation\Asset\Types\AssetTypeFactory as AssetFactory;
class AssetServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
if (! config('app.installed')) {
return;
}
$this->addThemesAssets();
$this->addModulesAssets();
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton(AssetManager::class, FleetCartAssetManager::class);
$this->app->singleton(AssetPipeline::class, function ($app) {
return new FleetCartAssetPipeline($app[AssetManager::class]);
});
}
/**
* Add themes assets to the asset manager.
*
* @return void
*/
private function addThemesAssets()
{
$theme = strtolower(setting('active_theme'));
if (! is_null($assets = config("fleetcart.themes.{$theme}.assets"))) {
$this->addAssets($assets);
}
}
/**
* Add modules assets to the asset manager.
*
* @return void
*/
private function addModulesAssets()
{
foreach ($this->app['modules']->allEnabled() as $module) {
$assets = config("fleetcart.modules.{$module->get('alias')}.assets");
if (! is_null($assets)) {
$this->addAssets($assets);
}
}
}
/**
* Add the assets from the config file on the asset manager.
*
* @param array $allAssets
* @return void
*/
private function addAssets($assets)
{
// Add all assets to the AssetManager
foreach (array_get($assets, 'all_assets', []) as $assetName => $assetPath) {
$url = $this->app[AssetFactory::class]->make($assetPath)->url();
$this->app[AssetManager::class]->addAsset($assetName, $url);
}
// Add required assets directly to the AssetPipeline
$this->app[AssetPipeline::class]->requireAssets(array_get($assets, 'required_assets', []));
}
}

View File

@@ -0,0 +1,203 @@
<?php
namespace Modules\Core\Providers;
use Exception;
use Modules\Support\Locale;
use Modules\Setting\Entities\Setting;
use Illuminate\Support\ServiceProvider;
use Modules\Setting\Repository as SettingRepository;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class CoreServiceProvider extends ServiceProvider
{
/**
* Core module specific middleware.
*
* @var array
*/
protected $middleware = [
'auth' => \Modules\Core\Http\Middleware\Authenticate::class,
'admin' => \Modules\Core\Http\Middleware\AdminMiddleware::class,
'guest' => \Modules\Core\Http\Middleware\GuestMiddleware::class,
'can' => \Modules\Core\Http\Middleware\Authorization::class,
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
'locale_session_redirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
'localization_redirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
];
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
if (! config('app.installed')) {
return;
}
$this->setupSupportedLocales();
$this->registerSetting();
$this->setupAppLocale();
$this->setupAppCacheDriver();
$this->hideDefaultLocaleInURL();
$this->setupAppTimezone();
$this->setupMailConfig();
$this->registerMiddleware();
$this->registerInAdminPanelState();
$this->blacklistAdminRoutesOnFrontend();
}
/**
* Setup supported locales.
*
* @return void
*/
private function setupSupportedLocales()
{
$supportedLocales = [];
foreach ($this->getSupportedLocales() as $locale) {
$supportedLocales[$locale]['name'] = Locale::name($locale);
}
$this->app['config']->set('laravellocalization.supportedLocales', $supportedLocales);
}
/**
* Get supported locales from database.
*
* @return array
*/
private function getSupportedLocales()
{
try {
return Setting::get('supported_locales', [config('app.locale')]);
} catch (Exception $e) {
return [config('app.locale')];
}
}
/**
* Hide default locale in url for non multi-locale mode.
*
* @return void
*/
private function hideDefaultLocaleInURL()
{
if (! is_multilingual()) {
$this->app['config']->set('laravellocalization.hideDefaultLocaleInURL', true);
}
}
/**
* Register setting binding.
*
* @return void
*/
private function registerSetting()
{
$this->app->singleton('setting', function () {
return new SettingRepository(Setting::allCached());
});
}
/**
* Setup application locale.
*
* @return string
*/
private function setupAppLocale()
{
$this->app['config']->set('app.locale', $defaultLocale = Setting::get('default_locale'));
$this->app['config']->set('app.fallback_locale', $defaultLocale);
$locale = is_null(LaravelLocalization::setLocale()) ? $defaultLocale : null;
LaravelLocalization::setLocale($locale);
}
/**
* Setup application cache driver.
*
* @return void
*/
private function setupAppCacheDriver()
{
$this->app['config']->set('cache.default', config('app.cache') ? 'file' : 'array');
}
/**
* Setup application timezone.
*
* @return void
*/
private function setupAppTimezone()
{
$timezone = setting('default_timezone') ?? config('app.timezone');
date_default_timezone_set($timezone);
$this->app['config']->set('app.timezone', $timezone);
}
/**
* Setup application mail config.
*
* @return void
*/
private function setupMailConfig()
{
$this->app['config']->set('mail.default', 'smtp');
$this->app['config']->set('mail.from.address', setting('mail_from_address'));
$this->app['config']->set('mail.from.name', setting('mail_from_name'));
$this->app['config']->set('mail.mailers.smtp.host', setting('mail_host'));
$this->app['config']->set('mail.mailers.smtp.port', setting('mail_port'));
$this->app['config']->set('mail.mailers.smtp.username', setting('mail_username'));
$this->app['config']->set('mail.mailers.smtp.password', setting('mail_password'));
$this->app['config']->set('mail.mailers.smtp.encryption', setting('mail_encryption'));
}
/**
* Register the filters.
*
* @return void
*/
private function registerMiddleware()
{
foreach ($this->middleware as $name => $middleware) {
$this->app['router']->aliasMiddleware($name, $middleware);
}
}
/**
* Register inAdminPanel state to the IoC container.
*
* @return void
*/
private function registerInAdminPanelState()
{
if ($this->app->runningInConsole()) {
return $this->app['inAdminPanel'] = false;
}
$index = in_array($this->app['request']->segment(1), setting('supported_locales'))
? 2
: 1;
$this->app['inAdminPanel'] = $this->app['request']->segment($index) === 'admin';
}
/**
* Blacklist admin routes on frontend for ziggy package.
*
* @return void
*/
private function blacklistAdminRoutesOnFrontend()
{
if (! $this->app['inAdminPanel']) {
$this->app['config']->set('ziggy.blacklist', ['admin.*']);
}
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace Modules\Core\Providers;
use Nwidart\Modules\Module;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Factory as ModelFactory;
class ModuleServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
foreach ($this->app['modules']->allEnabled() as $module) {
$this->loadViews($module);
$this->loadTranslations($module);
$this->loadConfigs($module);
$this->loadMigrations($module);
$this->loadModelFactories($module);
}
}
/**
* Load views for the given module.
*
* @param \Nwidart\Modules\Module $module
* @return void
*/
private function loadViews(Module $module)
{
$this->loadViewsFrom("{$module->getPath()}/Resources/views", $module->get('alias'));
}
/**
* Load translations for the given module.
*
* @param \Nwidart\Modules\Module $module
* @return void
*/
private function loadTranslations(Module $module)
{
$this->loadTranslationsFrom("{$module->getPath()}/Resources/lang", $module->get('alias'));
}
/**
* Load migrations for the given module.
*
* @param \Nwidart\Modules\Module $module
* @return void
*/
private function loadConfigs(Module $module)
{
collect([
'config' => "{$module->getPath()}/Config/config.php",
'assets' => "{$module->getPath()}/Config/assets.php",
'permissions' => "{$module->getPath()}/Config/permissions.php",
])->filter(function ($path) {
return file_exists($path);
})->each(function ($path, $filename) use ($module) {
$this->mergeConfigFrom($path, "fleetcart.modules.{$module->get('alias')}.{$filename}");
});
}
/**
* Load migrations for the given module.
*
* @param \Nwidart\Modules\Module $module
* @return void
*/
private function loadMigrations(Module $module)
{
$this->loadMigrationsFrom("{$module->getPath()}/Database/Migrations");
}
/**
* Load model factories for the given module.
*
* @param \Nwidart\Modules\Module $module
* @return void
*/
private function loadModelFactories(Module $module)
{
$this->callAfterResolving(ModelFactory::class, function (ModelFactory $factory) use ($module) {
$factory->load("{$module->getPath()}/Database/Factories");
});
}
}

View File

@@ -0,0 +1,121 @@
<?php
namespace Modules\Core\Providers;
use Illuminate\Support\Facades\Route;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
if (config('app.installed')) {
$this->mapModuleRoutes();
$this->mapThemeRoutes();
}
}
/**
* Map routes from all enabled modules.
*
* @return void
*/
private function mapModuleRoutes()
{
foreach ($this->app['modules']->allEnabled() as $module) {
$this->groupRoutes("Modules\\{$module->getName()}\\Http\\Controllers", function () use ($module) {
$this->mapAdminRoutes("{$module->getPath()}/Routes/admin.php");
$this->mapPublicRoutes("{$module->getPath()}/Routes/public.php");
$this->mapApiRoutes("{$module->getPath()}/Routes/api.php");
});
}
}
/**
* Map routes from active theme.
*
* @return void
*/
private function mapThemeRoutes()
{
$theme = $this->app['stylist']->get(setting('active_theme'));
$this->groupRoutes("Themes\\{$theme->getName()}\\Http\\Controllers", function () use ($theme) {
$this->mapAdminRoutes("{$theme->getPath()}/routes/admin.php");
$this->mapPublicRoutes("{$theme->getPath()}/routes/public.php");
$this->mapApiRoutes("{$theme->getPath()}/routes/api.php");
});
}
/**
* Group routes to common prefix and middleware.
*
* @param string $namespace
* @param \Closure $callback
* @return void
*/
private function groupRoutes($namespace, $callback)
{
Route::group([
'namespace' => $namespace,
'prefix' => LaravelLocalization::setLocale(),
'middleware' => ['localize', 'locale_session_redirect', 'localization_redirect', 'web'],
], function () use ($callback) {
$callback();
});
}
/**
* Map admin routes.
*
* @return void
*/
private function mapAdminRoutes($path)
{
if (! file_exists($path)) {
return;
}
Route::group([
'namespace' => 'Admin',
'prefix' => 'admin',
'middleware' => ['admin'],
], function () use ($path) {
require_once $path;
});
}
/**
* Map public routes.
*
* @param string $path
* @return void
*/
private function mapPublicRoutes($path)
{
if (file_exists($path)) {
require_once $path;
}
}
private function mapApiRoutes($path)
{
if (! file_exists($path)) {
return;
}
Route::group([
'namespace' => 'Api',
'prefix' => 'api',
'middleware' => ['api'],
], function () use ($path) {
require_once $path;
});
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Modules\Core\Providers;
use Illuminate\Support\ServiceProvider;
class SearchEngineServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
if (! config('app.installed')) {
return;
}
$this->app['config']->set([
'scout' => [
'driver' => setting('search_engine', 'mysql'),
'algolia' => [
'id' => setting('algolia_app_id'),
'secret' => setting('algolia_secret'),
],
'meilisearch' => [
'host' => setting('meilisearch_host'),
'key' => setting('meilisearch_key'),
],
],
]);
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace Modules\Core\Providers;
use Mehedi\Stylist\Theme\Json;
use Mehedi\Stylist\Theme\Theme;
use Illuminate\Support\ServiceProvider;
class ThemeServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
if (! config('app.installed')) {
return;
}
$activeTheme = setting('active_theme');
if (is_null($activeTheme)) {
return;
}
$this->app['stylist']->activate($activeTheme);
$this->bootTheme($this->app['stylist']->get($activeTheme));
}
/**
* Boot the given theme.
*
* @param \Mehedi\Stylist\Theme\Theme $theme
* @return void
*/
private function bootTheme(Theme $theme)
{
$themeJson = new Json($theme->getPath());
$providers = $themeJson->getJsonAttribute('providers') ?? [];
$themeAlias = $themeJson->getJsonAttribute('alias');
$files = $themeJson->getJsonAttribute('files') ?? [];
$this->registerProviders($providers);
$this->loadTranslations($theme, $themeAlias);
$this->loadConfigs($theme, $themeAlias);
$this->requireFiles($theme, $files);
}
/**
* Register given service providers.
*
* @param array $providers
* @return void
*/
private function registerProviders($providers = [])
{
foreach ($providers as $provider) {
$this->app->register($provider);
}
}
/**
* Load translations for the given theme.
*
* @param string $themeAlias
* @param \Mehedi\Stylist\Theme\Theme $theme
* @return void
*/
private function loadTranslations(Theme $theme, $themeAlias)
{
$this->loadTranslationsFrom("{$theme->getPath()}/resources/lang", $themeAlias);
}
/**
* Load configs for the given theme.
*
* @param string $themeAlias
* @param \Mehedi\Stylist\Theme\Theme $theme
* @return void
*/
private function loadConfigs(Theme $theme, $themeAlias)
{
collect([
'config' => "{$theme->getPath()}/config/config.php",
'assets' => "{$theme->getPath()}/config/assets.php",
'permissions' => "{$theme->getPath()}/config/permissions.php",
])->filter(function ($path) {
return file_exists($path);
})->each(function ($path, $filename) use ($themeAlias) {
$this->mergeConfigFrom($path, "fleetcart.themes.{$themeAlias}.{$filename}");
});
}
/**
* Require the given files.
*
* @param \Mehedi\Stylist\Theme\Theme $theme
* @param array $files
* @return void
*/
private function requireFiles(Theme $theme, $files = [])
{
foreach ($files as $file) {
require_once "{$theme->getPath()}/{$file}";
}
}
}

View File

@@ -0,0 +1,6 @@
<?php
return [
'the_given_data_was_invalid' => 'The given data was invalid.',
'mail_is_not_configured' => 'Mail is not configured properly.',
];

View File

@@ -0,0 +1,80 @@
<?php
return [
'captcha' => 'The captcha code is incorrect.',
'redis' => 'Could not connect to the redis server.',
'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute may only contain letters.',
'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.',
'alpha_num' => 'The :attribute may only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
'between' => [
'numeric' => 'The :attribute must be between :min and :max.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'The :attribute must be between :min and :max characters.',
'array' => 'The :attribute must have between :min and :max items.',
],
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'date' => 'The :attribute is not a valid date.',
'date_format' => 'The :attribute does not match the format :format.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'digits_between' => 'The :attribute must be between :min and :max digits.',
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'email' => 'The :attribute must be a valid email address.',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'max' => [
'numeric' => 'The :attribute may not be greater than :max.',
'file' => 'The :attribute may not be greater than :max kilobytes.',
'string' => 'The :attribute may not be greater than :max characters.',
'array' => 'The :attribute may not have more than :max items.',
],
'mimes' => 'The :attribute must be a file of type: :values.',
'mimetypes' => 'The :attribute must be a file of type: :values.',
'min' => [
'numeric' => 'The :attribute must be at least :min.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
],
'not_in' => 'The selected :attribute is invalid.',
'numeric' => 'The :attribute must be a number.',
'present' => 'The :attribute field must be present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values is present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'same' => 'The :attribute and :other must match.',
'size' => [
'numeric' => 'The :attribute must be :size.',
'file' => 'The :attribute must be :size kilobytes.',
'string' => 'The :attribute must be :size characters.',
'array' => 'The :attribute must contain :size items.',
],
'string' => 'The :attribute must be a string.',
'timezone' => 'The :attribute must be a valid zone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'url' => 'The :attribute format is invalid.',
];

View File

@@ -0,0 +1,34 @@
{
"name": "fleetcart/core",
"description": "The FleetCart Core Module.",
"authors": [
{
"name": "Envay Soft",
"email": "envaysoft@gmail.com"
}
],
"require": {
"php": "^8.0.2",
"algolia/algoliasearch-client-php": "^2.5",
"laravel/scout": "^9.0",
"league/flysystem-aws-s3-v3": "^3.12.2",
"mcamara/laravel-localization": "^1.4",
"meilisearch/meilisearch-php": "^0.18.3",
"predis/predis": "^1.1",
"tightenco/ziggy": "^1.5.0"
},
"autoload": {
"psr-4": {
"Modules\\Core\\": ""
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev"
}

14
Modules/Core/module.json Normal file
View File

@@ -0,0 +1,14 @@
{
"name": "Core",
"alias": "core",
"description": "The FleetCart Core Module.",
"priority": 0,
"providers": [
"Modules\\Core\\Providers\\CoreServiceProvider",
"Modules\\Core\\Providers\\ModuleServiceProvider",
"Modules\\Core\\Providers\\ThemeServiceProvider",
"Modules\\Core\\Providers\\AssetServiceProvider",
"Modules\\Core\\Providers\\SearchEngineServiceProvider",
"Modules\\Core\\Providers\\RouteServiceProvider"
]
}

1525
Modules/Core/yarn.lock Normal file

File diff suppressed because it is too large Load Diff