корзина кеш

This commit is contained in:
Alisa
2026-06-07 17:43:45 +03:00
parent 170bea76d5
commit 76bf5d8191
8 changed files with 530 additions and 15 deletions
+139
View File
@@ -211,6 +211,145 @@ final class ProductRepository extends BaseRepository
return $statement->fetchAll();
}
/**
* @param array<int, array<string, mixed>> $items
* @return array<int, array<string, mixed>>
*/
public function cartSnapshots(array $items): array
{
$result = [];
foreach ($items as $item) {
$key = (string) ($item['key'] ?? '');
$productId = (int) ($item['productId'] ?? 0);
$variantId = (int) ($item['variantId'] ?? 0);
$desiredPackageQuantity = (float) ($item['packageQuantity'] ?? 0);
if ($key === '' || $productId <= 0) {
continue;
}
$variantJoin = $variantId > 0
? 'v.product_id = p.id AND v.id = :variant_id'
: 'v.id = (
SELECT pv.id
FROM product_variants pv
WHERE pv.product_id = p.id
ORDER BY pv.is_default DESC, pv.sort_order, pv.id
LIMIT 1
)';
$statement = $this->pdo()->prepare(
'SELECT
p.id AS product_id,
p.name,
p.slug,
p.main_image_path,
p.is_published AS product_is_published,
p.is_available AS product_is_available,
v.id AS variant_id,
v.name AS variant_name,
v.unit,
v.package_quantity,
v.price_per_unit,
v.package_price,
v.is_published AS variant_is_published,
v.is_available AS variant_is_available
FROM products p
LEFT JOIN product_variants v ON ' . $variantJoin . '
WHERE p.id = :product_id
LIMIT 1'
);
$params = ['product_id' => $productId];
if ($variantId > 0) {
$params['variant_id'] = $variantId;
}
$statement->execute($params);
$row = $statement->fetch();
if (!$row) {
$result[] = [
'key' => $key,
'isAvailable' => false,
'reason' => 'Товар больше не найден в каталоге.',
];
continue;
}
if (empty($row['variant_id'])) {
$fallbackStatement = $this->pdo()->prepare(
'SELECT
p.id AS product_id,
p.name,
p.slug,
p.main_image_path,
p.is_published AS product_is_published,
p.is_available AS product_is_available,
v.id AS variant_id,
v.name AS variant_name,
v.unit,
v.package_quantity,
v.price_per_unit,
v.package_price,
v.is_published AS variant_is_published,
v.is_available AS variant_is_available
FROM products p
INNER JOIN product_variants v ON v.product_id = p.id
WHERE p.id = :product_id
ORDER BY
(v.is_published = 1 AND v.is_available = 1 AND v.package_price > 0) DESC,
CASE WHEN :package_quantity_check > 0 THEN ABS(v.package_quantity - :package_quantity) ELSE 0 END,
v.is_default DESC,
v.sort_order,
v.id
LIMIT 1'
);
$fallbackStatement->execute([
'product_id' => $productId,
'package_quantity' => $desiredPackageQuantity,
'package_quantity_check' => $desiredPackageQuantity,
]);
$fallbackRow = $fallbackStatement->fetch();
if ($fallbackRow) {
$row = $fallbackRow;
}
}
$productIsAvailable = (int) ($row['product_is_published'] ?? 0) === 1
&& (int) ($row['product_is_available'] ?? 0) === 1;
$variantIsAvailable = !empty($row['variant_id'])
&& (int) ($row['variant_is_published'] ?? 0) === 1
&& (int) ($row['variant_is_available'] ?? 0) === 1
&& (float) ($row['package_price'] ?? 0) > 0;
$reason = '';
if (!$productIsAvailable) {
$reason = 'Товар сейчас не опубликован или отсутствует в наличии.';
} elseif (!$variantIsAvailable) {
$reason = 'Выбранная фасовка сейчас недоступна.';
}
$result[] = [
'key' => $key,
'productId' => (int) $row['product_id'],
'variantId' => !empty($row['variant_id']) ? (int) $row['variant_id'] : $variantId,
'name' => (string) ($row['name'] ?? ''),
'slug' => (string) ($row['slug'] ?? ''),
'image' => (string) ($row['main_image_path'] ?? ''),
'variantName' => (string) ($row['variant_name'] ?? 'Фасовка'),
'unit' => (string) ($row['unit'] ?? ''),
'packageQuantity' => (float) ($row['package_quantity'] ?? 0),
'baseUnitPrice' => (float) ($row['price_per_unit'] ?? 0),
'basePackagePrice' => (float) ($row['package_price'] ?? 0),
'isAvailable' => $productIsAvailable && $variantIsAvailable,
'reason' => $reason,
];
}
return $result;
}
/**
* @return array<int, array<string, mixed>>
*/