¨4.0.1¨

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

View File

@@ -25,6 +25,18 @@ class Country
*/
private static $supported;
/**
* Get all country codes.
*
* @return array
*/
public static function codes()
{
return array_keys(self::all());
}
/**
* Get all countries.
*
@@ -39,33 +51,6 @@ class Country
return self::$countries;
}
/**
* Get all supported countries.
*
* @return array
*/
public static function supported()
{
if (! is_null(self::$supported)) {
return self::$supported;
}
$supportedCountries = setting('supported_countries');
return self::$supported = array_filter(static::all(), function ($code) use ($supportedCountries) {
return in_array($code, $supportedCountries);
}, ARRAY_FILTER_USE_KEY);
}
/**
* Get all country codes.
*
* @return array
*/
public static function codes()
{
return array_keys(self::all());
}
/**
* Get supported country codes.
@@ -77,10 +62,31 @@ class Country
return array_keys(self::supported());
}
/**
* Get all supported countries.
*
* @return array
*/
public static function supported()
{
if (!is_null(self::$supported)) {
return self::$supported;
}
$supportedCountries = setting('supported_countries');
return self::$supported = array_filter(static::all(), function ($code) use ($supportedCountries) {
return in_array($code, $supportedCountries);
}, ARRAY_FILTER_USE_KEY);
}
/**
* Get name of the given country code.
*
* @param string $code
*
* @return string
*/
public static function name($code)

View File

@@ -7,6 +7,25 @@ use Illuminate\Database\Eloquent\Model as Eloquent;
abstract class Model extends Eloquent
{
public static function queryWithoutEagerRelations()
{
return (new static)->newQueryWithoutEagerRelations();
}
/**
* Register a new active global scope on the model.
*
* @return void
*/
public static function addActiveGlobalScope()
{
static::addGlobalScope('active', function ($query) {
$query->where('is_active', true);
});
}
/**
* Perform any actions required before the model boots.
*
@@ -23,10 +42,6 @@ abstract class Model extends Eloquent
});
}
public static function queryWithoutEagerRelations()
{
return (new static)->newQueryWithoutEagerRelations();
}
public function newQueryWithoutEagerRelations()
{
@@ -35,20 +50,9 @@ abstract class Model extends Eloquent
);
}
public function clearEntityTaggedCache()
{
Cache::tags($this->getTable())->flush();
}
/**
* Register a new active global scope on the model.
*
* @return void
*/
public static function addActiveGlobalScope()
{
static::addGlobalScope('active', function ($query) {
$query->where('is_active', true);
});
}
}

View File

@@ -18,10 +18,12 @@ trait Sluggable
});
}
/**
* Set the slug attribute.
*
* @param string $value
*
* @return void
*/
public function setSlug($value = null)
@@ -33,10 +35,12 @@ trait Sluggable
$this->attributes['slug'] = $this->generateSlug($value);
}
/**
* Generate slug by the given value.
*
* @param string $value
*
* @return string
*/
private function generateSlug($value)

View File

