From c811a3402792bb7db4abbf3f78745cb6eb320b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20M=2E?= Date: Thu, 31 Oct 2024 17:47:21 +0100 Subject: [PATCH] Code refactoring (#13) --- composer.json | 12 +- src/Auth/Concerns/WithAuthentication.php | 15 +- src/Forms/Concerns/WithAttributes.php | 92 ++++++++++ src/Forms/Support/Form.php | 87 +--------- src/Layout/Concerns/WithScroll.php | 160 ------------------ src/Support/Blade/Bladeable.php | 38 ----- .../Blade/Concerns/WithBladeMacros.php | 97 ----------- src/Views/Concerns/WithLayout.php | 15 -- src/Views/Concerns/WithLivewire.php | 4 +- src/Views/Support/Component.php | 4 +- src/WireUseServiceProvider.php | 19 +-- testbench.yaml | 22 --- tests/Pest.php | 1 - tests/src/Models/Post.php | 2 - tests/src/TestCase.php | 2 + 15 files changed, 123 insertions(+), 447 deletions(-) create mode 100644 src/Forms/Concerns/WithAttributes.php delete mode 100644 src/Layout/Concerns/WithScroll.php delete mode 100644 src/Support/Blade/Bladeable.php delete mode 100644 src/Support/Blade/Concerns/WithBladeMacros.php delete mode 100644 src/Views/Concerns/WithLayout.php delete mode 100644 testbench.yaml diff --git a/composer.json b/composer.json index 947390f3..5af839ce 100644 --- a/composer.json +++ b/composer.json @@ -1,11 +1,14 @@ { "name": "foxws/wireuse", - "description": "Collection of essential Livewire utilities", + "description": "Collection of useful Livewire utilities", "keywords": [ "foxws", + "wireuse", "laravel", "livewire", - "wireuse" + "utilities", + "traits", + "helpers" ], "homepage": "https://github.com/foxws/wireuse", "license": "MIT", @@ -18,13 +21,14 @@ ], "require": { "php": "^8.2", + "illuminate/cache": "^10.0|^11.0", "illuminate/contracts": "^10.0|^11.0", "illuminate/support": "^10.0|^11.0", "illuminate/view": "^10.0|^11.0", "laravel/scout": "^10.0|^11.0", "livewire/livewire": "^3.4", - "spatie/laravel-package-tools": "^1.16.5", - "artesaos/seotools": "^1.3" + "artesaos/seotools": "^1.3", + "spatie/laravel-package-tools": "^1.16.5" }, "require-dev": { "larastan/larastan": "^2.9", diff --git a/src/Auth/Concerns/WithAuthentication.php b/src/Auth/Concerns/WithAuthentication.php index b14bf488..da66bd22 100644 --- a/src/Auth/Concerns/WithAuthentication.php +++ b/src/Auth/Concerns/WithAuthentication.php @@ -2,23 +2,24 @@ namespace Foxws\WireUse\Auth\Concerns; -use Illuminate\Foundation\Auth\User; +use Illuminate\Contracts\Auth\Authenticatable; +use Illuminate\Support\Facades\Auth; trait WithAuthentication { protected function isAuthenticated(): bool { - return auth()->check(); + return Auth::check(); } protected function getAuthId(): int|string|null { - return auth()->id(); + return Auth::id(); } - protected function getAuthModel(): ?User + protected function getAuthModel(): ?Authenticatable { - return auth()->user(); + return Auth::getUser(); } protected function getAuthKey(): int|string|null @@ -28,11 +29,11 @@ protected function getAuthKey(): int|string|null protected function can(string $ability, mixed $arguments = []): bool { - return $this->getAuthModel()?->can($ability, $arguments); + return Auth::user()?->can($ability, $arguments); } protected function cannot(string $ability, mixed $arguments = []): bool { - return $this->getAuthModel()?->cannot($ability, $arguments); + return Auth::user()?->cannot($ability, $arguments); } } diff --git a/src/Forms/Concerns/WithAttributes.php b/src/Forms/Concerns/WithAttributes.php new file mode 100644 index 00000000..238a1c75 --- /dev/null +++ b/src/Forms/Concerns/WithAttributes.php @@ -0,0 +1,92 @@ +all()); + } + + public function fill($values) + { + $values = $this->callHook('beforeFill', $values); + + return parent::fill($values); + } + + public function get(string $key, mixed $default = null): mixed + { + return $this->getPropertyValue($key) ?: $default; + } + + public function has(...$properties): bool + { + return $this->toCollection() + ->has($properties); + } + + public function contains(string $property, mixed $args): bool + { + $propertyValue = $this->get($property); + + if (is_array($propertyValue)) { + return in_array($args, $propertyValue); + } + + return $propertyValue === $args; + } + + public function is(string $property, mixed $args = null): bool + { + return $this->get($property) == $args; + } + + public function isStrict(string $property, mixed $args = null): bool + { + return $this->get($property) === $args; + } + + public function filled(...$properties): bool + { + return $this->toCollection($properties) + ->filter() + ->isNotEmpty(); + } + + public function blank(...$properties): bool + { + return $this->toCollection($properties) + ->filter() + ->isEmpty(); + } + + public function clear(bool $submit = true): void + { + $properties = $this->keys(); + + $this->reset($properties); + + if ($submit && method_exists($this, 'submit')) { + $this->submit(); + } + } + + protected function toCollection(...$properties): Collection + { + return $properties + ? new Collection($this->only(...$properties)) + : new Collection($this->all()); + } + + protected function toFluent(...$properties): Fluent + { + return $properties + ? new Fluent($this->only(...$properties)) + : new Fluent($this->all()); + } +} diff --git a/src/Forms/Support/Form.php b/src/Forms/Support/Form.php index 21f5769a..680a656f 100644 --- a/src/Forms/Support/Form.php +++ b/src/Forms/Support/Form.php @@ -4,17 +4,17 @@ use Foxws\WireUse\Auth\Concerns\WithAuthorization; use Foxws\WireUse\Exceptions\RateLimitedException; +use Foxws\WireUse\Forms\Concerns\WithAttributes; use Foxws\WireUse\Forms\Concerns\WithSession; use Foxws\WireUse\Forms\Concerns\WithThrottle; use Foxws\WireUse\Forms\Concerns\WithValidation; use Foxws\WireUse\Support\Concerns\WithHooks; use Foxws\WireUse\Views\Concerns\WithHash; -use Illuminate\Support\Collection; -use Illuminate\Support\Fluent; use Livewire\Form as BaseForm; abstract class Form extends BaseForm { + use WithAttributes; use WithAuthorization; use WithHash; use WithHooks; @@ -49,87 +49,4 @@ protected function handle(): void { // } - - protected function keys(): array - { - return array_keys($this->all()); - } - - public function fill($values) - { - $values = $this->callHook('beforeFill', $values); - - return parent::fill($values); - } - - public function get(string $key, mixed $default = null): mixed - { - return $this->getPropertyValue($key) ?: $default; - } - - public function has(...$properties): bool - { - return $this->toCollection() - ->has($properties); - } - - public function contains(string $property, mixed $args): bool - { - $propertyValue = $this->get($property); - - if (is_array($propertyValue)) { - return in_array($args, $propertyValue); - } - - return $propertyValue === $args; - } - - public function is(string $property, mixed $args = null): bool - { - return $this->get($property) == $args; - } - - public function isStrict(string $property, mixed $args = null): bool - { - return $this->get($property) === $args; - } - - public function filled(...$properties): bool - { - return $this->toCollection($properties) - ->filter() - ->isNotEmpty(); - } - - public function blank(...$properties): bool - { - return $this->toCollection($properties) - ->filter() - ->isEmpty(); - } - - public function clear(bool $submit = true): void - { - $properties = $this->keys(); - - $this->reset($properties); - - if ($submit && method_exists($this, 'submit')) { - $this->submit(); - } - } - - protected function toCollection(...$properties): Collection - { - return $properties - ? new Collection($this->only(...$properties)) - : new Collection($this->all()); - } - - protected function toFluent(...$properties): Fluent - { - return $properties - ? new Fluent($this->only(...$properties)) - : new Fluent($this->all()); - } } diff --git a/src/Layout/Concerns/WithScroll.php b/src/Layout/Concerns/WithScroll.php deleted file mode 100644 index 190281a7..00000000 --- a/src/Layout/Concerns/WithScroll.php +++ /dev/null @@ -1,160 +0,0 @@ -getBuilder() instanceof Builder || ! $this->getBuilder() instanceof Scout) - ); - - data_set($this, 'models', collect(), false); - } - - public function mountWithScroll(): void - { - if ($this->models->isEmpty()) { - $this->fillScrollItems(); - } - } - - #[Computed(persist: true, seconds: 3600)] - public function items(): Collection - { - return $this->models; - } - - public function fetch(): void - { - $page = $this->getScrollPage(); - - $limit = $this->getScrollPageLimit(); - - if (! $this->hasMorePages() || (is_numeric($limit) && $page > $limit)) { - return; - } - - $this->nextPage(pageName: $this->getScrollPageName()); - - $this->fillPageScrollItems(); - } - - public function clear(): void - { - $this->models = collect(); - - unset($this->items); - - $this->resetPage(); - } - - public function getScrollPage(): ?int - { - return $this->getPage(pageName: $this->getScrollPageName()); - } - - public function hasMorePages(): bool - { - return $this->getScrollBuilder()->hasMorePages(); - } - - public function onFirstPage(): bool - { - return $this->getScrollBuilder()->onFirstPage(); - } - - public function onLastPage(): bool - { - return $this->getScrollBuilder()->onLastPage(); - } - - protected function fillPageScrollItems(): void - { - $items = $this->getScrollBuilder()->getCollection(); - - $this->mergeScrollItems($items); - } - - protected function fillScrollItems(?int $page = null): void - { - $builder = $this->getScrollBuilder(); - - $pages = $this->getScrollPages($page); - - $limit = $this->getScrollPageLimit(); - - $pages->each(function (int $page) use ($builder, $limit) { - if (! $this->hasMorePages() || (is_numeric($limit) && $page > $limit)) { - return false; - } - - $this->mergeScrollItems( - $builder->getCollection() - ); - - $this->nextPage(pageName: $this->getScrollPageName()); - }); - } - - protected function mergeScrollItems(Collection $items): void - { - $this->models = $this->models - ->merge($items->filter()->all()) - ->unique($this->getScrollPageUniqueKey()); - - unset($this->items); - } - - protected function getScrollBuilder(): Paginator - { - $perPage = $this->getScrollPerPage(); - - $limit = $this->getScrollPageLimit(); - - return $this->getBuilder() - ->simplePaginate(perPage: $perPage); - } - - protected function getScrollPages(?int $page = null): Collection - { - $page ??= $this->getScrollPage(); - - return collect(range(1, $page ?? 1)); - } - - protected function getScrollPerPage(): int - { - return 16; - } - - protected function getScrollPageLimit(): ?int - { - return null; - } - - protected function getScrollPageUniqueKey(): ?string - { - return 'id'; - } - - protected function getScrollPageName(): string - { - return 'page'; - } -} diff --git a/src/Support/Blade/Bladeable.php b/src/Support/Blade/Bladeable.php deleted file mode 100644 index 19da34da..00000000 --- a/src/Support/Blade/Bladeable.php +++ /dev/null @@ -1,38 +0,0 @@ -map(function (mixed $value = null, int|string $key) use ($attributeBag) { - if (is_bool($value) && $value === false) { - return; - } - - $key = static::classKeys( - is_numeric($key) ? $value : $key - ); - - return $attributeBag->get($key->first(), ''); - }); - } - - public static function classAttributes(ComponentAttributeBag $attributeBag): Collection - { - return str($attributeBag->whereStartsWith('class:'))->matchAll('/class:(.*?)\=/s'); - } - - public static function classKeys(...$keys): Collection - { - return collect($keys) - ->map(fn (string $value) => str($value)->startsWith('class:') ? $value : "class:{$value}"); - } -} diff --git a/src/Support/Blade/Concerns/WithBladeMacros.php b/src/Support/Blade/Concerns/WithBladeMacros.php deleted file mode 100644 index 147d6249..00000000 --- a/src/Support/Blade/Concerns/WithBladeMacros.php +++ /dev/null @@ -1,97 +0,0 @@ - $value) { - $key = Bladeable::classKeys($key)->first(); - - /** @var ComponentAttributeBag $this */ - if (! $this->has($key)) { - $this->offsetSet($key, $value); - } - } - - return $this; - }); - } - - protected function classMerge(): void - { - ComponentAttributeBag::macro('classMerge', function (?array $values = null): mixed { - /** @var ComponentAttributeBag $this */ - $classes = Bladeable::classMerged($this, $values) - ->merge($this->get('class')) - ->join(' '); - - $this->offsetSet('class', $classes); - - return $this - ->withoutClass(); - }); - } - - protected function withoutClass(): void - { - ComponentAttributeBag::macro('withoutClass', function (): mixed { - /** @var ComponentAttributeBag $this */ - return $this - ->whereDoesntStartWith('class:'); - }); - } - - protected function withoutWireModel(): void - { - ComponentAttributeBag::macro('withoutWireModel', function (): mixed { - /** @var ComponentAttributeBag $this */ - return $this - ->whereDoesntStartWith('wire:model'); - }); - } - - protected function mergeAttributes(): void - { - ComponentAttributeBag::macro('mergeAttributes', function (array $values = []): mixed { - foreach ($values as $key => $value) { - /** @var ComponentAttributeBag $this */ - $this->offsetSet($key, $value); - } - - return $this; - }); - } - - protected function classFor(): void - { - ComponentAttributeBag::macro('classFor', function (string $key, string $default = ''): mixed { - /** @var ComponentAttributeBag $this */ - $class = Bladeable::classKeys($key)->first(); - - return $this->get($class, $default); - }); - - } - - protected function wireModel(): void - { - ComponentAttributeBag::macro('wireModel', function (): mixed { - /** @var ComponentAttributeBag $this */ - return $this->whereStartsWith('wire:model')->first(); - }); - } - - protected function wireKey(): void - { - ComponentAttributeBag::macro('wireKey', function (): mixed { - /** @var ComponentAttributeBag $this */ - return $this->wireModel() ?: $this->first('id') ?: $this->first('name'); - }); - } -} diff --git a/src/Views/Concerns/WithLayout.php b/src/Views/Concerns/WithLayout.php deleted file mode 100644 index 0589982c..00000000 --- a/src/Views/Concerns/WithLayout.php +++ /dev/null @@ -1,15 +0,0 @@ -attributes->get( - app(Bladeable::class)::classKeys($key)->first(), $default - ); - } -} diff --git a/src/Views/Concerns/WithLivewire.php b/src/Views/Concerns/WithLivewire.php index bed878e6..9a3afe14 100644 --- a/src/Views/Concerns/WithLivewire.php +++ b/src/Views/Concerns/WithLivewire.php @@ -7,9 +7,9 @@ trait WithLivewire { - public function wireKey(): string + public function wireKey(): ?string { - return $this->attributes->get('id', $this->wireModel() ?? (string) $this->uuid()); + return $this->attributes->get('id', $this->wireModel()); } public function wireModel(): ?string diff --git a/src/Views/Support/Component.php b/src/Views/Support/Component.php index ef5c8234..59238ca3 100644 --- a/src/Views/Support/Component.php +++ b/src/Views/Support/Component.php @@ -5,13 +5,13 @@ use Foxws\WireUse\Views\Concerns\WithHash; use Foxws\WireUse\Views\Concerns\WithLivewire; use Illuminate\Support\Traits\Conditionable; -use Illuminate\Support\Traits\Tappable; +use Illuminate\Support\Traits\Macroable; use Illuminate\View\Component as BaseComponent; abstract class Component extends BaseComponent { use Conditionable; - use Tappable; + use Macroable; use WithHash; use WithLivewire; } diff --git a/src/WireUseServiceProvider.php b/src/WireUseServiceProvider.php index 4b587c52..d264fc48 100644 --- a/src/WireUseServiceProvider.php +++ b/src/WireUseServiceProvider.php @@ -29,9 +29,13 @@ public function packageRegistered(): void public function packageBooted(): void { - $this - ->registerFeatures() - ->registerMixins(); + if (count(config('wireuse.features', false))) { + $this->registerFeatures(); + } + + if (config('wireuse.html.mixins', false)) { + $this->registerHtmlMixins(); + } } protected function registerFeatures(): static @@ -45,15 +49,6 @@ protected function registerFeatures(): static return $this; } - protected function registerMixins(): static - { - if (config('wireuse.html.mixins', false)) { - $this->registerHtmlMixins(); - } - - return $this; - } - protected function registerStructureDiscovery(): static { if (! InstalledVersions::isInstalled('spatie/php-structure-discoverer')) { diff --git a/testbench.yaml b/testbench.yaml deleted file mode 100644 index 252777c2..00000000 --- a/testbench.yaml +++ /dev/null @@ -1,22 +0,0 @@ -providers: - # - Workbench\App\Providers\WorkbenchServiceProvider - -migrations: - - workbench/database/migrations - -seeders: - - Workbench\Database\Seeders\DatabaseSeeder - -workbench: - start: "/" - install: true - health: false - discovers: - web: true - api: false - commands: false - components: false - views: false - build: [] - assets: [] - sync: [] diff --git a/tests/Pest.php b/tests/Pest.php index 527f14f8..adebd5cc 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -6,7 +6,6 @@ ->extend('toBeSameModel', fn (Model $model) => $this->is($model)->toBeTrue()); beforeEach(function () { - // Fake instances \Illuminate\Support\Facades\Bus::fake(); \Illuminate\Support\Facades\Mail::fake(); \Illuminate\Support\Facades\Notification::fake(); diff --git a/tests/src/Models/Post.php b/tests/src/Models/Post.php index e7e10e7c..f02aea49 100644 --- a/tests/src/Models/Post.php +++ b/tests/src/Models/Post.php @@ -6,12 +6,10 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use Illuminate\Database\Eloquent\SoftDeletes; class Post extends Model { use HasFactory; - use SoftDeletes; protected $guarded = []; diff --git a/tests/src/TestCase.php b/tests/src/TestCase.php index d65a727c..f7021bfb 100644 --- a/tests/src/TestCase.php +++ b/tests/src/TestCase.php @@ -29,6 +29,8 @@ protected function setUp(): void protected function getEnvironmentSetUp($app) { + $app['config']->set('broadcasting.default', 'log'); + $app['config']->set('cache.default', 'file'); $app['config']->set('database.default', 'sqlite');