generated from boboko/starter
76 lines
2.3 KiB
PHP
76 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Catalog\ProductCard;
|
|
use App\Models\StoicPage;
|
|
use Modules\Core\Catalog\DTOs\ProductFilters;
|
|
use Modules\Core\Catalog\Services\CollectionService;
|
|
use Modules\Core\Catalog\Services\ProductService;
|
|
|
|
class HomeController extends Controller
|
|
{
|
|
/** Slug of the hero collection in the "Homepage" collection group. */
|
|
private const HERO_COLLECTION_SLUG = 'hero';
|
|
|
|
private const HERO_FALLBACK_COUNT = 5;
|
|
|
|
private const CLASSICS_COUNT = 8;
|
|
|
|
public function __construct(
|
|
private readonly ProductService $products,
|
|
private readonly CollectionService $collections,
|
|
) {}
|
|
|
|
public function index(string $locale)
|
|
{
|
|
$page = StoicPage::localized('home');
|
|
|
|
if (! $page) {
|
|
abort(404);
|
|
}
|
|
|
|
// Random pool for the classics carousel, and for the hero too when the
|
|
// hero collection is missing or empty. Oversized so hero products can be
|
|
// excluded from it and still leave enough.
|
|
$random = collect($this->products->random(self::HERO_FALLBACK_COUNT + self::CLASSICS_COUNT));
|
|
|
|
$hero = collect($this->heroCollectionProducts());
|
|
|
|
if ($hero->isEmpty()) {
|
|
$hero = $random->take(self::HERO_FALLBACK_COUNT);
|
|
}
|
|
|
|
$heroIds = $hero->pluck('id')->all();
|
|
|
|
$classics = $random
|
|
->reject(fn (array $product) => in_array($product['id'], $heroIds))
|
|
->take(self::CLASSICS_COUNT);
|
|
|
|
return view('home', [
|
|
'page' => $page,
|
|
'heroProducts' => $hero->map(fn (array $product) => ProductCard::fromIndexed($product))->values(),
|
|
'classicsProducts' => $classics->map(fn (array $product) => ProductCard::fromIndexed($product))->values(),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Products the store owner picked for the hero, via the Lunar collection
|
|
* with slug "hero". Not in the owner's drag order yet: the product index
|
|
* doesn't carry per-collection position (pending a boboko-core task).
|
|
*/
|
|
private function heroCollectionProducts(): array
|
|
{
|
|
$collection = $this->collections->getBySlug(self::HERO_COLLECTION_SLUG);
|
|
|
|
if ($collection === null) {
|
|
return [];
|
|
}
|
|
|
|
return $this->products
|
|
->list(new ProductFilters(collectionId: $collection['id']))
|
|
->products
|
|
->items();
|
|
}
|
|
}
|