From 615263f233dcf25cd23204a4ac2d838a630f0512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Munsch?= Date: Fri, 8 Sep 2023 16:02:21 +0200 Subject: [PATCH] Refactor and fixes Fixes #33 Fixes #34 --- app/Enums/Products/CertificationEnum.php | 2 +- app/Enums/Products/ClaimEnum.php | 2 +- .../Products/DistributionNetworkEnum.php | 2 +- app/Enums/Products/GeoAreaEnum.php | 2 +- app/Enums/Products/OriginEnum.php | 2 +- app/Enums/Products/RangeEnum.php | 2 +- app/Enums/Products/RayEnum.php | 2 +- app/Enums/Products/SourceEnum.php | 2 +- app/Http/Resources/ProductResource.php | 68 ++----- app/Models/Keyword.php | 7 +- app/Models/Product.php | 169 ++++++++++++------ app/Models/ProductComment.php | 36 ++-- .../views/documents/product-body.blade.php | 68 +++---- 13 files changed, 195 insertions(+), 169 deletions(-) diff --git a/app/Enums/Products/CertificationEnum.php b/app/Enums/Products/CertificationEnum.php index fb960eb..85eb0d0 100644 --- a/app/Enums/Products/CertificationEnum.php +++ b/app/Enums/Products/CertificationEnum.php @@ -4,7 +4,7 @@ namespace App\Enums\Products; use App\Traits\Enums\BaseEnum; -enum CertificationEnum : int +enum CertificationEnum: int { use BaseEnum; diff --git a/app/Enums/Products/ClaimEnum.php b/app/Enums/Products/ClaimEnum.php index 89141be..785549a 100644 --- a/app/Enums/Products/ClaimEnum.php +++ b/app/Enums/Products/ClaimEnum.php @@ -4,7 +4,7 @@ namespace App\Enums\Products; use App\Traits\Enums\BaseEnum; -enum ClaimEnum : int +enum ClaimEnum: int { use BaseEnum; diff --git a/app/Enums/Products/DistributionNetworkEnum.php b/app/Enums/Products/DistributionNetworkEnum.php index d5df782..0a47007 100644 --- a/app/Enums/Products/DistributionNetworkEnum.php +++ b/app/Enums/Products/DistributionNetworkEnum.php @@ -4,7 +4,7 @@ namespace App\Enums\Products; use App\Traits\Enums\BaseEnum; -enum DistributionNetworkEnum : int +enum DistributionNetworkEnum: int { use BaseEnum; diff --git a/app/Enums/Products/GeoAreaEnum.php b/app/Enums/Products/GeoAreaEnum.php index b4b1659..42fd192 100644 --- a/app/Enums/Products/GeoAreaEnum.php +++ b/app/Enums/Products/GeoAreaEnum.php @@ -4,7 +4,7 @@ namespace App\Enums\Products; use App\Traits\Enums\BaseEnum; -enum GeoAreaEnum : int +enum GeoAreaEnum: int { use BaseEnum; diff --git a/app/Enums/Products/OriginEnum.php b/app/Enums/Products/OriginEnum.php index eb584c1..c8cb0e0 100644 --- a/app/Enums/Products/OriginEnum.php +++ b/app/Enums/Products/OriginEnum.php @@ -4,7 +4,7 @@ namespace App\Enums\Products; use App\Traits\Enums\BaseEnum; -enum OriginEnum : int +enum OriginEnum: int { use BaseEnum; diff --git a/app/Enums/Products/RangeEnum.php b/app/Enums/Products/RangeEnum.php index 8feb410..5ee737a 100644 --- a/app/Enums/Products/RangeEnum.php +++ b/app/Enums/Products/RangeEnum.php @@ -4,7 +4,7 @@ namespace App\Enums\Products; use App\Traits\Enums\BaseEnum; -enum RangeEnum : int +enum RangeEnum: int { use BaseEnum; diff --git a/app/Enums/Products/RayEnum.php b/app/Enums/Products/RayEnum.php index ddd32c0..5ec3fca 100644 --- a/app/Enums/Products/RayEnum.php +++ b/app/Enums/Products/RayEnum.php @@ -4,7 +4,7 @@ namespace App\Enums\Products; use App\Traits\Enums\BaseEnum; -enum RayEnum : int +enum RayEnum: int { use BaseEnum; diff --git a/app/Enums/Products/SourceEnum.php b/app/Enums/Products/SourceEnum.php index 9c0e61c..64d0f92 100644 --- a/app/Enums/Products/SourceEnum.php +++ b/app/Enums/Products/SourceEnum.php @@ -4,7 +4,7 @@ namespace App\Enums\Products; use App\Traits\Enums\BaseEnum; -enum SourceEnum : int +enum SourceEnum: int { use BaseEnum; diff --git a/app/Http/Resources/ProductResource.php b/app/Http/Resources/ProductResource.php index 54431c5..8e93bb3 100644 --- a/app/Http/Resources/ProductResource.php +++ b/app/Http/Resources/ProductResource.php @@ -2,13 +2,10 @@ namespace App\Http\Resources; -use App\Enums\Products\CertificationEnum; use App\Enums\Products\ClaimEnum; use App\Enums\Products\OriginEnum; -use App\Models\Brand; +use App\Models\Keyword; use App\Models\Product; -use App\Models\User; -use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; class ProductResource extends JsonResource @@ -19,8 +16,8 @@ class ProductResource extends JsonResource /** @var array */ private static $skeleton = [ 'id' => null, - 'user_id' => null, - 'brand_id' => null, + 'user' => null, + 'brand' => null, 'name' => null, 'seen_at' => null, 'source' => null, @@ -65,56 +62,13 @@ class ProductResource extends JsonResource */ public function toArray($request = null) { - foreach (CertificationEnum::toArray() as $enumValue) { - if ($this->product->certification->value === $enumValue->value) { - $certification = $enumValue->label; - } - } - if (count($this->product->origins)) { - $origins = ""; - foreach ($this->product->origins as $originValue) { - /** @var \App\Enums\Products\OriginEnum $enumValue */ - foreach (OriginEnum::toArray() as $enumValue) { - if ($originValue === $enumValue->value) { - $origins = $origins . $enumValue->label . ", "; - } - } - } - } - if (count($this->product->claims)) { - $claims = ""; - foreach ($this->product->claims as $originValue) { - /** @var \App\Enums\Products\ClaimEnum $enumValue */ - foreach (ClaimEnum::toArray() as $enumValue) { - if ($originValue === $enumValue->value) { - if ($enumValue->value === ClaimEnum::others->value) { - $claims = $claims . $enumValue->label . ": " . $this->product->specified_claim . ", "; - } else { - $claims = $claims . $enumValue->label . ", "; - } - } - } - } - } - foreach ($this->product->productComments as $productComment) { - $productComment->date = Carbon::createFromFormat( - 'Y-m-d H:i:s', - $productComment->created_at - )->format('d/m/Y'); - } - if (count($this->product->productKeywords)) { - $productKeywords = ""; - foreach ($this->product->productKeywords as $productKeyword) { - $productKeywords = $productKeywords . $productKeyword->label . ", "; - } - } return array_intersect_key( [ 'id' => $this->product->id, - 'user_id' => User::where('id', $this->product->user_id)->firstOrFail(), - 'brand_id' => Brand::where('id', $this->product->brand_id)->firstOrFail(), + 'user' => (object)$this->product->user->toArray(), + 'brand' => (object)$this->product->brand->toArray(), 'name' => $this->product->name, - 'seen_at' => Carbon::createFromFormat('Y-m-d H:i:s', $this->product->seen_at)->format('d/m/Y'), + 'seen_at' => $this->product->seen_at->isoFormat('DD\/MM\/YYYY \à HH\hmm'), 'source' => $this->product->source->label(), 'fair' => $this->product->fair, 'shop' => $this->product->shop, @@ -125,16 +79,18 @@ class ProductResource extends JsonResource 'picture' => $this->product->picture, 'picture_alt' => $this->product->picture_alt, 'picture_title' => $this->product->picture_title, - 'certification' => $certification, - 'origins' => $origins ?? null, - 'claims' => $claims ?? null, + 'certification' => \optional($this->product->certification)->label, + 'origins' => $this->product->origins_enum->map(fn (OriginEnum $enum) => $enum->label())->implode(', '), + 'claims' => $this->product->claims_enum->map(fn (ClaimEnum $enum) => $enum->label())->implode(', '), 'distribution_network' => $this->product->distribution_network->label(), 'ray' => $this->product->ray->label(), 'product_range' => $this->product->product_range->label(), 'geo_area' => $this->product->geo_area->label(), 'freeComment' => $this->product->comment, 'productComments' => $this->product->productComments, - 'productKeywords' => $productKeywords ?? null, + 'productKeywords' => $this->product->productKeywords + ->map(fn (Keyword $keyword) => $keyword->label) + ->implode(', '), ], $this->getSkeleton() ); diff --git a/app/Models/Keyword.php b/app/Models/Keyword.php index 2607945..f933142 100644 --- a/app/Models/Keyword.php +++ b/app/Models/Keyword.php @@ -11,7 +11,10 @@ use Illuminate\Database\Eloquent\Model; * @property \App\Enums\KeywordCategoryEnum $keyword_cat * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property Keywordable[] $keywordables + * + * * RELATIONSHIPS + * @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products + * @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Keyword> $keywordables */ class Keyword extends Model { @@ -34,6 +37,8 @@ class Keyword extends Model 'keyword_cat' => KeywordCategoryEnum::class ]; + // * RELATIONSHIPS + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ diff --git a/app/Models/Product.php b/app/Models/Product.php index 77901de..094a602 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -3,8 +3,10 @@ namespace App\Models; use App\Enums\Products\CertificationEnum; +use App\Enums\Products\ClaimEnum; use App\Enums\Products\DistributionNetworkEnum; use App\Enums\Products\GeoAreaEnum; +use App\Enums\Products\OriginEnum; use App\Enums\Products\RangeEnum; use App\Enums\Products\RayEnum; use App\Enums\Products\SourceEnum; @@ -13,43 +15,53 @@ use App\Lib\Helpers\FileStorageHelper; use App\Lib\Helpers\ToolboxHelper; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Storage; use Mccarlosen\LaravelMpdf\LaravelMpdf; use Symfony\Component\HttpFoundation\StreamedResponse; /** - * @property integer $id - * @property integer $user_id - * @property integer $brand_id - * @property string $name - * @property string $brand - * @property string $seen_at - * @property enum $source - * @property string $fair - * @property string $shop - * @property string $catalogue - * @property string $gencod - * @property string $picture - * @property array $docs - * @property string $url - * @property enum $certification - * @property array $origins - * @property array $claims - * @property string $specified_claim - * @property enum $distribution_network - * @property enum $ray - * @property enum $product_range - * @property enum $geo area - * @property integer $weight - * @property integer $pvc - * @property string $comment - * @property boolean $is_tasted - * @property integer $tasters_number - * @property string $created_at - * @property string $updated_at - * @property string $deleted_at - * @property ProductComment[] $productComments - * @property User $user + * FIXME: using migration, do not set nullable props without a real need. + * + * @property integer $id + * @property integer $user_id + * @property integer $brand_id + * @property string $name + * @property \Carbon\Carbon $seen_at + * @property \App\Enums\Products\SourceEnum $source + * @property string|null $fair + * @property string|null $shop + * @property string|null $catalogue + * @property string|null $gencod + * @property string|null $picture + * @property string $picture_alt + * @property string $picture_title + * @property array|null $docs + * @property string|null $url + * @property \App\Enums\Products\CertificationEnum|null $certification + * @property array|null $origins + * @property \Illuminate\Support\Collection<\App\Enums\Products\OriginEnum> $origins_enum + * @property array|null $claims + * @property \Illuminate\Support\Collection<\App\Enums\Products\OriginEnum> $claims_enum + * @property string|null $specified_claim + * @property \App\Enums\Products\DistributionNetworkEnum $distribution_network + * @property \App\Enums\Products\RayEnum $ray + * @property \App\Enums\Products\RangeEnum $product_range + * @property \App\Enums\Products\GeoAreaEnum $geo area + * @property integer|null $weight + * @property integer|null $pvc + * @property string|null $comment + * @property boolean $is_tasted + * @property integer|null $tasters_number + * @property \Carbon\Carbon|null $created_at + * @property \Carbon\Carbon|null $updated_at + * @property \Carbon\Carbon|null $deleted_at + * + * * RELATIONSHIPS + * @property-read \App\Models\Brand $brand + * @property-read \App\Models\User $user + * @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\ProductComment> $productComments + * @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Keyword> $productKeywords */ class Product extends Model { @@ -109,10 +121,10 @@ class Product extends Model 'product_range' => RangeEnum::class, 'geo_area' => GeoAreaEnum::class, 'is_tasted' => 'boolean', - 'seen_at' => 'datetime:Y-m-d', - 'created_at' => 'datetime:Y-m-d', - 'updated_at' => 'datetime:Y-m-d', - 'deleted_at' => 'datetime:Y-m-d', + 'seen_at' => 'datetime', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'deleted_at' => 'datetime', ]; // * EVENTS @@ -292,28 +304,29 @@ class Product extends Model /** * Generate a pdf with multiple products. * - * @param array $printMultiProduct - * @param string $title + * @param array $printMultiProduct + * @param string $title * @return \Mccarlosen\LaravelMpdf\LaravelMpdf */ public static function generateMultipleProductPdf(array $printMultiProduct, string $title) { - /** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */ + /** @var \Mccarlosen\LaravelMpdf\LaravelMpdf|null */ $pdf = null; - // Loop all views. + // * Loop all Model ids. foreach ($printMultiProduct as $productId) { - $product = Product::where('id', $productId)->firstOrFail(); - // If not yet defined, set the first page. + /** @var \App\Models\Product */ + $product = Product::query()->where('id', $productId)->firstOrFail(); + // * If not yet defined, set the first page. if (is_null($pdf)) { $pdf = Product::generateProductPdf($product, $title); - } else { - // Add another page and add HTML from view to this. - $pdf->getMpdf()->AddPage(); - $pdf->getMpdf()->WriteHTML((string)view( - 'documents.product-body', - ['product' => \json_decode(\json_encode(new ProductResource($product)))], - )); } + + // * Add another page and add HTML from view to this. + $pdf->getMpdf()->AddPage(); + $pdf->getMpdf()->WriteHTML((string)view( + 'documents.product-body', + ['product' => (object)(new ProductResource($product))->toArray()], + )); } return $pdf; } @@ -349,14 +362,64 @@ class Product extends Model ])->send(); } - // * RELATIONS + // * GETTERS + + /** + * Get origins_enum attribute + * + * @return \Illuminate\Support\Collection<\App\Enums\Ingredients\OriginEnum> + */ + public function getOriginsEnumAttribute(): Collection + { + return \collect($this->getAttribute('origins'))->filter() + ->map(fn (int $originEnumValue) => OriginEnum::make($originEnumValue)); + } + + /** + * Set origins_enum attribute + * + * @param mixed $value + * @return void + */ + public function setOriginsEnumAttribute(mixed $value): void + { + $this->setAttribute('origins', \collect($value)->filter() + ->map(fn ($originEnumValue) => OriginEnum::make($originEnumValue)->value()) + ->all()); + } + + /** + * Get claims_enum attribute + * + * @return \Illuminate\Support\Collection<\App\Enums\Ingredients\ClaimEnum> + */ + public function getClaimsEnumAttribute(): Collection + { + return \collect($this->getAttribute('claims'))->filter() + ->map(fn (int $originEnumValue) => ClaimEnum::make($originEnumValue)); + } + + /** + * Set claims_enum attribute + * + * @param mixed $value + * @return void + */ + public function setClaimsEnumAttribute(mixed $value): void + { + $this->setAttribute('claims', \collect($value)->filter() + ->map(fn ($claimEnumValue) => OriginEnum::make($claimEnumValue)->value()) + ->all()); + } + + // * RELATIONSHIPS /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function productComments() { - return $this->hasMany('App\Models\ProductComment'); + return $this->hasMany(ProductComment::class); } /** @@ -364,7 +427,7 @@ class Product extends Model */ public function user() { - return $this->belongsTo('App\Models\User'); + return $this->belongsTo(User::class); } /** @@ -372,7 +435,7 @@ class Product extends Model */ public function brand() { - return $this->belongsTo('App\Models\Brand'); + return $this->belongsTo(Brand::class); } /** diff --git a/app/Models/ProductComment.php b/app/Models/ProductComment.php index 53a482c..231139a 100644 --- a/app/Models/ProductComment.php +++ b/app/Models/ProductComment.php @@ -6,16 +6,18 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; /** - * @property integer $id - * @property integer $product_id - * @property string $evaluation - * @property string $aspect - * @property string $taste - * @property string $odor - * @property string $texture - * @property string $created_at - * @property string $updated_at - * @property Product $product + * @property integer $id + * @property integer $product_id + * @property string $evaluation + * @property string|null $aspect + * @property string|null $taste + * @property string|null $odor + * @property string|null $texture + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * + * * RELATIONSHIPS + * @property-read \App\Models\Product $product */ class ProductComment extends Model { @@ -35,11 +37,23 @@ class ProductComment extends Model 'updated_at' ]; + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + ]; + + // * RELATIONSHIPS + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function product() { - return $this->belongsTo('App\Models\Product'); + return $this->belongsTo(Product::class); } } diff --git a/resources/views/documents/product-body.blade.php b/resources/views/documents/product-body.blade.php index 6a97672..6e5907d 100644 --- a/resources/views/documents/product-body.blade.php +++ b/resources/views/documents/product-body.blade.php @@ -13,21 +13,13 @@ @else @endif - @if (isset($product->brand_id->name)) -

