ldc-boutique-cnc-sable/app/Dto/ProductDto.php
Jérémy Munsch 70600ea623
refactor(products): migrate BO and FO ProductsControllers to CQS pattern
- Refactor Bo\ProductsController to use ActionExecutor and Queries
- Refactor Fo\Pages\ProductsController and Fo\Ajax\ProductsController to CQS
- Add Actions: CreateProduct, UpdateProduct, DeleteProduct with Inputs
- Add Queries: GetBoPaginatedProductsQuery, GetProductFormDataQuery, GetFoProductIndexPageQuery, GetFoFilteredProductsQuery
- Add DTOs: ProductFormDataDto and enrich ProductDto
- Encapsulate Action/Query inputs conversion in FormRequests
- Remove obsolete ProductDirectory and EloquentProductDirectory
- Add tests for Fo\Ajax\ProductsController
2026-10-27 09:58:42 +01:00

125 lines
4.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Dto;
use App\Models\Product;
use Domain\Enums\ProductBrand;
use Domain\Enums\SellUnit;
use Illuminate\Contracts\Routing\UrlRoutable;
use Illuminate\Contracts\Support\Arrayable;
use Money\Money;
/**
* @implements Arrayable<string, mixed>
*/
final readonly class ProductDto implements Arrayable, UrlRoutable
{
public function __construct(
public string $id,
public string $name,
public string $slug,
public ?ProductBrand $brand = null,
public ?ProductIncoDto $inco = null,
public ?string $picture = null,
public ?string $picture_alt = null,
public ?string $picture_title = null,
public ?string $picture_large = null,
public ?string $picture_large_alt = null,
public ?string $picture_large_title = null,
public ?Money $price = null,
public ?DiscountDto $discount = null,
public int $stock = 0,
public ?SellUnit $sell_unit = null,
public ?RangeDto $range = null,
public int $order = 0,
public bool $status = false,
public bool $star = false,
public ?string $short_description = null,
public ?string $description = null,
) {
}
public static function fromModel(Product $product): self
{
return new self(
id: (string) $product->id,
name: $product->name,
slug: (string) $product->slug,
brand: $product->brand,
inco: $product->relationLoaded('inco') && $product->inco ? ProductIncoDto::fromModel($product->inco) : null,
picture: is_string($product->picture) ? $product->picture : null,
picture_alt: $product->picture_alt,
picture_title: $product->picture_title,
picture_large: is_string($product->picture_large) ? $product->picture_large : null,
picture_large_alt: $product->picture_large_alt,
picture_large_title: $product->picture_large_title,
price: $product->price instanceof Money ? $product->price : null,
discount: $product->relationLoaded('discount') && $product->discount ? DiscountDto::fromModel($product->discount) : null,
stock: (int) $product->stock,
sell_unit: $product->sell_unit,
range: $product->relationLoaded('range') && $product->range ? RangeDto::fromModel($product->range) : null,
order: (int) $product->order,
status: (bool) $product->status,
star: (bool) $product->star,
short_description: $product->short_description,
description: $product->description,
);
}
#[\Override]
public function getRouteKey(): mixed
{
return $this->slug;
}
#[\Override]
public function getRouteKeyName(): string
{
return 'slug';
}
#[\Override]
public function resolveRouteBinding($value, $field = null): mixed
{
return null;
}
#[\Override]
public function resolveChildRouteBinding($childType, $value, $field): mixed
{
return null;
}
/**
* @return array<string, mixed>
*/
#[\Override]
public function toArray(): array
{
return [
'id' => $this->id,
'name' => $this->name,
'slug' => $this->slug,
'brand' => $this->brand?->value,
'inco' => $this->inco?->toArray(),
'picture' => $this->picture,
'picture_alt' => $this->picture_alt,
'picture_title' => $this->picture_title,
'picture_large' => $this->picture_large,
'picture_large_alt' => $this->picture_large_alt,
'picture_large_title' => $this->picture_large_title,
'price' => $this->price?->getAmount(),
'discount' => $this->discount?->toArray(),
'stock' => $this->stock,
'sell_unit' => $this->sell_unit?->value,
'range' => $this->range?->toArray(),
'order' => $this->order,
'status' => $this->status,
'star' => $this->star,
'short_description' => $this->short_description,
'description' => $this->description,
];
}
}