Files
new.rybstock.ru/app/Repositories/ProductRepository.php
T
2026-06-04 00:27:17 +03:00

104 lines
3.0 KiB
PHP

<?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;
}
}