Files
new.rybstock.ru/views/partials/product-card.php
T
2026-06-07 21:14:30 +03:00

207 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
/** @var array<string, mixed> $product */
$variants = $product['preview_variants'] ?? [];
$activeVariant = $variants[0] ?? [
'name' => $product['variant_name'] ?? '',
'unit' => $product['unit'] ?? '',
'price_per_unit' => $product['price_per_unit'] ?? null,
'package_price' => $product['package_price'] ?? null,
'package_quantity' => $product['package_quantity'] ?? 0,
'old_package_price' => $product['old_package_price'] ?? null,
];
$showUnitPriceForVariant = static function (array $variant) use ($product): bool {
if (function_exists('product_should_show_unit_price')) {
return product_should_show_unit_price($product, $variant);
}
$unit = (string) ($variant['unit'] ?? $product['base_unit'] ?? '');
if (!in_array($unit, ['kg', 'кг'], true)) {
return false;
}
if (($variant['price_per_unit'] ?? null) === null || (float) $variant['price_per_unit'] <= 0) {
return false;
}
$packageQuantity = (float) ($variant['package_quantity'] ?? 0);
if ($packageQuantity < 1) {
return false;
}
$lower = static function (string $value): string {
return function_exists('mb_strtolower') ? mb_strtolower($value, 'UTF-8') : strtolower($value);
};
return preg_match('/(^|[\s,.;])\d+(?:[.,]\d+)?\s*(мл|шт)\.?($|[\s,.;])/u', $lower((string) ($variant['name'] ?? ''))) !== 1;
};
$cardId = 'product-card-' . (int) ($product['id'] ?? 0);
$activePackagePrice = (float) ($activeVariant['package_price'] ?? 0);
$activeUnitPrice = $activeVariant['price_per_unit'] === null ? null : (float) $activeVariant['price_per_unit'];
$activePackageQuantity = (float) ($activeVariant['package_quantity'] ?? 0);
$activeVariantOldPackagePrice = $activeVariant['old_package_price'] ?? null;
$activeOldPackagePrice = (
$activeVariantOldPackagePrice !== null
&& (float) $activeVariantOldPackagePrice > $activePackagePrice
)
? (float) $activeVariantOldPackagePrice
: null;
$activeOldUnitPrice = ($activeOldPackagePrice !== null && $activePackageQuantity > 0 && $activeUnitPrice !== null)
? $activeOldPackagePrice / $activePackageQuantity
: null;
if ($activeOldUnitPrice !== null && $activeOldUnitPrice <= $activeUnitPrice) {
$activeOldUnitPrice = null;
}
$activeShowsUnitPrice = $showUnitPriceForVariant($activeVariant);
$activeTierBase = $activeShowsUnitPrice ? ($activeUnitPrice ?? $activePackagePrice) : $activePackagePrice;
$activeTierUnit = $activeShowsUnitPrice ? unit_label((string) ($activeVariant['unit'] ?? '')) : 'фасовку';
$isPublished = (int) ($product['is_published'] ?? 1) === 1;
$isAvailable = (int) ($product['is_available'] ?? 1) === 1;
$isPurchasable = $isPublished && $isAvailable && $activePackagePrice > 0;
?>
<article
class="product-card price-aware<?= $isPurchasable ? '' : ' is-unavailable' ?>"
id="<?= e($cardId) ?>"
data-product-id="<?= e((string) ($product['id'] ?? '')) ?>"
data-product-name="<?= e((string) ($product['name'] ?? '')) ?>"
data-product-slug="<?= e((string) ($product['slug'] ?? '')) ?>"
data-product-image="<?= e((string) ($product['main_image_path'] ?? '')) ?>"
data-show-unit-price="<?= $activeShowsUnitPrice ? '1' : '0' ?>"
>
<?php if (!$isPurchasable): ?>
<span class="product-unavailable-badge"><?= !$isPublished ? 'Ожидается поступление' : 'Нет в наличии' ?></span>
<?php endif; ?>
<?php if (!empty($product['badge_label']) && $isPurchasable): ?>
<span class="product-card-badge is-<?= e((string) ($product['badge_kind'] ?? 'default')) ?>"><?= e((string) $product['badge_label']) ?></span>
<?php endif; ?>
<?php if (!empty($product['main_image_path']) && $isPurchasable): ?>
<a class="product-card-image" href="/product/<?= e($product['slug']) ?>" aria-label="<?= e($product['name']) ?>">
<img src="<?= e((string) $product['main_image_path']) ?>" alt="<?= e((string) $product['name']) ?>">
</a>
<?php elseif (!empty($product['main_image_path'])): ?>
<div class="product-card-image" aria-label="<?= e($product['name']) ?>">
<img src="<?= e((string) $product['main_image_path']) ?>" alt="<?= e((string) $product['name']) ?>">
</div>
<?php elseif ($isPurchasable): ?>
<a class="product-card-image product-card-image-placeholder" href="/product/<?= e($product['slug']) ?>" aria-label="<?= e($product['name']) ?>">
<span>Рыбсток</span>
</a>
<?php else: ?>
<div class="product-card-image product-card-image-placeholder" aria-label="<?= e($product['name']) ?>">
<span>Рыбсток</span>
</div>
<?php endif; ?>
<p class="product-category"><?= e($product['category_display_name'] ?? $product['category_name'] ?? 'Каталог') ?></p>
<h3>
<?php if ($isPurchasable): ?>
<a href="/product/<?= e($product['slug']) ?>"><?= e($product['name']) ?></a>
<?php else: ?>
<span><?= e($product['name']) ?></span>
<?php endif; ?>
</h3>
<?php if ($variants !== []): ?>
<div class="variant-choice" aria-label="Выбор фасовки">
<span>Доступные фасовки:</span>
<div class="variant-choice-list">
<?php foreach ($variants as $index => $variant): ?>
<?php
$variantPackagePrice = (float) ($variant['package_price'] ?? 0);
$variantUnitPrice = $variant['price_per_unit'] === null ? null : (float) $variant['price_per_unit'];
$variantPackageQuantity = (float) ($variant['package_quantity'] ?? 0);
$variantOldPackagePrice = (
!empty($variant['old_package_price'])
&& (float) $variant['old_package_price'] > $variantPackagePrice
)
? (float) $variant['old_package_price']
: null;
$variantOldUnitPrice = ($variantOldPackagePrice !== null && $variantPackageQuantity > 0 && $variantUnitPrice !== null)
? $variantOldPackagePrice / $variantPackageQuantity
: null;
if ($variantOldUnitPrice !== null && $variantOldUnitPrice <= $variantUnitPrice) {
$variantOldUnitPrice = null;
}
$variantShowsUnitPrice = $showUnitPriceForVariant($variant);
?>
<button
class="variant-choice-button<?= $index === 0 ? ' is-active' : '' ?>"
type="button"
data-card="<?= e($cardId) ?>"
data-variant-id="<?= e((string) ($variant['id'] ?? $index)) ?>"
data-variant-name="<?= e((string) ($variant['name'] ?? '')) ?>"
data-unit="<?= e(unit_label((string) $variant['unit'])) ?>"
data-package-quantity="<?= e((string) ($variant['package_quantity'] ?? '')) ?>"
data-base-unit-price="<?= e((string) ($variant['price_per_unit'] ?? '')) ?>"
data-old-unit-price="<?= e($variantOldUnitPrice === null ? '' : (string) $variantOldUnitPrice) ?>"
data-base-package-price="<?= e((string) ($variant['package_price'] ?? '')) ?>"
data-variant-package-label="<?= e((string) ($variant['name'] ?? '')) ?>"
data-variant-unit-price-label="<?= e(money_label($variant['price_per_unit'])) ?>"
data-variant-package-price-label="<?= e(money_label($variant['package_price'])) ?>"
data-old-price="<?= e($variantOldPackagePrice === null ? '' : money_label($variantOldPackagePrice)) ?>"
data-show-unit-price="<?= $variantShowsUnitPrice ? '1' : '0' ?>"
>
<?= e((string) $variant['name']) ?>
</button>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<?php if ($isPurchasable): ?>
<span class="price-line<?= $activeShowsUnitPrice ? '' : ' is-price-placeholder' ?>" data-unit-price-row aria-hidden="<?= $activeShowsUnitPrice ? 'false' : 'true' ?>">
<span class="price-unit-label">Цена за <span data-unit-label><?= e(unit_label((string) $activeVariant['unit'])) ?></span>:</span>
<span class="price-unit-values">
<span class="old-price" data-old-unit-price-display<?= $activeOldUnitPrice === null ? ' hidden' : '' ?>><?= e(money_label($activeOldUnitPrice)) ?></span>
<b data-price-unit data-dynamic-unit-price data-base-unit-price="<?= e((string) $activeUnitPrice) ?>"><?= e(money_label($activeVariant['price_per_unit'])) ?></b>
<?php if ($isPurchasable): ?>
<button class="price-tier-trigger" type="button" aria-label="Показать градацию цены">?</button>
<?php endif; ?>
</span>
</span>
<?php endif; ?>
<?php if ($isPurchasable && $activeVariant['package_price'] !== null): ?>
<strong class="package-price-line">
<span class="package-price-label">За фасовку <span data-package-label-display><?= e((string) $activeVariant['name']) ?></span>:</span>
<span class="package-price-values">
<span class="old-price" data-old-package-price-display<?= $activeOldPackagePrice === null ? ' hidden' : '' ?>><?= e(money_label($activeOldPackagePrice)) ?></span>
<span data-package-price data-dynamic-package-price data-base-package-price="<?= e((string) $activePackagePrice) ?>"><?= e(money_label($activeVariant['package_price'])) ?></span>
<button class="price-tier-trigger" data-package-tier-trigger type="button" aria-label="Показать градацию цены"<?= $activeShowsUnitPrice ? ' hidden' : '' ?>>?</button>
</span>
</strong>
<?php if ($isPurchasable): ?>
<span class="package-price-note<?= $activeShowsUnitPrice ? '' : ' is-price-placeholder' ?>" data-package-price-note aria-hidden="<?= $activeShowsUnitPrice ? 'false' : 'true' ?>">Цена за <span data-unit-label-note><?= e(unit_label((string) $activeVariant['unit'])) ?></span> × <span data-package-label-note><?= e((string) $activeVariant['name']) ?></span></span>
<?php endif; ?>
<?php elseif (!$isPurchasable): ?>
<div class="product-card-unavailable-note">Цену уточним после поступления товара.</div>
<?php endif; ?>
<?php if ($isPurchasable): ?>
<div class="price-tier-popover" role="tooltip">
<strong>Варианты цены за <span data-tier-unit-label><?= e($activeTierUnit) ?></span> при наличном расчете:</strong>
<dl>
<div><dt>Базовая цена</dt><dd data-tier-base><?= e(money_label($activeTierBase)) ?></dd></div>
<div><dt>При заказе от 20 000р.</dt><dd data-tier-cash-20><?= e(money_label(floor($activeTierBase * 0.95))) ?></dd></div>
<div><dt>При заказе от 50 000р.</dt><dd data-tier-cash-50><?= e(money_label(floor($activeTierBase * 0.93))) ?></dd></div>
</dl>
</div>
<div class="product-card-actions">
<div class="quantity-stepper" data-quantity-control aria-label="Количество фасовок">
<button type="button" data-quantity-minus aria-label="Уменьшить количество">-</button>
<input data-quantity-input type="text" inputmode="numeric" value="1" aria-label="Количество">
<button type="button" data-quantity-plus aria-label="Увеличить количество">+</button>
</div>
<button class="add-to-cart-button" type="button">В корзину</button>
</div>
<?php else: ?>
<div class="product-card-actions">
<button class="notify-arrival-button" type="button" data-notify-arrival>Сообщить о поступлении</button>
</div>
<?php endif; ?>
</article>