96 lines
3.7 KiB
PHP
96 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\System;
|
|
|
|
use App\Enums\PriceType;
|
|
use App\Models\Category;
|
|
use App\Models\Product;
|
|
use App\Models\SystemConfiguration;
|
|
use App\Services\Manage\CuttingResultPriceResolver;
|
|
use App\Services\System\Setting\HomepageSettingService;
|
|
use App\Settings\SocialMediaSettings;
|
|
use App\Settings\SystemSettings;
|
|
use App\Support\Media\MediaPresenter;
|
|
|
|
class HomepageService
|
|
{
|
|
public function __construct(
|
|
private readonly CuttingResultPriceResolver $cuttingResultPriceResolver,
|
|
private readonly HomepageSettingService $homepageSettingService,
|
|
) {}
|
|
|
|
public function pageData(): array
|
|
{
|
|
$categories = Category::getActiveWithProducts();
|
|
$products = $this->getProducts();
|
|
|
|
$configuration = SystemConfiguration::instance();
|
|
$logo = MediaPresenter::first($configuration, 'logo');
|
|
$logoUrl = $logo['url'] ?? null;
|
|
|
|
$settings = app(SystemSettings::class);
|
|
$socialSettings = app(SocialMediaSettings::class);
|
|
|
|
return [
|
|
'categories' => $categories,
|
|
'products' => $products,
|
|
'appName' => $settings->app_name ?? 'DST Collection',
|
|
'aboutApp' => $settings->about_app ?? '',
|
|
'contactEmail' => $settings->email ?? '',
|
|
'contactPhone' => $settings->phone ?? '',
|
|
'contactAddress' => $settings->address ?? '',
|
|
'logoUrl' => $logoUrl,
|
|
'instagramUrl' => $socialSettings->instagram_url ?? null,
|
|
'facebookUrl' => $socialSettings->facebook_url ?? null,
|
|
'tiktokUrl' => $socialSettings->tiktok_url ?? null,
|
|
'homepage' => $this->homepageSettingService->homepageData(),
|
|
];
|
|
}
|
|
|
|
private function getProducts(): array
|
|
{
|
|
$products = Product::getActiveWithVariantsAndCategories();
|
|
|
|
$allVariantIds = $products
|
|
->flatMap(fn ($product) => $product->variants->pluck('id'))
|
|
->all();
|
|
|
|
$allPricesByVariant = $this->cuttingResultPriceResolver->latestPricesForVariants($allVariantIds);
|
|
|
|
// Convert entirely to plain arrays — never store Eloquent models in
|
|
// Redis, as PHP serialize/unserialize can produce __PHP_Incomplete_Class
|
|
// and json_encode may produce {} instead of [] for keyed collections.
|
|
return $products->map(function ($product) use ($allPricesByVariant) {
|
|
$variants = $product->variants->map(function ($variant) use ($allPricesByVariant) {
|
|
$variantPrices = $allPricesByVariant->get($variant->id, collect());
|
|
|
|
return [
|
|
'id' => $variant->id,
|
|
'name' => $variant->name,
|
|
'stock' => $variant->stock,
|
|
'images' => MediaPresenter::collection($variant, 'images'),
|
|
'prices' => $variantPrices->map(fn ($price) => [
|
|
'type' => $price['price_type'],
|
|
'type_label' => PriceType::from($price['price_type'])->label(),
|
|
'price' => $price['price'],
|
|
'price_formatted' => $price['price_formatted'],
|
|
])->values()->all(),
|
|
];
|
|
})->values()->all();
|
|
|
|
return [
|
|
'id' => $product->id,
|
|
'name' => $product->name,
|
|
'description' => $product->description,
|
|
'slug' => $product->slug ?? null,
|
|
'categories' => $product->categories->map(fn ($cat) => [
|
|
'id' => $cat->id,
|
|
'name' => $cat->name,
|
|
'slug' => $cat->slug,
|
|
])->values()->all(),
|
|
'variants' => $variants,
|
|
];
|
|
})->values()->all();
|
|
}
|
|
}
|