шаг 3 завершен
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Services\PriceTierService;
|
||||
|
||||
final class ProductRepository extends BaseRepository
|
||||
{
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function popularPreview(int $limit = 10): array
|
||||
{
|
||||
$limit = max(1, min($limit, 30));
|
||||
$sql = $this->previewSelectSql(
|
||||
'ORDER BY p.sales_count DESC, RAND()',
|
||||
$limit
|
||||
);
|
||||
|
||||
$statement = $this->pdo()->query($sql);
|
||||
|
||||
return $this->attachPriceTiers($statement->fetchAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function catalogPreview(int $limit = 24): array
|
||||
{
|
||||
$limit = max(1, min($limit, 60));
|
||||
$sql = $this->previewSelectSql(
|
||||
'ORDER BY p.sort_order, p.name',
|
||||
$limit
|
||||
);
|
||||
|
||||
$statement = $this->pdo()->query($sql);
|
||||
|
||||
return $this->attachPriceTiers($statement->fetchAll());
|
||||
}
|
||||
|
||||
private function previewSelectSql(string $orderBy, int $limit): string
|
||||
{
|
||||
return 'SELECT
|
||||
p.id,
|
||||
p.name,
|
||||
p.slug,
|
||||
p.legacy_path,
|
||||
p.h1,
|
||||
p.seo_title,
|
||||
p.seo_description,
|
||||
p.seo_keywords,
|
||||
c.name AS category_name,
|
||||
c.slug AS category_slug,
|
||||
p.main_image_path,
|
||||
p.base_unit,
|
||||
p.package_display_mode,
|
||||
p.sales_count,
|
||||
v.id AS variant_id,
|
||||
v.name AS variant_name,
|
||||
v.unit,
|
||||
v.package_quantity,
|
||||
v.price_per_unit,
|
||||
v.package_price
|
||||
FROM products p
|
||||
LEFT JOIN categories c ON c.id = p.category_id
|
||||
LEFT JOIN product_variants v
|
||||
ON v.id = (
|
||||
SELECT pv.id
|
||||
FROM product_variants pv
|
||||
WHERE pv.product_id = p.id
|
||||
AND pv.is_published = 1
|
||||
AND pv.is_available = 1
|
||||
ORDER BY pv.is_default DESC, pv.sort_order, pv.id
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE p.is_published = 1
|
||||
AND p.is_available = 1
|
||||
' . $orderBy . '
|
||||
LIMIT ' . $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $products
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function attachPriceTiers(array $products): array
|
||||
{
|
||||
$priceTierService = new PriceTierService();
|
||||
|
||||
foreach ($products as &$product) {
|
||||
$basePrice = $product['price_per_unit'] ?? $product['package_price'] ?? null;
|
||||
$product['price_tiers'] = $basePrice === null
|
||||
? []
|
||||
: $priceTierService->forAmount((float) $basePrice);
|
||||
}
|
||||
|
||||
unset($product);
|
||||
|
||||
return $products;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user