2026-09-03 11:47:38 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Catalog;
|
|
|
|
|
|
|
|
|
|
/**
|
2026-09-03 16:28:10 +03:00
|
|
|
* Presentation shaping — how a storefront product listing/grid card is built:
|
|
|
|
|
* name, price, image, href. Deliberately not in boboko-core: `href` depends on
|
|
|
|
|
* this storefront's own routes, and another app on the same core package could
|
|
|
|
|
* want an entirely different card shape. One place, so HomeController /
|
|
|
|
|
* CategoryController / ProductController / SearchController don't each
|
|
|
|
|
* hand-write the same name/price/image/href mapping.
|
|
|
|
|
*
|
2026-09-04 13:07:57 +03:00
|
|
|
* One source: a localized index array — ProductService::list()/getById()/
|
|
|
|
|
* random(), and now ProductSearchService::search() too, all return the exact
|
|
|
|
|
* same document shape (see ProductListingResult), so this is the only mapping
|
|
|
|
|
* every storefront listing page needs.
|
2026-09-03 11:47:38 +03:00
|
|
|
*/
|
|
|
|
|
final class ProductCard
|
|
|
|
|
{
|
2026-09-03 16:28:10 +03:00
|
|
|
/**
|
|
|
|
|
* @param array<string, mixed> $product one item from ProductService's localized array shape
|
|
|
|
|
* @return array{name: ?string, price: ?string, image: ?string, href: string}
|
2026-09-03 11:47:38 +03:00
|
|
|
*/
|
|
|
|
|
public static function fromIndexed(array $product): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'name' => $product['name'],
|
|
|
|
|
'price' => $product['price'],
|
|
|
|
|
'image' => $product['media'][0]['url'] ?? null,
|
|
|
|
|
'href' => route('product.show', ['id' => $product['id']]),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|