add: full multi-tenancy control
This commit is contained in:
26
packages/Webkul/Core/composer.json
Executable file
26
packages/Webkul/Core/composer.json
Executable file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "krayin/laravel-core",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jitendra Singh",
|
||||
"email": "jitendra@webkul.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webkul\\Core\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\Core\\Providers\\CoreServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
125
packages/Webkul/Core/src/Acl.php
Normal file
125
packages/Webkul/Core/src/Acl.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Webkul\Core\Acl\AclItem;
|
||||
|
||||
class Acl
|
||||
{
|
||||
/**
|
||||
* acl items.
|
||||
*/
|
||||
protected array $items = [];
|
||||
|
||||
/**
|
||||
* Add a new acl item.
|
||||
*/
|
||||
public function addItem(AclItem $aclItem): void
|
||||
{
|
||||
$this->items[] = $aclItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all acl items.
|
||||
*/
|
||||
public function getItems(): Collection
|
||||
{
|
||||
if (! $this->items) {
|
||||
$this->prepareAclItems();
|
||||
}
|
||||
|
||||
return collect($this->items)
|
||||
->sortBy('sort')
|
||||
->values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Acl Config.
|
||||
*/
|
||||
private function getAclConfig(): array
|
||||
{
|
||||
static $aclConfig;
|
||||
|
||||
if ($aclConfig) {
|
||||
return $aclConfig;
|
||||
}
|
||||
|
||||
$aclConfig = config('acl');
|
||||
|
||||
return $aclConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all roles.
|
||||
*/
|
||||
public function getRoles(): Collection
|
||||
{
|
||||
static $roles;
|
||||
|
||||
if ($roles) {
|
||||
return $roles;
|
||||
}
|
||||
|
||||
$roles = collect($this->getAclConfig())
|
||||
->mapWithKeys(function ($role) {
|
||||
if (is_array($role['route'])) {
|
||||
return collect($role['route'])->mapWithKeys(function ($route) use ($role) {
|
||||
return [$route => $role['key']];
|
||||
});
|
||||
} else {
|
||||
return [$role['route'] => $role['key']];
|
||||
}
|
||||
});
|
||||
|
||||
return $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare acl items.
|
||||
*/
|
||||
private function prepareAclItems(): void
|
||||
{
|
||||
$aclWithDotNotation = [];
|
||||
|
||||
foreach ($this->getAclConfig() as $item) {
|
||||
$aclWithDotNotation[$item['key']] = $item;
|
||||
}
|
||||
|
||||
$acl = Arr::undot(Arr::dot($aclWithDotNotation));
|
||||
|
||||
foreach ($acl as $aclItemKey => $aclItem) {
|
||||
$subAclItems = $this->processSubAclItems($aclItem);
|
||||
|
||||
$this->addItem(new AclItem(
|
||||
key: $aclItemKey,
|
||||
name: trans($aclItem['name']),
|
||||
route: $aclItem['route'],
|
||||
sort: $aclItem['sort'],
|
||||
children: $subAclItems,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sub acl items.
|
||||
*/
|
||||
private function processSubAclItems($aclItem): Collection
|
||||
{
|
||||
return collect($aclItem)
|
||||
->sortBy('sort')
|
||||
->filter(fn ($value, $key) => is_array($value) && $key !== 'route')
|
||||
->map(function ($subAclItem) {
|
||||
$subSubAclItems = $this->processSubAclItems($subAclItem);
|
||||
|
||||
return new AclItem(
|
||||
key: $subAclItem['key'],
|
||||
name: trans($subAclItem['name']),
|
||||
route: $subAclItem['route'],
|
||||
sort: $subAclItem['sort'],
|
||||
children: $subSubAclItems,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
19
packages/Webkul/Core/src/Acl/AclItem.php
Normal file
19
packages/Webkul/Core/src/Acl/AclItem.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Acl;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class AclItem
|
||||
{
|
||||
/**
|
||||
* Create a new AclItem instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $key,
|
||||
public string $name,
|
||||
public array|string $route,
|
||||
public int $sort,
|
||||
public Collection $children,
|
||||
) {}
|
||||
}
|
||||
25
packages/Webkul/Core/src/Config/concord.php
Normal file
25
packages/Webkul/Core/src/Config/concord.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'modules' => [
|
||||
\Webkul\Activity\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Admin\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Attribute\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Automation\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Contact\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Core\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\DataGrid\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\EmailTemplate\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Email\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Lead\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Product\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Quote\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Tag\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\User\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Warehouse\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\WebForm\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\DataTransfer\Providers\ModuleServiceProvider::class,
|
||||
],
|
||||
|
||||
'register_route_models' => true,
|
||||
];
|
||||
62
packages/Webkul/Core/src/Config/cors.php
Normal file
62
packages/Webkul/Core/src/Config/cors.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Laravel CORS Options
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The allowed_methods and allowed_headers options are case-insensitive.
|
||||
|
|
||||
| You don't need to provide both allowed_origins and allowed_origins_patterns.
|
||||
| If one of the strings passed matches, it is considered a valid origin.
|
||||
|
|
||||
| If ['*'] is provided to allowed_methods, allowed_origins or allowed_headers
|
||||
| all methods / origins / headers are allowed.
|
||||
|
|
||||
*/
|
||||
|
||||
/*
|
||||
* You can enable CORS for 1 or multiple paths.
|
||||
* Example: ['api/*']
|
||||
*/
|
||||
'paths' => [
|
||||
'admin/web-forms/forms/*',
|
||||
],
|
||||
|
||||
/*
|
||||
* Matches the request method. `['*']` allows all methods.
|
||||
*/
|
||||
'allowed_methods' => ['*'],
|
||||
|
||||
/*
|
||||
* Matches the request origin. `['*']` allows all origins. Wildcards can be used, eg `*.mydomain.com`
|
||||
*/
|
||||
'allowed_origins' => ['*'],
|
||||
|
||||
/*
|
||||
* Patterns that can be used with `preg_match` to match the origin.
|
||||
*/
|
||||
'allowed_origins_patterns' => [],
|
||||
|
||||
/*
|
||||
* Sets the Access-Control-Allow-Headers response header. `['*']` allows all headers.
|
||||
*/
|
||||
'allowed_headers' => ['*'],
|
||||
|
||||
/*
|
||||
* Sets the Access-Control-Expose-Headers response header with these headers.
|
||||
*/
|
||||
'exposed_headers' => [],
|
||||
|
||||
/*
|
||||
* Sets the Access-Control-Max-Age response header when > 0.
|
||||
*/
|
||||
'max_age' => 0,
|
||||
|
||||
/*
|
||||
* Sets the Access-Control-Allow-Credentials header.
|
||||
*/
|
||||
'supports_credentials' => false,
|
||||
];
|
||||
65
packages/Webkul/Core/src/Config/sanctum.php
Normal file
65
packages/Webkul/Core/src/Config/sanctum.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Stateful Domains
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Requests from the following domains / hosts will receive stateful API
|
||||
| authentication cookies. Typically, these should include your local
|
||||
| and production domains which access your API via a frontend SPA.
|
||||
|
|
||||
*/
|
||||
|
||||
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
|
||||
'%s%s',
|
||||
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
|
||||
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
|
||||
))),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Guards
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This array contains the authentication guards that will be checked when
|
||||
| Sanctum is trying to authenticate a request. If none of these guards
|
||||
| are able to authenticate the request, Sanctum will use the bearer
|
||||
| token that's present on an incoming request for authentication.
|
||||
|
|
||||
*/
|
||||
|
||||
'guard' => ['user'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Expiration Minutes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value controls the number of minutes until an issued token will be
|
||||
| considered expired. If this value is null, personal access tokens do
|
||||
| not expire. This won't tweak the lifetime of first-party sessions.
|
||||
|
|
||||
*/
|
||||
|
||||
'expiration' => null,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When authenticating your first-party SPA with Sanctum you may need to
|
||||
| customize some of the middleware Sanctum uses while processing the
|
||||
| request. You may change the middleware listed below as required.
|
||||
|
|
||||
*/
|
||||
|
||||
'middleware' => [
|
||||
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
|
||||
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
|
||||
],
|
||||
|
||||
];
|
||||
42
packages/Webkul/Core/src/Console/Commands/Version.php
Normal file
42
packages/Webkul/Core/src/Console/Commands/Version.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class Version extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'krayin-crm:version';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Displays current version of Krayin CRM installed';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->comment('v'.core()->version());
|
||||
}
|
||||
}
|
||||
5
packages/Webkul/Core/src/Contracts/CoreConfig.php
Normal file
5
packages/Webkul/Core/src/Contracts/CoreConfig.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Contracts;
|
||||
|
||||
interface CoreConfig {}
|
||||
5
packages/Webkul/Core/src/Contracts/Country.php
Normal file
5
packages/Webkul/Core/src/Contracts/Country.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Contracts;
|
||||
|
||||
interface Country {}
|
||||
5
packages/Webkul/Core/src/Contracts/CountryState.php
Normal file
5
packages/Webkul/Core/src/Contracts/CountryState.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Contracts;
|
||||
|
||||
interface CountryState {}
|
||||
30
packages/Webkul/Core/src/Contracts/Validations/Code.php
Executable file
30
packages/Webkul/Core/src/Contracts/Validations/Code.php
Executable file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Contracts\Validations;
|
||||
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
class Code implements Rule
|
||||
{
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
return preg_match('/^[a-zA-Z]+[a-zA-Z0-9_]+$/', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return trans('core::app.validations.code');
|
||||
}
|
||||
}
|
||||
21
packages/Webkul/Core/src/Contracts/Validations/Decimal.php
Executable file
21
packages/Webkul/Core/src/Contracts/Validations/Decimal.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Contracts\Validations;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
|
||||
class Decimal implements ValidationRule
|
||||
{
|
||||
/**
|
||||
* Run the validation rule.
|
||||
*
|
||||
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
if (! preg_match('/^\d*(\.\d{1,4})?$/', $value)) {
|
||||
$fail(trans('admin::app.validations.message.decimal', ['attribute' => $attribute]));
|
||||
}
|
||||
}
|
||||
}
|
||||
243
packages/Webkul/Core/src/Core.php
Normal file
243
packages/Webkul/Core/src/Core.php
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Webkul\Core\Repositories\CoreConfigRepository;
|
||||
use Webkul\Core\Repositories\CountryRepository;
|
||||
use Webkul\Core\Repositories\CountryStateRepository;
|
||||
|
||||
class Core
|
||||
{
|
||||
/**
|
||||
* The Krayin version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const KRAYIN_VERSION = '2.1.5';
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected CountryRepository $countryRepository,
|
||||
protected CoreConfigRepository $coreConfigRepository,
|
||||
protected CountryStateRepository $countryStateRepository
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Get the version number of the Krayin.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function version()
|
||||
{
|
||||
return static::KRAYIN_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all timezones.
|
||||
*/
|
||||
public function timezones(): array
|
||||
{
|
||||
$timezones = [];
|
||||
|
||||
foreach (timezone_identifiers_list() as $timezone) {
|
||||
$timezones[$timezone] = $timezone;
|
||||
}
|
||||
|
||||
return $timezones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all locales.
|
||||
*/
|
||||
public function locales(): array
|
||||
{
|
||||
$options = [];
|
||||
|
||||
foreach (config('app.available_locales') as $key => $title) {
|
||||
$options[] = [
|
||||
'title' => $title,
|
||||
'value' => $key,
|
||||
];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all countries.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function countries()
|
||||
{
|
||||
return $this->countryRepository->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns country name by code.
|
||||
*/
|
||||
public function country_name(string $code): string
|
||||
{
|
||||
$country = $this->countryRepository->findOneByField('code', $code);
|
||||
|
||||
return $country ? $country->name : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns state name by code.
|
||||
*/
|
||||
public function state_name(string $code): string
|
||||
{
|
||||
$state = $this->countryStateRepository->findOneByField('code', $code);
|
||||
|
||||
return $state ? $state->name : $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all country states.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function states(string $countryCode)
|
||||
{
|
||||
return $this->countryStateRepository->findByField('country_code', $countryCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all grouped states by country code.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function groupedStatesByCountries()
|
||||
{
|
||||
$collection = [];
|
||||
|
||||
foreach ($this->countryStateRepository->all() as $state) {
|
||||
$collection[$state->country_code][] = $state->toArray();
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all grouped states by country code.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function findStateByCountryCode($countryCode = null, $stateCode = null)
|
||||
{
|
||||
$collection = [];
|
||||
|
||||
$collection = $this->countryStateRepository->findByField([
|
||||
'country_code' => $countryCode,
|
||||
'code' => $stateCode,
|
||||
]);
|
||||
|
||||
if (count($collection)) {
|
||||
return $collection->first();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create singleton object through single facade.
|
||||
*
|
||||
* @param string $className
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSingletonInstance($className)
|
||||
{
|
||||
static $instances = [];
|
||||
|
||||
if (array_key_exists($className, $instances)) {
|
||||
return $instances[$className];
|
||||
}
|
||||
|
||||
return $instances[$className] = app($className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatDate($date, $format = 'd M Y h:iA')
|
||||
{
|
||||
return Carbon::parse($date)->format($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Week range.
|
||||
*
|
||||
* @param string $date
|
||||
* @param int $day
|
||||
* @return string
|
||||
*/
|
||||
public function xWeekRange($date, $day)
|
||||
{
|
||||
$ts = strtotime($date);
|
||||
|
||||
if (! $day) {
|
||||
$start = (date('D', $ts) == 'Sun') ? $ts : strtotime('last sunday', $ts);
|
||||
|
||||
return date('Y-m-d', $start);
|
||||
} else {
|
||||
$end = (date('D', $ts) == 'Sat') ? $ts : strtotime('next saturday', $ts);
|
||||
|
||||
return date('Y-m-d', $end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return currency symbol from currency code.
|
||||
*
|
||||
* @param float $price
|
||||
* @return string
|
||||
*/
|
||||
public function currencySymbol($code)
|
||||
{
|
||||
$formatter = new \NumberFormatter(app()->getLocale().'@currency='.$code, \NumberFormatter::CURRENCY);
|
||||
|
||||
return $formatter->getSymbol(\NumberFormatter::CURRENCY_SYMBOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format price with base currency symbol. This method also give ability to encode
|
||||
* the base currency symbol and its optional.
|
||||
*
|
||||
* @param float $price
|
||||
* @return string
|
||||
*/
|
||||
public function formatBasePrice($price)
|
||||
{
|
||||
if (is_null($price)) {
|
||||
$price = 0;
|
||||
}
|
||||
|
||||
$formatter = new \NumberFormatter(app()->getLocale(), \NumberFormatter::CURRENCY);
|
||||
|
||||
return $formatter->formatCurrency($price, config('app.currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config field.
|
||||
*/
|
||||
public function getConfigField(string $fieldName): ?array
|
||||
{
|
||||
return system_config()->getConfigField($fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information for configuration.
|
||||
*/
|
||||
public function getConfigData(string $field): mixed
|
||||
{
|
||||
return system_config()->getConfigData($field);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('core_config', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('code');
|
||||
$table->string('value');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('core_config');
|
||||
}
|
||||
};
|
||||
@@ -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.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('countries', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('code');
|
||||
$table->string('name');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('countries');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('country_states', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('country_code');
|
||||
$table->string('code');
|
||||
$table->string('name');
|
||||
|
||||
$table->integer('country_id')->unsigned();
|
||||
$table->foreign('country_id')->references('id')->on('countries')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('country_states');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?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::table('core_config', function (Blueprint $table) {
|
||||
$table->text('value')->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('core_config', function (Blueprint $table) {
|
||||
$table->string('value')->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
146
packages/Webkul/Core/src/Eloquent/Repository.php
Executable file
146
packages/Webkul/Core/src/Eloquent/Repository.php
Executable file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Eloquent;
|
||||
|
||||
use Prettus\Repository\Contracts\CacheableInterface;
|
||||
use Prettus\Repository\Eloquent\BaseRepository;
|
||||
use Prettus\Repository\Traits\CacheableRepository;
|
||||
|
||||
abstract class Repository extends BaseRepository implements CacheableInterface
|
||||
{
|
||||
use CacheableRepository;
|
||||
|
||||
/**
|
||||
* Find data by field and value
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
* @param array $columns
|
||||
* @return mixed
|
||||
*/
|
||||
public function findOneByField($field, $value = null, $columns = ['*'])
|
||||
{
|
||||
$model = $this->findByField($field, $value, $columns = ['*']);
|
||||
|
||||
return $model->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find data by field and value
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
* @param array $columns
|
||||
* @return mixed
|
||||
*/
|
||||
public function findOneWhere(array $where, $columns = ['*'])
|
||||
{
|
||||
$model = $this->findWhere($where, $columns);
|
||||
|
||||
return $model->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find data by id
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $columns
|
||||
* @return mixed
|
||||
*/
|
||||
public function find($id, $columns = ['*'])
|
||||
{
|
||||
$this->applyCriteria();
|
||||
$this->applyScope();
|
||||
$model = $this->model->find($id, $columns);
|
||||
$this->resetModel();
|
||||
|
||||
return $this->parserResult($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find data by id
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $columns
|
||||
* @return mixed
|
||||
*/
|
||||
public function findOrFail($id, $columns = ['*'])
|
||||
{
|
||||
$this->applyCriteria();
|
||||
$this->applyScope();
|
||||
$model = $this->model->findOrFail($id, $columns);
|
||||
$this->resetModel();
|
||||
|
||||
return $this->parserResult($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count results of repository
|
||||
*
|
||||
* @param string $columns
|
||||
* @return int
|
||||
*/
|
||||
public function count(array $where = [], $columns = '*')
|
||||
{
|
||||
$this->applyCriteria();
|
||||
$this->applyScope();
|
||||
|
||||
if ($where) {
|
||||
$this->applyConditions($where);
|
||||
}
|
||||
|
||||
$result = $this->model->count($columns);
|
||||
$this->resetModel();
|
||||
$this->resetScope();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columns
|
||||
* @return mixed
|
||||
*/
|
||||
public function sum($columns)
|
||||
{
|
||||
$this->applyCriteria();
|
||||
$this->applyScope();
|
||||
|
||||
$sum = $this->model->sum($columns);
|
||||
$this->resetModel();
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columns
|
||||
* @return mixed
|
||||
*/
|
||||
public function avg($columns)
|
||||
{
|
||||
$this->applyCriteria();
|
||||
$this->applyScope();
|
||||
|
||||
$avg = $this->model->avg($columns);
|
||||
$this->resetModel();
|
||||
|
||||
return $avg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getModel($data = [])
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RepositoryException
|
||||
*/
|
||||
public function resetModel()
|
||||
{
|
||||
$this->makeModel();
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
23
packages/Webkul/Core/src/Eloquent/TranslatableModel.php
Executable file
23
packages/Webkul/Core/src/Eloquent/TranslatableModel.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Eloquent;
|
||||
|
||||
use Astrotomic\Translatable\Translatable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TranslatableModel extends Model
|
||||
{
|
||||
use Translatable;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function locale()
|
||||
{
|
||||
if ($this->defaultLocale) {
|
||||
return $this->defaultLocale;
|
||||
}
|
||||
|
||||
return config('translatable.locale') ?: app()->make('translator')->getLocale();
|
||||
}
|
||||
}
|
||||
17
packages/Webkul/Core/src/Exceptions/ViterNotFound.php
Executable file
17
packages/Webkul/Core/src/Exceptions/ViterNotFound.php
Executable file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Exceptions;
|
||||
|
||||
class ViterNotFound extends \Exception
|
||||
{
|
||||
/**
|
||||
* Create an instance.
|
||||
*
|
||||
* @param string $theme
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($namespace)
|
||||
{
|
||||
parent::__construct("Viter with `$namespace` namespace not found. Please add `$namespace` namespace in the `config/krayin-vite.php` file.", 1);
|
||||
}
|
||||
}
|
||||
18
packages/Webkul/Core/src/Facades/Acl.php
Normal file
18
packages/Webkul/Core/src/Facades/Acl.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class Acl extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'acl';
|
||||
}
|
||||
}
|
||||
18
packages/Webkul/Core/src/Facades/Core.php
Executable file
18
packages/Webkul/Core/src/Facades/Core.php
Executable file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class Core extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'core';
|
||||
}
|
||||
}
|
||||
18
packages/Webkul/Core/src/Facades/Menu.php
Normal file
18
packages/Webkul/Core/src/Facades/Menu.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class Menu extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'menu';
|
||||
}
|
||||
}
|
||||
18
packages/Webkul/Core/src/Facades/SystemConfig.php
Normal file
18
packages/Webkul/Core/src/Facades/SystemConfig.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class SystemConfig extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'system_config';
|
||||
}
|
||||
}
|
||||
27
packages/Webkul/Core/src/Helpers/Helper.php
Normal file
27
packages/Webkul/Core/src/Helpers/Helper.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Helpers;
|
||||
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return array
|
||||
*/
|
||||
public function jsonTranslations($packageName)
|
||||
{
|
||||
$currentLocale = app()->getLocale();
|
||||
|
||||
$path = __DIR__."/../../../$packageName/src/Resources/lang/$currentLocale/app.php";
|
||||
|
||||
if (is_string($path) && is_readable($path)) {
|
||||
return include $path;
|
||||
} else {
|
||||
$currentLocale = 'en';
|
||||
|
||||
$path = __DIR__."/../../../$packageName/src/Resources/lang/$currentLocale/app.php";
|
||||
|
||||
return include $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
packages/Webkul/Core/src/Http/Controllers/CoreController.php
Normal file
40
packages/Webkul/Core/src/Http/Controllers/CoreController.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class CoreController extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view($this->_config['view'], $this->_config);
|
||||
}
|
||||
}
|
||||
74
packages/Webkul/Core/src/Http/helpers.php
Executable file
74
packages/Webkul/Core/src/Http/helpers.php
Executable file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
use Webkul\Core\Acl;
|
||||
use Webkul\Core\Core;
|
||||
use Webkul\Core\Menu;
|
||||
use Webkul\Core\SystemConfig;
|
||||
use Webkul\Core\ViewRenderEventManager;
|
||||
use Webkul\Core\Vite;
|
||||
|
||||
if (! function_exists('core')) {
|
||||
/**
|
||||
* Core helper.
|
||||
*/
|
||||
function core(): Core
|
||||
{
|
||||
return app('core');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('menu')) {
|
||||
/**
|
||||
* Menu helper.
|
||||
*/
|
||||
function menu(): Menu
|
||||
{
|
||||
return app('menu');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('acl')) {
|
||||
/**
|
||||
* Acl helper.
|
||||
*/
|
||||
function acl(): Acl
|
||||
{
|
||||
return app('acl');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('system_config')) {
|
||||
/**
|
||||
* System Config helper.
|
||||
*/
|
||||
function system_config(): SystemConfig
|
||||
{
|
||||
return app('system_config');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('view_render_event')) {
|
||||
/**
|
||||
* View render event helper.
|
||||
*/
|
||||
function view_render_event($eventName, $params = null)
|
||||
{
|
||||
app()->singleton(ViewRenderEventManager::class);
|
||||
|
||||
$viewEventManager = app()->make(ViewRenderEventManager::class);
|
||||
|
||||
$viewEventManager->handleRenderEvent($eventName, $params);
|
||||
|
||||
return $viewEventManager->render();
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('vite')) {
|
||||
/**
|
||||
* Vite helper.
|
||||
*/
|
||||
function vite(): Vite
|
||||
{
|
||||
return app(Vite::class);
|
||||
}
|
||||
}
|
||||
188
packages/Webkul/Core/src/Menu.php
Normal file
188
packages/Webkul/Core/src/Menu.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Webkul\Core\Menu\MenuItem;
|
||||
|
||||
class Menu
|
||||
{
|
||||
/**
|
||||
* Menu items.
|
||||
*/
|
||||
private array $items = [];
|
||||
|
||||
/**
|
||||
* Config menu.
|
||||
*/
|
||||
private array $configMenu = [];
|
||||
|
||||
/**
|
||||
* Contains current item key.
|
||||
*/
|
||||
private string $currentKey = '';
|
||||
|
||||
/**
|
||||
* Menu area for admin.
|
||||
*/
|
||||
const ADMIN = 'admin';
|
||||
|
||||
/**
|
||||
* Menu area for customer.
|
||||
*/
|
||||
const CUSTOMER = 'customer';
|
||||
|
||||
/**
|
||||
* Add a new menu item.
|
||||
*/
|
||||
public function addItem(MenuItem $menuItem): void
|
||||
{
|
||||
$this->items[] = $menuItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all menu items.
|
||||
*/
|
||||
public function getItems(?string $area = null, string $key = ''): Collection
|
||||
{
|
||||
if (! $area) {
|
||||
throw new \Exception('Area must be provided to get menu items.');
|
||||
}
|
||||
|
||||
static $items;
|
||||
|
||||
if ($items) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
$configMenu = collect(config("menu.$area"))->map(function ($item) {
|
||||
return Arr::except([
|
||||
...$item,
|
||||
'url' => route($item['route'], $item['params'] ?? []),
|
||||
], ['params']);
|
||||
});
|
||||
|
||||
switch ($area) {
|
||||
case self::ADMIN:
|
||||
$this->configMenu = $configMenu
|
||||
->filter(fn ($item) => bouncer()->hasPermission($item['key']))
|
||||
->toArray();
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->configMenu = $configMenu->toArray();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (! $this->items) {
|
||||
$this->prepareMenuItems();
|
||||
}
|
||||
|
||||
$items = collect($this->items)->sortBy(fn ($item) => $item->getPosition());
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get admin menu by key or keys.
|
||||
*/
|
||||
public function getAdminMenuByKey(array|string $keys): mixed
|
||||
{
|
||||
$items = $this->getItems('admin');
|
||||
|
||||
$keysArray = (array) $keys;
|
||||
|
||||
$filteredItems = $items->filter(fn ($item) => in_array($item->getKey(), $keysArray));
|
||||
|
||||
return is_array($keys) ? $filteredItems : $filteredItems->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare menu items.
|
||||
*/
|
||||
private function prepareMenuItems(): void
|
||||
{
|
||||
$menuWithDotNotation = [];
|
||||
|
||||
foreach ($this->configMenu as $item) {
|
||||
if (strpos(request()->url(), route($item['route'])) !== false) {
|
||||
$this->currentKey = $item['key'];
|
||||
}
|
||||
|
||||
$menuWithDotNotation[$item['key']] = $item;
|
||||
}
|
||||
|
||||
$menu = Arr::undot(Arr::dot($menuWithDotNotation));
|
||||
|
||||
foreach ($menu as $menuItemKey => $menuItem) {
|
||||
$this->addItem(new MenuItem(
|
||||
key: $menuItemKey,
|
||||
name: trans($menuItem['name']),
|
||||
route: $menuItem['route'],
|
||||
url: $menuItem['url'],
|
||||
sort: $menuItem['sort'],
|
||||
icon: $menuItem['icon-class'],
|
||||
info: trans($menuItem['info'] ?? ''),
|
||||
children: $this->processSubMenuItems($menuItem),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sub menu items.
|
||||
*/
|
||||
private function processSubMenuItems($menuItem): Collection
|
||||
{
|
||||
return collect($menuItem)
|
||||
->sortBy('sort')
|
||||
->filter(fn ($value) => is_array($value))
|
||||
->map(function ($subMenuItem) {
|
||||
$subSubMenuItems = $this->processSubMenuItems($subMenuItem);
|
||||
|
||||
return new MenuItem(
|
||||
key: $subMenuItem['key'],
|
||||
name: trans($subMenuItem['name']),
|
||||
route: $subMenuItem['route'],
|
||||
url: $subMenuItem['url'],
|
||||
sort: $subMenuItem['sort'],
|
||||
icon: $subMenuItem['icon-class'],
|
||||
info: trans($subMenuItem['info'] ?? ''),
|
||||
children: $subSubMenuItems,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current active menu.
|
||||
*/
|
||||
public function getCurrentActiveMenu(?string $area = null): ?MenuItem
|
||||
{
|
||||
$currentKey = implode('.', array_slice(explode('.', $this->currentKey), 0, 2));
|
||||
|
||||
return $this->findMatchingItem($this->getItems($area), $currentKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finding the matching item.
|
||||
*/
|
||||
private function findMatchingItem($items, $currentKey): ?MenuItem
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
if ($item->key == $currentKey) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
if ($item->haveChildren()) {
|
||||
$matchingChild = $this->findMatchingItem($item->getChildren(), $currentKey);
|
||||
|
||||
if ($matchingChild) {
|
||||
return $matchingChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
200
packages/Webkul/Core/src/Menu/MenuItem.php
Normal file
200
packages/Webkul/Core/src/Menu/MenuItem.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Menu;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class MenuItem
|
||||
{
|
||||
/**
|
||||
* Create a new MenuItem instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
private string $key,
|
||||
private string $name,
|
||||
private string $route,
|
||||
private string $url,
|
||||
private int $sort,
|
||||
private string $icon,
|
||||
private string $info,
|
||||
private Collection $children,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Set name of menu item.
|
||||
*/
|
||||
public function setName(string $name): self
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of menu item.
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set position of menu item.
|
||||
*/
|
||||
public function setPosition(int $sort): self
|
||||
{
|
||||
$this->sort = $sort;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get position of menu item.
|
||||
*/
|
||||
public function getPosition()
|
||||
{
|
||||
return $this->sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set icon of menu item.
|
||||
*/
|
||||
public function setIcon(string $icon): self
|
||||
{
|
||||
$this->icon = $icon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the icon of menu item.
|
||||
*/
|
||||
public function getIcon(): string
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set info of menu item.
|
||||
*/
|
||||
public function setInfo(string $info): self
|
||||
{
|
||||
$this->info = $info;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get info of menu item.
|
||||
*/
|
||||
public function getInfo(): string
|
||||
{
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route of menu item.
|
||||
*/
|
||||
public function setRoute(string $route): self
|
||||
{
|
||||
$this->route = $route;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current route.
|
||||
*/
|
||||
public function getRoute(): string
|
||||
{
|
||||
return $this->route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set url of menu item.
|
||||
*/
|
||||
public function setUrl(string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url of the menu item.
|
||||
*/
|
||||
public function getUrl(): string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the key of the menu item.
|
||||
*/
|
||||
public function setKey(string $key): self
|
||||
{
|
||||
$this->key = $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key of the menu item.
|
||||
*/
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set children of menu item.
|
||||
*/
|
||||
public function setChildren(Collection $children): self
|
||||
{
|
||||
$this->children = $children;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check weather menu item have children or not.
|
||||
*/
|
||||
public function haveChildren(): bool
|
||||
{
|
||||
return $this->children->isNotEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children of menu item.
|
||||
*/
|
||||
public function getChildren(): Collection
|
||||
{
|
||||
if (! $this->haveChildren()) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check weather menu item is active or not.
|
||||
*/
|
||||
public function isActive(): bool
|
||||
{
|
||||
if (request()->fullUrlIs($this->getUrl().'*')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->haveChildren()) {
|
||||
foreach ($this->getChildren() as $child) {
|
||||
if ($child->isActive()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
24
packages/Webkul/Core/src/Models/CoreConfig.php
Executable file
24
packages/Webkul/Core/src/Models/CoreConfig.php
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Core\Contracts\CoreConfig as CoreConfigContract;
|
||||
|
||||
class CoreConfig extends Model implements CoreConfigContract
|
||||
{
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $table = 'core_config';
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'value',
|
||||
'locale',
|
||||
];
|
||||
|
||||
protected $hidden = ['token'];
|
||||
}
|
||||
7
packages/Webkul/Core/src/Models/CoreConfigProxy.php
Normal file
7
packages/Webkul/Core/src/Models/CoreConfigProxy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CoreConfigProxy extends ModelProxy {}
|
||||
11
packages/Webkul/Core/src/Models/Country.php
Executable file
11
packages/Webkul/Core/src/Models/Country.php
Executable file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Core\Contracts\Country as CountryContract;
|
||||
|
||||
class Country extends Model implements CountryContract
|
||||
{
|
||||
public $timestamps = false;
|
||||
}
|
||||
7
packages/Webkul/Core/src/Models/CountryProxy.php
Normal file
7
packages/Webkul/Core/src/Models/CountryProxy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CountryProxy extends ModelProxy {}
|
||||
11
packages/Webkul/Core/src/Models/CountryState.php
Executable file
11
packages/Webkul/Core/src/Models/CountryState.php
Executable file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Core\Contracts\CountryState as CountryStateContract;
|
||||
|
||||
class CountryState extends Model implements CountryStateContract
|
||||
{
|
||||
public $timestamps = false;
|
||||
}
|
||||
7
packages/Webkul/Core/src/Models/CountryStateProxy.php
Normal file
7
packages/Webkul/Core/src/Models/CountryStateProxy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CountryStateProxy extends ModelProxy {}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Providers;
|
||||
|
||||
use Konekt\Concord\BaseModuleServiceProvider as ConcordBaseModuleServiceProvider;
|
||||
|
||||
class BaseModuleServiceProvider extends ConcordBaseModuleServiceProvider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
if ($this->areMigrationsEnabled()) {
|
||||
$this->registerMigrations();
|
||||
}
|
||||
|
||||
if ($this->areModelsEnabled()) {
|
||||
$this->registerModels();
|
||||
$this->registerEnums();
|
||||
$this->registerRequestTypes();
|
||||
}
|
||||
|
||||
if ($this->areViewsEnabled()) {
|
||||
$this->registerViews();
|
||||
}
|
||||
|
||||
if ($routes = $this->config('routes', true)) {
|
||||
$this->registerRoutes($routes);
|
||||
}
|
||||
}
|
||||
}
|
||||
90
packages/Webkul/Core/src/Providers/CoreServiceProvider.php
Normal file
90
packages/Webkul/Core/src/Providers/CoreServiceProvider.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Providers;
|
||||
|
||||
use Illuminate\Foundation\AliasLoader;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Webkul\Core\Acl;
|
||||
use Webkul\Core\Console\Commands\Version;
|
||||
use Webkul\Core\Core;
|
||||
use Webkul\Core\Facades\Acl as AclFacade;
|
||||
use Webkul\Core\Facades\Core as CoreFacade;
|
||||
use Webkul\Core\Facades\Menu as MenuFacade;
|
||||
use Webkul\Core\Facades\SystemConfig as SystemConfigFacade;
|
||||
use Webkul\Core\Menu;
|
||||
use Webkul\Core\SystemConfig;
|
||||
|
||||
class CoreServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
include __DIR__.'/../Http/helpers.php';
|
||||
|
||||
$this->loadMigrationsFrom(__DIR__.'/../Database/Migrations');
|
||||
|
||||
$this->loadTranslationsFrom(__DIR__.'/../Resources/lang', 'core');
|
||||
|
||||
$this->publishes([
|
||||
dirname(__DIR__).'/Config/concord.php' => config_path('concord.php'),
|
||||
dirname(__DIR__).'/Config/cors.php' => config_path('cors.php'),
|
||||
dirname(__DIR__).'/Config/sanctum.php' => config_path('sanctum.php'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->registerCommands();
|
||||
|
||||
$this->registerFacades();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Bouncer as a singleton.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerFacades()
|
||||
{
|
||||
$loader = AliasLoader::getInstance();
|
||||
|
||||
$loader->alias('acl', AclFacade::class);
|
||||
|
||||
$loader->alias('core', CoreFacade::class);
|
||||
|
||||
$loader->alias('system_config', SystemConfigFacade::class);
|
||||
|
||||
$loader->alias('menu', MenuFacade::class);
|
||||
|
||||
$this->app->singleton('acl', fn () => app(Acl::class));
|
||||
|
||||
$this->app->singleton('core', fn () => app(Core::class));
|
||||
|
||||
$this->app->singleton('system_config', fn () => app()->make(SystemConfig::class));
|
||||
|
||||
$this->app->singleton('menu', fn () => app()->make(Menu::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the console commands of this package.
|
||||
*/
|
||||
protected function registerCommands(): void
|
||||
{
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->commands([
|
||||
Version::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
packages/Webkul/Core/src/Providers/ModuleServiceProvider.php
Normal file
12
packages/Webkul/Core/src/Providers/ModuleServiceProvider.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Providers;
|
||||
|
||||
class ModuleServiceProvider extends BaseModuleServiceProvider
|
||||
{
|
||||
protected $models = [
|
||||
\Webkul\Core\Models\CoreConfig::class,
|
||||
\Webkul\Core\Models\Country::class,
|
||||
\Webkul\Core\Models\CountryState::class,
|
||||
];
|
||||
}
|
||||
234
packages/Webkul/Core/src/Repositories/CoreConfigRepository.php
Executable file
234
packages/Webkul/Core/src/Repositories/CoreConfigRepository.php
Executable file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Repositories;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Webkul\Core\Contracts\CoreConfig;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
|
||||
class CoreConfigRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* Specify model class name.
|
||||
*/
|
||||
public function model(): string
|
||||
{
|
||||
return CoreConfig::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration title.
|
||||
*/
|
||||
protected function getTranslatedTitle(mixed $configuration): string
|
||||
{
|
||||
if (
|
||||
method_exists($configuration, 'getTitle')
|
||||
&& ! is_null($configuration->getTitle())
|
||||
) {
|
||||
return trans($configuration->getTitle());
|
||||
}
|
||||
|
||||
if (
|
||||
method_exists($configuration, 'getName')
|
||||
&& ! is_null($configuration->getName())
|
||||
) {
|
||||
return trans($configuration->getName());
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children and fields.
|
||||
*/
|
||||
protected function getChildrenAndFields(mixed $configuration, string $searchTerm, array $path, array &$results): void
|
||||
{
|
||||
if (
|
||||
method_exists($configuration, 'getChildren')
|
||||
|| method_exists($configuration, 'getFields')
|
||||
) {
|
||||
$children = $configuration->haveChildren()
|
||||
? $configuration->getChildren()
|
||||
: $configuration->getFields();
|
||||
|
||||
$tempPath = array_merge($path, [[
|
||||
'key' => $configuration->getKey() ?? null,
|
||||
'title' => $this->getTranslatedTitle($configuration),
|
||||
]]);
|
||||
|
||||
$results = array_merge($results, $this->search($children, $searchTerm, $tempPath));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search configuration.
|
||||
*
|
||||
* @param array $items
|
||||
*/
|
||||
public function search(Collection $items, string $searchTerm, array $path = []): array
|
||||
{
|
||||
$results = [];
|
||||
|
||||
foreach ($items as $configuration) {
|
||||
$title = $this->getTranslatedTitle($configuration);
|
||||
|
||||
if (
|
||||
stripos($title, $searchTerm) !== false
|
||||
&& count($path)
|
||||
) {
|
||||
$queryParam = $path[1]['key'] ?? $configuration->getKey();
|
||||
|
||||
$results[] = [
|
||||
'title' => implode(' > ', [...Arr::pluck($path, 'title'), $title]),
|
||||
'url' => route('admin.configuration.index', Str::replace('.', '/', $queryParam)),
|
||||
];
|
||||
}
|
||||
|
||||
$this->getChildrenAndFields($configuration, $searchTerm, $path, $results);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create core configuration.
|
||||
*/
|
||||
public function create(array $data): void
|
||||
{
|
||||
unset($data['_token']);
|
||||
|
||||
$preparedData = [];
|
||||
|
||||
foreach ($data as $method => $fieldData) {
|
||||
$recursiveData = $this->recursiveArray($fieldData, $method);
|
||||
|
||||
foreach ($recursiveData as $fieldName => $value) {
|
||||
if (
|
||||
is_array($value)
|
||||
&& isset($value['delete'])
|
||||
) {
|
||||
$coreConfigValues = $this->model->where('code', $fieldName)->get();
|
||||
|
||||
if ($coreConfigValues->isNotEmpty()) {
|
||||
foreach ($coreConfigValues as $coreConfig) {
|
||||
if (! empty($coreConfig['value'])) {
|
||||
Storage::delete($coreConfig['value']);
|
||||
}
|
||||
|
||||
parent::delete($coreConfig['id']);
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($recursiveData as $fieldName => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $key => $val) {
|
||||
$fieldNameWithKey = $fieldName.'.'.$key;
|
||||
|
||||
$coreConfigValues = $this->model->where('code', $fieldNameWithKey)->get();
|
||||
|
||||
if (request()->hasFile($fieldNameWithKey)) {
|
||||
$val = request()->file($fieldNameWithKey)->store('configuration');
|
||||
}
|
||||
|
||||
if ($coreConfigValues->isNotEmpty()) {
|
||||
foreach ($coreConfigValues as $coreConfig) {
|
||||
if (request()->hasFile($fieldNameWithKey)) {
|
||||
Storage::delete($coreConfig['value']);
|
||||
}
|
||||
|
||||
parent::update(['code' => $fieldNameWithKey, 'value' => $val], $coreConfig->id);
|
||||
}
|
||||
} else {
|
||||
parent::create(['code' => $fieldNameWithKey, 'value' => $val]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (request()->hasFile($fieldName)) {
|
||||
$value = request()->file($fieldName)->store('configuration');
|
||||
}
|
||||
|
||||
$preparedData[] = [
|
||||
'code' => $fieldName,
|
||||
'value' => $value,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($preparedData)) {
|
||||
foreach ($preparedData as $dataItem) {
|
||||
$coreConfigValues = $this->model->where('code', $dataItem['code'])->get();
|
||||
|
||||
if ($coreConfigValues->isNotEmpty()) {
|
||||
foreach ($coreConfigValues as $coreConfig) {
|
||||
parent::update($dataItem, $coreConfig->id);
|
||||
}
|
||||
} else {
|
||||
parent::create($dataItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Event::dispatch('core.configuration.save.after');
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive array.
|
||||
*/
|
||||
public function recursiveArray(array $formData, string $method): array
|
||||
{
|
||||
static $data = [];
|
||||
|
||||
static $recursiveArrayData = [];
|
||||
|
||||
foreach ($formData as $form => $formValue) {
|
||||
$value = $method.'.'.$form;
|
||||
|
||||
if (is_array($formValue)) {
|
||||
$dim = $this->countDim($formValue);
|
||||
|
||||
if ($dim > 1) {
|
||||
$this->recursiveArray($formValue, $value);
|
||||
} elseif ($dim == 1) {
|
||||
$data[$value] = $formValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
$field = core()->getConfigField($key);
|
||||
|
||||
if ($field) {
|
||||
$recursiveArrayData[$key] = $value;
|
||||
} else {
|
||||
foreach ($value as $key1 => $val) {
|
||||
$recursiveArrayData[$key.'.'.$key1] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $recursiveArrayData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return dimension of the array.
|
||||
*/
|
||||
public function countDim(array|string $array): int
|
||||
{
|
||||
if (is_array(reset($array))) {
|
||||
$return = $this->countDim(reset($array)) + 1;
|
||||
} else {
|
||||
$return = 1;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
21
packages/Webkul/Core/src/Repositories/CountryRepository.php
Executable file
21
packages/Webkul/Core/src/Repositories/CountryRepository.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Repositories;
|
||||
|
||||
use Prettus\Repository\Traits\CacheableRepository;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
|
||||
class CountryRepository extends Repository
|
||||
{
|
||||
use CacheableRepository;
|
||||
|
||||
/**
|
||||
* Specify Model class name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function model()
|
||||
{
|
||||
return 'Webkul\Core\Contracts\Country';
|
||||
}
|
||||
}
|
||||
21
packages/Webkul/Core/src/Repositories/CountryStateRepository.php
Executable file
21
packages/Webkul/Core/src/Repositories/CountryStateRepository.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Repositories;
|
||||
|
||||
use Prettus\Repository\Traits\CacheableRepository;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
|
||||
class CountryStateRepository extends Repository
|
||||
{
|
||||
use CacheableRepository;
|
||||
|
||||
/**
|
||||
* Specify Model class name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function model()
|
||||
{
|
||||
return 'Webkul\Core\Contracts\CountryState';
|
||||
}
|
||||
}
|
||||
8
packages/Webkul/Core/src/Resources/lang/ar/app.php
Normal file
8
packages/Webkul/Core/src/Resources/lang/ar/app.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'validations' => [
|
||||
'code' => 'يجب أن يكون الحقل رمزًا صالحًا.',
|
||||
'decimal' => 'يجب أن يكون الحقل رقمًا عشريًا.',
|
||||
],
|
||||
];
|
||||
8
packages/Webkul/Core/src/Resources/lang/en/app.php
Normal file
8
packages/Webkul/Core/src/Resources/lang/en/app.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'validations' => [
|
||||
'code' => 'The field must be a valid code.',
|
||||
'decimal' => 'The field must be a decimal number.',
|
||||
],
|
||||
];
|
||||
8
packages/Webkul/Core/src/Resources/lang/es/app.php
Normal file
8
packages/Webkul/Core/src/Resources/lang/es/app.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'validations' => [
|
||||
'code' => 'El campo debe ser un código válido.',
|
||||
'decimal' => 'El campo debe ser un número decimal.',
|
||||
],
|
||||
];
|
||||
8
packages/Webkul/Core/src/Resources/lang/fa/app.php
Normal file
8
packages/Webkul/Core/src/Resources/lang/fa/app.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'validations' => [
|
||||
'code' => 'این فیلد باید یک کد معتبر باشد.',
|
||||
'decimal' => 'این فیلد باید یک عدد اعشاری باشد.',
|
||||
],
|
||||
];
|
||||
8
packages/Webkul/Core/src/Resources/lang/pt_BR/app.php
Normal file
8
packages/Webkul/Core/src/Resources/lang/pt_BR/app.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'validations' => [
|
||||
'code' => 'O campo deve ser um código válido.',
|
||||
'decimal' => 'O campo deve ser um número decimal.',
|
||||
],
|
||||
];
|
||||
8
packages/Webkul/Core/src/Resources/lang/tr/app.php
Normal file
8
packages/Webkul/Core/src/Resources/lang/tr/app.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'validations' => [
|
||||
'code' => 'Alan geçerli bir kod olmalıdır.',
|
||||
'decimal' => 'Alan ondalık bir sayı olmalıdır.',
|
||||
],
|
||||
];
|
||||
8
packages/Webkul/Core/src/Resources/lang/vi/app.php
Normal file
8
packages/Webkul/Core/src/Resources/lang/vi/app.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'validations' => [
|
||||
'code' => 'Trường phải là một mã hợp lệ.',
|
||||
'decimal' => 'Trường phải là một số thập phân.',
|
||||
],
|
||||
];
|
||||
188
packages/Webkul/Core/src/SystemConfig.php
Normal file
188
packages/Webkul/Core/src/SystemConfig.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Webkul\Core\Repositories\CoreConfigRepository;
|
||||
use Webkul\Core\SystemConfig\Item;
|
||||
|
||||
class SystemConfig
|
||||
{
|
||||
/**
|
||||
* Items array.
|
||||
*/
|
||||
public array $items = [];
|
||||
|
||||
/**
|
||||
* Create a new class instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(protected CoreConfigRepository $coreConfigRepository) {}
|
||||
|
||||
/**
|
||||
* Add Item.
|
||||
*/
|
||||
public function addItem(Item $item): void
|
||||
{
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all configuration items.
|
||||
*/
|
||||
public function getItems(): Collection
|
||||
{
|
||||
if (! $this->items) {
|
||||
$this->prepareConfigurationItems();
|
||||
}
|
||||
|
||||
return collect($this->items)
|
||||
->sortBy('sort');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Core Config
|
||||
*/
|
||||
private function retrieveCoreConfig(): array
|
||||
{
|
||||
static $items;
|
||||
|
||||
if ($items) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
return $items = config('core_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare configuration items.
|
||||
*/
|
||||
public function prepareConfigurationItems()
|
||||
{
|
||||
$configWithDotNotation = [];
|
||||
|
||||
foreach ($this->retrieveCoreConfig() as $item) {
|
||||
$configWithDotNotation[$item['key']] = $item;
|
||||
}
|
||||
|
||||
$configs = Arr::undot(Arr::dot($configWithDotNotation));
|
||||
|
||||
foreach ($configs as $configItem) {
|
||||
$subConfigItems = $this->processSubConfigItems($configItem);
|
||||
|
||||
$this->addItem(new Item(
|
||||
children: $subConfigItems,
|
||||
fields: $configItem['fields'] ?? null,
|
||||
icon: $configItem['icon'] ?? null,
|
||||
key: $configItem['key'],
|
||||
name: trans($configItem['name']),
|
||||
route: $configItem['route'] ?? null,
|
||||
info: trans($configItem['info']) ?? null,
|
||||
sort: $configItem['sort'],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sub config items.
|
||||
*/
|
||||
private function processSubConfigItems($configItem): Collection
|
||||
{
|
||||
return collect($configItem)
|
||||
->sortBy('sort')
|
||||
->filter(fn ($value) => is_array($value) && isset($value['name']))
|
||||
->map(function ($subConfigItem) {
|
||||
$configItemChildren = $this->processSubConfigItems($subConfigItem);
|
||||
|
||||
return new Item(
|
||||
children: $configItemChildren,
|
||||
fields: $subConfigItem['fields'] ?? null,
|
||||
icon: $subConfigItem['icon'] ?? null,
|
||||
key: $subConfigItem['key'],
|
||||
name: trans($subConfigItem['name']),
|
||||
info: trans($subConfigItem['info']) ?? null,
|
||||
route: $subConfigItem['route'] ?? null,
|
||||
sort: $subConfigItem['sort'] ?? null,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active configuration item.
|
||||
*/
|
||||
public function getActiveConfigurationItem(): ?Item
|
||||
{
|
||||
if (! $slug = request()->route('slug')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$activeItem = $this->getItems()->where('key', $slug)->first() ?? null;
|
||||
|
||||
if (! $activeItem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($slug2 = request()->route('slug2')) {
|
||||
$activeItem = $activeItem->getChildren()[$slug2];
|
||||
}
|
||||
|
||||
return $activeItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config field.
|
||||
*/
|
||||
public function getConfigField(string $fieldName): ?array
|
||||
{
|
||||
foreach ($this->retrieveCoreConfig() as $coreData) {
|
||||
if (! isset($coreData['fields'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($coreData['fields'] as $field) {
|
||||
$name = $coreData['key'].'.'.$field['name'];
|
||||
|
||||
if ($name == $fieldName) {
|
||||
return $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default config.
|
||||
*/
|
||||
private function getDefaultConfig(string $field): mixed
|
||||
{
|
||||
$configFieldInfo = $this->getConfigField($field);
|
||||
|
||||
$fields = explode('.', $field);
|
||||
|
||||
array_shift($fields);
|
||||
|
||||
$field = implode('.', $fields);
|
||||
|
||||
return Config::get($field, $configFieldInfo['default'] ?? null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information for configuration
|
||||
*/
|
||||
public function getConfigData(string $field): mixed
|
||||
{
|
||||
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
|
||||
'code' => $field,
|
||||
]);
|
||||
|
||||
if (! $coreConfigValue) {
|
||||
return $this->getDefaultConfig($field);
|
||||
}
|
||||
|
||||
return $coreConfigValue->value;
|
||||
}
|
||||
}
|
||||
123
packages/Webkul/Core/src/SystemConfig/Item.php
Normal file
123
packages/Webkul/Core/src/SystemConfig/Item.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\SystemConfig;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Item
|
||||
{
|
||||
/**
|
||||
* Create a new Item instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public Collection $children,
|
||||
public ?array $fields,
|
||||
public ?string $icon,
|
||||
public ?string $info,
|
||||
public string $key,
|
||||
public string $name,
|
||||
public ?string $route = null,
|
||||
public ?int $sort = null
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Get name of config item.
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Format options.
|
||||
*/
|
||||
private function formatOptions($options)
|
||||
{
|
||||
return is_array($options) ? $options : (is_string($options) ? $options : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fields of config item.
|
||||
*/
|
||||
public function getFields(): Collection
|
||||
{
|
||||
return collect($this->fields)->map(function ($field) {
|
||||
return new ItemField(
|
||||
item_key: $this->key,
|
||||
name: $field['name'],
|
||||
title: $field['title'],
|
||||
info: $field['info'] ?? null,
|
||||
type: $field['type'],
|
||||
depends: $field['depends'] ?? null,
|
||||
path: $field['path'] ?? null,
|
||||
validation: $field['validation'] ?? null,
|
||||
default: $field['default'] ?? null,
|
||||
channel_based: $field['channel_based'] ?? null,
|
||||
locale_based: $field['locale_based'] ?? null,
|
||||
options: $this->formatOptions($field['options'] ?? null),
|
||||
tinymce: $field['tinymce'] ?? false,
|
||||
is_visible: true,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of config item.
|
||||
*/
|
||||
public function getInfo(): ?string
|
||||
{
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current route.
|
||||
*/
|
||||
public function getRoute(): string
|
||||
{
|
||||
return $this->route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url of the config item.
|
||||
*/
|
||||
public function getUrl(): string
|
||||
{
|
||||
return route($this->getRoute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key of the config item.
|
||||
*/
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Icon.
|
||||
*/
|
||||
public function getIcon(): ?string
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check weather config item have children or not.
|
||||
*/
|
||||
public function haveChildren(): bool
|
||||
{
|
||||
return $this->children->isNotEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children of config item.
|
||||
*/
|
||||
public function getChildren(): Collection
|
||||
{
|
||||
if (! $this->haveChildren()) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return $this->children;
|
||||
}
|
||||
}
|
||||
244
packages/Webkul/Core/src/SystemConfig/ItemField.php
Normal file
244
packages/Webkul/Core/src/SystemConfig/ItemField.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\SystemConfig;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ItemField
|
||||
{
|
||||
/**
|
||||
* Laravel to Vee Validation mappings.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $veeValidateMappings = [
|
||||
'min'=> 'min_value',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new ItemField instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $item_key,
|
||||
public string $name,
|
||||
public string $title,
|
||||
public ?string $info,
|
||||
public string $type,
|
||||
public ?string $path,
|
||||
public ?string $validation,
|
||||
public ?string $depends,
|
||||
public ?string $default,
|
||||
public ?bool $channel_based,
|
||||
public ?bool $locale_based,
|
||||
public array|string $options,
|
||||
public bool $is_visible = true,
|
||||
public bool $tinymce = false,
|
||||
) {
|
||||
$this->options = $this->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of config item.
|
||||
*/
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get info of config item.
|
||||
*/
|
||||
public function getInfo(): ?string
|
||||
{
|
||||
return $this->info ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title of config item.
|
||||
*/
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the field should use TinyMCE.
|
||||
*/
|
||||
public function getTinymce(): bool
|
||||
{
|
||||
return $this->tinymce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type of config item.
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path of config item.
|
||||
*/
|
||||
public function getPath(): ?string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item key of config item.
|
||||
*/
|
||||
public function getItemKey(): string
|
||||
{
|
||||
return $this->item_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get validation of config item.
|
||||
*/
|
||||
public function getValidations(): ?string
|
||||
{
|
||||
if (empty($this->validation)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
foreach ($this->veeValidateMappings as $laravelRule => $veeValidateRule) {
|
||||
$this->validation = str_replace($laravelRule, $veeValidateRule, $this->validation);
|
||||
}
|
||||
|
||||
return $this->validation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get depends of config item.
|
||||
*/
|
||||
public function getDepends(): ?string
|
||||
{
|
||||
return $this->depends;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default value of config item.
|
||||
*/
|
||||
public function getDefault(): ?string
|
||||
{
|
||||
return $this->default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get channel based of config item.
|
||||
*/
|
||||
public function getChannelBased(): ?bool
|
||||
{
|
||||
return $this->channel_based;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get locale based of config item.
|
||||
*/
|
||||
public function getLocaleBased(): ?bool
|
||||
{
|
||||
return $this->locale_based;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name field for forms in configuration page.
|
||||
*/
|
||||
public function getNameKey(): string
|
||||
{
|
||||
return $this->item_key.'.'.$this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the field is required.
|
||||
*/
|
||||
public function isRequired(): string
|
||||
{
|
||||
return Str::contains($this->getValidations(), 'required') ? 'required' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get options of config item.
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
if (is_array($this->options)) {
|
||||
return collect($this->options)->map(fn ($option) => [
|
||||
'title' => trans($option['title']),
|
||||
'value' => $option['value'],
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
return collect($this->getFieldOptions($this->options))->map(fn ($option) => [
|
||||
'title' => trans($option['title']),
|
||||
'value' => $option['value'],
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the field to an array.
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getName(),
|
||||
'title' => $this->getTitle(),
|
||||
'info' => $this->getInfo(),
|
||||
'type' => $this->getType(),
|
||||
'path' => $this->getPath(),
|
||||
'depends' => $this->getDepends(),
|
||||
'validation' => $this->getValidations(),
|
||||
'default' => $this->getDefault(),
|
||||
'channel_based' => $this->getChannelBased(),
|
||||
'locale_based' => $this->getLocaleBased(),
|
||||
'options' => $this->getOptions(),
|
||||
'item_key' => $this->getItemKey(),
|
||||
'tinymce' => $this->getTinymce(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name field for forms in configuration page.
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function getNameField($key = null)
|
||||
{
|
||||
if (! $key) {
|
||||
$key = $this->item_key.'.'.$this->name;
|
||||
}
|
||||
|
||||
$nameField = '';
|
||||
|
||||
foreach (explode('.', $key) as $key => $field) {
|
||||
$nameField .= $key === 0 ? $field : '['.$field.']';
|
||||
}
|
||||
|
||||
return $nameField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get depend the field name.
|
||||
*/
|
||||
public function getDependFieldName(): string
|
||||
{
|
||||
if (empty($depends = $this->getDepends())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$dependNameKey = $this->getItemKey().'.'.collect(explode(':', $depends))->first();
|
||||
|
||||
return $this->getNameField($dependNameKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the select options for the field.
|
||||
*/
|
||||
protected function getFieldOptions(string $options): array
|
||||
{
|
||||
[$class, $method] = Str::parseCallback($options);
|
||||
|
||||
return app($class)->$method();
|
||||
}
|
||||
}
|
||||
65
packages/Webkul/Core/src/Traits/PDFHandler.php
Normal file
65
packages/Webkul/Core/src/Traits/PDFHandler.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Traits;
|
||||
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Illuminate\Support\Str;
|
||||
use Mpdf\Mpdf;
|
||||
|
||||
trait PDFHandler
|
||||
{
|
||||
/**
|
||||
* Download PDF.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected function downloadPDF(string $html, ?string $fileName = null)
|
||||
{
|
||||
if (is_null($fileName)) {
|
||||
$fileName = Str::random(32);
|
||||
}
|
||||
|
||||
$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
|
||||
|
||||
if (in_array($direction = app()->getLocale(), ['ar', 'he'])) {
|
||||
$mPDF = new Mpdf([
|
||||
'margin_left' => 0,
|
||||
'margin_right' => 0,
|
||||
'margin_top' => 0,
|
||||
'margin_bottom'=> 0,
|
||||
]);
|
||||
|
||||
$mPDF->SetDirectionality($direction);
|
||||
|
||||
$mPDF->SetDisplayMode('fullpage');
|
||||
|
||||
$mPDF->WriteHTML($this->adjustArabicAndPersianContent($html));
|
||||
|
||||
return response()->streamDownload(fn () => print ($mPDF->Output('', 'S')), $fileName.'.pdf');
|
||||
}
|
||||
|
||||
return PDF::loadHTML($this->adjustArabicAndPersianContent($html))
|
||||
->setPaper('A4', 'portrait')
|
||||
->set_option('defaultFont', 'Courier')
|
||||
->download($fileName.'.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust arabic and persian content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function adjustArabicAndPersianContent(string $html)
|
||||
{
|
||||
$arabic = new \ArPHP\I18N\Arabic;
|
||||
|
||||
$p = $arabic->arIdentify($html);
|
||||
|
||||
for ($i = count($p) - 1; $i >= 0; $i -= 2) {
|
||||
$utf8ar = $arabic->utf8Glyphs(substr($html, $p[$i - 1], $p[$i] - $p[$i - 1]));
|
||||
$html = substr_replace($html, $utf8ar, $p[$i - 1], $p[$i] - $p[$i - 1]);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
81
packages/Webkul/Core/src/Traits/Sanitizer.php
Normal file
81
packages/Webkul/Core/src/Traits/Sanitizer.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core\Traits;
|
||||
|
||||
use enshrined\svgSanitize\data\AllowedAttributes;
|
||||
use enshrined\svgSanitize\data\AllowedTags;
|
||||
use enshrined\svgSanitize\Sanitizer as MainSanitizer;
|
||||
use Exception;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
/**
|
||||
* Trait for sanitizing SVG uploads to prevent security vulnerabilities.
|
||||
*/
|
||||
trait Sanitizer
|
||||
{
|
||||
/**
|
||||
* Sanitize an SVG file to remove potentially malicious content.
|
||||
*/
|
||||
public function sanitizeSvg(string $path, UploadedFile $file): void
|
||||
{
|
||||
if (! $this->isSvgFile($file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$svgContent = Storage::get($path);
|
||||
|
||||
if (! $svgContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sanitizer = new MainSanitizer;
|
||||
$sanitizer->setAllowedAttrs(new AllowedAttributes);
|
||||
$sanitizer->setAllowedTags(new AllowedTags);
|
||||
|
||||
$sanitizer->minify(true);
|
||||
$sanitizer->removeRemoteReferences(true);
|
||||
$sanitizer->removeXMLTag(true);
|
||||
|
||||
$sanitizer->setXMLOptions(LIBXML_NONET | LIBXML_NOBLANKS);
|
||||
|
||||
$sanitizedContent = $sanitizer->sanitize($svgContent);
|
||||
|
||||
if ($sanitizedContent === false) {
|
||||
$patterns = [
|
||||
'/<script\b[^>]*>(.*?)<\/script>/is',
|
||||
'/\bon\w+\s*=\s*["\'][^"\']*["\']/i',
|
||||
'/javascript\s*:/i',
|
||||
'/data\s*:[^,]*base64/i',
|
||||
];
|
||||
|
||||
$sanitizedContent = $svgContent;
|
||||
|
||||
foreach ($patterns as $pattern) {
|
||||
$sanitizedContent = preg_replace($pattern, '', $sanitizedContent);
|
||||
}
|
||||
|
||||
Storage::put($path, $sanitizedContent);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$sanitizedContent = preg_replace('/(<script.*?>.*?<\/script>)|(\son\w+\s*=\s*["\'][^"\']*["\'])/is', '', $sanitizedContent);
|
||||
|
||||
Storage::put($path, $sanitizedContent);
|
||||
} catch (Exception $e) {
|
||||
report($e->getMessage());
|
||||
|
||||
Storage::delete($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the uploaded file is an SVG based on both extension and mime type.
|
||||
*/
|
||||
public function isSvgFile(UploadedFile $file): bool
|
||||
{
|
||||
return str_contains(strtolower($file->getClientOriginalExtension()), 'svg');
|
||||
}
|
||||
}
|
||||
89
packages/Webkul/Core/src/ViewRenderEventManager.php
Executable file
89
packages/Webkul/Core/src/ViewRenderEventManager.php
Executable file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core;
|
||||
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
class ViewRenderEventManager
|
||||
{
|
||||
/**
|
||||
* Contains all templates
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $templates = [];
|
||||
|
||||
/**
|
||||
* Parameters passed with event
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
/**
|
||||
* Fires event for rendering template
|
||||
*
|
||||
* @param string $eventName
|
||||
* @param array|null $params
|
||||
* @return string
|
||||
*/
|
||||
public function handleRenderEvent($eventName, $params = null)
|
||||
{
|
||||
$this->params = $params ?? [];
|
||||
|
||||
Event::dispatch($eventName, $this);
|
||||
|
||||
return $this->templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* get params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* get param
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParam($name)
|
||||
{
|
||||
return optional($this->params)[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add templates for render
|
||||
*
|
||||
* @param string $template
|
||||
* @return void
|
||||
*/
|
||||
public function addTemplate($template)
|
||||
{
|
||||
array_push($this->templates, $template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders templates
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$string = '';
|
||||
|
||||
foreach ($this->templates as $template) {
|
||||
if (view()->exists($template)) {
|
||||
$string .= view($template, $this->params)->render();
|
||||
} elseif (is_string($template)) {
|
||||
$string .= $template;
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
49
packages/Webkul/Core/src/Vite.php
Normal file
49
packages/Webkul/Core/src/Vite.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Core;
|
||||
|
||||
use Illuminate\Support\Facades\Vite as BaseVite;
|
||||
use Webkul\Core\Exceptions\ViterNotFound;
|
||||
|
||||
class Vite
|
||||
{
|
||||
/**
|
||||
* Return the asset URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function asset(string $filename, string $namespace = 'admin')
|
||||
{
|
||||
$viters = config('krayin-vite.viters');
|
||||
|
||||
if (empty($viters[$namespace])) {
|
||||
throw new ViterNotFound($namespace);
|
||||
}
|
||||
|
||||
$url = trim($filename, '/');
|
||||
|
||||
$viteUrl = trim($viters[$namespace]['package_assets_directory'], '/').'/'.$url;
|
||||
|
||||
return BaseVite::useHotFile($viters[$namespace]['hot_file'])
|
||||
->useBuildDirectory($viters[$namespace]['build_directory'])
|
||||
->asset($viteUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set krayin vite.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function set(mixed $entryPoints, string $namespace = 'admin')
|
||||
{
|
||||
$viters = config('krayin-vite.viters');
|
||||
|
||||
if (empty($viters[$namespace])) {
|
||||
throw new ViterNotFound($namespace);
|
||||
}
|
||||
|
||||
return BaseVite::useHotFile($viters[$namespace]['hot_file'])
|
||||
->useBuildDirectory($viters[$namespace]['build_directory'])
|
||||
->withEntryPoints($entryPoints);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user