@@ -2,6 +2,7 @@
namespace Modules\Support\Eloquent;
use Illuminate\Database\Eloquent\Builder;
use Astrotomic\Translatable\Translatable as AstrotomicTranslatable;
trait Translatable
@@ -12,6 +13,7 @@ trait Translatable
* Save the model to the database.
*
* @param array $options
*
* @return bool
*/
public function save(array $options = [])
@@ -23,20 +25,22 @@ trait Translatable
return false;
}
/**
* This scope filters results by checking the translation fields.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param Builder $query
* @param string $key
* @param array $values
* @param string $locale
* @return \Illuminate\Database\Eloquent\Builder|static
*
* @return Builder|static
*/
public function scopeWhereTranslationIn($query, $key, array $values, $locale = null)
{
return $query->whereHas('translations', function ($query) use ($key, $values, $locale) {
$query->whereIn($key, $values)
->when(! is_null($locale), function ($query) use ($locale) {
->when(!is_null($locale), function ($query) use ($locale) {
$query->where('locale', $locale);
});
});

View File

@@ -13,6 +13,7 @@ abstract class TranslationModel extends Model
*/
public $timestamps = false;
/**
* Perform any actions required before the model boots.
*

View File

@@ -3,6 +3,7 @@
namespace Modules\Support\Http\Controllers;
use Modules\Support\State;
use Illuminate\Http\Response;
class CountryStateController
{
@@ -10,7 +11,8 @@ class CountryStateController
* Display a listing of the resource.
*
* @param string $countryCode
* @return \Illuminate\Http\Response
*
* @return Response
*/
public function index($countryCode)
{

View File

@@ -18,6 +18,18 @@ class Locale
*/
private static $locales;
/**
* Get all locale codes.
*
* @return void
*/
public static function codes()
{
return array_keys(static::all());
}
/**
* Get all locales.
*
@@ -32,20 +44,12 @@ class Locale
return self::$locales;
}
/**
* Get all locale codes.
*
* @return void
*/
public static function codes()
{
return array_keys(static::all());
}
/**
* Get name of the given locale code.
*
* @param string $code
*
* @return string
*/
public static function name($code)

View File

@@ -6,21 +6,25 @@ abstract class Manager
{
private $drivers = [];
public function all()
{
return collect($this->drivers);
}
public function names()
{
return array_keys($this->drivers);
}
public function get($name)
{
return array_get($this->drivers, $name);
}
public function register($name, $driver)
{
$this->drivers[$name] = is_callable($driver) ? call_user_func($driver) : $driver;
@@ -28,18 +32,21 @@ abstract class Manager
return $this;
}
public function count()
{
return count($this->drivers);
}
public function isNotEmpty()
{
return !$this->isEmpty();
}
public function isEmpty()
{
return empty($this->drivers);
}
public function isNotEmpty()
{
return ! $this->isEmpty();
}
}

View File

@@ -13,49 +13,44 @@ class Money implements JsonSerializable
private $amount;
private $currency;
public function __construct($amount, $currency)
{
$this->amount = $amount;
$this->currency = $currency;
}
public static function inDefaultCurrency($amount)
{
return new self($amount, setting('default_currency'));
}
public static function inCurrentCurrency($amount)
{
return new self($amount, currency());
}
private function newInstance($amount)
{
return new self($amount, $this->currency);
}
public function amount()
{
return $this->amount;
}
public function subunit()
{
$fraction = 10 ** Currency::subunit($this->currency);
return (int) round($this->amount * $fraction);
}
public function currency()
{
return $this->currency;
}
public function isZero()
{
return $this->amount == 0;
}
public function add($addend)
{
$addend = $this->convertToSameCurrency($addend);
@@ -63,70 +58,18 @@ class Money implements JsonSerializable
return $this->newInstance($this->amount + $addend->amount);
}
public function subtract($subtrahend)
{
$subtrahend = $this->convertToSameCurrency($subtrahend);
return $this->newInstance($this->amount - $subtrahend->amount);
public function isNotSameCurrency($other)
{
return !$this->isSameCurrency($other);
}
public function multiply($multiplier)
{
return $this->newInstance($this->amount * $multiplier);
}
public function divide($divisor)
{
return $this->newInstance($this->amount / $divisor);
}
public function lessThan($other)
{
return $this->amount < $other->amount;
}
public function lessThanOrEqual($other)
{
return $this->amount <= $other->amount;
}
public function greaterThan($other)
{
return $this->amount > $other->amount;
}
public function greaterThanOrEqual($other)
{
return $this->amount >= $other->amount;
}
private function convertToSameCurrency($other)
{
if ($this->isNotSameCurrency($other)) {
$other = $other->convertToDefaultCurrency();
}
$this->assertSameCurrency($other);
return $other;
}
public function isSameCurrency($other)
{
return $this->currency === $other->currency;
}
public function isNotSameCurrency($other)
{
return ! $this->isSameCurrency($other);
}
private function assertSameCurrency($other)
{
if ($this->isNotSameCurrency($other)) {
throw new InvalidArgumentException('Mismatch money currency.');
}
}
public function convertToDefaultCurrency()
{
@@ -139,22 +82,51 @@ class Money implements JsonSerializable
return new self($this->amount / $currencyRate, setting('default_currency'));
}
public function convertToCurrentCurrency($currencyRate = null)
public function subtract($subtrahend)
{
return $this->convert(currency(), $currencyRate);
$subtrahend = $this->convertToSameCurrency($subtrahend);
return $this->newInstance($this->amount - $subtrahend->amount);
}
public function convert($currency, $currencyRate = null)
public function multiply($multiplier)
{
$currencyRate = $currencyRate ?: CurrencyRate::for($currency);
if (is_null($currencyRate)) {
throw new InvalidArgumentException("Cannot convert the money to currency [$currency].");
}
return new self($this->amount * $currencyRate, $currency);
return $this->newInstance($this->amount * $multiplier);
}
public function divide($divisor)
{
return $this->newInstance($this->amount / $divisor);
}
public function lessThan($other)
{
return $this->amount < $other->amount;
}
public function lessThanOrEqual($other)
{
return $this->amount <= $other->amount;
}
public function greaterThan($other)
{
return $this->amount > $other->amount;
}
public function greaterThanOrEqual($other)
{
return $this->amount >= $other->amount;
}
public function round($precision = null, $mode = null)
{
if (is_null($precision)) {
@@ -166,16 +138,45 @@ class Money implements JsonSerializable
return $this->newInstance($amount);
}
public function subunit()
{
$fraction = 10 ** Currency::subunit($this->currency);
return (int)round($this->amount * $fraction);
}
public function ceil()
{
return $this->newInstance(ceil($this->amount));
}
public function floor()
{
return $this->newInstance(floor($this->amount));
}
public function jsonSerialize(): mixed
{
return array_merge($this->toArray(), [
'inCurrentCurrency' => $this->convertToCurrentCurrency()->toArray(),
]);
}
public function toArray()
{
return [
'amount' => $this->amount,
'formatted' => $this->format(),
'currency' => $this->currency,
];
}
public function format($currency = null, $locale = null)
{
$currency = $currency ?: currency();
@@ -197,24 +198,53 @@ class Money implements JsonSerializable
return $amount;
}
public function toArray()
public function convertToCurrentCurrency($currencyRate = null)
{
return [
'amount' => $this->amount,
'formatted' => $this->format(),
'currency' => $this->currency,
];
return $this->convert(currency(), $currencyRate);
}
public function jsonSerialize()
public function convert($currency, $currencyRate = null)
{
return array_merge($this->toArray(), [
'inCurrentCurrency' => $this->convertToCurrentCurrency()->toArray(),
]);
$currencyRate = $currencyRate ?: CurrencyRate::for($currency);
if (is_null($currencyRate)) {
throw new InvalidArgumentException("Cannot convert the money to currency [$currency].");
}
return new self($this->amount * $currencyRate, $currency);
}
public function __toString()
{
return (string) $this->amount;
return (string)$this->amount;
}
private function convertToSameCurrency($other)
{
if ($this->isNotSameCurrency($other)) {
$other = $other->convertToDefaultCurrency();
}
$this->assertSameCurrency($other);
return $other;
}
private function assertSameCurrency($other)
{
if ($this->isNotSameCurrency($other)) {
throw new InvalidArgumentException('Mismatch money currency.');
}
}
private function newInstance($amount)
{
return new self($amount, $this->currency);
}
}

View File

@@ -62,6 +62,7 @@ class RTLDetector
'yi',
];
public static function detect($locale)
{
return in_array($locale, self::$rtlLocales);

View File

@@ -2,12 +2,15 @@
namespace Modules\Support\Search;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
class Builder
{
/**
* The model instance.
*
* @var \Illuminate\Database\Eloquent\Model
* @var Model
*/
private $model;
@@ -25,11 +28,13 @@ class Builder
*/
private $keys = [];
/**
* Create a new instance.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param Model $model
* @param \Laravel\Scout\Builder $scoutBuilder
*
* @return void
*/
public function __construct($model, $scoutBuilder)
@@ -38,6 +43,7 @@ class Builder
$this->scoutBuilder = $scoutBuilder;
}
/**
* Apply filter to the search results.
*
@@ -48,6 +54,7 @@ class Builder
return $filter->apply($this->query());
}
/**
* Get the query builder of the model.
*
@@ -64,6 +71,7 @@ class Builder
return $query;
}
/**
* Get keys of search result.
*
@@ -78,6 +86,18 @@ class Builder
return $this->keys;
}
/**
* Get the results of the search.
*
* @return Collection
*/
public function get()
{
return $this->query()->get();
}
/**
* Determine if query should order by relevance.
*
@@ -85,13 +105,15 @@ class Builder
*/
private function shouldOrderByRelevance()
{
return ! request()->has('sort') || request('sort') === 'relevance';
return !request()->has('sort') || request('sort') === 'relevance';
}
/**
* Order query by relevance.
*
* @param \Illuminate\Database\Query\Builder $query
*
* @return void
*/
private function orderByRelevance($query)
@@ -102,14 +124,4 @@ class Builder
$query->orderByRaw("FIELD({$this->model->getQualifiedKeyName()}, {$ids->implode(',')})");
}
}
/**
* Get the results of the search.
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function get()
{
return $this->query()->get();
}
}

View File

@@ -5,6 +5,9 @@ namespace Modules\Support\Search;
use Laravel\Scout\Builder;
use Laravel\Scout\Engines\Engine;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Illuminate\Database\Eloquent\Model;
class MySqlSearchEngine extends Engine
{
@@ -13,26 +16,49 @@ class MySqlSearchEngine extends Engine
//
}
public function delete($models)
{
//
}
/**
* Pluck and return the primary keys of the given results.
*
* @param mixed $results
* @return \Illuminate\Support\Collection
*
* @return Collection
*/
public function mapIds($results)
{
return $results['results'];
}
/**
* Perform the given search on the engine.
*
* @param \Laravel\Scout\Builder $builder
* @param \Modules\Support\Search\Builder $builder
* @param int $perPage
* @param int $page
*
* @return mixed
*/
public function paginate(Builder $builder, $perPage, $page)
{
$builder->limit = $perPage;
$builder->offset = ($perPage * $page) - $perPage;
return $this->search($builder);
}
/**
* Perform the given search on the engine.
*
* @param Builder $builder
*
* @return mixed
*/
public function search(Builder $builder)
@@ -51,7 +77,7 @@ class MySqlSearchEngine extends Engine
$result['count'] = $query->count();
if (property_exists($builder, 'orders') && ! empty($builder->orders)) {
if (property_exists($builder, 'orders') && !empty($builder->orders)) {
foreach ($builder->orders as $order) {
$query->orderBy($order['column'], $order['direction']);
}
@@ -70,10 +96,94 @@ class MySqlSearchEngine extends Engine
return $result;
}
/**
* Map the given results to instances of the given model.
*
* @param Laravel\Scout\Builder $builder
* @param Model $model
*
* @return Collection
*/
public function map(Builder $builder, $results, $model)
{
return $results['results'];
}
/**
* Map the given results to instances of the given model via a lazy collection.
*
* @param Builder $builder
* @param mixed $results
* @param Model $model
*
* @return LazyCollection
*/
public function lazyMap(Builder $builder, $results, $model)
{
//
}
/**
* Get the totalPrice count from a raw result returned by the engine.
*
* @param mixed $results
*
* @return int
*/
public function getTotalCount($results)
{
return $results['count'];
}
/**
* Flush all the model's records from the engine.
*
* @param Model $model
*
* @return void
*/
public function flush($model)
{
//
}
/**
* Create a search index.
*
* @param string $name
* @param array $options
*
* @return mixed
*/
public function createIndex($name, array $options = [])
{
//
}
/**
* Delete a search index.
*
* @param string $name
*
* @return mixed
*/
public function deleteIndex($name)
{
//
}
/**
* Get the search query.
*
* @param \Laravel\Scout\Builder $builder
* @param Builder $builder
*
* @return string
*/
private function getSearchKeyword($builder)
@@ -84,90 +194,4 @@ class MySqlSearchEngine extends Engine
return '+' . preg_replace('/[-+~*()><@"]/', ' ', $builder->query) . '*';
}
/**
* Perform the given search on the engine.
*
* @param \Modules\Support\Search\Builder $builder
* @param int $perPage
* @param int $page
* @return mixed
*/
public function paginate(Builder $builder, $perPage, $page)
{
$builder->limit = $perPage;
$builder->offset = ($perPage * $page) - $perPage;
return $this->search($builder);
}
/**
* Map the given results to instances of the given model.
*
* @param Laravel\Scout\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Support\Collection
*/
public function map(Builder $builder, $results, $model)
{
return $results['results'];
}
/**
* Map the given results to instances of the given model via a lazy collection.
*
* @param \Laravel\Scout\Builder $builder
* @param mixed $results
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Support\LazyCollection
*/
public function lazyMap(Builder $builder, $results, $model)
{
//
}
/**
* Get the total count from a raw result returned by the engine.
*
* @param mixed $results
* @return int
*/
public function getTotalCount($results)
{
return $results['count'];
}
/**
* Flush all of the model's records from the engine.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function flush($model)
{
//
}
/**
* Create a search index.
*
* @param string $name
* @param array $options
* @return mixed
*/
public function createIndex($name, array $options = [])
{
//
}
/**
* Delete a search index.
*
* @param string $name
* @return mixed
*/
public function deleteIndex($name)
{
//
}
}

View File

@@ -15,9 +15,10 @@ trait Searchable
*
* @param string $query
* @param Closure $callback
* @return \Modules\Support\Search\Builder
*
* @return Builder
*/
public function search($query, $callback = null)
public function search($query, $callback = null): Builder
{
$scoutBuilder = $this->scoutSearch($query, $callback);

View File

@@ -18,10 +18,18 @@ class State
*/
private static $states;
public static function name($countryCode, $stateCode)
{
return array_get(self::get($countryCode), $stateCode);
}
/**
* Get all states of the given country code.
*
* @param string $code
*
* @return array|null
*/
public static function get($code)
@@ -36,9 +44,4 @@ class State
return self::$states[$code] = require $path;
}
}
public static function name($countryCode, $stateCode)
{
return array_get(self::get($countryCode), $stateCode);
}
}

