diff --git a/Dockerfile b/Dockerfile index 341cf29..54d20ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -119,13 +119,11 @@ COPY docker/php/php.dev.ini /etc/php/8.5/cli/conf.d/99-app.ini WORKDIR /var/www/html -COPY composer.json composer.lock ./ -RUN composer install \ - --no-interaction \ - --no-scripts \ - --prefer-dist \ - --ignore-platform-reqs - +# No build-time `composer install` here: composer.json's boboko/core path repo +# (../boboko-core) isn't visible in the build context, only once bind-mounted at +# container start — entrypoint.sh already runs composer install + +# composer update boboko/* on every boot, so this would be redundant even if it +# could work. COPY docker/entrypoint.sh /entrypoint.sh COPY docker/entrypoint-worker.sh /entrypoint-worker.sh RUN chmod +x /entrypoint.sh /entrypoint-worker.sh diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index 406e6bf..87aa156 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -2,7 +2,6 @@ namespace App\Http\Controllers; -use Illuminate\Pagination\LengthAwarePaginator; use Lunar\Models\Collection; use Modules\Core\Catalog\ProductFilters; use Modules\Core\Catalog\ProductService; @@ -19,29 +18,19 @@ public function show(string $locale, Collection $collection) $page = (int) request('page', 1); // Listing/filtering reads from the Meilisearch index via ProductService, - // not Eloquent — see Modules\Core\Catalog\ProductService. It returns plain - // arrays (already localized/flattened), not Product models. - $result = $this->products->list( + // not Eloquent — see Modules\Core\Catalog\ProductService. list() returns a + // real LengthAwarePaginator of plain arrays (already localized/flattened), + // not Product models. + $products = $this->products->list( filters: new ProductFilters(collectionId: $collection->id), perPage: $perPage, page: $page, - ); - - $products = new LengthAwarePaginator( - items: collect($result['data'])->map(fn (array $product) => [ - 'name' => $product['name'], - 'price' => $product['price'], - 'image' => $product['media'][0]['url'] ?? null, - 'href' => route('product.show', ['product' => $product['id']]), - ]), - total: $result['meta']['total'], - perPage: $result['meta']['per_page'], - currentPage: $result['meta']['current_page'], - options: [ - 'path' => request()->url(), - 'query' => request()->query(), - ], - ); + )->through(fn (array $product) => [ + 'name' => $product['name'], + 'price' => $product['price'], + 'image' => $product['media'][0]['url'] ?? null, + 'href' => route('product.show', ['id' => $product['id']]), + ]); return view('category.show', [ 'collection' => $collection, diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 6f76ada..5717aec 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -23,7 +23,7 @@ public function index(string $locale) 'name' => $product->translateAttribute('name'), 'price' => $product->variants->first()?->prices->first()?->price->decimal, 'image' => $product->media->first()?->getUrl(), - 'href' => route('product.show', ['product' => $product]), + 'href' => route('product.show', ['id' => $product->id]), ]); return view('home', [ diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index 852bfbb..1765a9d 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -2,44 +2,44 @@ namespace App\Http\Controllers; -use Lunar\Models\Product; +use Illuminate\Http\Response; +use Lunar\Models\Collection; +use Modules\Core\Catalog\ProductService; class ProductController extends Controller { - public function show(string $locale, Product $product) + public function __construct(private readonly ProductService $products) {} + + public function show(string $locale, int $id) { - $product->load([ - "variants.prices.currency", - "variants.values.option", - "media", - "collections", - ]); + $product = $this->products->getById($id); - $option = $product->variants->first()?->values->first()?->option; + abort_if($product === null, Response::HTTP_NOT_FOUND); - $variantsData = $product->variants - ->map( - fn($v) => [ - "id" => $v->id, - "price" => $v->prices->first()?->price->decimal, - "image" => null, // variant-level media not differentiated yet - ], - ) + $collection = $product['collections'][0] ?? null; + $collectionModel = $collection !== null ? Collection::find($collection) : null; + + $variantsData = collect($product['variants']) + ->map(fn (array $variant) => [ + 'id' => $variant['id'], + 'price' => $variant['prices'][0]['price'] ?? null, + 'image' => $variant['media'][0]['url'] ?? null, + ]) ->values() - ->toArray(); + ->all(); - $firstImage = $product->media->first()?->getUrl(); + $firstVariant = $product['variants'][0] ?? null; + $option = $firstVariant['options'][0]['option'] ?? null; // temp categories here - $categories = \Lunar\Models\Collection::orderBy("_lft")->get(); + $categories = Collection::orderBy('_lft')->get(); - // dd($product); - - return view("product.show", [ - "categories" => $categories, - "product" => $product, - "option" => $option, - "variantsData" => $variantsData, + return view('product.show', [ + 'categories' => $categories, + 'collection' => $collectionModel, + 'product' => $product, + 'option' => $option, + 'variantsData' => $variantsData, ]); } } diff --git a/resources/views/components/ui/color-swatch.blade.php b/resources/views/components/ui/color-swatch.blade.php index c64a5bd..5a2562d 100644 --- a/resources/views/components/ui/color-swatch.blade.php +++ b/resources/views/components/ui/color-swatch.blade.php @@ -1,29 +1,32 @@ +{{-- $variants: array of Modules\Core\Search\ProductIndexer's mapVariant() shape + (id, options: [{option, value, meta}], ...) — plain arrays, not Eloquent + models, since this is fed from Modules\Core\Catalog\ProductService. --}} @props(['variants', 'option' => null])
- {{ $option->translate('name') }}: + {{ $option }}:
@endif