211 lines
12 KiB
PHP
211 lines
12 KiB
PHP
<?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;
|
||
$sourceImagePath = (string) ($product['main_image_path'] ?? '');
|
||
$previewImagePath = function_exists('optimized_image_path')
|
||
? optimized_image_path($sourceImagePath, 'preview')
|
||
: $sourceImagePath;
|
||
?>
|
||
<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($previewImagePath) ?>"
|
||
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 ($previewImagePath !== '' && $isPurchasable): ?>
|
||
<a class="product-card-image" href="/product/<?= e($product['slug']) ?>" aria-label="<?= e($product['name']) ?>">
|
||
<img src="<?= e($previewImagePath) ?>" alt="<?= e((string) $product['name']) ?>" loading="lazy" decoding="async">
|
||
</a>
|
||
<?php elseif ($previewImagePath !== ''): ?>
|
||
<div class="product-card-image" aria-label="<?= e($product['name']) ?>">
|
||
<img src="<?= e($previewImagePath) ?>" alt="<?= e((string) $product['name']) ?>" loading="lazy" decoding="async">
|
||
</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>
|