View File

@@ -13,6 +13,7 @@ class TimeZone
*/
private static $timeZones;
/**
* Get all defined time zones.
*
@@ -20,7 +21,7 @@ class TimeZone
*/
public static function all()
{
if (! is_null(self::$timeZones)) {
if (!is_null(self::$timeZones)) {
return self::$timeZones;
}

View File

@@ -6,12 +6,13 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cookie;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
if (! function_exists('str_between')) {
if (!function_exists('str_between')) {
/**
* Get the portion of a string between the given values.
*
* @param string $subject
* @param string $search
*
* @return string
*/
function str_between($subject, $startsWith, $endsWith)
@@ -20,7 +21,7 @@ if (! function_exists('str_between')) {
}
}
if (! function_exists('locale')) {
if (!function_exists('locale')) {
/**
* Get current locale.
*
@@ -32,11 +33,12 @@ if (! function_exists('locale')) {
}
}
if (! function_exists('is_rtl')) {
if (!function_exists('is_rtl')) {
/**
* Determine if the given / current locale is RTL script.
*
* @param string|null $locale
*
* @return bool
*/
function is_rtl($locale = null)
@@ -45,7 +47,7 @@ if (! function_exists('is_rtl')) {
}
}
if (! function_exists('currency')) {
if (!function_exists('currency')) {
/**
* Get current currency.
*
@@ -59,7 +61,7 @@ if (! function_exists('currency')) {
$currency = Cookie::get('currency');
if (! in_array($currency, setting('supported_currencies'))) {
if (!in_array($currency, setting('supported_currencies'))) {
$currency = setting('default_currency');
}
@@ -67,7 +69,7 @@ if (! function_exists('currency')) {
}
}
if (! function_exists('supported_locales')) {
if (!function_exists('supported_locales')) {
/**
* Get all supported locales.
*
@@ -79,7 +81,7 @@ if (! function_exists('supported_locales')) {
}
}
if (! function_exists('supported_locale_keys')) {
if (!function_exists('supported_locale_keys')) {
/**
* Get all supported locale keys.
*
@@ -91,12 +93,13 @@ if (! function_exists('supported_locale_keys')) {
}
}
if (! function_exists('localized_url')) {
if (!function_exists('localized_url')) {
/**
* Returns an URL adapted to the given locale.
* Returns a URL adapted to the given locale.
*
* @param string $locale
* @param string $url
*
* @return string
*/
function localized_url($locale, $url = null)
@@ -105,11 +108,12 @@ if (! function_exists('localized_url')) {
}
}
if (! function_exists('non_localized_url')) {
if (!function_exists('non_localized_url')) {
/**
* It returns an URL without locale.
* It returns a URL without locale.
*
* @param string $url
*
* @return string
*/
function non_localized_url($url = null)
@@ -118,9 +122,9 @@ if (! function_exists('non_localized_url')) {
}
}
if (! function_exists('is_multilingual')) {
if (!function_exists('is_multilingual')) {
/**
* Determine if the app has multi language.
* Determine if the app has multi-language.
*
* @return bool
*/
@@ -130,7 +134,7 @@ if (! function_exists('is_multilingual')) {
}
}
if (! function_exists('is_multi_currency')) {
if (!function_exists('is_multi_currency')) {
/**
* Determine if the app has multi currency.
*
@@ -142,11 +146,12 @@ if (! function_exists('is_multi_currency')) {
}
}
if (! function_exists('is_module_enabled')) {
if (!function_exists('is_module_enabled')) {
/**
* Determine if the given module is enabled.
*
* @param string $module
*
* @return bool
*/
function is_module_enabled($module)
@@ -155,11 +160,12 @@ if (! function_exists('is_module_enabled')) {
}
}
if (! function_exists('is_core_module')) {
if (!function_exists('is_core_module')) {
/**
* Determine if the given module is core module.
*
* @param string $module
*
* @return bool
*/
function is_core_module($module)
@@ -168,7 +174,7 @@ if (! function_exists('is_core_module')) {
}
}
if (! function_exists('slugify')) {
if (!function_exists('slugify')) {
/**
* Generate a URL friendly "slug" from a given string
*
@@ -186,11 +192,12 @@ if (! function_exists('slugify')) {
}
}
if (! function_exists('v')) {
if (!function_exists('v')) {
/**
* Version a relative asset using the time its contents last changed.
*
* @param string $value
*
* @return string
*/
function v($path)
@@ -205,7 +212,7 @@ if (! function_exists('v')) {
}
}
if (! function_exists('fleetcart_version')) {
if (!function_exists('fleetcart_version')) {
/**
* Get the fleetcart version.
*
@@ -217,13 +224,14 @@ if (! function_exists('fleetcart_version')) {
}
}
if (! function_exists('old_json')) {
if (!function_exists('old_json')) {
/**
* Retrieve and json encode an old input item.
*
* @param string $array
* @param mixed $default
* @param mixed $options
*
* @return string
*/
function old_json($key, $default = [], $options = null)
@@ -234,12 +242,13 @@ if (! function_exists('old_json')) {
}
}
if (! function_exists('array_reset_index')) {
if (!function_exists('array_reset_index')) {
/**
* Reset numeric index of an array recursively.
*
* @param array $array
* @return array|\Illuminate\Support\Collection
*
* @return array|Collection
*
* @see https://stackoverflow.com/a/12399408/5736257
*/
@@ -263,11 +272,12 @@ if (! function_exists('array_reset_index')) {
}
}
if (! function_exists('html_attrs')) {
if (!function_exists('html_attrs')) {
/**
* Convert array to html attributes.
*
* @param array $attributes
*
* @return string
*/
function html_attrs(array $attributes)