diff --git a/packages/admin/config/components.php b/packages/admin/config/components.php index 3e4520347..c18d20e98 100644 --- a/packages/admin/config/components.php +++ b/packages/admin/config/components.php @@ -37,6 +37,7 @@ | Shops Livewire Components |-------------------------------------------------------------------------- */ + 'attributes.browse' => Components\Attributes\Browse::class, 'attributes.create' => Components\Attributes\Create::class, 'attributes.edit' => Components\Attributes\Edit::class, diff --git a/packages/admin/config/models.php b/packages/admin/config/models.php deleted file mode 100644 index c0d3337b4..000000000 --- a/packages/admin/config/models.php +++ /dev/null @@ -1,58 +0,0 @@ - Brand::class, - - /* - * Eloquent model should be used to retrieve your categories. Of course, - * it is often just the "Category" model but you may use whatever you like. - * - * The model you want to use as a Category model needs to extends the - * `\Shopper\Core\Models\Category` model. - */ - 'category' => Category::class, - - /* - * Eloquent model should be used to retrieve your collections. Of course, - * it is often just the "Collection" model but you may use whatever you like. - * - * The model you want to use as a Collection model needs to extends the - * `\Shopper\Core\Models\Collection` model. - */ - 'collection' => Collection::class, - - /* - * Eloquent model should be used to retrieve your products. Of course, - * it is often just the "Product" model but you may use whatever you like. - * - * The model you want to use as a Product model needs to extends the - * `\Shopper\Core\Models\Product` model. - */ - 'product' => Product::class, - - /* - * Eloquent model should be used to retrieve your channels. Of course, - * it is often just the "Channel" model but you may use whatever you like. - * - * The model you want to use as a Channel model needs to extends the - * `\Shopper\Core\Models\Channel` model. - */ - 'channel' => Channel::class, - -]; diff --git a/packages/admin/config/settings.php b/packages/admin/config/settings.php index ac7e03b6d..4f7a62778 100644 --- a/packages/admin/config/settings.php +++ b/packages/admin/config/settings.php @@ -10,7 +10,7 @@ |-------------------------------------------------------------------------- | | The menu for the generation of the page settings and layout. - | BladeUIKit Heroicon is the icon used. See https://blade-ui-kit.com/blade-icons?set=1 + | BladeUIKit UntitledUI is the icon used. See https://blade-ui-kit.com/blade-icons?set=74 | */ diff --git a/packages/admin/resources/lang/en/notifications.php b/packages/admin/resources/lang/en/notifications.php index ce1f851b8..464f4a924 100644 --- a/packages/admin/resources/lang/en/notifications.php +++ b/packages/admin/resources/lang/en/notifications.php @@ -4,9 +4,60 @@ return [ + 'actions' => [ + 'create' => ':item successfully added', + 'update' => ':item successfully updated', + 'remove' => ':item successfully removed', + ], + + 'attributes' => [ + 'remove' => 'The attribute has successfully removed', + 'enable' => 'The attribute has successfully enabled', + 'disable' => 'The attribute has successfully disabled', + ], + + 'auth' => [ + 'password' => 'This password does not match our records.', + ], + + 'analytics' => 'Your analytics configurations have been correctly updated', + + 'store_info' => 'Shop informations have been successfully updated', + + 'inventory' => [ + 'removed' => 'Inventory Successfully removed.', + ], + + 'initialize' => 'Store successfully setup, you can now manage everything.', + + 'legal' => 'Your legal policy has been successfully updated', + 'users_roles' => [ 'role_added' => 'A role has been successfully created', + 'role_deleted' => 'Role deleted successfully.', 'admin_deleted' => 'Admin deleted successfully', + 'permission_add' => 'A new permission has been create and add to this role', + 'permission_revoke' => 'Permission :permission has been revoked to this role', + 'permission_allow' => 'Permission :permission has been given to this role', + 'password_changed' => 'You have been successfully updated your password', + 'current_password' => 'That is not your current password.', + 'profile_update' => 'Your profile have been successfully updated', + 'two_factor_enabled' => 'You have successfully enabled two-factor authentication', + 'two_factor_disabled' => 'You have successfully disabled two-factor authentication', + 'two_factor_generate' => 'You have successfully regenerated your two-factor authentication recovery codes.', + ], + + 'orders' => [ + 'archived' => 'Order successfully archived', + ], + + 'payment' => [ + 'add' => 'Your payment method have been correctly added!', + 'update' => 'Your payment method have been correctly updated', + ], + + 'products' => [ + 'remove' => 'The :item has been correctly removed.', ], ]; diff --git a/packages/admin/resources/lang/en/pages/brands.php b/packages/admin/resources/lang/en/pages/brands.php index 210932ac3..285b3ee27 100644 --- a/packages/admin/resources/lang/en/pages/brands.php +++ b/packages/admin/resources/lang/en/pages/brands.php @@ -9,9 +9,4 @@ 'empty_brand' => 'No brand', - 'notifications' => [ - 'created' => 'Brand successfully added!', - 'updated' => 'Brand successfully updated!', - ], - ]; diff --git a/packages/admin/resources/lang/en/pages/categories.php b/packages/admin/resources/lang/en/pages/categories.php index 1bc6fd1dc..ee6d5095b 100644 --- a/packages/admin/resources/lang/en/pages/categories.php +++ b/packages/admin/resources/lang/en/pages/categories.php @@ -10,9 +10,4 @@ 'empty_parent' => 'No parent category', 'parent' => 'in :parent', - 'notifications' => [ - 'created' => 'Category successfully added!', - 'updated' => 'Category successfully updated!', - ], - ]; diff --git a/packages/admin/resources/lang/en/pages/products.php b/packages/admin/resources/lang/en/pages/products.php index 66d8393e4..b75c5b33a 100644 --- a/packages/admin/resources/lang/en/pages/products.php +++ b/packages/admin/resources/lang/en/pages/products.php @@ -117,6 +117,8 @@ 'empty' => 'No adjustments made to inventory.', 'movement' => 'Quantity Movement', 'initial' => 'Initial inventory', + 'add' => 'Manually added', + 'remove' => 'Manually removed', ], 'seo' => [ diff --git a/packages/admin/resources/lang/en/status.php b/packages/admin/resources/lang/en/status.php index 1f83b33fa..618831a77 100644 --- a/packages/admin/resources/lang/en/status.php +++ b/packages/admin/resources/lang/en/status.php @@ -3,9 +3,15 @@ declare(strict_types=1); return [ + + 'cancelled' => 'Cancelled', + 'completed' => 'Completed', + 'paid' => 'Paid', + 'partial-refund' => 'Partially refunded', 'pending' => 'Pending', 'registered' => 'Registered', - 'paid' => 'Paid', - 'completed' => 'Completed', - 'cancelled' => 'Cancelled', + 'treatment' => 'Treatment', + 'refunded' => 'Refunded', + 'rejected' => 'Rejected', + ]; diff --git a/packages/admin/resources/lang/en/words.php b/packages/admin/resources/lang/en/words.php index cc7a8d6aa..e4fd2622f 100644 --- a/packages/admin/resources/lang/en/words.php +++ b/packages/admin/resources/lang/en/words.php @@ -15,6 +15,7 @@ 'review' => 'Review', 'account' => 'Account', 'users' => 'Users', + 'user' => 'User', 'analytics' => 'Analytics', 'system' => 'System', 'purchased' => 'Purchased', @@ -25,6 +26,9 @@ 'per_page_items' => 'Per page items', 'not_available' => 'Not available', 'available' => 'Available', + 'stock' => 'Stock', + 'permission' => 'Permission', + 'role' => 'Role', 'payment_method' => 'Payment Method', 'shipping_method' => 'Shipping method', diff --git a/packages/admin/resources/lang/fr/notifications.php b/packages/admin/resources/lang/fr/notifications.php index 930edad61..4d2f19cb2 100644 --- a/packages/admin/resources/lang/fr/notifications.php +++ b/packages/admin/resources/lang/fr/notifications.php @@ -4,9 +4,60 @@ return [ + 'actions' => [ + 'create' => ':item ajouté avec succès', + 'update' => ':item mis à jour avec succès', + 'remove' => ':item supprimé(e) avec succès', + ], + + 'attributes' => [ + 'remove' => 'L\'attribut a été supprimé avec succès', + 'enable' => 'L\'attribut a été activé avec succès', + 'disable' => 'L\'attribut a été désactivé avec succès', + ], + + 'auth' => [ + 'password' => 'Ce mot de passe ne correspond pas à nos archives', + ], + + 'analytics' => 'Vos configurations analytiques ont été correctement mises à jour', + + 'store_info' => 'Les informations sur le magasin ont été mises à jour avec succès', + + 'inventory' => [ + 'removed' => 'Inventaire supprimé avec succès', + ], + + 'initialize' => 'Le magasin ayant été configuré avec succès, vous pouvez maintenant tout gérer', + + 'legal' => 'Votre politique juridique a été mise à jour avec succès', + 'users_roles' => [ + 'role_deleted' => 'Rôle supprimé avec succès', 'role_added' => 'Un nouveau rôle a été ajouté avec succès', 'admin_deleted' => 'Admin supprimé avec succès', + 'permission_add' => 'Une nouvelle autorisation a été créée et ajoutée à ce rôle', + 'permission_revoke' => 'La permission :permission a été révoquée pour ce rôle', + 'permission_allow' => 'La permission :permission a été donnée à ce rôle', + 'password_changed' => 'Vous avez mis à jour votre mot de passe avec succès', + 'current_password' => 'Ce n\'est pas votre mot de passe actuel', + 'profile_update' => 'Votre profil a été mis à jour avec succès', + 'two_factor_enabled' => 'Vous avez activé avec succès l\'authentification à deux facteurs', + 'two_factor_disabled' => 'Vous avez désactivé avec succès l\'authentification à deux facteurs', + 'two_factor_generate' => 'Vous avez régénéré avec succès vos codes de récupération de l\'authentification à deux facteurs', + ], + + 'orders' => [ + 'archived' => 'Commande archivée avec succès', + ], + + 'payment' => [ + 'add' => 'Votre méthode de paiement a été correctement ajoutée', + 'update' => 'Votre mode de paiement a été correctement mis à jour', + ], + + 'products' => [ + 'remove' => ':item a été correctement supprimé', ], ]; diff --git a/packages/admin/resources/lang/fr/pages/brands.php b/packages/admin/resources/lang/fr/pages/brands.php index 33004bcc3..860a4c9a6 100644 --- a/packages/admin/resources/lang/fr/pages/brands.php +++ b/packages/admin/resources/lang/fr/pages/brands.php @@ -9,9 +9,4 @@ 'empty_brand' => 'Aucune marque', - 'notifications' => [ - 'created' => 'Marque ajoutée avec succès !', - 'updated' => 'Marque mise à jour avec succès !', - ], - ]; diff --git a/packages/admin/resources/lang/fr/pages/categories.php b/packages/admin/resources/lang/fr/pages/categories.php index 71801a108..190fb839f 100644 --- a/packages/admin/resources/lang/fr/pages/categories.php +++ b/packages/admin/resources/lang/fr/pages/categories.php @@ -10,9 +10,4 @@ 'empty_parent' => 'Pas de catégorie parente', 'parent' => 'dans :parent', - 'notifications' => [ - 'created' => 'Catégorie ajoutée avec succès!', - 'updated' => 'Catégorie mise à jour avec succès!', - ], - ]; diff --git a/packages/admin/resources/lang/fr/pages/products.php b/packages/admin/resources/lang/fr/pages/products.php index e3e48521b..a66361286 100644 --- a/packages/admin/resources/lang/fr/pages/products.php +++ b/packages/admin/resources/lang/fr/pages/products.php @@ -117,6 +117,8 @@ 'empty' => 'Aucun ajustement n\'a été effectué sur l\'inventaire.', 'movement' => 'Mouvement des quantités', 'initial' => 'Stock initial', + 'add' => 'Ajout manuel', + 'remove' => 'Retrait manuel', ], 'seo' => [ diff --git a/packages/admin/resources/lang/fr/status.php b/packages/admin/resources/lang/fr/status.php index ed3767bf5..57a73ad43 100644 --- a/packages/admin/resources/lang/fr/status.php +++ b/packages/admin/resources/lang/fr/status.php @@ -3,9 +3,15 @@ declare(strict_types=1); return [ + + 'cancelled' => 'Annulé', + 'completed' => 'Complète', + 'paid' => 'Payé', 'pending' => 'En attente', 'registered' => 'Enregistré', - 'paid' => 'Payé', - 'completed' => 'Complète', - 'cancelled' => 'Annulé', + 'treatment' => 'Traitement', + 'refunded' => 'Remboursé', + 'rejected' => 'Rejeté', + 'partial-refund' => 'Remboursement partiel', + ]; diff --git a/packages/admin/resources/lang/fr/words.php b/packages/admin/resources/lang/fr/words.php index d06756b07..a6f35f794 100644 --- a/packages/admin/resources/lang/fr/words.php +++ b/packages/admin/resources/lang/fr/words.php @@ -15,6 +15,7 @@ 'review' => 'Avis', 'account' => 'Compte', 'users' => 'Utilisateurs', + 'user' => 'Utilisateur', 'analytics' => 'Analytics', 'system' => 'Système', 'purchased' => 'Acheté', @@ -25,8 +26,11 @@ 'per_page_items' => 'Éléments par page', 'not_available' => 'Indisponible', 'available' => 'Disponible', + 'stock' => 'Stock', + 'permission' => 'Permission', + 'role' => 'Rôle', - 'payment_method' => 'Moyen de paiement', + 'payment_method' => 'Méthode de paiement', 'shipping_method' => 'Mode de livraison', 'no_shipping' => 'Pas de méthode d\'expédition', 'estimated' => 'Délai de livraison estimé', @@ -42,7 +46,7 @@ 'to' => 'à', 'of' => 'de', 'results' => 'résultats', - 'media' => 'Media', + 'media' => 'Média', 'hide' => 'Masquer', 'show' => 'Afficher', diff --git a/packages/admin/resources/views/components/learn-more.blade.php b/packages/admin/resources/views/components/learn-more.blade.php index 6324d1d91..7a90675a0 100644 --- a/packages/admin/resources/views/components/learn-more.blade.php +++ b/packages/admin/resources/views/components/learn-more.blade.php @@ -5,7 +5,7 @@
{{ __('shopper::components.learn_more') }} - + {{ $name }} diff --git a/packages/admin/resources/views/livewire/account/dropdown.blade.php b/packages/admin/resources/views/livewire/account/dropdown.blade.php index 66ad452a3..5a0177c38 100644 --- a/packages/admin/resources/views/livewire/account/dropdown.blade.php +++ b/packages/admin/resources/views/livewire/account/dropdown.blade.php @@ -14,8 +14,12 @@ class="mt-4 relative rounded-lg p-2 group hover:bg-white dark:hover:bg-secondary - {{ $user->full_name }} - {{ $user->email }} + + {{ $user->full_name }} + + + {{ $user->email }} + diff --git a/packages/admin/src/Exports/ProductInventoryExport.php b/packages/admin/src/Exports/ProductInventoryExport.php index b7ca3f64a..d5e8c9fc4 100644 --- a/packages/admin/src/Exports/ProductInventoryExport.php +++ b/packages/admin/src/Exports/ProductInventoryExport.php @@ -21,12 +21,12 @@ public function headings(): array { return [ '#', - __('Product'), - __('Stock'), - __('Event'), - __('Inventory'), - __('User'), - __('Date'), + __('shopper::words.product'), + __('shopper::words.stock'), + __('shopper::words.event'), + __('shopper::words.location'), + __('shopper::words.user'), + __('shopper::words.date'), ]; } diff --git a/packages/admin/src/Http/Livewire/Components/Account/Devices.php b/packages/admin/src/Http/Livewire/Components/Account/Devices.php index e258309c4..61a8936cb 100644 --- a/packages/admin/src/Http/Livewire/Components/Account/Devices.php +++ b/packages/admin/src/Http/Livewire/Components/Account/Devices.php @@ -16,7 +16,7 @@ class Devices extends Component { public function getSessionsProperty(): Collection { - if ('database' !== config('session.driver')) { + if (config('session.driver') !== 'database') { return collect(); } diff --git a/packages/admin/src/Http/Livewire/Components/Account/Password.php b/packages/admin/src/Http/Livewire/Components/Account/Password.php index 29408454f..234be5d08 100644 --- a/packages/admin/src/Http/Livewire/Components/Account/Password.php +++ b/packages/admin/src/Http/Livewire/Components/Account/Password.php @@ -32,12 +32,11 @@ public function save(): void $this->reset('current_password', 'password', 'password_confirmation'); Notification::make() - ->title(__('Password Changed!')) - ->body(__('You have been successfully updated your password!')) + ->body(__('shopper::notifications.users_roles.password_changed')) ->success() ->send(); } else { - session()->flash('error', __('That is not your current password.')); + session()->flash('error', __('shopper::notifications.users_roles.current_password')); } } diff --git a/packages/admin/src/Http/Livewire/Components/Account/Profile.php b/packages/admin/src/Http/Livewire/Components/Account/Profile.php index 9ae074033..2a00aac39 100644 --- a/packages/admin/src/Http/Livewire/Components/Account/Profile.php +++ b/packages/admin/src/Http/Livewire/Components/Account/Profile.php @@ -9,6 +9,7 @@ use Illuminate\Validation\Rule; use Livewire\Component; use Livewire\WithFileUploads; +use Shopper\Core\Models\User; use Shopper\Core\Rules\RealEmailValidator; use Shopper\Traits\HasAuthenticated; @@ -29,12 +30,13 @@ class Profile extends Component public function mount(): void { + /** @var User $user */ $user = $this->getUser(); - $this->first_name = $user->first_name; // @phpstan-ignore-line - $this->last_name = $user->last_name; // @phpstan-ignore-line - $this->email = $user->email; // @phpstan-ignore-line - $this->phone_number = $user->phone_number; // @phpstan-ignore-line + $this->first_name = $user->first_name; + $this->last_name = $user->last_name; + $this->email = $user->email; + $this->phone_number = $user->phone_number; } public function updatedPicture(): void @@ -77,8 +79,7 @@ public function save(): void $this->emit('updatedProfile'); Notification::make() - ->title(__('Profile Updated')) - ->body(__('Your profile have been successfully updated!')) + ->body(__('shopper::notifications.users_roles.profile_update')) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Account/TwoFactor.php b/packages/admin/src/Http/Livewire/Components/Account/TwoFactor.php index 56500db9e..6917f4ab5 100644 --- a/packages/admin/src/Http/Livewire/Components/Account/TwoFactor.php +++ b/packages/admin/src/Http/Livewire/Components/Account/TwoFactor.php @@ -41,7 +41,7 @@ public function enableTwoFactorAuthentication(EnableTwoFactorAuthentication $ena $this->showingRecoveryCodes = true; Notification::make() - ->body(__('You have successfully enabled two-factor authentication.')) + ->body(__('shopper::notifications.users_roles.two_factor_enabled')) ->success() ->send(); } @@ -66,7 +66,7 @@ public function regenerateRecoveryCodes(GenerateNewRecoveryCodes $generate): voi $this->showingRecoveryCodes = true; Notification::make() - ->body(__('You have successfully regenerated your two-factor authentication recovery codes.')) + ->body(__('shopper::notifications.users_roles.two_factor_generate')) ->success() ->send(); } @@ -80,7 +80,7 @@ public function disableTwoFactorAuthentication(DisableTwoFactorAuthentication $d $disable(Shopper::auth()->user()); Notification::make() - ->body(__('You have successfully disabled two-factor authentication.')) + ->body(__('shopper::notifications.users_roles.two_factor_disabled')) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Brands/Create.php b/packages/admin/src/Http/Livewire/Components/Brands/Create.php index 905e6af97..17a7fd0bb 100644 --- a/packages/admin/src/Http/Livewire/Components/Brands/Create.php +++ b/packages/admin/src/Http/Livewire/Components/Brands/Create.php @@ -28,7 +28,7 @@ public function store(): void $brand->addMedia($this->fileUrl)->toMediaCollection(config('shopper.core.storage.collection_name')); } - session()->flash('success', __('shopper::pages/brands.notifications.created')); + session()->flash('success', __('shopper::notifications.actions.create', ['item' => __('shopper::words.brand')])); $this->redirectRoute('shopper.brands.index'); } diff --git a/packages/admin/src/Http/Livewire/Components/Brands/Edit.php b/packages/admin/src/Http/Livewire/Components/Brands/Edit.php index 84c9270f6..8227115e9 100644 --- a/packages/admin/src/Http/Livewire/Components/Brands/Edit.php +++ b/packages/admin/src/Http/Livewire/Components/Brands/Edit.php @@ -47,7 +47,7 @@ public function store(): void $this->brand->addMedia($this->fileUrl)->toMediaCollection(config('shopper.core.storage.collection_name')); } - session()->flash('success', __('shopper::pages/brands.notifications.updated')); + session()->flash('success', __('shopper::notifications.actions.update', ['item' => __('shopper::words.brand')])); $this->redirectRoute('shopper.brands.index'); } diff --git a/packages/admin/src/Http/Livewire/Components/Categories/Create.php b/packages/admin/src/Http/Livewire/Components/Categories/Create.php index aaf7dfa7e..a368406a3 100644 --- a/packages/admin/src/Http/Livewire/Components/Categories/Create.php +++ b/packages/admin/src/Http/Livewire/Components/Categories/Create.php @@ -30,7 +30,7 @@ public function store(): void $category->addMedia($this->fileUrl)->toMediaCollection(config('shopper.core.storage.collection_name')); } - session()->flash('success', __('shopper::pages/categories.notifications.created')); + session()->flash('success', __('shopper::notifications.actions.create', ['item' => __('shopper::words.category')])); $this->redirectRoute('shopper.categories.index'); } diff --git a/packages/admin/src/Http/Livewire/Components/Categories/Edit.php b/packages/admin/src/Http/Livewire/Components/Categories/Edit.php index e74286e23..3d66254aa 100644 --- a/packages/admin/src/Http/Livewire/Components/Categories/Edit.php +++ b/packages/admin/src/Http/Livewire/Components/Categories/Edit.php @@ -52,7 +52,7 @@ public function store(): void $this->category->addMedia($this->fileUrl)->toMediaCollection(config('shopper.core.storage.collection_name')); } - session()->flash('success', __('shopper::pages/categories.notifications.updated')); + session()->flash('success', __('shopper::notifications.actions.update', ['item' => __('shopper::words.category')])); $this->redirectRoute('shopper.categories.index'); } diff --git a/packages/admin/src/Http/Livewire/Components/Collections/Create.php b/packages/admin/src/Http/Livewire/Components/Collections/Create.php index efa4e1000..c898e0b16 100644 --- a/packages/admin/src/Http/Livewire/Components/Collections/Create.php +++ b/packages/admin/src/Http/Livewire/Components/Collections/Create.php @@ -7,6 +7,8 @@ use Carbon\Carbon; use Illuminate\Contracts\View\View; use Livewire\Component; +use Shopper\Core\Enum\CollectionType; +use Shopper\Core\Models\Collection; use Shopper\Core\Models\CollectionRule; use Shopper\Core\Repositories\Ecommerce\CollectionRepository; use Shopper\Core\Traits\Attributes\WithConditions; @@ -62,6 +64,7 @@ public function store(): void { $this->validate($this->rules()); + /** @var Collection $collection */ $collection = (new CollectionRepository())->create([ 'name' => $this->name, 'slug' => $this->name, @@ -74,14 +77,13 @@ public function store(): void ]); if ($this->fileUrl) { - // @phpstan-ignore-next-line $collection->addMedia($this->fileUrl)->toMediaCollection(config('shopper.core.storage.collection_name')); } - if ('auto' === $this->type && count($this->conditions) > 0 && $this->rule) { + if ($this->type === CollectionType::AUTO->value && count($this->conditions) > 0 && $this->rule) { foreach ($this->rule as $key => $value) { CollectionRule::query()->create([ - 'collection_id' => $collection->id, // @phpstan-ignore-line + 'collection_id' => $collection->id, 'rule' => $this->rule[$key], 'operator' => $this->operator[$key], 'value' => $this->value[$key], @@ -92,7 +94,7 @@ public function store(): void $this->resetConditionsFields(); } - session()->flash('success', __('Collection successfully added!')); + session()->flash('success', __('shopper::notifications.actions.create', ['item' => __('shopper::words.collection')])); $this->redirectRoute('shopper.collections.edit', $collection); } diff --git a/packages/admin/src/Http/Livewire/Components/Collections/Edit.php b/packages/admin/src/Http/Livewire/Components/Collections/Edit.php index 0d06be7b2..97cd0bc47 100644 --- a/packages/admin/src/Http/Livewire/Components/Collections/Edit.php +++ b/packages/admin/src/Http/Livewire/Components/Collections/Edit.php @@ -92,7 +92,7 @@ public function store(): void $this->collection->addMedia($this->fileUrl)->toMediaCollection(config('shopper.core.storage.collection_name')); } - session()->flash('success', __('Collection successfully updated!')); + session()->flash('success', __('shopper::notifications.actions.update', ['item' => __('shopper::words.collection')])); $this->redirectRoute('shopper.collections.index'); } diff --git a/packages/admin/src/Http/Livewire/Components/Customers/Addresses.php b/packages/admin/src/Http/Livewire/Components/Customers/Addresses.php index dbc8fb1d4..303dfab08 100644 --- a/packages/admin/src/Http/Livewire/Components/Customers/Addresses.php +++ b/packages/admin/src/Http/Livewire/Components/Customers/Addresses.php @@ -21,7 +21,11 @@ public function mount($adresses): void public function render(): View { return view('shopper::livewire.customers.addresses', [ - 'addresses' => Cache::remember('customer-addresses', 60 * 60 * 24, fn () => $this->addresses), + 'addresses' => Cache::remember( + key: 'customer-addresses', + ttl: 60 * 60 * 24, + callback: fn () => $this->addresses + ), ]); } } diff --git a/packages/admin/src/Http/Livewire/Components/Customers/Create.php b/packages/admin/src/Http/Livewire/Components/Customers/Create.php index d82d32c52..b1acd128d 100644 --- a/packages/admin/src/Http/Livewire/Components/Customers/Create.php +++ b/packages/admin/src/Http/Livewire/Components/Customers/Create.php @@ -7,7 +7,9 @@ use Illuminate\Contracts\View\View; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Hash; +use Shopper\Core\Models\Address; use Shopper\Core\Models\Country; +use Shopper\Core\Models\User; use Shopper\Core\Repositories\UserRepository; use Shopper\Core\Rules\Phone; use Shopper\Core\Traits\Attributes\WithAddress; @@ -38,6 +40,7 @@ public function store(): void { $this->validate($this->rules()); + /** @var User $customer */ $customer = (new UserRepository())->create([ 'last_name' => $this->last_name, 'first_name' => $this->first_name, @@ -48,10 +51,8 @@ public function store(): void 'opt_in' => $this->opt_in, ]); - // @phpstan-ignore-next-line $customer->assignRole(config('shopper.core.users.default_role')); - // @phpstan-ignore-next-line $customer->addresses()->create([ 'first_name' => $this->address_first_name, 'last_name' => $this->address_last_name, @@ -62,14 +63,14 @@ public function store(): void 'street_address' => $this->street_address, 'street_address_plus' => $this->street_address_plus, 'is_default' => true, - 'type' => 'shipping', + 'type' => Address::TYPE_SHIPPING, ]); if ($this->send_mail) { - $customer->notify(new CustomerSendCredentials($this->password)); // @phpstan-ignore-line + $customer->notify(new CustomerSendCredentials($this->password)); } - session()->flash('success', __('Customer successfully added!')); + session()->flash('success', __('shopper::notifications.actions.create', ['item' => __('shopper::words.customer')])); $this->redirectRoute('shopper.customers.show', $customer); } @@ -95,7 +96,10 @@ public function rules(): array public function render(): View { return view('shopper::livewire.customers.create', [ - 'countries' => Cache::get('countries-settings', fn () => Country::orderBy('name')->get()), + 'countries' => Cache::get( + key: 'countries-settings', + default: fn () => Country::query()->orderBy('name')->get() + ), ]); } } diff --git a/packages/admin/src/Http/Livewire/Components/Customers/Profile.php b/packages/admin/src/Http/Livewire/Components/Customers/Profile.php index ac4f5a90d..f4933e538 100644 --- a/packages/admin/src/Http/Livewire/Components/Customers/Profile.php +++ b/packages/admin/src/Http/Livewire/Components/Customers/Profile.php @@ -59,11 +59,7 @@ public function saveFirstName(): void { $this->validate(['firstName' => 'sometimes|required']); - $this->updateValue( - 'first_name', - $this->firstName, - __('Customer First name updated successfully.') - ); + $this->updateValue(field: 'first_name', value: $this->firstName); $this->firstNameUpdate = false; $this->emit('profileUpdate'); @@ -73,11 +69,7 @@ public function saveLastName(): void { $this->validate(['lastName' => 'sometimes|required']); - $this->updateValue( - 'last_name', - $this->lastName, - __('Customer Last name updated successfully.') - ); + $this->updateValue(field: 'last_name', value: $this->lastName); $this->lastNameUpdate = false; $this->emit('profileUpdate'); @@ -94,11 +86,7 @@ public function saveEmail(): void ], ]); - $this->updateValue( - 'email', - $this->email, - __('Customer Email address updated successfully.') - ); + $this->updateValue(field: 'email', value: $this->email); $this->emailUpdate = false; $this->emit('profileUpdate'); @@ -112,11 +100,7 @@ public function cancelEmail(): void public function saveBirthDate(): void { - $this->updateValue( - 'birth_date', - $this->birthDate, - __('Customer birth date updated successfully.') - ); + $this->updateValue(field: 'birth_date', value: $this->birthDate); $this->birthDateUpdate = false; $this->birthDateFormatted = $this->customer->birth_date_formatted; @@ -124,22 +108,14 @@ public function saveBirthDate(): void public function saveGender(): void { - $this->updateValue( - 'gender', - $this->gender, - __('Customer gender updated successfully.') - ); + $this->updateValue(field: 'gender', value: $this->gender); $this->genderUpdate = false; } public function updatedOptIn(): void { - $this->updateValue( - 'opt_in', - $this->optIn, - __("You have updated the customer's marketing email subscription.") - ); + $this->updateValue(field: 'opt_in', value: $this->optIn); } public function render(): View @@ -147,13 +123,12 @@ public function render(): View return view('shopper::livewire.customers.profile'); } - private function updateValue(string $field, mixed $value, string $message): void + private function updateValue(string $field, mixed $value): void { $this->customer->update([$field => $value]); Notification::make() - ->title(__('shopper::layout.status.updated')) - ->body($message) + ->body(__('shopper::notifications.actions.update', ['item' => __('shopper::words.customer')])) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Customers/Show.php b/packages/admin/src/Http/Livewire/Components/Customers/Show.php index defde3ea5..38d7c6068 100644 --- a/packages/admin/src/Http/Livewire/Components/Customers/Show.php +++ b/packages/admin/src/Http/Livewire/Components/Customers/Show.php @@ -53,7 +53,7 @@ public function store(): void 'first_name' => $this->first_name, ]); - session()->flash('success', __('Customer successfully updated!')); + session()->flash('success', __('shopper::notifications.actions.update', ['item' => __('shopper::words.customer')])); $this->redirectRoute('shopper.customers.index'); } diff --git a/packages/admin/src/Http/Livewire/Components/Discounts/Browse.php b/packages/admin/src/Http/Livewire/Components/Discounts/Browse.php index 7a692ae3f..5e6b5751e 100644 --- a/packages/admin/src/Http/Livewire/Components/Discounts/Browse.php +++ b/packages/admin/src/Http/Livewire/Components/Discounts/Browse.php @@ -36,11 +36,11 @@ public function render(): View 'total' => Discount::query()->count(), 'discounts' => Discount::query()->where('code', 'like', '%' . $this->search . '%') ->where(function (Builder $query): void { - if (null !== $this->isActive) { + if ($this->isActive !== null) { $query->where('is_active', (bool) ($this->isActive)); } - if (null !== $this->date) { + if ($this->date !== null) { $query->whereDate('start_at', $this->date) ->orWhereDate('end_at', $this->date); } diff --git a/packages/admin/src/Http/Livewire/Components/Discounts/Create.php b/packages/admin/src/Http/Livewire/Components/Discounts/Create.php index e19fb4efd..5d13351d6 100644 --- a/packages/admin/src/Http/Livewire/Components/Discounts/Create.php +++ b/packages/admin/src/Http/Livewire/Components/Discounts/Create.php @@ -38,7 +38,7 @@ public function rules(): array public function store(): void { - if ('none' !== $this->minRequired) { + if ($this->minRequired !== 'none') { $this->validate(['minRequiredValue' => 'required']); } @@ -55,7 +55,7 @@ public function store(): void 'value' => $this->value, 'apply_to' => $this->apply, 'min_required' => $this->minRequired, - 'min_required_value' => 'none' !== $this->minRequired ? $this->minRequiredValue : null, + 'min_required_value' => $this->minRequired !== 'none' ? $this->minRequiredValue : null, 'eligibility' => $this->eligibility, 'usage_limit' => $this->usage_limit ?? null, 'usage_limit_per_user' => $this->usage_limit_per_user, @@ -63,7 +63,7 @@ public function store(): void 'end_at' => $this->dateEnd ? Carbon::createFromFormat('Y-m-d H:i', $this->dateEnd)->toDateTimeString() : null, ]); - if ('products' === $this->apply) { + if ($this->apply === 'products') { // Associate the discount to all the selected products. foreach ($this->selectedProducts as $productId) { DiscountDetail::query()->create([ @@ -75,7 +75,7 @@ public function store(): void } } - if ('customers' === $this->eligibility) { + if ($this->eligibility === 'customers') { // Associate the discount to all the selected users. foreach ($this->selectedCustomers as $customerId) { DiscountDetail::query()->create([ diff --git a/packages/admin/src/Http/Livewire/Components/Discounts/Edit.php b/packages/admin/src/Http/Livewire/Components/Discounts/Edit.php index 236d3f2a9..4eb9ecb11 100644 --- a/packages/admin/src/Http/Livewire/Components/Discounts/Edit.php +++ b/packages/admin/src/Http/Livewire/Components/Discounts/Edit.php @@ -38,7 +38,7 @@ public function mount(Discount $discount): void $this->apply = $discount->apply_to; $this->eligibility = $discount->eligibility; $this->usage_limit = $discount->usage_limit; - $this->usage_number = null !== $discount->usage_limit; + $this->usage_number = $discount->usage_limit !== null; $this->usage_limit_per_user = $discount->usage_limit_per_user; $this->is_active = $discount->is_active; $this->dateStart = $discount->start_at->format('Y-m-d H:m'); @@ -53,9 +53,11 @@ public function mount(Discount $discount): void ->where('condition', 'eligibility') ->get(); $customers = collect(); + foreach ($customerConditions as $customerCondition) { $customers->push($customerCondition->discountable); } + $this->selectedCustomers = $customers->pluck('id')->all(); $this->customers = (new UserRepository()) @@ -70,9 +72,11 @@ public function mount(Discount $discount): void ->where('condition', 'apply_to') ->get(); $products = collect(); + foreach ($productConditions as $productCondition) { $products->push($productCondition->discountable); } + $this->selectedProducts = $products->pluck('id')->all(); $this->products = (new ProductRepository()) @@ -99,7 +103,7 @@ public function rules(): array public function store(): void { - if ('none' !== $this->minRequired) { + if ($this->minRequired !== 'none') { $this->validate(['minRequiredValue' => 'required']); } @@ -116,7 +120,7 @@ public function store(): void 'value' => $this->value, 'apply_to' => $this->apply, 'min_required' => $this->minRequired, - 'min_required_value' => 'none' !== $this->minRequired ? $this->minRequiredValue : null, + 'min_required_value' => $this->minRequired !== 'none' ? $this->minRequiredValue : null, 'eligibility' => $this->eligibility, 'usage_limit' => $this->usage_limit ?? null, 'usage_limit_per_user' => $this->usage_limit_per_user, @@ -124,7 +128,7 @@ public function store(): void 'end_at' => $this->dateEnd ? Carbon::createFromFormat('Y-m-d H:i', $this->dateEnd)->toDateTimeString() : null, ]); - if ('products' === $this->apply) { + if ($this->apply === 'products') { $this->discount->items() ->where('condition', 'apply_to') ->whereNotIn('discountable_id', $this->selectedProducts) @@ -143,7 +147,7 @@ public function store(): void $this->discount->items()->where('condition', 'apply_to')->delete(); } - if ('customers' === $this->eligibility) { + if ($this->eligibility === 'customers') { $this->discount->items() ->where('condition', 'eligibility') ->whereNotIn('discountable_id', $this->selectedCustomers) diff --git a/packages/admin/src/Http/Livewire/Components/Discounts/WithDiscountActions.php b/packages/admin/src/Http/Livewire/Components/Discounts/WithDiscountActions.php index a0dd95876..ba63364f9 100644 --- a/packages/admin/src/Http/Livewire/Components/Discounts/WithDiscountActions.php +++ b/packages/admin/src/Http/Livewire/Components/Discounts/WithDiscountActions.php @@ -21,11 +21,11 @@ public function isEmpty(): bool public function getProductSize(): string { - if (0 === count($this->selectedProducts)) { + if (count($this->selectedProducts) === 0) { return mb_strtolower(__('shopper::layout.sidebar.products')); } - if (1 === count($this->selectedProducts)) { + if (count($this->selectedProducts) === 1) { return $this->products->first()->name; // @phpstan-ignore-line } @@ -34,11 +34,11 @@ public function getProductSize(): string public function getCustomSize(): ?string { - if (0 === count($this->selectedCustomers) || 'everyone' === $this->eligibility) { + if (count($this->selectedCustomers) === 0 || $this->eligibility === 'everyone') { return __('shopper::words.everyone'); } - if (1 === count($this->selectedCustomers)) { + if (count($this->selectedCustomers) === 1) { return __('shopper::words.for_name', ['name' => $this->customers->first()->first_name]); // @phpstan-ignore-line } @@ -55,15 +55,15 @@ public function getDateWord(): ?string $startDate = new Carbon($this->dateStart); $endDate = new Carbon($this->dateEnd); - if ($today->equalTo($startDate) && $today->equalTo($endDate) && null !== $this->dateEnd) { + if ($today->equalTo($startDate) && $today->equalTo($endDate) && $this->dateEnd !== null) { return __('shopper::pages/discounts.active_today'); } - if ($today->equalTo($startDate) && null === $this->dateEnd) { + if ($today->equalTo($startDate) && $this->dateEnd === null) { return __('shopper::pages/discounts.active_from_today'); } - if ($today->notEqualTo($startDate) && null === $this->dateEnd) { + if ($today->notEqualTo($startDate) && $this->dateEnd === null) { return __('shopper::pages/discounts.active_from', ['date' => $startDate->format('d M')]); } @@ -71,14 +71,14 @@ public function getDateWord(): ?string return __('shopper::pages/discounts.active_date', ['date' => $startDate->format('d M')]); } - if ($startDate->notEqualTo($endDate) && $startDate->lessThan($endDate) && null !== $this->dateEnd) { + if ($startDate->notEqualTo($endDate) && $startDate->lessThan($endDate) && $this->dateEnd !== null) { return __('shopper::pages/discounts.active_from_to', [ 'start' => $startDate->format('d M'), 'end' => $endDate->format('d M'), ]); } - if ($startDate->greaterThan($endDate) && null !== $this->dateEnd) { + if ($startDate->greaterThan($endDate) && $this->dateEnd !== null) { $this->dateEnd = Carbon::createFromFormat('Y-m-d H:i', $this->dateStart)->toDateString(); return __('shopper::pages/discounts.active_date', ['date' => $startDate->format('d M')]); @@ -89,7 +89,7 @@ public function getDateWord(): ?string public function getUsageLimitMessage(): ?string { - if ($this->usage_number && null !== $this->usage_limit && (int) $this->usage_limit > 0) { + if ($this->usage_number && $this->usage_limit !== null && (int) $this->usage_limit > 0) { $message = trans_choice('shopper::words.discount_use', $this->usage_limit, ['count' => $this->usage_limit]); $message .= $this->usage_limit_per_user ? ', ' . __('shopper::pages/discounts.one_per_customer') : ''; diff --git a/packages/admin/src/Http/Livewire/Components/Forms/Uploads/Multiple.php b/packages/admin/src/Http/Livewire/Components/Forms/Uploads/Multiple.php index a2b8672e6..9df21546d 100644 --- a/packages/admin/src/Http/Livewire/Components/Forms/Uploads/Multiple.php +++ b/packages/admin/src/Http/Livewire/Components/Forms/Uploads/Multiple.php @@ -52,8 +52,7 @@ public function removeMedia(int $id): void $this->emitSelf('fileDeleted'); Notification::make() - ->title(__('Removed')) - ->body(__('Media removed from the storage.')) + ->body(__('shopper::notifications.actions.remove', ['item' => __('shopper::words.media')])) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Forms/Uploads/Single.php b/packages/admin/src/Http/Livewire/Components/Forms/Uploads/Single.php index 84f7040a8..116bf69ec 100644 --- a/packages/admin/src/Http/Livewire/Components/Forms/Uploads/Single.php +++ b/packages/admin/src/Http/Livewire/Components/Forms/Uploads/Single.php @@ -47,8 +47,7 @@ public function removeMedia(int $id): void $this->media = null; Notification::make() - ->title(__('Removed')) - ->body(__('Media removed from the storage.')) + ->body(__('shopper::notifications.actions.remove', ['item' => __('shopper::words.media')])) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Orders/Show.php b/packages/admin/src/Http/Livewire/Components/Orders/Show.php index 5bc69287e..098cafaaa 100644 --- a/packages/admin/src/Http/Livewire/Components/Orders/Show.php +++ b/packages/admin/src/Http/Livewire/Components/Orders/Show.php @@ -9,6 +9,11 @@ use Livewire\Component; use Livewire\WithPagination; use Shopper\Core\Enum\OrderStatus; +use Shopper\Core\Events\Orders\AddNote; +use Shopper\Core\Events\Orders\Cancel; +use Shopper\Core\Events\Orders\Completed; +use Shopper\Core\Events\Orders\Paid; +use Shopper\Core\Events\Orders\Registered; use Shopper\Core\Models\Address; use Shopper\Core\Models\Order; @@ -31,7 +36,7 @@ public function cancelOrder(): void { $this->order->update(['status' => OrderStatus::CANCELLED->value]); - event(new \Shopper\Core\Events\Orders\Cancel($this->order)); + event(new Cancel($this->order)); Notification::make() ->body(__('shopper::pages/orders.notifications.cancelled')) @@ -45,7 +50,7 @@ public function leaveNotes(): void $this->order->update(['notes' => $this->notes]); - event(new \Shopper\Core\Events\Orders\AddNote($this->order)); + event(new AddNote($this->order)); Notification::make() ->body(__('shopper::pages/orders.notifications.note_added')) @@ -57,7 +62,7 @@ public function register(): void { $this->order->update(['status' => OrderStatus::REGISTER->value]); - event(new \Shopper\Core\Events\Orders\Registered($this->order)); + event(new Registered($this->order)); Notification::make() ->body(__('shopper::pages/orders.notifications.registered')) @@ -69,7 +74,7 @@ public function markPaid(): void { $this->order->update(['status' => OrderStatus::PAID->value]); - event(new \Shopper\Core\Events\Orders\Paid($this->order)); + event(new Paid($this->order)); Notification::make() ->body(__('shopper::pages/orders.notifications.paid')) @@ -81,7 +86,7 @@ public function markComplete(): void { $this->order->update(['status' => OrderStatus::COMPLETED->value]); - event(new \Shopper\Core\Events\Orders\Completed($this->order)); + event(new Completed($this->order)); Notification::make() ->body(__('shopper::pages/orders.notifications.completed')) diff --git a/packages/admin/src/Http/Livewire/Components/Products/Attributes/Text.php b/packages/admin/src/Http/Livewire/Components/Products/Attributes/Text.php index 6335f0940..b21f7b0e0 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Attributes/Text.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Attributes/Text.php @@ -38,7 +38,7 @@ public function mount(int $productId, string $type, int $attributeId): void ->where('product_id', $this->productId) ->where('attribute_id', $this->attributeId) ->first(); - $this->value = $this->model?->attribute_custom_value; // @phpstan-ignore-line + $this->value = $this->model?->attribute_custom_value; } public function onTrixValueUpdate(string $value): void diff --git a/packages/admin/src/Http/Livewire/Components/Products/Create.php b/packages/admin/src/Http/Livewire/Components/Products/Create.php index 9dcd8bf24..841161553 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Create.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Create.php @@ -8,6 +8,7 @@ use Milon\Barcode\Facades\DNS1DFacade; use Shopper\Core\Models\Channel; use Shopper\Core\Models\Inventory; +use Shopper\Core\Models\Product; use Shopper\Core\Repositories\Ecommerce\BrandRepository; use Shopper\Core\Repositories\Ecommerce\CategoryRepository; use Shopper\Core\Repositories\Ecommerce\CollectionRepository; @@ -74,6 +75,7 @@ public function store(): void { $this->validate($this->rules()); + /** @var Product $product */ $product = (new ProductRepository())->create([ 'name' => $this->name, 'slug' => $this->name, @@ -86,7 +88,7 @@ public function store(): void 'price_amount' => $this->price_amount, 'cost_amount' => $this->cost_amount, 'type' => $this->type, - 'requires_shipping' => $this->requiresShipping, + 'require_shipping' => $this->requiresShipping, 'backorder' => $this->backorder, 'published_at' => $this->publishedAt ?? now(), 'seo_title' => $this->seoTitle, @@ -104,31 +106,26 @@ public function store(): void if (collect($this->files)->isNotEmpty()) { collect($this->files)->each( - // @phpstan-ignore-next-line fn ($file) => $product->addMedia($file)->toMediaCollection(config('shopper.core.storage.collection_name')) ); } if (collect($this->category_ids)->isNotEmpty()) { - // @phpstan-ignore-next-line $product->categories()->attach($this->category_ids); } if (collect($this->collection_ids)->isNotEmpty()) { - // @phpstan-ignore-next-line $product->collections()->attach($this->collection_ids); } - // @phpstan-ignore-next-line $product->channels()->attach($this->defaultChannel->id); if ($this->quantity && count($this->quantity) > 0) { foreach ($this->quantity as $inventory => $value) { - // @phpstan-ignore-next-line $product->mutateStock( - $inventory, - (int) $value, - [ + inventoryId: $inventory, + quantity: (int) $value, + arguments: [ 'event' => __('shopper::pages/products.inventory.initial'), 'old_quantity' => $value, ] diff --git a/packages/admin/src/Http/Livewire/Components/Products/Form/Edit.php b/packages/admin/src/Http/Livewire/Components/Products/Form/Edit.php index e0d119002..748dad96b 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Form/Edit.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Form/Edit.php @@ -117,7 +117,6 @@ public function store(): void $this->emit('productHasUpdated', $this->productId); Notification::make() - ->title(__('shopper::layout.status.updated')) ->body(__('shopper::pages/products.notifications.update')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Products/Form/Inventory.php b/packages/admin/src/Http/Livewire/Components/Products/Form/Inventory.php index 606e155f0..e688f5017 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Form/Inventory.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Form/Inventory.php @@ -62,7 +62,6 @@ public function store(): void ]); Notification::make() - ->title(__('shopper::layout.status.updated')) ->body(__('shopper::pages/products.notifications.stock_update')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Products/Form/RelatedProducts.php b/packages/admin/src/Http/Livewire/Components/Products/Form/RelatedProducts.php index c05f4f33f..e95c0d4f3 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Form/RelatedProducts.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Form/RelatedProducts.php @@ -32,7 +32,6 @@ public function remove(int $id): void $this->emitSelf('onProductsAddInRelated'); Notification::make() - ->title(__('shopper::layout.status.delete')) ->body(__('shopper::pages/products.notifications.remove_related')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Products/Form/Seo.php b/packages/admin/src/Http/Livewire/Components/Products/Form/Seo.php index 39fcfed6b..30184149f 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Form/Seo.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Form/Seo.php @@ -53,7 +53,6 @@ public function store(): void $this->emit('productHasUpdated', $this->productId); Notification::make() - ->title(__('shopper::layout.status.updated')) ->body(__('shopper::pages/products.notifications.seo_update')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Products/Form/Shipping.php b/packages/admin/src/Http/Livewire/Components/Products/Form/Shipping.php index fa599dc6f..b9d83377f 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Form/Shipping.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Form/Shipping.php @@ -52,7 +52,6 @@ public function store(): void $this->emit('productHasUpdated', $this->productId); Notification::make() - ->title(__('shopper::layout.status.updated')) ->body(__('shopper::pages/products.notifications.shipping_update')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Products/Form/Variants.php b/packages/admin/src/Http/Livewire/Components/Products/Form/Variants.php index dedce4f58..8cdc877e5 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Form/Variants.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Form/Variants.php @@ -54,7 +54,6 @@ public function remove(int $id): void $this->dispatchBrowserEvent('item-removed'); Notification::make() - ->title(__('shopper::layout.status.delete')) ->body(__('shopper::pages/products.notifications.variation_delete')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Products/Variant.php b/packages/admin/src/Http/Livewire/Components/Products/Variant.php index f6cffb429..5c988ad09 100644 --- a/packages/admin/src/Http/Livewire/Components/Products/Variant.php +++ b/packages/admin/src/Http/Livewire/Components/Products/Variant.php @@ -93,7 +93,6 @@ public function store(): void $this->emitSelf('onVariantUpdated'); Notification::make() - ->title(__('shopper::layout.status.updated')) ->body(__('shopper::pages/products.notifications.variation_update')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Reviews/Show.php b/packages/admin/src/Http/Livewire/Components/Reviews/Show.php index 908fc4835..76281a406 100644 --- a/packages/admin/src/Http/Livewire/Components/Reviews/Show.php +++ b/packages/admin/src/Http/Livewire/Components/Reviews/Show.php @@ -27,7 +27,6 @@ public function updatedApproved(): void $this->review->update(['approved' => ! $this->review->approved]); Notification::make() - ->title(__('shopper::layout.status.updated')) ->body(__('shopper::pages/products.reviews.approved_message')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Analytics.php b/packages/admin/src/Http/Livewire/Components/Settings/Analytics.php index 5b4395890..23b92a364 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Analytics.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Analytics.php @@ -76,8 +76,7 @@ public function store(): void } Notification::make() - ->title(__('shopper::layout.status.updated')) - ->body(__('Your analytics configurations have been correctly updated')) + ->body(__('shopper::notifications.analytics')) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/General.php b/packages/admin/src/Http/Livewire/Components/Settings/General.php index 8e1a75ffe..6262e106e 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/General.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/General.php @@ -126,8 +126,7 @@ public function store(): void } Notification::make() - ->title(__('shopper::layout.status.updated')) - ->body(__('Shop informations have been correctly updated')) + ->body(__('shopper::notifications.store_info')) ->success() ->send(); } @@ -173,8 +172,7 @@ public function deleteCover(): void $this->shop_cover = null; Notification::make() - ->title(__('shopper::layout.status.delete')) - ->body(__('Shop cover have been correctly removed')) + ->body(__('shopper::notifications.store_info')) ->success() ->send(); } @@ -182,8 +180,14 @@ public function deleteCover(): void public function render(): View { return view('shopper::livewire.settings.general', [ - 'countries' => Cache::rememberForever('countries', fn () => Country::query()->orderBy('name')->get()), - 'currencies' => Cache::rememberForever('currencies', fn () => Currency::all()), + 'countries' => Cache::rememberForever( + key: 'countries', + callback: fn () => Country::query()->orderBy('name')->get() + ), + 'currencies' => Cache::rememberForever( + key: 'currencies', + callback: fn () => Currency::all() + ), ]); } } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Legal/Privacy.php b/packages/admin/src/Http/Livewire/Components/Settings/Legal/Privacy.php index 1cd8d05ea..8a4b83267 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Legal/Privacy.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Legal/Privacy.php @@ -29,8 +29,7 @@ public function store(): void $this->storeValues(__($this->title), $this->content, $this->isEnabled); Notification::make() - ->title(__('shopper::layout.status.updated')) - ->body(__('Your privacy policy has been successfully updated')) + ->body(__('shopper::notifications.legal')) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Legal/Refund.php b/packages/admin/src/Http/Livewire/Components/Settings/Legal/Refund.php index c9801a6fe..4b9083fed 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Legal/Refund.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Legal/Refund.php @@ -29,8 +29,7 @@ public function store(): void $this->storeValues(__($this->title), $this->content, $this->isEnabled); Notification::make() - ->title(__('shopper::layout.status.updated')) - ->body(__('Your refund policy has been successfully updated')) + ->body(__('shopper::notifications.legal')) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Legal/Shipping.php b/packages/admin/src/Http/Livewire/Components/Settings/Legal/Shipping.php index ba1d81cdf..4d2ed6687 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Legal/Shipping.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Legal/Shipping.php @@ -29,8 +29,7 @@ public function store(): void $this->storeValues(__($this->title), $this->content, $this->isEnabled); Notification::make() - ->title(__('shopper::layout.status.updated')) - ->body(__('Your shipping policy has been successfully updated')) + ->body(__('shopper::notifications.legal')) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Legal/Terms.php b/packages/admin/src/Http/Livewire/Components/Settings/Legal/Terms.php index bb9b1d628..2224eb551 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Legal/Terms.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Legal/Terms.php @@ -29,8 +29,7 @@ public function store(): void $this->storeValues(__($this->title), $this->content, $this->isEnabled); Notification::make() - ->title(__('shopper::layout.status.updated')) - ->body(__('Your terms of use has been successfully updated')) + ->body(__('shopper::notifications.legal')) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Management/CreateAdminUser.php b/packages/admin/src/Http/Livewire/Components/Settings/Management/CreateAdminUser.php index e31549706..6c4cb2f9c 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Management/CreateAdminUser.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Management/CreateAdminUser.php @@ -9,6 +9,7 @@ use Illuminate\Validation\Rule; use Illuminate\Validation\Rules\Password; use Shopper\Core\Models\Role; +use Shopper\Core\Models\User; use Shopper\Core\Repositories\UserRepository; use Shopper\Core\Rules\Phone; use Shopper\Core\Rules\RealEmailValidator; @@ -78,6 +79,7 @@ public function store(): void { $this->validate($this->rules(), $this->messages()); + /** @var User $user */ $user = (new UserRepository())->create([ 'email' => $this->email, 'first_name' => $this->first_name, @@ -88,15 +90,16 @@ public function store(): void 'email_verified_at' => now()->toDateTimeString(), ]); + /** @var Role $role */ $role = Role::findById((int) $this->role_id); - $user->assignRole([$role->name]); // @phpstan-ignore-line + $user->assignRole([$role->name]); if ($this->send_mail) { - $user->notify(new AdminSendCredentials($this->password)); // @phpstan-ignore-line + $user->notify(new AdminSendCredentials($this->password)); } - session()->flash('success', __('Admin :user added successfully.', ['user' => $user->full_name])); // @phpstan-ignore-line + session()->flash('success', __('shopper::notifications.actions.create', ['item' => $user->full_name])); $this->redirectRoute('shopper.settings.users'); } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Management/Management.php b/packages/admin/src/Http/Livewire/Components/Settings/Management/Management.php index 874e4acab..77def4996 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Management/Management.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Management/Management.php @@ -25,7 +25,6 @@ public function removeUser(int $id): void $this->dispatchBrowserEvent('user-removed'); Notification::make() - ->title(__('shopper::layout.forms.actions.deleted')) ->body(__('shopper::notifications.users_roles.admin_deleted')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Management/Permissions.php b/packages/admin/src/Http/Livewire/Components/Settings/Management/Permissions.php index 9f58c10cf..e3c57f274 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Management/Permissions.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Management/Permissions.php @@ -23,22 +23,21 @@ public function permissionAdded(int $id): void public function togglePermission(int $id): void { + /** @var Permission $permission */ $permission = Permission::query()->find($id); if ($this->role->hasPermissionTo($permission->name)) { $this->role->revokePermissionTo($permission->name); Notification::make() - ->title(__('Revoke Permission')) - ->body(__('Permission :permission has been revoked to this role.', ['permission' => $permission->display_name])) // @phpstan-ignore-line + ->body(__('shopper::notifications.users_roles.permission_revoke', ['permission' => $permission->display_name])) ->success() ->send(); } else { $this->role->givePermissionTo($permission->name); Notification::make() - ->title(__('Allow Permission')) - ->body(__('Permission :permission has been given to this role.', ['permission' => $permission->display_name])) // @phpstan-ignore-line + ->body(__('shopper::notifications.users_roles.permission_allow', ['permission' => $permission->display_name])) ->success() ->send(); } @@ -49,8 +48,7 @@ public function removePermission(int $id): void Permission::query()->find($id)->delete(); Notification::make() - ->title(__('Deleted')) - ->body(__('The permission has been correctly removed')) + ->body(__('shopper::notifications.actions.remove', ['item' => __('shopper::words.permission')])) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Management/Role.php b/packages/admin/src/Http/Livewire/Components/Settings/Management/Role.php index 30a55ff5c..17a5c8ae4 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Management/Role.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Management/Role.php @@ -32,11 +32,8 @@ public function save(): void $this->validate([ 'name' => [ 'required', - Rule::unique('roles', 'name')->ignore($this->role->id), + Rule::unique(config('permission.table_names')['roles'], 'name')->ignore($this->role->id), ], - ], [ - 'name.required' => __('The role name is required.'), - 'name.unique' => __('This name is already used.'), ]); RoleModel::query()->find($this->role->id)->update([ @@ -46,8 +43,7 @@ public function save(): void ]); Notification::make() - ->title(__('shopper::components.tables.status.updated')) - ->body(__('Role updated successfully')) + ->body(__('shopper::notifications.actions.update', ['item' => __('shopper::words.role')])) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Management/UsersRole.php b/packages/admin/src/Http/Livewire/Components/Settings/Management/UsersRole.php index d7f0b500a..849a9afec 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Management/UsersRole.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Management/UsersRole.php @@ -22,22 +22,21 @@ public function removeUser(int $id): void $this->dispatchBrowserEvent('user-removed'); Notification::make() - ->title(__('Deleted')) - ->body(__('Admin deleted successfully')) + ->body(__('shopper::notifications.users_roles.admin_deleted')) ->success() ->send(); } public function render(): View { - $users = (new UserRepository()) - ->makeModel() - ->whereHas('roles', function (Builder $query): void { - $query->where('name', $this->role->name); - }) - ->orderBy('created_at', 'desc') - ->get(); - - return view('shopper::livewire.settings.management.users-role', compact('users')); + return view('shopper::livewire.settings.management.users-role', [ + 'users' => (new UserRepository()) + ->makeModel() + ->whereHas('roles', function (Builder $query): void { + $query->where('name', $this->role->name); + }) + ->orderBy('created_at', 'desc') + ->get(), + ]); } } diff --git a/packages/admin/src/Http/Livewire/Components/Settings/Payments/General.php b/packages/admin/src/Http/Livewire/Components/Settings/Payments/General.php index 2f9a18af5..dc62328dc 100644 --- a/packages/admin/src/Http/Livewire/Components/Settings/Payments/General.php +++ b/packages/admin/src/Http/Livewire/Components/Settings/Payments/General.php @@ -20,13 +20,14 @@ class General extends Component public function toggleStatus(int $id, int $status): void { - PaymentMethod::query()->find($id)->update(['is_enabled' => ! (1 === $status)]); + PaymentMethod::query() + ->find($id) + ->update(['is_enabled' => ! ($status === 1)]); $this->dispatchBrowserEvent('toggle-saved-' . $id); Notification::make() - ->title(__('shopper::layout.status.updated')) - ->body(__('Your payment method status have been correctly updated')) + ->body(__('shopper::notifications.payment.update')) ->success() ->send(); } @@ -38,8 +39,7 @@ public function removePayment(int $id): void $this->dispatchBrowserEvent('item-update'); Notification::make() - ->title(__('Deleted')) - ->body(__('Your payment method have been correctly removed')) + ->body(__('shopper::notifications.actions.remove', ['item' => __('shopper::words.payment_method')])) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Modals/AddVariant.php b/packages/admin/src/Http/Livewire/Modals/AddVariant.php index 67dd1e16c..8bd2b1063 100644 --- a/packages/admin/src/Http/Livewire/Modals/AddVariant.php +++ b/packages/admin/src/Http/Livewire/Modals/AddVariant.php @@ -7,6 +7,7 @@ use Filament\Notifications\Notification; use Illuminate\Contracts\View\View; use LivewireUI\Modal\ModalComponent; +use Shopper\Core\Models\Product; use Shopper\Core\Repositories\Ecommerce\ProductRepository; use Shopper\Core\Repositories\InventoryRepository; use Shopper\Http\Livewire\Components\Products\WithAttributes; @@ -51,6 +52,7 @@ public function save(): void { $this->validate($this->rules()); + /** @var Product $product */ $product = (new ProductRepository())->create([ 'name' => $this->name, 'slug' => $this->name, @@ -67,14 +69,12 @@ public function save(): void if (collect($this->files)->isNotEmpty()) { collect($this->files)->each( - // @phpstan-ignore-next-line fn ($file) => $product->addMedia($file)->toMediaCollection(config('shopper.core.storage.collection_name')) ); } if ($this->quantity && count($this->quantity) > 0) { foreach ($this->quantity as $inventory => $value) { - // @phpstan-ignore-next-line $product->mutateStock( $inventory, (int) $value, diff --git a/packages/admin/src/Http/Livewire/Modals/ArchiveOrder.php b/packages/admin/src/Http/Livewire/Modals/ArchiveOrder.php index 3982f3cdb..c7fe4e96a 100644 --- a/packages/admin/src/Http/Livewire/Modals/ArchiveOrder.php +++ b/packages/admin/src/Http/Livewire/Modals/ArchiveOrder.php @@ -21,7 +21,7 @@ public function archived(): void { $this->order->delete(); - session()->flash('success', __('Order successfully archived')); + session()->flash('success', __('shopper::notifications.orders.archived')); $this->redirectRoute('shopper.orders.index'); } diff --git a/packages/admin/src/Http/Livewire/Modals/ConfirmPassword.php b/packages/admin/src/Http/Livewire/Modals/ConfirmPassword.php index b3b566563..615ace54d 100644 --- a/packages/admin/src/Http/Livewire/Modals/ConfirmPassword.php +++ b/packages/admin/src/Http/Livewire/Modals/ConfirmPassword.php @@ -25,7 +25,7 @@ public function confirmPassword(): void { if (! app(ConfirmPasswordAction::class)(Shopper::auth(), Shopper::auth()->user(), $this->confirmablePassword)) { throw ValidationException::withMessages([ - 'confirmable_password' => [__('This password does not match our records.')], + 'confirmable_password' => [__('shopper::notifications.auth.password')], ]); } diff --git a/packages/admin/src/Http/Livewire/Modals/CreatePaymentMethod.php b/packages/admin/src/Http/Livewire/Modals/CreatePaymentMethod.php index 3504cc3d2..b5e903216 100644 --- a/packages/admin/src/Http/Livewire/Modals/CreatePaymentMethod.php +++ b/packages/admin/src/Http/Livewire/Modals/CreatePaymentMethod.php @@ -52,8 +52,7 @@ public function save(): void } Notification::make() - ->title(__('Saved')) - ->body(__('Your payment method have been correctly added!')) + ->body(__('shopper::notifications.payment.add')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Modals/CreatePermission.php b/packages/admin/src/Http/Livewire/Modals/CreatePermission.php index b15d6350c..8da27a1db 100644 --- a/packages/admin/src/Http/Livewire/Modals/CreatePermission.php +++ b/packages/admin/src/Http/Livewire/Modals/CreatePermission.php @@ -34,6 +34,7 @@ public function save(): void 'display_name' => 'required|max:75', ]); + /** @var Permission $permission */ $permission = Permission::query()->create([ 'name' => $this->name, 'group_name' => $this->group, @@ -46,8 +47,7 @@ public function save(): void $this->dispatchBrowserEvent('permission-added'); Notification::make() - ->title(__('Saved')) - ->body(__('A new permission has been create and add to this role!')) + ->body(__('shopper::notifications.users_roles.permission_add')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Modals/CreateRole.php b/packages/admin/src/Http/Livewire/Modals/CreateRole.php index 47cbade7c..0690c5e06 100644 --- a/packages/admin/src/Http/Livewire/Modals/CreateRole.php +++ b/packages/admin/src/Http/Livewire/Modals/CreateRole.php @@ -19,10 +19,7 @@ class CreateRole extends ModalComponent public function save(): void { - $this->validate(['name' => 'required|unique:roles'], [ - 'name.required' => __('The role name is required.'), - 'name.unique' => __('This name is already used.'), - ]); + $this->validate(['name' => 'required|unique:' . config('permission.table_names')['roles']]); Role::create([ 'name' => $this->name, diff --git a/packages/admin/src/Http/Livewire/Modals/DeleteInventory.php b/packages/admin/src/Http/Livewire/Modals/DeleteInventory.php index d7808732c..eb5f0740a 100644 --- a/packages/admin/src/Http/Livewire/Modals/DeleteInventory.php +++ b/packages/admin/src/Http/Livewire/Modals/DeleteInventory.php @@ -24,7 +24,7 @@ public function delete(): void { Inventory::query()->find($this->inventoryId)->delete(); - session()->flash('success', __('Inventory Successfully removed.')); + session()->flash('success', __('shopper::notifications.inventory.removed')); $this->redirectRoute('shopper.settings.inventories.index'); } diff --git a/packages/admin/src/Http/Livewire/Modals/DeleteProduct.php b/packages/admin/src/Http/Livewire/Modals/DeleteProduct.php index 5f2b1d703..4bb5c7a4d 100644 --- a/packages/admin/src/Http/Livewire/Modals/DeleteProduct.php +++ b/packages/admin/src/Http/Livewire/Modals/DeleteProduct.php @@ -30,17 +30,13 @@ public function delete(): void event(new ProductDeleted($product)); - if ('product' === $this->type) { - $product->delete(); - } else { - $product->forceDelete(); - } + session()->flash('success', __('shopper::notifications.products.remove', ['item' => $this->type])); - session()->flash('success', __('The :item has been correctly removed.', ['item' => $this->type])); - - if ('product' === $this->type) { + if ($this->type === 'product') { + $product->delete(); $this->redirectRoute('shopper.products.index'); } else { + $product->forceDelete(); $this->redirect($this->route); } } diff --git a/packages/admin/src/Http/Livewire/Modals/DeleteRole.php b/packages/admin/src/Http/Livewire/Modals/DeleteRole.php index 0da823a86..399e7e35f 100644 --- a/packages/admin/src/Http/Livewire/Modals/DeleteRole.php +++ b/packages/admin/src/Http/Livewire/Modals/DeleteRole.php @@ -21,7 +21,7 @@ public function delete(): void { Role::query()->find($this->roleId)->delete(); - session()->flash('success', __('Role deleted successfully.')); + session()->flash('success', __('shopper::notifications.users_roles.role_deleted')); $this->redirectRoute('shopper.settings.users'); } diff --git a/packages/admin/src/Http/Livewire/Modals/LogoutOthersBrowser.php b/packages/admin/src/Http/Livewire/Modals/LogoutOthersBrowser.php index 1fb5a759f..752bf0070 100644 --- a/packages/admin/src/Http/Livewire/Modals/LogoutOthersBrowser.php +++ b/packages/admin/src/Http/Livewire/Modals/LogoutOthersBrowser.php @@ -25,7 +25,7 @@ public function logoutOtherBrowserSessions(StatefulGuard $guard): void // @phpstan-ignore-next-line if (! Hash::check($this->password, auth()->user()->password)) { - throw ValidationException::withMessages(['password' => [__('This password does not match our records.')]]); + throw ValidationException::withMessages(['password' => [__('shopper::notifications.auth.password')]]); } $guard->logoutOtherDevices($this->password); // @phpstan-ignore-line diff --git a/packages/admin/src/Http/Livewire/Modals/ProductsLists.php b/packages/admin/src/Http/Livewire/Modals/ProductsLists.php index 747c2c9d5..bc7166fc8 100644 --- a/packages/admin/src/Http/Livewire/Modals/ProductsLists.php +++ b/packages/admin/src/Http/Livewire/Modals/ProductsLists.php @@ -6,6 +6,7 @@ use Filament\Notifications\Notification; use Illuminate\Contracts\View\View; +use Illuminate\Database\Eloquent\Collection; use LivewireUI\Modal\ModalComponent; use Shopper\Core\Repositories\Ecommerce\CollectionRepository; use Shopper\Core\Repositories\Ecommerce\ProductRepository; @@ -31,7 +32,7 @@ public static function modalMaxWidth(): string return '2xl'; } - public function getProductsProperty() + public function getProductsProperty(): Collection { return (new ProductRepository()) ->where('name', '%' . $this->search . '%', 'like') diff --git a/packages/admin/src/Http/Livewire/Modals/UpdatePaymentMethod.php b/packages/admin/src/Http/Livewire/Modals/UpdatePaymentMethod.php index c4c383925..c8c503092 100644 --- a/packages/admin/src/Http/Livewire/Modals/UpdatePaymentMethod.php +++ b/packages/admin/src/Http/Livewire/Modals/UpdatePaymentMethod.php @@ -70,7 +70,7 @@ public function save(): void Notification::make() ->title(__('shopper::components.tables.status.updated')) - ->body(__('Your payment method have been correctly updated')) + ->body(__('shopper::notifications.payment.update')) ->success() ->send(); diff --git a/packages/admin/src/Http/Livewire/Modals/UpdateValue.php b/packages/admin/src/Http/Livewire/Modals/UpdateValue.php index b732f59d3..458ce7d7f 100644 --- a/packages/admin/src/Http/Livewire/Modals/UpdateValue.php +++ b/packages/admin/src/Http/Livewire/Modals/UpdateValue.php @@ -24,6 +24,7 @@ class UpdateValue extends ModalComponent public function mount(string $name, string $type, int $id): void { + /** @var AttributeValue $value */ $value = AttributeValue::query()->find($id); $this->valueId = $id; diff --git a/packages/admin/src/Http/Livewire/Pages/Auth/ForgotPassword.php b/packages/admin/src/Http/Livewire/Pages/Auth/ForgotPassword.php index 6d74bc60c..a6b9be68b 100644 --- a/packages/admin/src/Http/Livewire/Pages/Auth/ForgotPassword.php +++ b/packages/admin/src/Http/Livewire/Pages/Auth/ForgotPassword.php @@ -22,7 +22,7 @@ public function sendResetPasswordLink(): void $response = $this->broker()->sendResetLink(['email' => $this->email]); - if (Password::RESET_LINK_SENT === $response) { + if ($response === Password::RESET_LINK_SENT) { session()->flash('success', trans($response)); return; diff --git a/packages/admin/src/Http/Livewire/Pages/Auth/ResetPassword.php b/packages/admin/src/Http/Livewire/Pages/Auth/ResetPassword.php index c7145f236..665b555e2 100644 --- a/packages/admin/src/Http/Livewire/Pages/Auth/ResetPassword.php +++ b/packages/admin/src/Http/Livewire/Pages/Auth/ResetPassword.php @@ -39,12 +39,12 @@ public function resetPassword(): void ]); $response = $this->broker()->reset( - [ + credentials: [ 'token' => $this->token, 'email' => $this->email, 'password' => $this->password, ], - function ($user, string $password): void { + callback: function ($user, string $password): void { $user->password = Hash::make($password); $user->save(); @@ -52,7 +52,7 @@ function ($user, string $password): void { } ); - if (Password::PASSWORD_RESET === $response) { + if ($response === Password::PASSWORD_RESET) { $this->redirectRoute('shopper.dashboard'); } diff --git a/packages/admin/src/Http/Livewire/Pages/Initialization.php b/packages/admin/src/Http/Livewire/Pages/Initialization.php index 0b7fab1cf..8f94fa3bb 100644 --- a/packages/admin/src/Http/Livewire/Pages/Initialization.php +++ b/packages/admin/src/Http/Livewire/Pages/Initialization.php @@ -127,7 +127,7 @@ public function store(): void $this->storeHasSetup(); - session()->flash('success', __('Store successfully setup, you can now manage everything.')); + session()->flash('success', __('shopper::notifications.initialize')); $this->redirectRoute('shopper.dashboard'); } diff --git a/packages/admin/src/Http/Livewire/Tables/AttributesTable.php b/packages/admin/src/Http/Livewire/Tables/AttributesTable.php index 660342bd4..26cf56536 100644 --- a/packages/admin/src/Http/Livewire/Tables/AttributesTable.php +++ b/packages/admin/src/Http/Livewire/Tables/AttributesTable.php @@ -57,7 +57,7 @@ public function deleteSelected(): void Notification::make() ->title(__('shopper::components.tables.status.delete')) - ->body(__('The attribute has successfully removed!')) + ->body(__('shopper::notifications.attributes.remove')) ->success() ->send(); } @@ -76,7 +76,7 @@ public function enabled(): void Notification::make() ->title(__('shopper::components.tables.status.updated')) - ->body(__('The attribute has successfully enabled!')) + ->body(__('shopper::notifications.attributes.enable')) ->success() ->send(); } @@ -89,11 +89,13 @@ public function enabled(): void public function disabled(): void { if (count($this->getSelected()) > 0) { - Attribute::query()->whereIn('id', $this->getSelected())->update(['is_enabled' => false]); + Attribute::query() + ->whereIn('id', $this->getSelected()) + ->update(['is_enabled' => false]); Notification::make() ->title(__('shopper::components.tables.status.updated')) - ->body(__('The attribute has successfully disabled!')) + ->body(__('shopper::notifications.attributes.disable')) ->success() ->send(); } diff --git a/packages/admin/src/Http/Livewire/Tables/CollectionsTable.php b/packages/admin/src/Http/Livewire/Tables/CollectionsTable.php index 3242038d7..03c6a77fe 100644 --- a/packages/admin/src/Http/Livewire/Tables/CollectionsTable.php +++ b/packages/admin/src/Http/Livewire/Tables/CollectionsTable.php @@ -45,7 +45,7 @@ public function deleteSelected(): void Notification::make() ->title(__('shopper::components.tables.status.delete')) - ->body(__('The attribute has successfully disabled!')) + ->body(__('shopper::components.tables.messages.delete', ['name' => mb_strtolower(__('shopper::words.collection'))])) ->success() ->send(); } diff --git a/packages/admin/src/ShopperServiceProvider.php b/packages/admin/src/ShopperServiceProvider.php index 6831018fb..034895e61 100644 --- a/packages/admin/src/ShopperServiceProvider.php +++ b/packages/admin/src/ShopperServiceProvider.php @@ -35,7 +35,6 @@ final class ShopperServiceProvider extends PackageServiceProvider 'admin', 'auth', 'components', - 'models', 'routes', 'settings', ]; diff --git a/packages/admin/src/helpers.php b/packages/admin/src/helpers.php index 583ead344..eab1f1210 100644 --- a/packages/admin/src/helpers.php +++ b/packages/admin/src/helpers.php @@ -15,16 +15,3 @@ function is_active(array $routes): bool return (bool) call_user_func_array([app('router'), 'is'], $routes); } } - -if (! function_exists('isoToEmoji')) { - function isoToEmoji(string $code): string - { - return implode( - '', - array_map( - fn (string $letter) => mb_chr(ord($letter) % 32 + 0x1F1E5), - mb_str_split($code) - ) - ); - } -} diff --git a/packages/core/config/core.php b/packages/core/config/core.php index 6684230a1..9d52a7b85 100644 --- a/packages/core/config/core.php +++ b/packages/core/config/core.php @@ -62,18 +62,6 @@ 'disk_name' => 'public', ], - /* - |-------------------------------------------------------------------------- - | Locale Configuration - |-------------------------------------------------------------------------- - | - | Shopper PHP locale determines the default locale that will be used - | by the model date format function ->formatLocalized(). - | - */ - - 'locale' => 'en_EN', - /* |-------------------------------------------------------------------------- | Barcode type diff --git a/packages/core/config/media.php b/packages/core/config/media.php index 3e073596f..29f663453 100644 --- a/packages/core/config/media.php +++ b/packages/core/config/media.php @@ -37,4 +37,15 @@ ], ], + /* + |-------------------------------------------------------------------------- + | Fallback image URL + |-------------------------------------------------------------------------- + | + | If your media collection does not contain any items, this image should be displayed + | + */ + + 'fallback' => '/shopper/images/placeholder.jpg', + ]; diff --git a/packages/core/config/models.php b/packages/core/config/models.php new file mode 100644 index 000000000..ab9b0d247 --- /dev/null +++ b/packages/core/config/models.php @@ -0,0 +1,72 @@ + \Shopper\Core\Models\Brand::class, + + /* + |-------------------------------------------------------------------------- + | Category Model + |-------------------------------------------------------------------------- + | + | Eloquent model should be used to retrieve your categories. Of course, + | If you want to change this to use a custom model, your model needs to extends the + | \Shopper\Core\Models\Category model. + | + */ + + 'category' => \Shopper\Core\Models\Category::class, + + /* + |-------------------------------------------------------------------------- + | Collection Model + |-------------------------------------------------------------------------- + | + | Eloquent model should be used to retrieve your collections. Of course, + | if you want to change this to use a custom model, your model needs to extends the + | \Shopper\Core\Models\Collection model. + | + */ + + 'collection' => \Shopper\Core\Models\Collection::class, + + /* + |-------------------------------------------------------------------------- + | Product Model + |-------------------------------------------------------------------------- + | + | Eloquent model should be used to retrieve your products. Of course, + | If you want to change this to use a custom model, your model needs to extends the + | \Shopper\Core\Models\Product model. + | + */ + + 'product' => \Shopper\Core\Models\Product::class, + + /* + |-------------------------------------------------------------------------- + | Channel Model + |-------------------------------------------------------------------------- + | + | Eloquent model should be used to retrieve your channels. Of course, + | If you want to change this to use a custom model, your model needs to extends the + | \Shopper\Core\Models\Channel model. + | + */ + + 'channel' => \Shopper\Core\Models\Channel::class, + +]; diff --git a/packages/core/database/migrations/2020_00_02_000002_create_inventories_table.php b/packages/core/database/migrations/2020_00_02_000002_create_inventories_table.php index 1a625b952..5a28b551f 100644 --- a/packages/core/database/migrations/2020_00_02_000002_create_inventories_table.php +++ b/packages/core/database/migrations/2020_00_02_000002_create_inventories_table.php @@ -34,11 +34,10 @@ public function up(): void $this->addCommonFields($table); $table->morphs('stockable'); - $table->string('reference_type')->nullable(); - $table->unsignedBigInteger('reference_id')->nullable(); + $table->nullableMorphs('reference'); $table->integer('quantity'); $table->integer('old_quantity')->default(0); - $table->text('event')->nullable(); + $table->string('event', 75)->nullable(); $table->text('description')->nullable(); $this->addForeignKey($table, 'inventory_id', $this->getTableName('inventories'), false); diff --git a/packages/core/database/migrations/2020_00_02_000006_create_products_table.php b/packages/core/database/migrations/2020_00_02_000006_create_products_table.php index 935f1003b..076ab84ab 100644 --- a/packages/core/database/migrations/2020_00_02_000006_create_products_table.php +++ b/packages/core/database/migrations/2020_00_02_000006_create_products_table.php @@ -27,7 +27,7 @@ public function up(): void $table->enum('type', ['deliverable', 'downloadable'])->nullable(); $table->boolean('backorder')->default(false); $table->boolean('requires_shipping')->default(false); - $table->dateTimeTz('published_at')->default(now())->nullable(); + $table->dateTimeTz('published_at')->default(now()); $this->addSeoFields($table); $this->addShippingFields($table); diff --git a/packages/core/database/migrations/2020_00_03_000004_create_order_refunds_table.php b/packages/core/database/migrations/2020_00_03_000004_create_order_refunds_table.php index c3bc3dc8b..7f2d99738 100644 --- a/packages/core/database/migrations/2020_00_03_000004_create_order_refunds_table.php +++ b/packages/core/database/migrations/2020_00_03_000004_create_order_refunds_table.php @@ -15,7 +15,7 @@ public function up(): void $table->longText('refund_reason')->nullable(); $table->string('refund_amount')->nullable(); - $table->enum('status', ['pending', 'treatment', 'partial-refund', 'refunded', 'cancelled', 'rejected'])->default('pending'); + $table->string('status')->default(\Shopper\Core\Enum\OrderRefundStatus::PENDING->value); $table->longText('notes'); $this->addForeignKey($table, 'order_id', $this->getTableName('orders'), false); diff --git a/packages/core/database/migrations/2023_09_21_063717_rename_requires_shipping_columns_on_products_table.php b/packages/core/database/migrations/2023_09_21_063717_rename_requires_shipping_columns_on_products_table.php new file mode 100644 index 000000000..6eb7d5dc1 --- /dev/null +++ b/packages/core/database/migrations/2023_09_21_063717_rename_requires_shipping_columns_on_products_table.php @@ -0,0 +1,17 @@ +getTableName('products'), function (Blueprint $table): void { + $table->renameColumn(from: 'requires_shipping', to: 'require_shipping'); + }); + } +}; diff --git a/packages/core/database/seeders/LegalsPageTableSeeder.php b/packages/core/database/seeders/LegalsPageTableSeeder.php index 01b46e103..6313c6e0a 100644 --- a/packages/core/database/seeders/LegalsPageTableSeeder.php +++ b/packages/core/database/seeders/LegalsPageTableSeeder.php @@ -16,28 +16,28 @@ public function run(): void Legal::query()->create([ 'title' => $title = __('shopper::pages/settings.legal.refund'), - 'slug' => str_slug($title), + 'slug' => $title, 'is_enabled' => true, 'content' => null, ]); Legal::query()->create([ 'title' => $title = __('shopper::pages/settings.legal.privacy'), - 'slug' => str_slug($title), + 'slug' => $title, 'is_enabled' => true, 'content' => null, ]); Legal::query()->create([ 'title' => $title = __('shopper::pages/settings.legal.terms_of_use'), - 'slug' => str_slug($title), + 'slug' => $title, 'is_enabled' => true, 'content' => null, ]); Legal::query()->create([ 'title' => $title = __('shopper::pages/settings.legal.shipping'), - 'slug' => str_slug($title), + 'slug' => $title, 'is_enabled' => true, 'content' => null, ]); diff --git a/packages/core/src/CoreServiceProvider.php b/packages/core/src/CoreServiceProvider.php index c60ec65ca..69ecee0df 100644 --- a/packages/core/src/CoreServiceProvider.php +++ b/packages/core/src/CoreServiceProvider.php @@ -15,14 +15,15 @@ final class CoreServiceProvider extends ServiceProvider protected array $configFiles = [ 'core', 'media', + 'models', ]; protected string $root = __DIR__ . '/..'; public function boot(): void { - setlocale(LC_TIME, config('shopper.core.locale')); - Carbon::setLocale(config('shopper.core.locale')); + setlocale(LC_ALL, config('app.locale')); + Carbon::setLocale(config('app.locale')); } public function register(): void diff --git a/packages/core/src/Enum/CollectionType.php b/packages/core/src/Enum/CollectionType.php new file mode 100644 index 000000000..add3703f6 --- /dev/null +++ b/packages/core/src/Enum/CollectionType.php @@ -0,0 +1,12 @@ + __('shopper::status.pending'), - self::TREATMENT => __('Treatment'), - self::PARTIAL_REFUND => __('Partially refunded'), - self::REFUNDED => __('Refunded'), - self::REJECTED => __('Rejected'), + self::TREATMENT => __('shopper::status.treatment'), + self::PARTIAL_REFUND => __('shopper::status.partial-refund'), + self::REFUNDED => __('shopper::status.refunded'), + self::REJECTED => __('shopper::status.rejected'), self::CANCELLED => __('shopper::status.cancelled'), }; } diff --git a/packages/core/src/Enum/OrderStatus.php b/packages/core/src/Enum/OrderStatus.php index 83736ae08..b494068af 100644 --- a/packages/core/src/Enum/OrderStatus.php +++ b/packages/core/src/Enum/OrderStatus.php @@ -7,9 +7,13 @@ enum OrderStatus: string { case PENDING = 'pending'; + case REGISTER = 'registered'; + case PAID = 'completed'; + case COMPLETED = 'cancelled'; + case CANCELLED = 'paid'; public function badge(): string diff --git a/packages/core/src/Helpers/Migration.php b/packages/core/src/Helpers/Migration.php index 4cbced77a..42de3c7fc 100644 --- a/packages/core/src/Helpers/Migration.php +++ b/packages/core/src/Helpers/Migration.php @@ -6,6 +6,9 @@ use Illuminate\Database\Migrations\Migration as BaseMigration; use Illuminate\Database\Schema\Blueprint; +use Shopper\Core\Enum\Dimension\Length; +use Shopper\Core\Enum\Dimension\Volume; +use Shopper\Core\Enum\Dimension\Weight; abstract class Migration extends BaseMigration { @@ -39,26 +42,26 @@ public function addSeoFields(Blueprint $table): void public function addShippingFields(Blueprint $table): void { + $table->string('weight_unit')->default(Weight::KG->value); $table->decimal('weight_value', 10, 5)->nullable() ->default(0.00) ->unsigned(); - $table->string('weight_unit')->default('kg'); + $table->string('height_unit')->default(Length::CM->value); $table->decimal('height_value', 10, 5)->nullable() ->default(0.00) ->unsigned(); - $table->string('height_unit')->default('cm'); + $table->string('width_unit')->default(Length::CM->value); $table->decimal('width_value', 10, 5)->nullable() ->default(0.00) ->unsigned(); - $table->string('width_unit')->default('cm'); + $table->string('depth_unit')->default(Length::CM->value); $table->decimal('depth_value', 10, 5)->nullable() ->default(0.00) ->unsigned(); - $table->string('depth_unit')->default('cm'); + $table->string('volume_unit')->default(Volume::L->value); $table->decimal('volume_value', 10, 5)->nullable() ->default(0.00) ->unsigned(); - $table->string('volume_unit')->default('l'); } public function addForeignKey(Blueprint $table, string $columnName, string $tableName, bool $nullable = true): void diff --git a/packages/core/src/Models/Address.php b/packages/core/src/Models/Address.php index 0b2c2ad29..6b4e883bc 100644 --- a/packages/core/src/Models/Address.php +++ b/packages/core/src/Models/Address.php @@ -4,6 +4,7 @@ namespace Shopper\Core\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -14,7 +15,7 @@ * @property string|null $first_name * @property bool $is_default */ -class Address extends Model +final class Address extends Model { use HasFactory; @@ -67,16 +68,18 @@ public function getTable(): string return shopper_table('user_addresses'); } - public function getFullNameAttribute(): string + public function fullName(): Attribute { - return $this->last_name - ? $this->first_name . ' ' . $this->last_name - : $this->first_name; + return Attribute::make( + get: fn () => $this->first_name + ? $this->first_name . ' ' . $this->last_name + : $this->last_name + ); } public function isDefault(): bool { - return true === $this->is_default; + return $this->is_default === true; } public function user(): BelongsTo diff --git a/packages/core/src/Models/Attribute.php b/packages/core/src/Models/Attribute.php index 98fffc46b..7c3c6cbc9 100644 --- a/packages/core/src/Models/Attribute.php +++ b/packages/core/src/Models/Attribute.php @@ -22,7 +22,7 @@ * @property string|null $icon * @property \Illuminate\Database\Eloquent\Collection|array $values */ -class Attribute extends Model +final class Attribute extends Model { use HasFactory; use HasSlug; diff --git a/packages/core/src/Models/AttributeProduct.php b/packages/core/src/Models/AttributeProduct.php index b1f2d0472..4cd011767 100644 --- a/packages/core/src/Models/AttributeProduct.php +++ b/packages/core/src/Models/AttributeProduct.php @@ -9,7 +9,12 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; -class AttributeProduct extends Model +/** + * @property-read int $id + * @property string|null $attribute_custom_value + * @property AttributeValue|null $value + */ +final class AttributeProduct extends Model { use HasFactory; @@ -27,10 +32,10 @@ public function getTable(): string return shopper_table('attribute_product'); } - public function realValue(): AttributeCast + protected function realValue(): AttributeCast { return AttributeCast::make( - get: fn () => $this->attribute_custom_value ?? $this->value->value, + get: fn () => $this->attribute_custom_value ?? $this->value?->value, ); } diff --git a/packages/core/src/Models/AttributeValue.php b/packages/core/src/Models/AttributeValue.php index 5992416ec..9328827e9 100644 --- a/packages/core/src/Models/AttributeValue.php +++ b/packages/core/src/Models/AttributeValue.php @@ -14,7 +14,7 @@ * @property string $key * @property int $position */ -class AttributeValue extends Model +final class AttributeValue extends Model { use HasFactory; diff --git a/packages/core/src/Models/Brand.php b/packages/core/src/Models/Brand.php index ab27833e1..714c138c7 100644 --- a/packages/core/src/Models/Brand.php +++ b/packages/core/src/Models/Brand.php @@ -9,12 +9,14 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Shopper\Core\Traits\HasMedia; +use Shopper\Core\Traits\HasSlug; use Spatie\MediaLibrary\HasMedia as SpatieHasMedia; class Brand extends Model implements SpatieHasMedia { use HasFactory; use HasMedia; + use HasSlug; protected $guarded = []; diff --git a/packages/core/src/Models/Carrier.php b/packages/core/src/Models/Carrier.php index 504b9d0ba..5d73303c3 100644 --- a/packages/core/src/Models/Carrier.php +++ b/packages/core/src/Models/Carrier.php @@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Model; use Shopper\Core\Traits\HasSlug; -class Carrier extends Model +final class Carrier extends Model { use HasSlug; diff --git a/packages/core/src/Models/Channel.php b/packages/core/src/Models/Channel.php index 6b7ec48ff..054965d3c 100644 --- a/packages/core/src/Models/Channel.php +++ b/packages/core/src/Models/Channel.php @@ -26,7 +26,7 @@ public function getTable(): string return shopper_table('channels'); } - public function scopeIsDefault(Builder $query): Builder + public function scopeDefault(Builder $query): Builder { return $query->where('is_default', true); } diff --git a/packages/core/src/Models/Collection.php b/packages/core/src/Models/Collection.php index 776543790..8121d8c6b 100644 --- a/packages/core/src/Models/Collection.php +++ b/packages/core/src/Models/Collection.php @@ -9,10 +9,18 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphToMany; +use Shopper\Core\Enum\CollectionType; use Shopper\Core\Traits\HasMedia; use Shopper\Core\Traits\HasSlug; use Spatie\MediaLibrary\HasMedia as SpatieHasMedia; +/** + * @property-read int $id + * @property string $type + * @property string $name + * @property string $slug + * @property string|null $description + */ class Collection extends Model implements SpatieHasMedia { use HasFactory; @@ -32,17 +40,17 @@ public function getTable(): string public function scopeManual(Builder $query): Builder { - return $query->where('type', 'manual'); + return $query->where('type', CollectionType::MANUAL->value); } public function scopeAutomatic(Builder $query): Builder { - return $query->where('type', 'auto'); + return $query->where('type', CollectionType::AUTO->value); } public function isAutomatic(): bool { - return 'auto' === $this->type; // @phpstan-ignore-line + return $this->type === CollectionType::AUTO->value; } public function isManual(): bool diff --git a/packages/core/src/Models/Country.php b/packages/core/src/Models/Country.php index 9e3e9c407..e120f432a 100644 --- a/packages/core/src/Models/Country.php +++ b/packages/core/src/Models/Country.php @@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model; -class Country extends Model +final class Country extends Model { public $timestamps = false; diff --git a/packages/core/src/Models/Discount.php b/packages/core/src/Models/Discount.php index c03d1718e..e7b60886b 100644 --- a/packages/core/src/Models/Discount.php +++ b/packages/core/src/Models/Discount.php @@ -22,7 +22,7 @@ * @property \Illuminate\Support\Carbon $start_at * @property \Illuminate\Support\Carbon|null $end_at */ -class Discount extends Model +final class Discount extends Model { use HasFactory; diff --git a/packages/core/src/Models/DiscountDetail.php b/packages/core/src/Models/DiscountDetail.php index b36139f03..4dbb4fdcb 100644 --- a/packages/core/src/Models/DiscountDetail.php +++ b/packages/core/src/Models/DiscountDetail.php @@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; -class DiscountDetail extends Model +final class DiscountDetail extends Model { use HasFactory; diff --git a/packages/core/src/Models/Geolocation.php b/packages/core/src/Models/Geolocation.php index 5b80214b7..8eba627d2 100644 --- a/packages/core/src/Models/Geolocation.php +++ b/packages/core/src/Models/Geolocation.php @@ -5,8 +5,9 @@ namespace Shopper\Core\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; -class Geolocation extends Model +final class Geolocation extends Model { protected $guarded = []; @@ -14,4 +15,14 @@ public function getTable(): string { return shopper_table('users_geolocation_history'); } + + public function user(): BelongsTo + { + return $this->belongsTo(config('auth.providers.users.model', User::class), 'user_id'); + } + + public function order(): BelongsTo + { + return $this->belongsTo(Order::class, 'order_id'); + } } diff --git a/packages/core/src/Models/Inventory.php b/packages/core/src/Models/Inventory.php index e0c9bc1df..ada380ddd 100644 --- a/packages/core/src/Models/Inventory.php +++ b/packages/core/src/Models/Inventory.php @@ -4,6 +4,7 @@ namespace Shopper\Core\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -22,7 +23,7 @@ * @property string|null $phone_number * @property bool $is_default */ -class Inventory extends Model +final class Inventory extends Model { use HasFactory; @@ -54,6 +55,11 @@ public function getTable(): string return shopper_table('inventories'); } + public function scopeDefault(Builder $query): Builder + { + return $query->where('is_default', true); + } + public function country(): BelongsTo { return $this->belongsTo(Country::class, 'country_id'); diff --git a/packages/core/src/Models/InventoryHistory.php b/packages/core/src/Models/InventoryHistory.php index 32f5680aa..3a902326b 100644 --- a/packages/core/src/Models/InventoryHistory.php +++ b/packages/core/src/Models/InventoryHistory.php @@ -4,12 +4,22 @@ namespace Shopper\Core\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; -class InventoryHistory extends Model +/** + * @property-read int $id + * @property int $quantity + * @property int $old_quantity + * @property string|null $event + * @property string|null $description + * @property int $user_id + * @property int $inventory_id + */ +final class InventoryHistory extends Model { use HasFactory; @@ -19,11 +29,11 @@ class InventoryHistory extends Model 'reference_type', 'reference_id', 'inventory_id', + 'user_id', 'event', 'quantity', 'old_quantity', 'description', - 'user_id', ]; protected $appends = [ @@ -35,14 +45,13 @@ public function getTable(): string return shopper_table('inventory_histories'); } - public function getAdjustmentAttribute(): string + public function adjustment(): Attribute { - // @phpstan-ignore-next-line - if ($this->old_quantity > 0) { - return '+' . $this->old_quantity; - } - - return (string) $this->old_quantity; + return Attribute::make( + get: fn () => $this->old_quantity > 0 + ? '+' . $this->old_quantity + : $this->old_quantity + ); } public function inventory(): BelongsTo diff --git a/packages/core/src/Models/Legal.php b/packages/core/src/Models/Legal.php index bcbcca6dc..4aea5c7bb 100644 --- a/packages/core/src/Models/Legal.php +++ b/packages/core/src/Models/Legal.php @@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Model; use Shopper\Core\Traits\HasSlug; -class Legal extends Model +final class Legal extends Model { use HasSlug; diff --git a/packages/core/src/Models/Order.php b/packages/core/src/Models/Order.php index 8387fccd5..0b1d9f64e 100644 --- a/packages/core/src/Models/Order.php +++ b/packages/core/src/Models/Order.php @@ -20,7 +20,7 @@ * @property OrderStatus $status * @property int $shipping_total */ -class Order extends Model +final class Order extends Model { use HasFactory; use HasPrice; diff --git a/packages/core/src/Models/OrderItem.php b/packages/core/src/Models/OrderItem.php index b86bab99a..b2c2cd3e1 100644 --- a/packages/core/src/Models/OrderItem.php +++ b/packages/core/src/Models/OrderItem.php @@ -14,7 +14,7 @@ * @property int $quantity * @property int $unit_price_amount */ -class OrderItem extends Model +final class OrderItem extends Model { use HasFactory; diff --git a/packages/core/src/Models/OrderRefund.php b/packages/core/src/Models/OrderRefund.php index 573d9815f..9a3cb48ae 100644 --- a/packages/core/src/Models/OrderRefund.php +++ b/packages/core/src/Models/OrderRefund.php @@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Shopper\Core\Enum\OrderRefundStatus; -class OrderRefund extends Model +final class OrderRefund extends Model { use HasFactory; @@ -48,7 +48,7 @@ protected function setDefaultOrderRefundStatus(): void $this->setRawAttributes( array_merge( $this->attributes, - ['status' => OrderRefundStatus::PENDING->value()] + ['status' => OrderRefundStatus::PENDING->value] ), true ); diff --git a/packages/core/src/Models/OrderShipping.php b/packages/core/src/Models/OrderShipping.php index 979705b95..bf2d903d7 100644 --- a/packages/core/src/Models/OrderShipping.php +++ b/packages/core/src/Models/OrderShipping.php @@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; -class OrderShipping extends Model +final class OrderShipping extends Model { use HasFactory; diff --git a/packages/core/src/Models/PaymentMethod.php b/packages/core/src/Models/PaymentMethod.php index 0580a4e1a..c7a3078e5 100644 --- a/packages/core/src/Models/PaymentMethod.php +++ b/packages/core/src/Models/PaymentMethod.php @@ -18,7 +18,7 @@ * @property string|null $link_url * @property string|null $instructions */ -class PaymentMethod extends Model +final class PaymentMethod extends Model { use HasFactory; use HasSlug; diff --git a/packages/core/src/Models/Permission.php b/packages/core/src/Models/Permission.php index 99181db96..0c4a948b7 100644 --- a/packages/core/src/Models/Permission.php +++ b/packages/core/src/Models/Permission.php @@ -6,6 +6,12 @@ use Spatie\Permission\Models\Permission as SpatiePermission; +/** + * @property-read int $id + * @property string $name + * @property string|null $display_name + * @property bool $can_be_removed + */ final class Permission extends SpatiePermission { protected $casts = [ diff --git a/packages/core/src/Models/Product.php b/packages/core/src/Models/Product.php index 1f17f9135..13e187da4 100644 --- a/packages/core/src/Models/Product.php +++ b/packages/core/src/Models/Product.php @@ -12,6 +12,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphToMany; use Shopper\Core\Contracts\ReviewRateable; +use Shopper\Core\Enum\Dimension\Length; +use Shopper\Core\Enum\Dimension\Volume; +use Shopper\Core\Enum\Dimension\Weight; use Shopper\Core\Helpers\Price; use Shopper\Core\Traits\CanHaveDiscount; use Shopper\Core\Traits\HasMedia; @@ -28,6 +31,8 @@ * @property int|null $price_amount * @property int|null $old_price_amount * @property int|null $cost_amount + * @property \Carbon\Carbon|null $published_at + * @property-read int $stock */ class Product extends Model implements SpatieHasMedia, ReviewRateable { @@ -48,6 +53,10 @@ class Product extends Model implements SpatieHasMedia, ReviewRateable 'requires_shipping' => 'boolean', 'backorder' => 'boolean', 'published_at' => 'datetime', + 'depth_unit' => Length::class, + 'height_unit' => Length::class, + 'volume_unit' => Volume::class, + 'weight_unit' => Weight::class, ]; public function getTable(): string @@ -112,7 +121,7 @@ public function getCostAmount(): ?Price return Price::from($this->cost_amount); } - public function getVariationsStockAttribute(): int + public function variationsStock(): Attribute { $stock = 0; @@ -122,7 +131,9 @@ public function getVariationsStockAttribute(): int } } - return $stock; + return Attribute::make( + get: fn () => $stock, + ); } public function scopePublish(Builder $query): Builder diff --git a/packages/core/src/Models/Review.php b/packages/core/src/Models/Review.php index 3ae778745..7129dd777 100644 --- a/packages/core/src/Models/Review.php +++ b/packages/core/src/Models/Review.php @@ -14,7 +14,7 @@ * @property-read int $id * @property bool $approved */ -class Review extends Model +final class Review extends Model { use HasFactory; diff --git a/packages/core/src/Models/Setting.php b/packages/core/src/Models/Setting.php index 4bc15a802..652e0eca8 100644 --- a/packages/core/src/Models/Setting.php +++ b/packages/core/src/Models/Setting.php @@ -47,9 +47,9 @@ public static function lockedAttributesDisplayName(string $key): string 'shop_phone_number' => __('shopper::layout.forms.label.phone_number'), 'shop_lng' => __('shopper::layout.forms.label.longitude'), 'shop_lat' => __('shopper::layout.forms.label.latitude'), - 'shop_facebook_link' => __('Facebook'), - 'shop_instagram_link' => __('Twitter'), - 'shop_twitter_link' => __('Instagram'), + 'shop_facebook_link' => __('shopper::words.socials.facebook'), + 'shop_instagram_link' => __('shopper::words.socials.twitter'), + 'shop_twitter_link' => __('shopper::words.socials.instagram'), 'google_analytics_add_js' => __('shopper::layout.forms.label.ga_additional_script'), ][$key]; } diff --git a/packages/core/src/Models/User.php b/packages/core/src/Models/User.php index 6d79dd7ca..c7ff1261c 100644 --- a/packages/core/src/Models/User.php +++ b/packages/core/src/Models/User.php @@ -6,6 +6,7 @@ use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as Authenticatable; @@ -17,9 +18,14 @@ /** * @property-read int $id + * @property-read string $full_name + * @property-read string $picture * @property string|null $first_name * @property string $last_name * @property string $email + * @property string $avatar_type + * @property string|null $avatar_location + * @property string|null $phone_number * @property Carbon|null $email_verified_at * @property Carbon|null $birth_date * @property string|null $two_factor_recovery_codes @@ -81,34 +87,36 @@ public function isAdmin(): bool public function isVerified(): bool { - return null !== $this->email_verified_at; + return $this->email_verified_at !== null; } - public function getFullNameAttribute(): string + public function fullName(): Attribute { - return $this->first_name - ? $this->first_name . ' ' . $this->last_name - : $this->last_name; + return Attribute::make( + get: fn () => $this->first_name + ? $this->first_name . ' ' . $this->last_name + : $this->last_name + ); } - public function getBirthDateFormattedAttribute(): string + public function birthDateFormatted(): Attribute { - if ($this->birth_date) { - return $this->birth_date->formatLocalized('%d, %B %Y'); - } - - return __('shopper::words.not_defined'); + return Attribute::make( + get: fn () => $this->birth_date + ? $this->birth_date->isoFormat('%d, %B %Y') + : __('shopper::words.not_defined') + ); } - public function getRolesLabelAttribute(): string + public function rolesLabel(): Attribute { $roles = $this->roles()->pluck('display_name')->toArray(); - if (count($roles)) { - return implode(', ', array_map(fn ($item) => ucwords($item), $roles)); - } - - return 'N/A'; + return Attribute::make( + get: fn () => count($roles) + ? implode(', ', array_map(fn ($item) => ucwords($item), $roles)) + : 'N/A' + ); } public function scopeResearch(Builder $query, $term): Builder diff --git a/packages/core/src/Traits/ArrayableEnum.php b/packages/core/src/Traits/ArrayableEnum.php new file mode 100644 index 000000000..c52723390 --- /dev/null +++ b/packages/core/src/Traits/ArrayableEnum.php @@ -0,0 +1,23 @@ +realStock) { + if ($this->realStock === 0) { return; } @@ -48,18 +48,18 @@ public function decrementStock(): void public function updateCurrentStock(): void { - if (0 === $this->value) { + if ($this->value === 0) { return; } $this->validate(['value' => 'required|integer']); if ($this->realStock >= $this->stock) { - $this->product->increaseStock( + $this->product->mutateStock( $this->inventory, $this->value, [ - 'event' => __('Manually added'), + 'event' => __('shopper::pages/products.inventory.add'), 'old_quantity' => $this->value, ] ); @@ -68,7 +68,7 @@ public function updateCurrentStock(): void $this->inventory, $this->value, [ - 'event' => __('Manually removed'), + 'event' => __('shopper::pages/products.inventory.remove'), 'old_quantity' => $this->value, ] ); diff --git a/packages/core/src/Traits/HasMedia.php b/packages/core/src/Traits/HasMedia.php index 313943379..85448d141 100644 --- a/packages/core/src/Traits/HasMedia.php +++ b/packages/core/src/Traits/HasMedia.php @@ -17,7 +17,7 @@ public function registerMediaCollections(): void $this->addMediaCollection(config('shopper.core.storage.collection_name')) ->useDisk(config('shopper.core.storage.disk_name')) ->acceptsMimeTypes(config('shopper.media.accepts_mime_types')) - ->useFallbackUrl(url('/shopper/images/placeholder.jpg')); + ->useFallbackUrl(url(config('shopper.media.fallback_url'))); } public function registerMediaConversions(Media $media = null): void diff --git a/packages/core/src/Traits/HasProfilePhoto.php b/packages/core/src/Traits/HasProfilePhoto.php index 87cf66ae2..025f0b2ca 100644 --- a/packages/core/src/Traits/HasProfilePhoto.php +++ b/packages/core/src/Traits/HasProfilePhoto.php @@ -4,17 +4,18 @@ namespace Shopper\Core\Traits; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Support\Facades\Storage; trait HasProfilePhoto { - public function getPictureAttribute(): string + public function picture(): Attribute { - if ('storage' === $this->avatar_type) { - return Storage::disk(config('shopper.core.storage.disk_name'))->url($this->avatar_location); - } - - return $this->defaultProfilePhotoUrl(); + return Attribute::make( + get: fn () => $this->avatar_type === 'storage' + ? Storage::disk(config('shopper.core.storage.disk_name'))->url($this->avatar_location) + : $this->defaultProfilePhotoUrl() + ); } protected function defaultProfilePhotoUrl(): string diff --git a/packages/core/src/Traits/HasStock.php b/packages/core/src/Traits/HasStock.php index 473a1885d..3ede704f1 100644 --- a/packages/core/src/Traits/HasStock.php +++ b/packages/core/src/Traits/HasStock.php @@ -5,6 +5,7 @@ namespace Shopper\Core\Traits; use DateTimeInterface; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Support\Arr; use Illuminate\Support\Carbon; @@ -12,12 +13,19 @@ trait HasStock { - public function getStockAttribute(): int + public function stock(): Attribute { - return $this->stock(); + return Attribute::make( + get: fn () => $this->getStock(), + ); } - public function stock(DateTimeInterface $date = null): int + public function inStock(int $quantity = 1): bool + { + return $this->stock > 0 && $this->stock >= $quantity; + } + + public function getStock(DateTimeInterface $date = null): int { $date = $date ?: Carbon::now(); @@ -44,7 +52,7 @@ public function stockInventory(int $inventoryId, string $date = null): int ->sum('quantity'); } - public function increaseStock(int $inventoryId, int $quantity = 1, array $arguments = []): InventoryHistory + public function mutateStock(int $inventoryId, int $quantity = 1, array $arguments = []): InventoryHistory { return $this->createStockMutation($quantity, $inventoryId, $arguments); } @@ -54,11 +62,6 @@ public function decreaseStock(int $inventoryId, int $quantity = 1, array $argume return $this->createStockMutation(-1 * abs($quantity), $inventoryId, $arguments); } - public function mutateStock(int $inventoryId, int $quantity = 1, array $arguments = []): InventoryHistory - { - return $this->createStockMutation($quantity, $inventoryId, $arguments); - } - public function clearStock(int $inventoryId = null, int $newQuantity = null, array $arguments = []): bool { $this->inventoryHistories()->delete(); @@ -70,11 +73,6 @@ public function clearStock(int $inventoryId = null, int $newQuantity = null, arr return true; } - public function inStock(int $quantity = 1): bool - { - return $this->stock > 0 && $this->stock >= $quantity; - } - public function setStock(int $newQuantity, int $inventoryId, array $arguments = []): ?InventoryHistory { $currentStock = $this->stock; @@ -87,12 +85,7 @@ public function setStock(int $newQuantity, int $inventoryId, array $arguments = return $this->createStockMutation($deltaStock, $inventoryId, $arguments); } - public function inventoryHistories(): MorphMany - { - return $this->morphMany(InventoryHistory::class, 'stockable')->orderBy('created_at', 'desc'); - } - - protected function createStockMutation(int $quantity, int $inventoryId, array $arguments = []): InventoryHistory + public function createStockMutation(int $quantity, int $inventoryId, array $arguments = []): InventoryHistory { $reference = Arr::get($arguments, 'reference'); @@ -111,4 +104,9 @@ protected function createStockMutation(int $quantity, int $inventoryId, array $a return $this->inventoryHistories()->create($createArguments); } + + public function inventoryHistories(): MorphMany + { + return $this->morphMany(InventoryHistory::class, 'stockable')->orderBy('created_at', 'desc'); + } } diff --git a/packages/core/src/helpers.php b/packages/core/src/helpers.php index a3103a64e..8f0607844 100644 --- a/packages/core/src/helpers.php +++ b/packages/core/src/helpers.php @@ -16,7 +16,9 @@ if (! function_exists('generate_number')) { function generate_number(): string { - $lastOrder = Order::query()->orderBy('id', 'desc')->limit(1)->first(); + $lastOrder = Order::query()->orderBy('id', 'desc') + ->limit(1) + ->first(); $generator = [ 'start_sequence_from' => 1, @@ -46,7 +48,7 @@ function shopper_version(): string if (! function_exists('shopper_table')) { function shopper_table(string $table): string { - if ('' !== config('shopper.core.table_prefix')) { + if (config('shopper.core.table_prefix') !== '') { return config('shopper.core.table_prefix') . $table; } @@ -120,17 +122,32 @@ function shopper_setting(string $key): mixed } if (! function_exists('useTryCatch')) { - function useTryCatch(Closure $closure): array + function useTryCatch(Closure $closure, Closure $catchable = null): array { $result = null; $throwable = null; + $catch = $catchable ?? fn (Throwable $exception) => $exception; + try { $result = $closure(); } catch (Throwable $exception) { - $throwable = $exception; + $throwable = $catch($exception); } return [$throwable, $result]; } } + +if (! function_exists('isoToEmoji')) { + function isoToEmoji(string $code): string + { + return implode( + '', + array_map( + fn (string $letter) => mb_chr(ord($letter) % 32 + 0x1F1E5), + mb_str_split($code) + ) + ); + } +}