{{ __('Marque du produit : ') }}{{ $product->brand_id->name }}

- @endif - @if (isset($product->name)) -

{{ __('Nom du produit : ') }}{{ $product->name }}

- @endif +

{{ __('Marque du produit : ') }}{{ $product->brand->name }}

+

{{ __('Nom du produit : ') }}{{ $product->name }}

@if (isset($product->certification))

{{ __('Certification : ') }}{{ $product->certification }}

@endif - @if (isset($product->origins)) -

{{ __('Origines : ') }}{{ Str::replaceLast(', ', '', $product->origins) }}

- @endif - @if (isset($product->claims)) -

{{ __('Allégations : ') }}{{ Str::replaceLast(', ', '', $product->claims) }}

- @endif +

{{ __('Origines : ') }}{{ $product->origins }}

+

{{ __('Allégations : ') }}{{ $product->claims }}

@if (isset($product->gencod)) @@ -78,41 +70,37 @@ @if (isset($product->freeComment))

{{ __('Commentaire libre : ') }}{{ strip_tags($product->freeComment) }}

@endif -@if (isset($product->productComments)) - @foreach ($product->productComments as $productComment) -

{{ __('Commentaire dégustation du : ') }}{{ $productComment->date }}

-
- - - - - - - - - - - - - - -
{{ __('Appréciation') }}{{ __('Aspect') }}{{ __('Odeur') }}{{ __('Texture') }}{{ __('Goût') }}
{{ $productComment->evaluation }}{{ $productComment->aspect }}{{ $productComment->taste }}{{ $productComment->odor }}{{ $productComment->texture }}
- @endforeach -@endif +@foreach ($product->productComments as $productComment) +

{{ __('Commentaire dégustation du : ') }}{{ $productComment->created_at->isoFormat('DD\/MM\/YYYY') }}

+ + + + + + + + + + + + + + + +
{{ __('Appréciation') }}{{ __('Aspect') }}{{ __('Odeur') }}{{ __('Texture') }}{{ __('Goût') }}
{{ $productComment->evaluation }}{{ $productComment->aspect }}{{ $productComment->taste }}{{ $productComment->odor }}{{ $productComment->texture }}
+@endforeach - @if (isset($product->seen_at)) - - @endif + @if (isset($product->source)) @endif
- {{ __('Téléchargez les documents :') }} - {{ __('ICI') }} - + {{ __('Téléchargez les documents :') }} + {{ __('ICI') }} +

{{ __('Vu le : ') }}{{ $product->seen_at }}

{{ __('Lieu : ') }}{{ $product->source }}, {{ $product->fair }}{{ $product->shop }}{{ $product->catalogue }}

-

{{ __('Par : ') }}{{ $product->user_id->firstname }} {{ $product->user_id->lastname }}

+

{{ __('Par : ') }}{{ $product->user->firstname }} {{ $product->user->lastname }}