115 lines
3.0 KiB
PHP
115 lines
3.0 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use App\Core\View;
|
||
|
||
function app_env(string $key, ?string $default = null): ?string
|
||
{
|
||
$value = $_ENV[$key] ?? getenv($key);
|
||
|
||
if ($value === false || $value === null) {
|
||
return $default;
|
||
}
|
||
|
||
return (string) $value;
|
||
}
|
||
|
||
function base_path(string $path = ''): string
|
||
{
|
||
$base = dirname(__DIR__);
|
||
|
||
return $path === '' ? $base : $base . '/' . ltrim($path, '/');
|
||
}
|
||
|
||
function view(string $template, array $data = []): void
|
||
{
|
||
View::render($template, $data);
|
||
}
|
||
|
||
function e(?string $value): string
|
||
{
|
||
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
|
||
}
|
||
|
||
function unit_label(?string $unit): string
|
||
{
|
||
return match ((string) $unit) {
|
||
'kg' => 'кг',
|
||
'g' => 'г',
|
||
'l' => 'л',
|
||
'ml' => 'мл',
|
||
'pcs' => 'шт.',
|
||
default => (string) ($unit ?: 'ед.'),
|
||
};
|
||
}
|
||
|
||
function text_lower(string $value): string
|
||
{
|
||
if (function_exists('mb_strtolower')) {
|
||
return mb_strtolower($value, 'UTF-8');
|
||
}
|
||
|
||
return strtolower(strtr($value, [
|
||
'А' => 'а', 'Б' => 'б', 'В' => 'в', 'Г' => 'г', 'Д' => 'д',
|
||
'Е' => 'е', 'Ё' => 'ё', 'Ж' => 'ж', 'З' => 'з', 'И' => 'и',
|
||
'Й' => 'й', 'К' => 'к', 'Л' => 'л', 'М' => 'м', 'Н' => 'н',
|
||
'О' => 'о', 'П' => 'п', 'Р' => 'р', 'С' => 'с', 'Т' => 'т',
|
||
'У' => 'у', 'Ф' => 'ф', 'Х' => 'х', 'Ц' => 'ц', 'Ч' => 'ч',
|
||
'Ш' => 'ш', 'Щ' => 'щ', 'Ъ' => 'ъ', 'Ы' => 'ы', 'Ь' => 'ь',
|
||
'Э' => 'э', 'Ю' => 'ю', 'Я' => 'я',
|
||
]));
|
||
}
|
||
|
||
/**
|
||
* Price per kg helps with boxes and weight products, but confuses customers on
|
||
* caviar, cans, sauces, spices and small consumer packs. In those cases the
|
||
* storefront should sell by package and avoid derived kg prices.
|
||
*
|
||
* @param array<string, mixed> $product
|
||
* @param array<string, mixed> $variant
|
||
*/
|
||
function product_should_show_unit_price(array $product, array $variant): bool
|
||
{
|
||
$unit = (string) ($variant['unit'] ?? $product['base_unit'] ?? '');
|
||
$unitLabel = unit_label($unit);
|
||
|
||
if (!in_array($unit, ['kg', 'кг'], true) && $unitLabel !== 'кг') {
|
||
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 <= 0) {
|
||
return false;
|
||
}
|
||
|
||
if ($packageQuantity < 1) {
|
||
return false;
|
||
}
|
||
|
||
$variantName = text_lower((string) ($variant['name'] ?? ''));
|
||
if (preg_match('/(^|[\s,.;])\d+(?:[.,]\d+)?\s*(мл|шт)\.?($|[\s,.;])/u', $variantName) === 1) {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
function money_label(mixed $value): string
|
||
{
|
||
if ($value === null || $value === '') {
|
||
return '';
|
||
}
|
||
|
||
$number = (float) $value;
|
||
$formatted = abs($number - round($number)) < 0.005
|
||
? number_format($number, 0, ',', ' ')
|
||
: number_format($number, 2, ',', ' ');
|
||
|
||
return $formatted . ' руб.';
|
||
}
|