Files
kupshop/web/functions.common.php
2025-08-02 16:30:27 +02:00

3632 lines
112 KiB
PHP

<?php
use KupShop\AdminBundle\Util\ActivityLog;
use KupShop\AdminBundle\Util\LegacyAdminCredentials;
use KupShop\CatalogBundle\Section\SectionTree;
use KupShop\ContentBundle\Util\ImageLocator;
use KupShop\ContentBundle\Util\MenuUtil;
use KupShop\I18nBundle\Translations\ArticlesSectionsTranslation;
use KupShop\I18nBundle\Translations\PhotosTranslation;
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Context\CacheContext;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\DomainContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Context\VatContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Compat\SymfonyBridge;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Functional\Mapping;
use KupShop\KupShopBundle\Util\Smarty\SmartyML;
use Query\Operator;
use Query\QueryBuilder;
use Query\Translation;
use Symfony\Component\Routing\Router;
function autoload($fqcn)
{
global $cfg;
static $subclass = 1;
if (strpos($fqcn, '\\')) {
$fileName = strtr($fqcn, '\\', '/').'.php';
} else {
$fileName = "class.{$fqcn}.php";
}
$shopFile = $cfg['Path']['web_root'].$fileName;
$engineFile = $cfg['Path']['shared_class'].$fileName;
if (file_exists($engineFile)) {
require_once $engineFile;
}
if (!empty($cfg['autoload_web_root']) && file_exists($shopFile)) {
require_once $shopFile;
} else {
if (!class_exists($fqcn, 0) && class_exists($fqcn.'Base', 0)) {
list($namespace, $className) = parseClassName($fqcn);
eval("namespace {$namespace} {class {$className} extends {$className}Base {}}");
}
}
}
/**
* Splits FQCN into namespace part and class name part, returns tuple [$namespace, $className].
*
* @param string $className
*
* @return array
*/
function parseClassName($className)
{
$parts = explode('\\', $className);
$className = array_pop($parts);
return [implode('\\', $parts), $className];
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//
/**
* @param int $vat
* @param bool $ceil
* @param null $currency
*
* @return Decimal[]
*/
function formatPrice($price, $vat = 0, $ceil = true, $currency = null)
{
// pole, ktere se bude vracet
$price = toDecimal($price);
$PRICE['value_with_vat'] = $price;
// normalni cena s DPH
$PRICE['value_without_vat'] = $price;
// cena DPH
if (empty($currency)) {
$currencyContext = Contexts::get(CurrencyContext::class);
$currency = $currencyContext->getActive()->getSymbol();
$currencyObject = $currencyContext->getActive();
}
$PRICE['currency_object'] = $currencyObject ?? null;
$PRICE['currency'] = $currency;
// mena
$PRICE['vat'] = $vat;
// obsahuje hodnotu dane, ktera je pro tuto polozku
// -------------------------------------------------
// pricteni dane z ceny
if ($vat != 0) {
// normalni cena s DPH
$PRICE['value_with_vat'] = calcPrice($PRICE['value_without_vat'], $vat)->value(2); // ( $PRICE['value_without_vat'] * ( 1 + ( $vat / 100 ) ) );
// cena DPH
$PRICE['value_vat'] = $PRICE['value_with_vat']->sub(toDecimal($PRICE['value_without_vat']));
} else {
$PRICE['value_vat'] = toDecimal(0);
}
// cena pred bez zaokrouhleni
$PRICE['value_with_vat_no_rounding'] = $PRICE['value_with_vat'];
$PRICE['value_without_vat_no_rounding'] = $PRICE['value_without_vat'];
return $PRICE;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param int $discount
* @param int $vat
* @param null $IDproduct
* @param null $IDcategory
* @param null $IDproducer
*
* @return Decimal[]
*/
function formatCustomerPrice($price, $discount = 0, $vat = 0, $IDproduct = null, $IDcategory = null, $IDproducer = null, ?PriceLevel $priceLevel = null, $currency = null)
{
$discount = toDecimal($discount);
// pole, ktere se bude vracet
$PRICE['price_with_vat'] = toDecimal($price);
// normalni cena s DPH
$PRICE['price_without_vat'] = toDecimal($price);
// cena bez DPH
$currencyContext = Contexts::get(CurrencyContext::class);
if (!$currency) {
$currency = $currencyContext->getDefault();
}
$PRICE['currency_object'] = $currency;
$PRICE['currency'] = $currencyContext->getActive()->getSymbol();
// mena
$PRICE['vat'] = $vat;
// -------------------------------------------------
// sleva pro dealery
$PRICE = calcCustomerPrice($PRICE, $discount, $vat, $IDproduct, $IDcategory, $IDproducer, $priceLevel);
// -------------------------------------------------
// normalni sleva
if (!$discount->isZero() && empty($PRICE['B2B_discount'])) {
$PRICE['price_without_vat'] = calcPrice($PRICE['price_without_vat'], null, $discount);
$PRICE['price_with_vat'] = $PRICE['price_without_vat'];
}
// -------------------------------------------------
// pricteni dane z ceny
if ($vat != 0) {
// normalni cena s DPH
$PRICE['price_with_vat'] = calcPrice($PRICE['price_with_vat'], $vat);
}
// -------------------------------------------------
// rozhodnout, ktera cena se bude zapocitavat
if (!empty($PRICE['B2B_discount'])) {
$PRICE['value_with_vat'] = roundPrice($PRICE['B2B_price_with_vat']);
$PRICE['value_without_vat'] = $PRICE['value_with_vat']->removeVat($vat);
} else {
$PRICE['value_with_vat'] = roundPrice($PRICE['price_with_vat']);
$PRICE['value_without_vat'] = $PRICE['value_with_vat']->removeVat($vat);
}
// cena pred bez zaokrouhleni
$PRICE['value_with_vat_no_rounding'] = $PRICE['value_with_vat'];
$PRICE['value_without_vat_no_rounding'] = $PRICE['value_without_vat'];
// -------------------------------------------------
return $PRICE;
}
function calcCustomerPrice($PRICE, $discount, $vat, $IDproduct = null, $IDcategory = null, $IDproducer = null, ?PriceLevel $priceLevel = null)
{
if (!$priceLevel && findModule(Modules::PRICE_LEVELS)) {
/** @var \KupShop\KupShopBundle\Context\PriceLevelContext $plService */
$plService = ServiceContainer::getService(\KupShop\KupShopBundle\Context\PriceLevelContext::class);
$priceLevel = $plService->getActive();
}
if ($priceLevel) {
$PRICE['B2B_price_with_vat'] = null;
// cena s B2B slevou s dani
$PRICE['B2B_price_without_vat'] = null;
// cena s B2B slevou bez dane
$PRICE['B2B_discount'] = null;
// obsahuje hodnotu dane slevy
$PRICE['B2B_discount_unit'] = null;
// obsahuje jednotku slevy
// $discount = 0;
$B2B_discount = null;
$B2B_unit = null;
// urceni slevy podle slevy k produktu
if ($IDproduct > 0 && isset($priceLevel->products[$IDproduct])) {
$B2B_discount = $priceLevel->products[$IDproduct]['discount'];
$B2B_unit = $priceLevel->products[$IDproduct]['unit'];
} // urceni slevy podle slevy k sekci
elseif (!is_array($IDcategory) && $IDcategory > 0 && isset($priceLevel->sections[$IDcategory])) {
$B2B_discount = $priceLevel->sections[$IDcategory]['discount'];
$B2B_unit = $priceLevel->sections[$IDcategory]['unit'];
} // urceni slevy podle slevy k vyrobci
elseif ($IDproducer > 0 && isset($priceLevel->producers[$IDproducer])) {
$B2B_discount = $priceLevel->producers[$IDproducer]['discount'];
$B2B_unit = $priceLevel->producers[$IDproducer]['unit'];
} // urceni slevy pokud neni urcena sekce - dohledat sekci k produktu
else {
if ($IDproduct > 0 && (is_null($IDcategory) || is_array($IDcategory)) && !empty($priceLevel->sections)) {
if (is_null($IDcategory)) {
$IDcategory = sqlQueryBuilder()->select('id_section')->from('products_in_sections')
->where(\Query\Operator::equals(['id_product' => $IDproduct]))
->execute()->fetchAll();
$IDcategory = array_column($IDcategory, 'id_section');
}
foreach ($IDcategory as $id_section) {
if (isset($priceLevel->sections[$id_section])) {
if (is_null($B2B_discount)
|| ($priceLevel->sections[$id_section]['discount'] > $B2B_discount
&& $priceLevel->sections[$id_section]['unit'] == $B2B_unit)
|| ($priceLevel->sections[$id_section]['unit'] == 'perc'
&& $B2B_unit == 'price')
) {
$B2B_discount = $priceLevel->sections[$id_section]['discount'];
$B2B_unit = $priceLevel->sections[$id_section]['unit'];
// ulozit nalezenou informaci o zbozi
$priceLevel->products[$IDproduct]['discount'] = $B2B_discount;
$priceLevel->products[$IDproduct]['unit'] = $B2B_unit;
}
}
}
}
// urceni slevy podle vyrobce - dohledat vyrobce k produktu
if (is_null($B2B_discount) && is_null($IDproducer) && $IDproduct > 0 && !empty($priceLevel->producers)) {
$SQL3 = sqlQuery('SELECT p.producer
FROM products AS p
WHERE p.id=:id_product', ['id_product' => $IDproduct]);
while ($row = sqlFetchArray($SQL3)) {
if (isset($priceLevel->producers[$row['producer']])) {
$B2B_discount = $priceLevel->producers[$row['producer']]['discount'];
$B2B_unit = $priceLevel->producers[$row['producer']]['unit'];
}
}
sqlFreeResult($SQL3);
}
if ($range = $priceLevel->getRangeByPrice($PRICE['price_without_vat'])) {
$B2B_discount = $range['discount'];
$B2B_unit = $range['unit'];
}
}
// globalni sleva
if (is_null($B2B_discount)) {
$B2B_discount = $priceLevel->discount;
$B2B_unit = $priceLevel->unit;
}
// Sleva ze slevy
if (!$discount->isZero() && !is_null($priceLevel->discount_discount)) {
$B2B_discount = $priceLevel->discount_discount;
}
$PRICE['B2B_price_original'] = $PRICE['price_without_vat'];
$PRICE['B2B_price_original_vat'] = calcPrice($PRICE['price_without_vat'], $vat);
$currency = Contexts::get(CurrencyContext::class)->getActive();
switch ($B2B_unit) {
case 'perc':
if (!$discount->isZero()) {
if ($priceLevel->add) {
$B2B_discount = toDecimal(100)->sub(
toDecimal(100)->sub(toDecimal($B2B_discount))->mul(toDecimal(100)->sub($discount))->div(toDecimal(100)));
} else {
$B2B_discount = toDecimal($B2B_discount)->lowerThan($discount) ? $discount : $B2B_discount;
}
}
$PRICE['B2B_price_without_vat'] = calcPrice($PRICE['price_with_vat'], 0, $B2B_discount);
$PRICE['B2B_discount'] = toDecimal($B2B_discount)->round(2);
$PRICE['B2B_discount_unit'] = '%';
$PRICE['B2B_discount_name'] = $priceLevel->name;
break;
case 'price':
$PRICE['B2B_price_without_vat'] = $PRICE['price_with_vat']->sub(toDecimal($B2B_discount));
$PRICE['B2B_discount'] = toDecimal($B2B_discount);
$PRICE['B2B_discount_unit'] = $currency->getSymbol();
if ($PRICE['B2B_price_without_vat']->isNegative()) {
$PRICE['B2B_price_without_vat'] = DecimalConstants::zero();
}
break;
case 'final_price':
$PRICE['B2B_price_without_vat'] = toDecimal($B2B_discount);
$PRICE['B2B_discount'] = $PRICE['B2B_price_without_vat']->sub(toDecimal($B2B_discount));
$PRICE['B2B_discount_unit'] = $currency->getSymbol();
break;
}
$PRICE['B2B_price_with_vat'] = $PRICE['B2B_price_without_vat'];
// pricteni dane z ceny
if ($vat != 0) {
$PRICE['B2B_price_with_vat'] = calcPrice($PRICE['B2B_price_without_vat'], $vat);
// ( $PRICE['B2B_price_without_vat'] * ( 1 + ( $vat / 100 ) ) );
// normalni B2B cena s DPH
}
}
if (findModule('currencies')) {
$fields = ['B2B_price_with_vat',
'B2B_price_without_vat',
'B2B_price_original',
'B2B_price_original_vat',
'price_with_vat',
'price_without_vat',
'value_with_vat',
'value_without_vat',
'value_with_vat_no_rounding',
'value_without_vat_no_rounding',
];
foreach ($fields as $field) {
if (isset($PRICE[$field])) {
$PRICE[$field] = applyCurrency($PRICE[$field], $PRICE['currency_object']);
}
}
}
return $PRICE;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// Prepocita castu podle meny, kterou ma nastaven aktualne prihlaseny uzivatel
/**
* @deprecated Use PriceConverter
*
* @return Decimal
*/
function applyCurrency($price, $currencyObject = null)
{
$price = toDecimal($price);
$currency = Contexts::get(CurrencyContext::class)->getActive();
if ($currencyObject && $currencyObject->getId() == $currency->getId()) {
return $price;
}
if (!$currency->getRate()->equals(DecimalConstants::one())) {
$price = $price->div($currency->getRate());
}
return $price;
}
/**
* @deprecated Use PriceConverter
*
* @return Decimal
*/
function unapplyCurrency($price)
{
$price = toDecimal($price);
$currency = Contexts::get(CurrencyContext::class)->getActive();
if (!$currency->getRate()->equals(DecimalConstants::one())) {
$price = $price->mul($currency->getRate());
}
return $price;
}
$activeCurrency = null;
/**
* @return array
*
* @deprecated Pouzij CurrencyContext
*/
function getCustomerCurrency()
{
$currency = Contexts::get(CurrencyContext::class)->getActive();
return [
'name' => $currency->getName(),
'code' => $currency->getId(),
'symbol' => $currency->getSymbol(),
'price_round' => $currency->getPriceRound(),
'price_round_order' => $currency->getPriceRoundOrder(),
'price_round_direction' => $currency->getPriceRoundDirection(),
'price_precision' => $currency->getPricePrecision(),
'price_decimal_mark' => $currency->getPriceDecimalMark(),
'rate' => $currency->getRate(),
];
}
/**
* @deprecated Use ContextManager
*/
function changeCurrency($currency = 'rollback')
{
static $currency_stack = [];
global $activeCurrency;
$currencyContext = Contexts::get(CurrencyContext::class);
$activeCurrency = null;
if ($currency == 'rollback') {
$currency = array_pop($currency_stack);
} elseif (!empty($currencyContext->getActive())) {
array_push($currency_stack, $currencyContext->getActive());
}
if (is_object($currency)) {
$currencyContext->activate($currency->getId());
} else {
if ($currency == null) {
$currency = 'CZK';
}
$currencyContext->activate($currency);
}
return $currency;
}
/**
* @deprecated Use PriceLevelContext
*/
function changePriceLevel($priceLevel = null)
{
static $static_price_level = null;
global $ctrl;
if ($priceLevel === null) {
$priceLevel = $static_price_level;
} elseif (!empty($ctrl['dealerPricelevel']) && is_null($static_price_level)) {
$static_price_level = $ctrl['dealerPricelevel'];
}
$ctrl['dealerPricelevel'] = $priceLevel;
return $priceLevel;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function printPrice($PRICE, $param = [])
{
global $cfg;
$PRICE = \KupShop\KupShopBundle\Wrapper\PriceWrapper::unwrap($PRICE);
$dbcfg = Settings::getDefault();
$currencyContext = Contexts::get(CurrencyContext::class);
$currency = $currencyContext->getActive();
$source = null;
// class Price to array
if ($PRICE instanceof KupShop\KupShopBundle\Util\Price\Price) {
$source = $PRICE->getSource();
// convert currency
$price = \KupShop\KupShopBundle\Util\Price\PriceCalculator::convert($PRICE, $currency);
$ceil = ($param['ceil'] ?? null);
$round = !($ceil === false);
$PRICE = [
'value_with_vat' => $price->getPriceWithVat($round),
'value_without_vat' => $price->getPriceWithoutVat($round),
'currency' => $currency->getSymbol(),
'currency_object' => $currency,
'vat' => $price->getVat(),
];
}
// class Price to array
if ($PRICE instanceof KupShop\KupShopBundle\Util\Price\TotalPrice) {
// convert currency
$priceConverter = ServiceContainer::getService(\KupShop\I18nBundle\Util\PriceConverter::class);
$PRICE = [
'value_with_vat' => $priceConverter->convert($PRICE->getCurrency(), $currency, $PRICE->getPriceWithVat()),
'value_without_vat' => $priceConverter->convert($PRICE->getCurrency(), $currency, $PRICE->getPriceWithoutVat()),
'currency' => $currency->getSymbol(),
'currency_object' => $currency,
'vat' => 0,
];
}
// kontrola promenne $PRICE
if (!is_array($PRICE)) {
$price = toDecimal($PRICE);
$PRICE = [];
// obsahuje konecnou cenu s dani, ktera ma byt zapocitana
$PRICE['value_with_vat'] = $price;
// obsahuje konecnou cenu bez dane, ktera ma byt zapocitana
$PRICE['value_without_vat'] = $price;
// mena
if (!empty($param['currency'])) {
if ($param['currency'] instanceof \KupShop\I18nBundle\Entity\Currency) {
$currency = $param['currency'];
} else {
$currencies = $currencyContext->getAll();
if (array_key_exists($param['currency'], $currencies)) {
$currency = $currencies[$param['currency']];
}
}
}
$PRICE['currency'] = $currency->getSymbol();
$PRICE['currency_object'] = $currency;
// obsahuje hodnotu dane, ktera je pro tuto polozku
$PRICE['vat'] = 0;
}
$cond = [
'withVat' => $dbcfg['prod_show_price_vat'] == 'Y',
'ceil' => 'default',
'format' => true,
'printcurrency' => true,
'printdealerdiscount' => false,
'dealerdiscount' => true,
'decimal' => null,
];
$cond = array_merge($cond, $param);
if ($cond['withVat'] === 'dynamic') {
if (isset($_COOKIE['prices_vat'])) {
$cond['withVat'] = $_COOKIE['prices_vat'] == 'withVat';
} else {
$cond['withVat'] = $dbcfg['prod_show_price_vat'] == 'Y';
}
}
// zda pouzit cenu s / bez DPH
$price = ($cond['withVat']) ? $PRICE['value_with_vat'] : $PRICE['value_without_vat'];
if (!$cond['dealerdiscount'] && isset($PRICE['B2B_price_original'])) {
$price = ($cond['withVat']) ? $PRICE['B2B_price_original_vat'] : $PRICE['B2B_price_original'];
}
// Formatted price decimal places
$decimal = $currency->getPricePrecision();
// kdyz je format=default, tak rozhodnout podle nastaveni v DB
if ($cond['ceil'] == 'default') {
$cond['ceil'] = $currency->getPriceRound();
} elseif (!$cond['ceil']) {
$decimal = 2;
}
// Round price if set
if ($cond['ceil']) {
$price = roundPrice($price, -1, 'DB', 2, $currency, source: $source);
} else {
if ($price->round(2)->isZero() && !$price->isZero()) {
$price = roundPrice($price, 1, 'up', 4, $currency, source: $source);
}
}
if ($cond['format'] === 'float') {
return $price->asString();
}
if ($cond['decimal']) {
$decimal = $cond['decimal'];
}
// Backward compatibility if price_precision not set
if (is_null($decimal)) {
$decimal = $cond['ceil'] == 100 ? 0 : 2;
}
// Detect precision
if ($decimal == 'dynamic') {
$decimal = $price->round(2)->isInteger() ? 0 : 2;
}
$price = $price->printValue($decimal, $currency->getPriceDecimalMark());
// formatovani ceny pro vystup
if ($cond['format'] == true) {
// dopsat jednotku ceny
if ($cond['printcurrency']) {
$price_format = translate('price_format', 'functions', true) ?: ['price_value', ' ', 'currency_symbol'];
$price_format = array_map(function ($value) use ($price, $PRICE) {
return match ($value) {
'price_value' => $price,
'currency_symbol' => $PRICE['currency'],
'currency_id' => $PRICE['currency_object']->getId(),
default => $value,
};
}, $price_format);
$price = join('', $price_format);
}
// dopsat slevu dealera
if ($cond['printdealerdiscount'] && isset($PRICE['B2B_discount'])) {
$name = getVal('B2B_discount_name', $PRICE, translate('setPrice', 'functions')['b2b']);
if ($PRICE['B2B_discount_unit'] == '%') {
$price .= " <sub class='dealer_discount'>({$name}: {$PRICE['B2B_discount']}%)</sub>";
} else {
$price .= "<br><span class='dealer_discount'>({$name}: {$PRICE['B2B_discount']} {$PRICE['B2B_discount_unit']})</span>";
}
}
}
return $price;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param $price Decimal
* @param int $roundTo
* @param string $direction
* @param int $decimal
*
* @return Decimal
*/
function roundPrice($price, $roundTo = -1, $direction = 'DB', $decimal = null, ?KupShop\I18nBundle\Entity\Currency $currency = null, $bata = null, $source = null)
{
if (!$currency) {
$currency = Contexts::get(CurrencyContext::class)->getActive();
}
if ($source) {
$params = ['price' => &$price, 'roundTo' => &$roundTo, 'direction' => &$direction, 'decimal' => &$decimal, 'currency' => &$currency, 'bata' => &$bata];
Contexts::get(CurrencyContext::class)->getSourceRounding($source, $params);
}
if (!is_a($price, 'Decimal')) {
if (is_null($price)) {
$price = '0';
}
$price = toDecimal($price);
}
// kontrola zadanych parametru
if ($roundTo == -1 || $roundTo === null) {
$roundTo = $currency->getPriceRound();
}
if ($direction == 'DB' || $direction === null) {
$direction = $currency->getPriceRoundDirection();
}
if ($decimal === null) {
$decimal = $currency->getPricePrecision();
// Detect precision
if ($decimal == 'dynamic') {
$decimal = 2;
}
}
if ($bata === null) {
$bata = $currency->getBata();
}
// Pre-round input number to avoid invalid rounding of 5.00000213 numbers
$price = $price->value(4);
if (!$roundTo) {
return $price;
}
$original_price = $price;
$price = $price->value(2);
// Pri zaporne hodnote je potreba otocit up to down, aby vysla stejna cena v plusu i v minusu
if ($price->isNegative()) {
$price = $price->abs();
}
if ($bata) {
if ($price->isZero()) {
$bata = null;
} else {
$bata = toDecimal($bata);
$price = $price->add($bata);
$decimal = 2;
}
}
// kdyz zaokrouhlovat na cela cisla
if ($roundTo == 100) {
switch ($direction) {
case 'up':
$price = $price->ceil();
break;
case 'down':
$price = $price->floor();
break;
case 'math':
$price = $price->round();
break;
}
} elseif ($roundTo == -5 || $roundTo == -10) {
$money = $price->asFloat();
switch ($direction) {
case 'up':
$money = abs($roundTo) * ceil($money / abs($roundTo));
break;
case 'down':
$money = abs($roundTo) * floor($money / abs($roundTo));
break;
case 'math':
$money = abs($roundTo) * round($money / abs($roundTo));
break;
}
$price = toDecimal($money);
} elseif ($roundTo == 50 || $roundTo == 5 || $roundTo == 25) {
// kdyz zaokrouhlovat na 50satniky
// rozdelit cenu na koruny a halere
@list($money, $groat) = explode('.', $price->printFloatValue(2));
settype($money, 'integer');
settype($groat, 'integer');
$multiplier = $roundTo == 50 ? 2 : ($roundTo == 25 ? 4 : 20);
$groat = ($groat / pow(10, $decimal)) * $multiplier;
switch ($direction) {
case 'up':
$groat = ceil($groat);
break;
case 'down':
$groat = floor($groat);
break;
case 'math':
$groat = round($groat);
break;
}
$groat = $groat / $multiplier;
if ($price->isNegative()) {
$price = toDecimal($money)->sub(toDecimal($groat));
} else {
$price = toDecimal($money)->add(toDecimal($groat));
}
} elseif ($roundTo == 10) {
// zaokrouhleni bud na halere nebo na desetniky
$decimal = 1;
switch ($direction) {
case 'up':
$price = $price->ceil($decimal);
break;
case 'down':
$price = $price->floor($decimal);
break;
case 'math':
$price = $price->round($decimal);
break;
}
}
if ($bata) {
$price = $price->sub($bata);
}
if ($original_price->isNegative() && $price->isPositive()) {
$price = $price->additiveInverse();
}
if ($price->isZero() && !$original_price->isZero()) {
if ($roundTo > 0) {
$price = toDecimal($roundTo / 100);
} else {
$price = toDecimal(-$roundTo);
}
}
return $price->value($decimal);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
if (!function_exists('getVat')) {
function getVat(&$id = null)
{
$vatContext = Contexts::get(VatContext::class);
if (is_null($id)) {
$vat = $vatContext->getDefault();
$id = $vat['id'];
} else {
$vat = $vatContext->getVat($id);
}
return $vatContext->translate($vat['vat'] ?? 0);
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
if (!function_exists('getAdminVat')) {
/**
* @return array ['value' => 21, 'id' => 1]
*/
function getAdminVat(): array
{
static $defaultVat;
if (!isset($defaultVat)) {
$qb = sqlQueryBuilder()->select('id, vat')->from('vats')
->where("is_default='Y'");
if (findModule(Modules::OSS_VATS)) {
$qb->andWhere('automanaged=0')
->orderBy('id_country');
}
$vatRow = $qb->setMaxResults(1)->execute()->fetch();
$defaultVat = [
'value' => $vatRow ? $vatRow['vat'] : 21,
'id' => $vatRow ? $vatRow['id'] : null,
];
}
return $defaultVat;
}
}
/**
* @return \KupShop\KupShopBundle\Util\Logging\SentryLogger
*
* @deprecated Use \Sentry\captureException() directly
*/
function getRaven()
{
static $client = null;
if (!$client) {
$client = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Logging\SentryLogger::class);
}
return $client;
}
/**
* For debug logging only!
*/
function getLogger(): Psr\Log\LoggerInterface
{
static $logger = null;
if (!$logger) {
$logger = ServiceContainer::getService('logger');
}
return $logger;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function error_handler($errno, $errstr, $errfile, $errline, $errctx = null)
{
if (!($errno & error_reporting())) {
return;
}
if (isDevelopment()) {
return false;
}
if (isDebug()) {
// debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
exit("{$errfile}:{$errline} - Error: {$errstr}");
}
// disable logging into kibana - sentry shoul be used
// logError($errfile, $errline, "Error: {$errstr}", false);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function exception_handler($exception, $event_id = null)
{
http_response_code(500);
if (isSuperuser()) {
echo $exception->getTraceAsString();
exit("\n".$exception->getFile().':'.$exception->getLine().' - '.$exception->getMessage());
}
global $cfg;
if (getVal('SMARTY_DEBUG') || isDebug() || !empty($cfg['development'])) {
exit('Uncaught exception: '.$exception->getMessage());
}
if (!$event_id) {
$raven = getRaven();
$event_id = (string) $raven->captureException($exception);
}
logError('Exception', 0, "Uncaught exception: Event id: {$event_id}: {$exception->getMessage()}", false);
$smarty = createSmarty();
$smarty->assign([
'exception' => $exception,
'event_id' => $event_id,
'ctrl' => &$GLOBALS['ctrl'],
]);
$smarty->display('error500.tpl');
}
if (!isLocalDevelopment() && php_sapi_name() != 'cli') {
// Production
if (!findModule('components')) {
set_exception_handler('exception_handler');
}
} else {
// Local dev
ini_set('display_errors', 1);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// funkce zjistuje aktualni cas provadeni skriptu
function getScriptTime()
{
return microtime(true);
}
/**
* @deprecated Unused, delete
*/
function measureTime($name)
{
static $time = null;
if (!$time) {
$time = [$name, microtime(true)];
return;
}
wpj_debug("Time measurement '{$time[0]}: ".((microtime(true) - $time[1]) * 1000).'ms');
$time = [$name, microtime(true)];
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// funkce definuje
/**
* @deprecated Useless, delete
*/
function setStartTime()
{
if (!defined('SCRIPT_START_TIME')) {
define('SCRIPT_START_TIME', getScriptTime());
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// funkce kontroluje cas provadeni skriptu a kdyz tak prodlouzi time limit
/**
* @deprecated Useless, delete
*/
function controlTimeLimit()
{
if (!defined('SCRIPT_START_TIME')) {
return;
}
if ((getScriptTime() - SCRIPT_START_TIME) >= (ini_get('max_execution_time') - 1)) {
@set_time_limit(ini_get('max_execution_time') + 5);
// echo ini_get('max_execution_time')."<br>";
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Do not use, type table name directly
*/
function getTableName($name, $quote = true)
{
$old_mapping = [
'photos-products' => 'photos_products_relation',
'products-related' => 'products_related',
'products-favorites' => 'products_favorites',
'products-sections' => 'products_in_sections',
'photos_articles' => 'photos_articles_relation',
];
if (array_key_exists($name, $old_mapping)) {
return $old_mapping[$name];
}
if (strstr($name, '.') !== false) {
return $name;
}
return ($quote == true) ? '`'.$name.'`' : $name;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// funkce na monitorovani chyb v systemu
// $file = soubor, $line = radka, $text = pridavny text chyby,
// $repeatMsg = zda opakovat chybove hlaseni, nebo staci jen jednou
/**
* @deprecated Use logger directly
*/
function logError($file, $line, $text, $repeatMsg = true)
{
static $logger = null;
$logger = $logger ?? ServiceContainer::getService('logger');
$logger->error($text, ['file' => $file, 'line' => $line]);
return;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param null $submodule
* @param null $default
*/
function findModule($module, $submodule = null, $default = null)
{
$array = &$GLOBALS['cfg']['Modules'];
if (!empty($array[$module])) {
if (is_null($submodule)) {
return true;
}
return getVal($submodule, $array[$module], $default);
} elseif (array_search($module, $array, true) === false) {
if ($default === null) {
return false;
}
return $default;
} else {
if (!is_null($default)) {
return $default;
}
return is_null($submodule);
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Use built-in Smarty template loading mechanism
*/
function findTemplate($file, $dir = 'null')
{
return $file;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Use getImage with prefetched photo id, update_date and description
*/
function leadImage($IDa, $imgType = 1, $type = 'PRODUCT')
{
$ret = null;
switch ($type) {
case 'PRODUCT':
$qb = sqlQueryBuilder()
->select('ph.id, ph.descr, ph.source, ph.image_2, ph.date_update')
->from('photos_products_relation', 'ppr')
->leftJoin('ppr', 'photos', 'ph', 'ppr.id_photo = ph.id')
->where(Translation::coalesceTranslatedFields(PhotosTranslation::class))
->andWhere('ppr.id_product=:id_product AND ppr.show_in_lead="Y" AND ppr.active="Y"')
->setParameter('id_product', $IDa)
->setMaxResults(1);
break;
case 'ARTICLE':
$qb = sqlQueryBuilder()
->select('ph.id, ph.descr, ph.source, ph.image_2, ph.date_update')
->from('photos_articles_relation', 'pa')
->leftJoin('pa', 'photos', 'ph', 'pa.id_photo = ph.id')
->where(Translation::coalesceTranslatedFields(PhotosTranslation::class))
->andWhere('pa.id_art=:id_art AND pa.show_in_lead="Y" AND pa.active="Y"')
->setParameter('id_art', $IDa)
->setMaxResults(1);
break;
}
if ($photo = $qb->execute()->fetchAssociative()) {
$ret = getImage($photo['id'], $photo['image_2'], $photo['source'], $imgType, $photo['descr'], strtotime($photo['date_update']));
}
return $ret;
}
function quickLoadImage($ID, $size, $photoId)
{
if (empty($photoId) || ($image = getImage($photoId, null, null, $size)) === false) {
$image = leadImage($ID, $size);
}
return $image;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function productCampaign($field, &$codes = null)
{
global $cfg;
$campaign = [];
$explodedCampaign = explodeFlags($field);
foreach (getCampaigns() as $flag => $name) {
if (!empty($explodedCampaign[$flag])) {
$campaign[] = $name['singular'];
$codes[$flag] = $name;
}
}
return join(' + ', $campaign);
}
function getCampaigns()
{
$cfg = Config::get();
$languageContext = Contexts::get(LanguageContext::class);
if ($languageContext->translationActive()) {
$translator = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Locale\PHPArrayTranslator::class);
$campaignTranslations = [];
$translator->loadTranslations($campaignTranslations, 'campaigns', false, $languageContext->getActiveId());
if (isset($campaignTranslations['campaigns'])) {
return array_replace_recursive($cfg['Products']['Flags'], $campaignTranslations['campaigns']);
}
}
return $cfg['Products']['Flags'];
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function getCategoryFullPath($IDCat)
{
$cat_parts = getReturnNavigation($IDCat);
$category = '';
if (count($cat_parts) > 0) {
$category = join(' / ', array_map(function ($x) {
return $x['text'];
}, array_slice($cat_parts[0], 1)));
}
return $category;
}
function getCategoryUrl($IDCat, $campaign = '', $producer = '')
{
$cat_parts = getReturnNavigation($IDCat, 'ESHOP_CATEGORY', [], $campaign, $producer);
if (count($cat_parts) > 0) {
$parents = [];
foreach ($cat_parts[0] as $part) {
if (!empty($part['ID'])) {
$parents[$part['ID']] = $part['text'];
}
}
return createScriptURL([
's' => 'category',
'IDcat' => $campaign.$IDCat,
'IDpd' => $producer,
'parents' => $parents,
'TITLE' => $cat_parts[0][count($cat_parts[0]) - 1]['text'],
]);
}
return null;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function getReturnNavigation($IDcat, $type = 'ESHOP_CATEGORY', $linkplus = [], $catCampaign = '', $catProducer = '')
{
$ret_array = [];
$IDcat = intval($IDcat);
if ($IDcat > 0) {
switch ($type) {
case 'ESHOP_CATEGORY':
$section = ServiceContainer::getService(SectionTree::class)->get()->getSectionById($IDcat);
if (isset($section)) {
$retRow_array = [];
// load producer name
$catProducerTitle = '';
if (findModule(\Modules::PRODUCERS) && !empty($catProducer)) {
$qb = sqlQueryBuilder()->from('producers', 'pr')
->andWhere(\Query\Operator::equals(['pr.id' => $catProducer]))
->setMaxResults(1);
if (findModule(\Modules::TRANSLATIONS)) {
$qb->andWhere(
\Query\Translation::coalesceTranslatedFields(
\KupShop\I18nBundle\Translations\ProducersTranslation::class,
['name']
)
);
} else {
$qb->select('name');
}
$catProducerTitle = $qb->execute()->fetchColumn();
}
// add ancestor sections
foreach ($section->getParents() as $parent) {
if ($parent->getId() === $section->getId()) {
// add active section
array_push($retRow_array, [
'text' => $section->getNameShort() ? $section->getNameShort() : $section->getName(),
'ID' => $parent->getId(),
]);
} else {
array_push($retRow_array, [
'text' => $parent->getNameShort(),
'link' => createScriptURL([
'URL' => 'launch.php',
's' => 'category',
'IDcat' => $parent->getId().$catCampaign,
'IDpd' => $catProducer,
'producerTitle' => $catProducerTitle,
'TITLE' => $parent->getNameShort(),
'parents' => $parent->getParentIDs(),
]),
'ID' => $parent->getId(),
]);
}
}
// add producer
if (!empty($catProducerTitle)) {
$home = sprintf(translate('getSections', 'functions')['catalogProducer'], $catProducerTitle);
array_unshift($retRow_array, [
'text' => $home,
'link' => createScriptURL([
'URL' => 'launch.php',
's' => 'category',
'IDpd' => $catProducer,
'producerTitle' => $catProducerTitle,
'TITLE' => $home,
]),
'ID' => '0',
]);
}
array_unshift($retRow_array, [
'text' => translate('getSections', 'functions')['home'],
'link' => createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]),
]);
array_push($ret_array, $retRow_array);
}
break;
case 'PRODUCT':
$retRow_array = [];
$section = ServiceContainer::getService(SectionTree::class)->get()->getSectionById($IDcat);
if (isset($section)) {
foreach ($section->getParents() as $parent) {
array_push($retRow_array, [
'text' => $parent->getNameShort(),
'section_name' => $parent->getName(),
'link' => createScriptURL([
'URL' => 'launch.php',
's' => 'category',
'IDcat' => $parent->getId().$catCampaign,
'IDpd' => $catProducer,
'TITLE' => $parent->getNameShort(),
'parents' => $parent->getParentIDs(),
]),
'ID' => $parent->getId(),
]);
}
}
array_unshift($retRow_array, [
'text' => translate('getSections', 'functions')['home'],
'link' => createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]),
]);
array_push($ret_array, $retRow_array);
break;
case 'ARTICLE':
$ret_array[0] = [];
if (findModule(\Modules::ARTICLES_SECTIONS)) {
$branchID = $IDcat;
while (!empty($branchID)) {
$qb = sqlQueryBuilder()->select('ab.id, ab.top_branch')
->from('articles_branches', 'ab')
->andWhere(\Query\Operator::equals(['ab.id' => $branchID]))
->andWhere(\Query\Translation::coalesceTranslatedFields(ArticlesSectionsTranslation::class, ['name']))
->setMaxResults(1);
$qb->andWhere(Translation::joinTranslatedFields(ArticlesSectionsTranslation::class,
function (QueryBuilder $qb, $columnName, $translatedField) {
$qb->andWhere(Operator::coalesce($translatedField, 'ab.figure').' = "Y" ');
return false;
}, ['figure']));
$Row = $qb->execute()->fetch();
if ($Row) {
$branchID = $Row['top_branch'];
$Name = $Row['name'];
$IDCatCurr = $Row['id'];
$url = createScriptURL([
'URL' => 'launch.php',
's' => 'articles',
'IDb' => $IDCatCurr,
'TITLE' => $Name,
]);
array_unshift($ret_array[0], [
'text' => $Name,
'link' => $url,
'IDb' => $IDCatCurr,
]);
} else {
break;
}
}
} else {
$url = createScriptURL([
'URL' => 'launch.php',
's' => 'articles',
]);
array_unshift($ret_array[0], [
'text' => translate('getSections', 'functions')['articles'],
'link' => $url,
]);
}
$url = createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]);
array_unshift($ret_array[0],
[
'text' => translate('getSections', 'functions')['home'],
'link' => $url,
]/*,
[
"text"=>translate('getSections', 'functions')['articles'],
"link"=>$url . "clanky/"
]*/
);
break;
case 'ARTICLES_BRANCHES':
$ret_array[0] = [];
$i = 0;
while (!empty($IDcat)) {
$qb = sqlQueryBuilder()->select('ab.id, ab.top_branch')
->from('articles_branches', 'ab')
->andWhere(\Query\Operator::equals(['ab.id' => $IDcat]))
->andWhere(\Query\Translation::coalesceTranslatedFields(ArticlesSectionsTranslation::class, ['name']))
->setMaxResults(1);
$qb->andWhere(Translation::joinTranslatedFields(ArticlesSectionsTranslation::class,
function (QueryBuilder $qb, $columnName, $translatedField) {
$qb->andWhere(Operator::coalesce($translatedField, 'ab.figure').' = "Y" ');
return false;
}, ['figure']));
$Row = $qb->execute()->fetch();
if ($Row) {
if ($i > 0) {
$url = createScriptURL([
'URL' => 'launch.php',
's' => 'articles',
'IDb' => $IDcat,
'TITLE' => $Row['name'],
]);
array_unshift($ret_array[0], [
'text' => $Row['name'],
'link' => $url,
]);
} else {
array_unshift($ret_array[0], [
'text' => $Row['name'],
]);
}
$IDcat = $Row['top_branch'];
} else {
break;
}
$i++;
}
$url = createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]);
array_unshift(
$ret_array[0],
['text' => translate('getSections', 'functions')['home'], 'link' => $url]/*,
[ "text"=>translate('getSections', 'functions')['articles']]*/
);
break;
case 'PAGE':
$id_link = sqlQueryBuilder()->select('parent')
->from('menu_links')
->where(Operator::equals(['id' => $IDcat]))
->orderBy('parent', 'ASC')
->execute()->fetchColumn();
$ret_array[0] = [];
while ($id_link > 0) {
$qb = sqlQueryBuilder()->select('ml.id, ml.parent, ml.name, ml.url')
->from('menu_links', 'ml')
->andWhere(\Query\Operator::equals(['ml.id' => $id_link]))
->andWhere(Operator::equals(['ml.type' => MenuUtil::TYPE_PAGE]))
->andWhere(\Query\Translation::coalesceTranslatedFields(\KupShop\I18nBundle\Translations\MenuLinksTranslation::class, ['name', 'url']))
->setMaxResults(1);
$row = $qb->execute()->fetch();
if ($row) {
if ($id_link == $row['parent']) {
break;
}
$id_link = $row['parent'];
array_unshift($ret_array[0], [
'text' => $row['name'],
'link' => '/'.ltrim($row['url']),
]);
} else {
break;
}
}
$url = createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]);
array_unshift($ret_array[0], [
'text' => translate('getSections', 'functions')['home'],
'link' => $url,
]);
break;
}
} else {
// IDcat = 0
switch ($type) {
case 'ESHOP_CATEGORY':
$ret_array[0] = [];
$catProducerTitle = '';
if (!empty($catProducer)) {
$catProducerTitle = returnSQLResult('SELECT name
FROM '.getTableName('producers').'
WHERE id='.intval($catProducer).' LIMIT 1');
}
if (!empty($catProducer)) {
$home = sprintf(translate('getSections', 'functions')['catalogProducer'], $catProducerTitle);
} elseif ($catCampaign) {
$titles = translate('title', 'category');
switch ($catCampaign) {
case 'F':
$home = $titles['favorites'];
break;
case 'W':
$home = $titles['watchdog'];
break;
case 'N':
$home = $titles['news'];
break;
case 'A':
$home = $titles['sale'];
break;
case 'D':
$home = $titles['campaign'];
break;
case 'M':
$home = $titles['newsletter'];
break;
}
} else {
$home = translate('getSections', 'functions')['catalog'];
}
if (!empty($home)) {
array_unshift($ret_array[0], [
'text' => $home,
]);
}
array_unshift($ret_array[0], [
'text' => translate('getSections', 'functions')['home'],
'link' => createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]),
]);
break;
case 'ARTICLES_BRANCHES':
$ret_array[0] = [];
array_unshift($ret_array[0],
['text' => translate('getSections', 'functions')['home'], 'link' => '/'],
['text' => translate('getSections', 'functions')['articles']]
);
break;
case 'USER':
$ret_array[0] = [];
$url = path('account');
array_unshift($ret_array[0], [
'text' => translate('title', 'account'),
'link' => $url,
]);
$url = createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]);
array_unshift($ret_array[0], [
'text' => translate('getSections', 'functions')['home'],
'link' => $url,
]);
break;
case 'RECLAMATION':
array_unshift($linkplus, [
'text' => translate('reclamations', 'reclamations'),
'link' => path('kupshop_reclamations_reclamations_reclamations'),
]);
if (\User::getCurrentUserId()) {
return getReturnNavigation(-1, 'USER', $linkplus);
} else {
return getReturnNavigation(-1, 'NO_TYPE', $linkplus);
}
// no break
case 'RETURN':
array_unshift($linkplus, [
'text' => translate('returns_title', 'returns'),
'link' => path('kupshop_returns_returns_returns'),
]);
if (\User::getCurrentUserId()) {
return getReturnNavigation(-1, 'USER', $linkplus);
} else {
return getReturnNavigation(-1, 'NO_TYPE', $linkplus);
}
// no break
case 'NO_TYPE':
$ret_array[0] = [];
$url = createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]);
array_unshift($ret_array[0], [
'text' => translate('getSections', 'functions')['home'],
'link' => $url,
]);
break;
}
}
if ($type != 'ESHOP_CATEGORY' && $linkplus) {
foreach ($linkplus as $link) {
if (!is_array($link)) {
$link = ['text' => $link];
}
$ret_array[0][] = $link;
}
}
return $ret_array;
}
/**
* @deprecated Use Symfony Request, getClientIp method
*/
function getIP()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) { // if from shared
return $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { // if from a proxy
return $_SERVER['HTTP_X_FORWARDED_FOR'];
}
return $_SERVER['REMOTE_ADDR'] ?? '';
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function stripTags($String, $Convert = false, $NL = '\r\n')
{
if ($Convert) {
$String = preg_replace("@((<br( /)?>)|<\/p>)@i", $NL, $String);
}
$String = preg_replace('/(<[^>]*>)/i', ' ', $String);
if ($Convert) {
$String = str_replace('&nbsp;', ' ', $String);
$String = str_replace('&quot;', '"', $String);
$String = str_replace('&gt;', '>', $String);
$String = str_replace('&lt;', '<', $String);
$String = str_replace('&amp;', '&', $String);
}
$String = preg_replace('/( )+/i', ' ', $String);
$String = trim($String);
return $String;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated in favour of \KupShop\KupShopBundle\Util\StringUtil::normalizeWhitespace()
*
* @return string|string[]|null
*/
function CutString($String)
{
$String = trim($String);
$String = preg_replace("/[\t\r\n]/i", '', $String);
$String = preg_replace('/( )+/i', ' ', $String);
return $String;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// vybere polozku ze selectoveho menu
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function CheckSelect($Value1, $Value2)
{
if ($Value1 == $Value2) {
return ' selected="selected"';
} else {
return '';
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// zaskrtne checkbox
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function CheckRadio($Value1, $Value2)
{
if ($Value1 == $Value2) {
return ' checked="checked"';
} else {
return '';
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function setCookies($Name, $Value, $Expiry = 2592000, $options = [])
{
if (isFunctionalTests()) {
return true;
}
$time = null;
if ($Expiry < 0) { // Remove
$Value = '';
unset($_COOKIE[$Name]);
} else {
$_COOKIE[$Name] = $Value;
}
if (!is_null($Expiry)) {
$time = time() + $Expiry;
}
setcookie($Name, $Value, array_merge([
'expires' => $time,
'path' => '/',
'secure' => true,
'samesite' => 'Lax',
], $options));
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Unused, delete
*/
function ShortText($Text, $Reduce)
{
$Word = preg_split('/[[:blank:]]+/', $Text);
$NoWords = count($Word);
$Length = 0;
$RtrnText = '';
for ($i = 0; $i < $NoWords; $i++) {
$RtrnText .= $Word[$i].' ';
$Length = strlen($RtrnText);
if ($Length + 3 + strlen($Word[$i]) >= $Reduce) {
break;
}
}
if (strlen($RtrnText) >= $Reduce) {
$RtrnText = substr($RtrnText, 0, $Reduce - 3);
}
if (strlen($Text) > strlen($RtrnText)) {
$RtrnText .= '...';
}
return wordwrap($RtrnText, 60, "\n", 1);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Unused, delete
*/
function getInputsFromString($String, $ex1, $ex2, $except = [])
{
$return = '';
$Input = explode($ex1, $String);
for ($i = 0; $i < count($Input); $i++) {
if ($Input[$i] != '') {
$data = explode($ex2, $Input[$i]);
if (array_search($data[0], $except) === false) {
$return .= '<input type="hidden" name="'.$data[0].'" value="'.$data[1].'" />';
}
}
}
return $return;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// FUNKCE: pridava vytvari URL odkazu bud klasickou nebo SEO friendly
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
if (!function_exists('createScriptURL')) {
function createScriptURL($params)
{
/** @var $legacyUrlGenerator \KupShop\KupShopBundle\Util\LegacyUrlGenerator */
$legacyUrlGenerator = ServiceContainer::getService(\KupShop\KupShopBundle\Util\LegacyUrlGenerator::class);
return $legacyUrlGenerator->generate($params);
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// FUNKCE: pridava do vytvarene URL dalsi parametry
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function createScriptURL_Next_Params($SEO_URL, $params)
{
if (count($params) == 0) {
return $SEO_URL;
}
// zda se ma URL Encodovat
$ENCODE_URL = !empty($params['ESCAPE']) && ($params['ESCAPE'] != 'NO');
unset($params['ESCAPE']);
$QS = '';
foreach ($params as $param => $value) {
if ($param != 'URL' && $param != 'TITLE') {
if ($ENCODE_URL) {
$value = urlencode($value);
}
$QS .= '&'.$param.'='.$value;
}
}
if ($QS != '') {
if (strpos($SEO_URL, '?') === false) {
$SEO_URL .= '?';
$QS = substr($QS, 1);
}
if ($ENCODE_URL) {
$QS = htmlspecialchars($QS);
}
$SEO_URL .= $QS;
}
return $SEO_URL;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// FUNKCE: vytvari ze stringu SEO friendly URL
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Use StringUtil::slugify
*/
function createScriptURL_Text($string)
{
return \KupShop\KupShopBundle\Util\StringUtil::slugify($string);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Do nothing
*/
function sqlConnect()
{
return true;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param array $params
* @param array $types
*
* @return \Doctrine\DBAL\Statement
*/
function sqlQuery($Query, $params = '', $types = [])
{
if (is_array($params)) {
return sqlQueryParams($Query, $params, $types);
}
wpj_debug($Query);
$stmt = sqlGetConnection()->query($Query);
return $stmt;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function sqlQueryParams($Query, $params = [], $types = [])
{
wpj_debug([$Query, $params]);
$stmt = sqlGetConnection()->executeQuery($Query, $params, $types);
return $stmt;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Unused, delete
*/
function sqlError($stmt, $logError = true, $printError = true, $exit = true, $msg = '')
{
// jinak chybu aspon zalogovat
if ($logError) {
$error = 'MySQL Error: '.print_r($stmt->errorInfo(), true);
if ($msg != '') {
$error .= "\r\nSQL: ".$msg;
}
// $error .= print_r(debug_backtrace(), true);
logError(__FILE__, __LINE__, $error);
}
// vypsat hlasku a ukoncit
if ($printError) {
echo "<i><b>Database Error: </b></i><pre>{$error}</pre>";
}
// ukoncit skript
if ($exit) {
exit;
}
return true;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function sqlPrepare($Query)
{
wpj_debug([$Query]);
$stmt = sqlGetConnection()->prepare($Query);
return $stmt;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function sqlExecute($stmt, $params)
{
wpj_debug([$stmt, $params]);
$stmt->execute($params);
return $stmt;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param $stmt \Doctrine\DBAL\Statement
*
* @return int
*/
function sqlNumRows($stmt)
{
if (!$stmt) {
return 0;
}
return $stmt->rowCount();
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Unused, delete
*/
function sqlNumFields($stmt)
{
if (($user = getAdminUser()) && $user['id'] === 0) {
exit('<br><strong>Použití sqlNumFields. Fuj!:</strong> '.print_r(debug_backtrace(), true));
}
return 0;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param $stmt \Doctrine\DBAL\Statement
*/
function sqlFetchArray($stmt)
{
return $stmt->fetch(PDO::FETCH_BOTH);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param $stmt \Doctrine\DBAL\Statement
*/
function sqlFetch($stmt)
{
return $stmt->fetch(PDO::FETCH_ASSOC);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param $stmt \Doctrine\DBAL\Statement
*
* @deprecated
*/
function sqlFetchRow($stmt)
{
return $stmt->fetch(PDO::FETCH_NUM);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param $stmt \Doctrine\DBAL\Statement
*/
function sqlFetchAssoc($stmt)
{
return $stmt->fetch(PDO::FETCH_ASSOC);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function sqlFetchAll($stmt, $field = null, $deduplicate = false)
{
if ($stmt instanceof \Doctrine\DBAL\Query\QueryBuilder) {
$stmt = $stmt->execute();
}
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($field) {
$values = $arr;
if (is_array($field)) { // Specify field for both key and value
$value = array_values($field)[0];
$field = array_keys($field)[0];
// Filter out only given value instead of whole array
$values = array_map(function ($row) use ($value) {
return $row[$value];
}, $values);
}
return array_combine(array_map(function ($row) use ($field) {
return $row[$field];
}, $arr), $values);
}
return $arr;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// formatuje vstup do SQL prikazu, zabraneni SQL Injection
/**
* @deprecated Use parameter binding
*/
function sqlFormatInput($input)
{
return $stmt = substr(sqlGetConnection()->quote($input), 1, -1);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Do nothing, delete
*/
function sqlResult($ID, $i, $field)
{
if (($user = getAdminUser()) && $user['id'] === 0) {
exit('<br><strong>Použití sqlResult. Fuj!:</strong> '.print_r(debug_backtrace(), true));
}
return null;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Unused, delete
*/
function sqlFieldName($ID, $i)
{
if (($user = getAdminUser()) && $user['id'] === 0) {
exit('<br><strong>Použití sqlFieldName. Fuj!:</strong> '.print_r(debug_backtrace(), true));
}
return null;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function sqlInsertId()
{
return sqlGetConnection()->lastInsertId();
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Do nothing, delete
*/
function sqlFreeResult($stmt)
{
unset($stmt);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function returnSQLResult($Query, $params = null, $types = [])
{
if ($params) {
$SQL = sqlQueryParams($Query, $params, $types);
} else {
$SQL = sqlQuery($Query);
}
$row = sqlFetchArray($SQL);
sqlFreeResult($SQL);
if ($row && count($row) > 0) {
return $row[0];
} else {
return false;
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Do nothing, delete
*/
function sqlClose()
{
sqlGetConnection()->close();
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Use sqlGetConnection()->transactional()
*/
function sqlStartTransaction()
{
sqlGetConnection()->beginTransaction();
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Use sqlGetConnection()->transactional()
*/
function sqlFinishTransaction()
{
sqlGetConnection()->commit();
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @return bool|void
*
* @deprecated Use sqlGetConnection()->transactional()
*
* @throws \Doctrine\DBAL\ConnectionException
*/
function sqlRollbackTransaction()
{
sqlGetConnection()->rollBack();
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function sqlAffectedRows($stmt)
{
return sqlNumRows($stmt);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @return \Doctrine\DBAL\Connection
*/
function sqlGetConnection()
{
return ServiceContainer::getService('doctrine.dbal.default_connection');
}
/**
* @return \Query\QueryBuilder
*/
function sqlQueryBuilder()
{
return ServiceContainer::getService(\Query\QueryBuilder::class);
}
define('HEAD_CRLF', "\r\n");
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Use Mail classes
*/
function SendMail($From, $For, $Subject, $Message, $contentType = null, $attachments = null, $cc = null, $bcc = null, $headers = [], $utm_campaign = null)
{
$emailSender = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Mail\EmailSender::class);
try {
$msg = $emailSender->createMessage($From, $For, $Subject, $Message, $contentType, $attachments, $cc, $bcc, $headers, $utm_campaign);
} catch (Exception $e) {
getRaven()->captureException($e);
return false;
}
return $emailSender->sendMessage($msg);
}
function getImagePath($id, $type, $ext = 'jpg', $lang = null, ?string $version = null)
{
static $imageLocator = null;
if (!$imageLocator) {
$imageLocator = ServiceContainer::getService(ImageLocator::class);
}
return $imageLocator->getPath($id, $type, $ext, $lang, $version);
}
function getImageSettings(&$type)
{
static $imageLocator = null;
if (!$imageLocator) {
$imageLocator = ServiceContainer::getService(ImageLocator::class);
}
return $imageLocator->getTypeConfig($type);
}
function getImage($id, $file, $folder, $type, $desc = '', ?int $dateUpdate = null, $data = null)
{
static $imageLocator = null;
if (!$imageLocator) {
$imageLocator = ServiceContainer::getService(ImageLocator::class);
}
return $imageLocator->getOldImageArray($id, $file, $folder, $type, $desc, $dateUpdate, $data);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function wpj_debug($string, $force = false)
{
static $used = false;
if (isset($_GET['wpj_debug']) || $force) {
if (!$used) {
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
}
if (!is_string($string)) {
$string = var_export($string, true);
}
echo "<!-- {$string} -->\n";
$used = true;
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function getProductDeliveryText(&$inStore, &$deliveryTime)
{
$cfg = Config::get();
$dbcfg = Settings::getDefault();
if ($inStore > 0) {
$deliveryTime = 0;
}
if ($inStore <= 0 && $deliveryTime == 0 && $dbcfg->prod_subtract_from_store != 'N') {
$deliveryTime = (isset($cfg['Products']['SoldOutIndex']) ? $cfg['Products']['SoldOutIndex'] : -1);
}
$inStore = max($inStore, 0);
$languageContext = Contexts::get(LanguageContext::class);
if ($deliveryTime <= 0) {
if (!$languageContext->translationActive()) {
return $cfg['Products']['DeliveryTime'][$deliveryTime] ?? '';
} else {
return translate_shop($deliveryTime, 'deliveryTime');
}
} else {
if (!$languageContext->translationActive()) {
return sprintf($cfg['Products']['DeliveryTime']['1'] ?? '', strval($deliveryTime));
} else {
return sprintf(translate('1', 'deliveryTime'), strval($deliveryTime));
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function getStatuses($status = null)
{
global $cfg;
// backward compatibility
if ($status === null) {
$status = 'handled';
$sentryLogger = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Logging\SentryLogger::class);
$sentryLogger->captureMessage('Function getStatuses() called with missing parameter "$status"', [], [], true);
}
switch ($status) {
case 'complete':
if (isset($cfg['Order']['Status']['complete'])) {
return $cfg['Order']['Status']['complete'];
} else {
return [0, 1];
}
// no break
case 'notpacked':
if (isset($cfg['Order']['Status']['notpacked'])) {
return [...$cfg['Order']['Status']['notpacked'], 100];
} else {
return [0, 1, 100];
}
// no break
case 'active':
if (isset($cfg['Order']['Status']['active'])) {
return $cfg['Order']['Status']['active'];
} else {
return [0, 1];
}
// no break
case 'editable':
if (isset($cfg['Order']['Status']['editable'])) {
return $cfg['Order']['Status']['editable'];
} else {
return [0, 1];
}
// no break
case 'reclamation':
if (isset($cfg['Order']['Status']['reclamation'])) {
return $cfg['Order']['Status']['reclamation'];
} else {
return [3];
}
// no break
case 'nothandled':
return array_diff(array_keys($cfg['Order']['Status']['global']), getStatuses('handled'));
case 'handled':
if (isset($cfg['Order']['Status']['handled'])) {
return $cfg['Order']['Status']['handled'];
} else {
return [2];
}
// no break
case 'invoice':
return getVal('invoice', $cfg['Order']['Status'], []);
case 'in_store': // Pokud je vypnuto odecitani ze skladu, v jakych stavech je produkt skladem
return getVal('in_store', $cfg['Order']['Status'], [0]);
case 'telfa_disallow_change_status': // Telfa pri techto stavech vraci sms, ze je obj uzavrena
return getVal('telfa_disallow_change_status', $cfg['Order']['Status'], getStatuses('handled'));
case 'payment_change_allowed':
return getVal('payment_change_allowed', $cfg['Order']['Status'], [0]);
default:
logError(__FILE__, __LINE__, "Unknown getStatuses status: {$status}");
return [];
}
}
function getOrderStatus($status)
{
return getOrderStatuses()[$status];
}
function getOrderStatuses()
{
static $statuses = null;
if (is_null($statuses)) {
global $cfg;
// $colors = ["ffffff", "d8edf6", "edf7d6", "c9f5b9", "baf0ee", "f6f6bb", "eaf4f8", "ffebfc", "c8c8c8", "fff3e6", "", "", ""];
$colors = ['EEEEEE', '9ED2E8', 'bfec55', 'FFFF78', 'F2AEF2', 'FCCF81', 'bac8f3', 'c8c8c8', 'e4f3ba', '8cd993', '', ''];
$info = getVal('global_info', $cfg['Order']['Status']);
foreach ($cfg['Order']['Status']['global'] as $status => $name) {
if (isset($info[$status]['color'])) {
$colors[$status] = $info[$status]['color'];
}
$statuses[$status] = ['name' => $name, 'color' => $colors[$status] ?? ''];
}
}
return $statuses;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function getMemcached()
{
static $m = null;
if ($m) {
return $m;
}
global $cfg;
$m = new Memcached('main_cache');
if (!count($m->getServerList())) {
if (!empty($cfg['Cache']['memcached'])) {
foreach (explode(',', $cfg['Cache']['memcached']) as $memcached) {
$m->addServer($memcached, 11211);
}
} else {
$m->addServer('/var/run/memcached/memcached.socket', 0);
}
$m->setOptions([
Memcached::OPT_BINARY_PROTOCOL => true,
Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
Memcached::OPT_PREFIX_KEY => $cfg['Cache']['prefix'],
]);
}
return $m;
}
function getRedisCache(): \Redis|\RedisCluster
{
static $r = null;
if (!$r) {
$r = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Redis\RedisService::class)->connect();
}
return $r;
}
function getCache($key, &$found = null)
{
if (getVal('skip_cache')) {
return null;
}
$key .= getenv('BUILD_ID');
if (findModule(Modules::COMPONENTS)) {
$redisCache = getRedisCache();
return $redisCache->get($key);
}
$m = getMemcached();
$ret = $m->get($key);
$found = $m->getResultCode() != Memcached::RES_NOTFOUND;
if (is_array($ret) && array_key_exists('@@OBJ@@', $ret)) {
return unserialize($ret['@@OBJ@@']);
}
return $ret;
}
function setCache($key, &$value, $ttl = 7200)
{
$key .= getenv('BUILD_ID');
if (findModule(Modules::COMPONENTS)) {
$redisCache = getRedisCache();
if (!$ttl) { // if ttl is 0, item never expires (Memcached BC)
return $redisCache->set($key, $value);
}
return $redisCache->set($key, $value, ['EX' => $ttl]);
}
$m = getMemcached();
if (is_object($value)) {
return $m->set($key, ['@@OBJ@@' => serialize($value)], $ttl);
}
return $m->set($key, $value, $ttl);
}
function clearCache($key, $prefix = false)
{
if (findModule(Modules::COMPONENTS)) {
$key .= getenv('BUILD_ID');
$redisCache = getRedisCache();
return $redisCache->del($key);
}
global $cfg;
if (!$prefix) {
$key .= getenv('BUILD_ID');
$m = getMemcached();
$m->delete($key);
} else {
$m = new Memcached();
if (!empty($cfg['Cache']['memcached'])) {
foreach (explode(',', $cfg['Cache']['memcached']) as $memcached) {
$m->addServer($memcached, 11211);
}
} else {
$m->addServer('/var/run/memcached/memcached.socket', 0);
}
$keys = (array) $m->getAllKeys();
$prefix = $cfg['Cache']['prefix'].$key;
foreach ($keys as $index => $key) {
if (strpos($key, $prefix) === 0) {
$splitKey = explode('/', $key);
if (isset($splitKey[1]) && \KupShop\KupShopBundle\Util\StringUtil::startsWith($splitKey[1], \KupShop\KupShopBundle\Util\Session\MemcachedSessionHandler::SESSION_PREFIX)) {
continue;
}
getMemcached()->delete(substr($key, strlen($cfg['Cache']['prefix'])));
}
}
}
return true;
}
function getLocalCache(): Symfony\Component\Cache\Adapter\AdapterInterface
{
static $cache = null;
if (is_null($cache)) {
$cache = ServiceContainer::getService('cache.app');
}
return $cache;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// funkce: emphasizeString
// popis: zadany retezec prohleda a oznaci slova, ktera jsou zadana
/**
* @deprecated Do not use
*/
function emphasizeString($text, $needle)
{
$text = html_entity_decode($text);
// Default highlighting
$highlight = '<span class="checkedExpression">\1</span>';
// Select pattern to use
$pattern = '#(?!<.*?)(%s)(?![^<>]*?>)#';
// Case sensitivity
$pattern .= 'i';
$needle = (array) $needle;
foreach ($needle as $needle_s) {
$needle_s = preg_quote($needle_s);
$regex = sprintf($pattern, $needle_s);
$text = preg_replace($regex, $highlight, $text);
}
return $text;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Use QueryBuilder::directValues
*/
function queryCreate($fields, $directValues = false, $notNull = [])
{
$ret = ' ';
$first = true;
foreach ($fields as $field => $variable) {
if (is_numeric($field)) {
$field = $variable;
}
if (!$directValues && !isset($GLOBALS[$variable])) {
continue;
}
if (!$directValues) {
$variable = $GLOBALS[$variable];
}
if (is_float($variable)) {
$variable = str_replace(',', '.', $variable);
}
if ((is_null($variable) || $variable === '') && array_search($field, $notNull) === false) {
$variable = 'NULL';
} else {
$variable = "'".sqlFormatInput($variable)."'";
}
$ret .= ($first ? '' : ', ')."`{$field}`={$variable} ";
$first = false;
}
return $ret;
}
/**
* @deprecated Use Query::equals or Query::equalsNullable specs
*/
function selectQueryCreate($fields, $directValues = false, $operator = 'AND', $notNull = [])
{
$ret = ' ';
$first = true;
foreach ($fields as $field => $variable) {
if (is_numeric($field)) {
$field = $variable;
}
if (!$directValues && !isset($GLOBALS[$variable])) {
continue;
}
if (!$directValues) {
$variable = $GLOBALS[$variable];
}
if ((is_null($variable) || $variable === '') && array_search($field, $notNull) === false) {
$ret .= ($first ? '' : " {$operator} ")."{$field} IS NULL";
} else {
$ret .= ($first ? '' : " {$operator} ")."{$field}='".sqlFormatInput($variable)."' ";
}
$first = false;
}
return $ret;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param int $id_category
*
* @return array
*/
function getDescendantCategories($id_category)
{
// Load from menu categories structure
$category = ServiceContainer::getService(SectionTree::class)->get()->getSectionById($id_category);
if (!$category) {
return [$id_category];
}
$ids = [];
getDescendantCategoriesFromMenu($ids, $category);
return $ids;
}
/**
* @deprecated Unused, delete
*/
function getDescendantCategoriesOld(&$where, $CatID)
{
if (empty($CatID)) {
$where .= ' 1 ';
return;
}
$ids = getDescendantCategories($CatID);
$where .= ' ps.id_section IN ('.join(',', $ids).') ';
}
/**
* @deprecated Unused, delete
*/
function getDescendantCategoriesFromMenu(&$ids, KupShop\CatalogBundle\Entity\Section $cat)
{
$ids[] = $cat->getId();
foreach ($cat->getChildren() as &$category) {
if ($category->getFigure() != 'N') {
getDescendantCategoriesFromMenu($ids, $category);
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function getVal($value, $array = null, $default = null)
{
if ($array !== null) {
return isset($array[$value]) ? $array[$value] : $default;
} else {
return isset($_REQUEST[$value]) ? $_REQUEST[$value] : $default;
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function generatePassword($seed, $length = 4)
{
$pass = md5($seed);
$pass = strtr($pass, '0123456789', 'ghijkmnspr');
return substr($pass, 0, $length);
}
function generateCaptcha($seed)
{
global $cfg;
$length = 4;
if (!empty($cfg['captcha']['length'])) {
$length = $cfg['captcha']['length'];
}
return generatePassword($seed, $length);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function isAjax()
{
return strtolower(getVal('HTTP_X_REQUESTED_WITH', $_SERVER, '')) == 'xmlhttprequest';
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @param $params string[]
*
* @return string
*/
function getAdminUrl($page, $params, bool $absolute = false)
{
global $cfg;
$admin_url = $cfg['Menu']['wpj_toolbar']['admin_url'];
$params['s'] = $page.'.php';
$params['acn'] = 'edit';
$params['inline'] = '1';
if ($absolute) {
$domainContext = ServiceContainer::getService(DomainContext::class);
$admin_url = "https://{$domainContext->getActiveId()}/".ltrim($admin_url, '/');
}
return $admin_url.'launch.php?'.http_build_query($params);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
define('POSITION_FIRST', 0);
define('POSITION_LAST', 10000);
define('POSITION_STANDARD', 5000);
function loadLanguage($category = 'main', $lng = null)
{
global $txt_str;
$translator = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Locale\PHPArrayTranslator::class);
$translator->loadTranslations($txt_str, $category, isAdministration(), $lng ?? $translator->getLanguage(isAdministration()));
return $txt_str;
}
function createSmarty($admin = false, $add_globals = false, $translate = null)
{
$cfg = &Config::get()->getContainer();
$translate = (findModule(\Modules::TRANSLATIONS) || findModule(\Modules::TEMPLATE_TRANSLATIONS)) && ($translate ?? (!$admin));
if (isFunctionalTests() || $admin) {
if ($translate) {
// Používá se pouze pro výchozí text emailů. Negenerují se ale nikde překlady :-(
$languageContext = Contexts::get(LanguageContext::class);
$smarty = new SmartyML($languageContext->getDefaultId());
} else {
$smarty = new Smarty();
}
$smarty->setMergeCompiledIncludes(true);
$smarty->setErrorReporting(E_ALL & ~(E_WARNING | E_NOTICE | E_USER_DEPRECATED));
// Register required administration modifiers
$smarty->registerPlugin('modifier', 'is_numeric', 'is_numeric');
$smarty->registerPlugin('modifier', 'translate_shop', 'translate_shop');
$smarty->registerPlugin('modifier', 'get_class', 'get_class');
$smarty->registerPlugin('modifier', 'json_encode', 'json_encode');
$smarty->registerPlugin('modifier', 'array_values', 'array_values');
$smarty->registerPlugin('modifier', 'strstr', 'strstr');
$smarty->registerPlugin('modifier', 'getShopName', 'getShopName');
$smarty->registerPlugin('modifier', 'isSuperuser', 'isSuperuser');
$smarty->registerPlugin('modifier', 'getAdminUser', 'getAdminUser');
$smarty->registerPlugin('modifier', 'isLocalDevelopment', 'isLocalDevelopment');
$smarty->registerPlugin('modifier', 'isDevelopment', 'isDevelopment');
$smarty->registerPlugin('modifier', 'is_null', 'is_null');
$smarty->registerPlugin('modifier', 'findModule', 'findModule');
$smarty->registerPlugin('modifier', 'is_string', 'is_string');
$smarty->registerPlugin('modifier', 'intval', 'intval');
$smarty->registerPlugin('modifier', 'ltrim', 'ltrim');
$smarty->registerPlugin('modifier', 'toDecimal', 'toDecimal');
$smarty->registerPlugin('modifier', 'json_decode', 'json_decode');
$smarty->registerPlugin('modifier', 'array_keys', 'array_keys');
$smarty->registerPlugin('modifier', 'array_splice', 'array_splice');
$smarty->registerPlugin('modifier', 'implode', 'implode');
$smarty->registerPlugin('modifier', 'lcfirst', 'lcfirst');
$smarty->registerPlugin('modifier', 'path', 'path');
$smarty->registerPlugin('modifier', 'getOrderStatuses', 'getOrderStatuses');
$smarty->registerPlugin('modifier', 'getStatuses', 'getStatuses');
$smarty->registerPlugin('modifier', 'min', 'min');
} else {
if ($translate) {
$languageContext = Contexts::get(LanguageContext::class);
$smarty = new SmartyML($languageContext->getActiveId());
} else {
$smarty = new Smarty();
}
$smarty->setMergeCompiledIncludes(true);
$smarty->setErrorReporting(E_ALL & ~(E_WARNING | E_NOTICE | E_STRICT | E_USER_DEPRECATED));
$smarty->muteUndefinedOrNullWarnings();
}
require_once './engine/bundles/KupShop/KupShopBundle/Util/Smarty/php7_functions.php';
// HACK: Short {t} tag does not compile well (leaves original translation in place)
// this transforms short call to call with parameter
// HACK: For BC use modified versions of some PHP functions that ignores errors
$smarty->registerFilter('pre', function ($source, Smarty_Internal_Template $template) {
$source = preg_replace('/\b(?<!\.)(in_array|array_values|array_filter|join|array_column|array_key_last|array_key_first|array_key_exists|array_keys|array_merge)\s*\(/', 'bc_$1(', $source);
return str_replace(['{t}'], ['{t 1=1}'], $source);
});
$compileDir = $cfg['Path']['data'].'tmp/templates';
if ($dir = getenv('CONTAINER_DIR')) {
$compileDir = realpath($cfg['Path']['web_root'])."/{$dir}/templates/";
}
$smarty->setCompileDir($compileDir)
->setCacheDir($compileDir)
->setTemplateDir([]);
$smarty->setCompileCheck(isProduction() ? Smarty::COMPILECHECK_OFF : Smarty::COMPILECHECK_ON);
if ($admin) {
$templates = [
'admin' => $cfg['Path']['admin'].'templates/',
];
$smartyPlugins = [
'../smarty_plugins/',
];
} else {
$templates = [
'web' => $cfg['Path']['smarty_tpl']['templates'],
];
$smartyPlugins = [
'smarty_plugins/',
];
}
if (isFunctionalTests()) {
$templates['test'] = './engine/tests/functional/templates/';
}
if (!$admin && findModule(\Modules::COMPONENTS)) {
$templates = [...$templates, 'twig_compat' => './engine/web/templates/twig_compat'];
}
try {
/** @var \KupShop\KupShopBundle\Util\System\BundleFinder $bundleFinder */
$bundleFinder = ServiceContainer::getService('kupshop.util_system.bundle_finder');
if ($admin) {
$templates = array_merge($templates, array_reverse($bundleFinder->getBundlesPath('Admin/templates')));
$smartyPlugins = array_merge($smartyPlugins, Mapping::mapKeys(array_reverse($bundleFinder->getBundlesPath('Admin/smarty_plugins')), function ($k, $v) { return [$k.'_admin', $v]; }));
$smartyPlugins = array_merge($smartyPlugins, array_reverse($bundleFinder->getBundlesPath('Resources/smarty_plugins')));
} else {
$templates = array_merge($templates, array_reverse($bundleFinder->getBundlesPath('Resources/templates')));
$smartyPlugins = array_merge($smartyPlugins, array_reverse($bundleFinder->getBundlesPath('Resources/smarty_plugins')));
}
} catch (Exception $e) {
// Ignore Symfony initialization errors to make less Sentry noise
}
if ($admin) {
$templates['shared'] = $cfg['Path']['shared_version'].'admin/templates/';
$smartyPlugins[] = $cfg['Path']['shared_version'].'admin/class/smarty_plugins';
$smartyPlugins[] = $cfg['Path']['shared_version'].'class/smarty_plugins/';
} else {
$templates['shared'] = $cfg['Path']['shared_version']."web/templates/{$cfg['Path']['smarty_tpl']['theme']}/";
$templates['common'] = $cfg['Path']['shared_version'].'web/common/templates/';
$smartyPlugins[] = $cfg['Path']['shared_version'].'class/smarty_plugins/';
}
$smarty->addTemplateDir($templates)
->addPluginsDir($smartyPlugins);
$smarty->debugging_ctrl = 'URL';
$smarty->escape_html = true;
$smarty->debug_tpl = 'engine/bundles/KupShop/KupShopBundle/Util/Smarty/smarty_debug.tpl';
if (getVal('SMARTY_DEBUG')) {
$smarty->force_compile = true;
}
unset($cfg['Connection']['password']);
unset($cfg['Connection']['host']);
unset($cfg['Connection']['user']);
unset($cfg['Admin']['Login']['User']);
unset($cfg['Admin']['Login']['Password']);
unset($cfg['Admin']['Login']['MasterPassword']);
if ($add_globals) {
if ($translate && !$admin) {
$cacheContext = Contexts::get(CacheContext::class);
$cacheKey = $cacheContext->getKey([CacheContext::TYPE_TEXT]);
$dbcfg = Settings::getFromCache($cacheKey);
} else {
$dbcfg = Settings::getDefault();
}
$configLoader = Config::get();
$smarty->assign([
'cfg' => &$configLoader,
'dbcfg' => &$dbcfg,
'ctrl' => &$GLOBALS['ctrl'],
'module' => ModulesWrapper::getInstance(),
]);
}
return $smarty;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function translate($key, $section = null, $silent = false, $isAdministration = null)
{
global $txt_str;
$translator = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Locale\PHPArrayTranslator::class);
$isAdministration = $isAdministration ?? isAdministration();
$lang = $translator->getLanguage($isAdministration);
static $languageTranslations = [];
if (!array_key_exists($lang, $languageTranslations)) {
$languageTranslations[$lang] = ($isAdministration) ? $txt_str : [];
}
if (empty($txt_str)) {
$txt_str = &$languageTranslations[$lang];
}
return $translator->translate($languageTranslations[$lang], $key, $section, $silent, $isAdministration);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function translate_template($key, $lang = null)
{
if (!findModule(\Modules::TRANSLATIONS) && !findModule(\Modules::TEMPLATE_TRANSLATIONS)) {
return $key;
}
if (!$lang) {
global $cfg;
$lang = getVal('language', $cfg['Lang'], 'czech');
}
// TODO: Symfony
return \KupShop\KupShopBundle\Util\Locale\TemplateTranslator::getService()->get($lang)->gettext($key);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
function getAdminUser(bool $forceUpdate = false)
{
static $user = null;
if (is_null($user) || $forceUpdate) {
global $cfg;
$legacyAdminCredentials = ServiceContainer::getService(LegacyAdminCredentials::class);
$user = false;
if ($legacyAdminCredentials->isLogged()) {
$adminID = $legacyAdminCredentials->getAdminID();
$user = LegacyAdminCredentials::getAdminById((int) $adminID);
}
}
return $user;
}
function getAdminID($superAdminValue = 0)
{
$user = getAdminUser();
if (getVal('superuser', $user, false)) {
return $superAdminValue;
}
return $user['id'] ?? null;
}
function isSuperuser()
{
$user = getAdminUser();
return getVal('superuser', $user, false);
}
function addUserEmail($email, $groups = [], $fields = ['figure' => 'N'], $confirmed = false)
{
if (empty($email)) {
return false;
}
return sqlGetConnection()->transactional(function () use ($email, $groups, $fields, $confirmed) {
$fields['email'] = $email;
$existing_user = sqlQueryBuilder()->select('get_news')->from('users')
->where('email=:email')->setParameter('email', $email)
->execute()->fetch();
$new_user = ($existing_user ? false : true);
if (!empty($fields['get_news'])) {
$newsletter = $fields['get_news'];
unset($fields['get_news']);
} else {
$newsletter = ($new_user ? 'N' : $existing_user['get_news']);
}
if (findModule(Modules::CURRENCIES) && $new_user) {
$currencyContext = Contexts::get(CurrencyContext::class);
$fields['currency'] = $currencyContext->getActiveId();
}
if (findModule(Modules::TRANSLATIONS) && $new_user) {
$languageContext = Contexts::get(LanguageContext::class);
$fields['id_language'] = $languageContext->getActiveId();
}
$qb = sqlQueryBuilder()->insert('users')->directValues($fields)->setValue('date_updated', 'NOW()');
$sql = $qb->getSQL().' ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), date_updated=NOW()';
sqlQuery($sql, $qb->getParameters(), $qb->getParameterTypes());
$user_id = sqlInsertID();
foreach ($groups as $group) {
sqlQuery('INSERT INTO '.getTableName('users_groups')." (name) VALUES ('{$group}')
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)");
$group_id = sqlInsertID();
sqlQuery('INSERT IGNORE INTO '.getTableName('users_groups_relations')." (id_group, id_user) VALUES ('{$group_id}', '{$user_id}')");
}
$userConsent = ServiceContainer::getService(\KupShop\UserBundle\Util\UserConsent::class);
$userConsent->updateNewsletter($user_id, $newsletter, $new_user, $confirmed);
return $user_id;
});
}
function isAdministration()
{
global $ctrl;
return getVal('admin', $ctrl, false);
}
function isDebug()
{
global $cfg;
return getVal('debug', $cfg) || getVal('wpj_debug');
}
function isDevelopment()
{
global $cfg;
return !empty($cfg['development']);
}
function isBeta()
{
if (isDevelopment()) {
return true;
}
if (!empty(getenv('STABLE_BETA'))) {
return true;
}
return false;
}
function isProduction()
{
return !isBeta();
}
function isStage()
{
return isBeta();
}
function isAutoDeploy()
{
return !empty(getenv('VIRTUAL_HOST'));
}
function isLocalDevelopment()
{
return !isAutoDeploy();
}
function isFunctionalTests()
{
return defined('TEST_SUITE') ? TEST_SUITE : false;
}
function isCacheEnabled()
{
return !getVal('skip_cache');
}
function isRunningOnCluster()
{
return getenv('KUPSHOP_ENV') === 'kube';
}
function isLive()
{
return Settings::getDefault()->eshop_live == 'Y';
}
function isFrontendTests(): bool
{
return (bool) getenv('FRONTEND_TESTS');
}
function isFrontend(): bool
{
return !isAdministration() && PHP_SAPI !== 'cli';
}
/**
* @deprecated Use \KupShop\CatalogBundle\Query\Search::searchFields
*
* @param $search string search term
* @param $fields array Definition of search fields
* 'field' => database field name
* 'match' => type of value matching. one of 'exact', 'left', 'right', 'both', 'numeric'
* 'order' => order by this field, if exact match, display first
*
* @return string[] Array containing keys 'where', 'data', 'order'
*
* Example:
* $fields = [
* ['field' => 'p.title', 'match' => 'both'],
* ['field' => 'p.short_descr', 'match' => 'exact'],
* ['field' => 'p.code', 'match' => 'left', 'order' => true],
* ];
* $search = get_search_query($search_term, $fields);
*/
function get_search_query($search, $fields, $operator = 'AND')
{
static $counter = 0;
// Limit search size
$search = substr(trim($search), 0, 100);
// Preprocess search terms
$words = preg_split('/[[:blank:]]+/', $search);
foreach ($words as &$word) {
// odstraneni znaku procento
$word = str_replace('%', '\\%', $word);
// odstraneni znaku PODTRZITKO
$word = str_replace('_', '\\_', $word);
// zmena znaku hvezdicka na procento
$word = str_replace('*', '%', $word);
// zmena znaku OTAZNIK na PODTRZITKO
$word = str_replace('?', '_', $word);
}
unset($word);
// Return non-existing search query
if (count($words) <= 0) {
return ['where' => '1=0', 'data' => []];
}
$keys = range($counter, $counter + count($words) - 1);
$words = array_combine($keys, $words);
$search_param = 'search_'.$counter;
// Prepare field search terms
$terms = [];
$order = [];
foreach ($fields as $field) {
if ($field['match'] == 'numeric') {
$terms[] = "{$field['field']} = :field__numeric";
} else {
$terms[] = "{$field['field']} LIKE :field__{$field['match']}";
}
if (!empty($field['order'])) {
$order[] = "{$field['field']} = :{$search_param} DESC";
}
}
// Generate data fields
$data = [$search_param => $search];
foreach ($words as $index => $word) {
$data["field_{$index}_numeric"] = is_numeric($word) ? $word : null; // Limit numeric to only numbers
$data["field_{$index}_exact"] = $word;
$data["field_{$index}_left"] = "{$word}%";
$data["field_{$index}_both"] = "%{$word}%";
$counter++;
}
// Generate whole query
$where = '('.join(') '.$operator.' (', array_map(function ($index) use ($terms) {
return '('.join(') OR (', array_map(function ($term) use ($index) {
return str_replace(':field__', ":field_{$index}_", $term);
}, $terms)).')';
}, array_keys($words))).')';
return ['where' => $where, 'data' => $data, 'order' => $order ? join(',', $order) : null];
}
/**
* @deprecated Use Decimal {remove|add}Vat, {remove|ddd}Discount
*/
function calcPrice($value, $vat = null, $discount = null, $force_return_decimal = true)
{
if (!is_a($value, 'Decimal')) {
$value = Decimal::fromString((string) $value);
}
// pricteni dane z ceny
if (!is_null($vat)) {
$vat_decimal = Decimal::fromFloat(abs((float) $vat))->add(Decimal::fromInteger(100))->div(Decimal::fromInteger(100));
if ($vat > 0) {
$value = $value->mul($vat_decimal);
} else {
$value = $value->div($vat_decimal);
}
}
if (!is_a($discount, 'Decimal')) {
$discount = Decimal::fromString((string) $discount);
}
// normalni sleva
if (!$discount->isZero()) {
$value = $value->sub($value->mul($discount)->div(toDecimal(100)));
}
return $force_return_decimal ? $value->value() : (string) $value->value();
}
function toDecimal($value)
{
return Decimal::ensureDecimal($value);
}
function formatEAN($ean)
{
return !empty($ean) ? sprintf('%013d', $ean) : $ean;
}
/**
* @param \KupShop\ContentBundle\Entity\Placeholder[] $placeholders
*/
function replacePlaceholders($str, $params, $callback = null, array $placeholders = [])
{
return preg_replace_callback('/{(.+?)}/', function ($matches) use ($placeholders, $params, $callback) {
if (isset($params[$matches[1]])) {
return $params[$matches[1]];
}
foreach ($placeholders as $placeholder) {
if ($placeholder->code == $matches[1]) {
return $placeholder->getValue();
}
}
if ($callback) {
return call_user_func($callback, $matches[1]);
}
}, $str);
}
/**
* @deprecated Unused, delete
*/
function implodeKeyValue($array, $keyValueGlue, $itemGlue)
{
return implode($itemGlue, array_map(function ($key, $value) use ($keyValueGlue) {
return $key.$keyValueGlue.$value;
}, array_keys($array), $array));
}
function explodeFlags($flags)
{
if (is_string($flags)) {
$flags = array_flip(explode(',', $flags));
}
$flags = $flags ?? [];
foreach ($flags as &$flag) {
$flag = '1';
}
return $flags;
}
function logged()
{
global $ctrl;
return $ctrl['logged'];
}
/**
* @deprecated Use SecurityTrait
*/
function loggedRedirect()
{
if (!logged()) {
redirection('LOGIN');
}
}
function f_prop($objectProperty)
{
return function ($object) use ($objectProperty) {
return $object->{$objectProperty};
};
}
function f_field($arrayField)
{
return function (array $array) use ($arrayField) {
return $array[$arrayField];
};
}
function f_call($objectMethod)
{
return function ($object) use ($objectMethod) {
return call_user_func([$object, $objectMethod]);
};
}
function f_valueIs($value)
{
return function ($toFilter) use ($value) {
return $toFilter === $value;
};
}
function indexByMethod(array $arrayOfObjects, $objectMethodName)
{
return array_combine(array_map(f_call($objectMethodName), $arrayOfObjects), $arrayOfObjects);
}
function indexByField(array $arrayOfArrays, $arrayField)
{
return array_combine(array_map(f_field($arrayField), $arrayOfArrays), $arrayOfArrays);
}
if (!class_exists('JsonException')) {
class JsonException extends RuntimeException
{
}
}
/**
* Calls json_decode(), but throws exception on failure.
*/
function json_decode_strict($json, $assoc = false, $depth = 512, $options = 0)
{
$result = json_decode($json, $assoc, $depth, $options);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new JsonException(/* json_last_error_msg() */
'Error decoding JSON', json_last_error());
}
return $result;
}
/**
* @return array
*/
function array_merge_strict(array $array1, array $array2)
{
foreach ($array2 as $key2 => $value2) {
if (
isset($array1[$key2])
// is_array() is slow. `(array) $var === $var` is much faster
&& (array) $array1[$key2] === $array1[$key2]
&& (array) $value2 === $value2
) {
$value2 = array_merge_strict($array1[$key2], $value2);
}
$array1[$key2] = $value2;
}
return $array1;
}
/**
* @return \Symfony\Component\DependencyInjection\ContainerInterface
*
* @deprecated Use \KupShop\KupShopBundle\Util\Compat\ServiceContainer instead
*/
function getSymfonyContainer()
{
return ServiceContainer::getContainer();
}
/**
* @param $service string #Service to get
*
* @return object
*
* @deprecated Use \KupShop\KupShopBundle\Util\Compat\ServiceContainer instead
*/
function getSymfonyService($service)
{
return ServiceContainer::getService($service);
}
/**
* @see UrlGeneratorInterface
*
* @param string $name #Route
* @param array $parameters
* @param int $referenceType
*/
function path($name, $parameters = [], $referenceType = Router::ABSOLUTE_PATH)
{
/** @var Router $router */
$router = ServiceContainer::getService('router');
if ($referenceType == Router::ABSOLUTE_URL) {
if (isLocalDevelopment() && !isFunctionalTests()) {
$router->getContext()
->setHost('www.kupshop.local')
->setScheme('https');
} else {
$domainContext = ServiceContainer::getService(\KupShop\KupShopBundle\Context\DomainContext::class);
$router->getContext()
->setHost($domainContext->getActiveId())
->setScheme('https');
}
}
return call_user_func_array([$router, 'generate'], func_get_args());
}
function loadBundlesAdmin($path)
{
/** @var \KupShop\KupShopBundle\Util\System\BundleFinder $bundleFinder */
$bundleFinder = ServiceContainer::getService('kupshop.util_system.bundle_finder');
$files = $bundleFinder->getExistingBundlesPath('Admin/'.$path);
uasort($files, function ($a, $b) {
// bundles/KupShop soubory davam az na konec pole, aby na prvnich mistech byyl shop a external bundly
return (strpos($a, 'bundles/KupShop') !== false ? 1 : 0) <=> (strpos($b, 'bundles/KupShop') !== false ? 1 : 0);
});
return reset($files);
}
function loadBundles($path)
{
/** @var \KupShop\KupShopBundle\Util\System\BundleFinder $bundleFinder */
$bundleFinder = ServiceContainer::getService('kupshop.util_system.bundle_finder');
$files = $bundleFinder->getExistingBundlesPath($path);
uasort($files, function ($a, $b) {
// bundles/KupShop soubory davam az na konec pole, aby na prvnich mistech byyl shop a external bundly
return (strpos($a, 'bundles/KupShop') !== false ? 1 : 0) <=> (strpos($b, 'bundles/KupShop') !== false ? 1 : 0);
});
return reset($files);
}
function getShopUniqueName()
{
return Config::get()['Connection']['database'];
}
function getUserKey()
{
$userKey = Cart::getCartID();
return $userKey;
}
/**
* @param string $message User message to display
* @param string $severity One of success, info, warning, danger
* @param array $data Data specific to this message
*
* @return bool
*/
function addUserMessage($message, $severity = 'warning', $data = [])
{
/** @var \Symfony\Component\HttpFoundation\Session\Session $session */
$session = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService('session');
$message = ['text' => $message, 'severity' => $severity];
if ($data) {
$session->getFlashBag()->add($severity, array_merge($message, $data));
} else {
$session->getFlashBag()->add($severity, $message);
}
return true;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/**
* @deprecated Use addActivityLog
*/
function writeDownActivity($text, $repeatMsgs = false, $robot = false)
{
$text = trim($text);
$text = stripTags($text);
$text = ucfirst($text);
addActivityLog(ActivityLog::SEVERITY_NOTICE, ActivityLog::TYPE_CHANGE, $text);
return true;
}
function addActivityLog(string $severity, string $type, string $message, ?array $data = [], ?array $tags = [])
{
$activityLog = ServiceContainer::getService(ActivityLog::class);
return $activityLog->addActivityLog($severity, $type, $message, $data, $tags);
}
/**
* @return false|string
*/
function increaseMemoryLimit(int $MB)
{
$memoryLimit = ini_get('memory_limit');
$memoryLimitUnit = substr($memoryLimit, -1, 1);
$memoryLimitValue = (int) substr($memoryLimit, 0, -1);
switch ($memoryLimitUnit) {
case 'M': $memoryLimitValue += $MB;
break;
case 'K': $memoryLimitValue += $MB * 1024;
break;
case 'G': $memoryLimitValue += ceil($MB / 1024);
break;
}
return ini_set('memory_limit', $memoryLimitValue.$memoryLimitUnit);
}
function increaseMaxExecutionTime(int $seconds): int
{
$oldValue = ini_get('max_execution_time');
// unlimited
if ($oldValue === '0') {
return 0;
}
$newValue = ((int) $oldValue) + $seconds;
ini_set('max_execution_time', (string) $newValue);
return $newValue;
}
function getShopName()
{
return getenv('BRANCH') ?: 'no';
}
function translate_shop($key, $section = null, $silent = false)
{
if (!isAdministration()) {
return translate($key, $section, $silent, false);
}
$translator = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Locale\PHPArrayTranslator::class);
$lang = $translator->getShopLanguage();
static $shop_translations = [];
if (!array_key_exists($lang, $shop_translations)) {
$shop_translations[$lang] = [];
}
if (empty($shop_translations[$lang])) {
$shop_translations[$lang] = $translator->loadShopMainTranslations();
}
$translator->loadTranslations($shop_translations[$lang], $section, false, $translator->getShopLanguage());
return $translator->translate($shop_translations[$lang], $key, $section, $silent);
}
function redirection($URL, $typeOrPermanent = null)
{
if (isAdministration()) {
redirect($URL, $typeOrPermanent ?? 'header');
}
$typeOrPermanent ??= false;
if ($URL == 'NEXT') {
if (!empty($_GET['next'])) {
redirection($_GET['next']);
} else {
redirection('REFERER');
}
}
if ($URL == 'REFERER') {
if (!empty($_SERVER['HTTP_REFERER'])) {
$URL = $_SERVER['HTTP_REFERER'];
} else {
$URL = './';
}
}
if ($URL == 'REFRESH') {
$URL = $_SERVER['REQUEST_URI'];
} elseif ($URL == 'LOGIN') {
$request = SymfonyBridge::getCurrentRequest();
redirection(createScriptURL([
'URL' => 'launch.php',
's' => 'login',
'msg' => '1',
'url' => urlencode($request->getUri()),
'ESCAPE' => 'NO',
]));
} elseif ($URL == 'MODUL_NOT_FOUND') {
// zalogovat chybu
// logError(__FILE__, __LINE__, "Presmerovani MODUL NOT FOUND referer: ".$GLOBALS['HTTP_REFERER'], false);
$URL = createScriptURL([
'URL' => 'launch.php',
's' => 'error404',
]);
} elseif ($URL == 'INDEX') {
$URL = createScriptURL([
'URL' => 'launch.php',
's' => 'index',
]);
} elseif ($URL == 'REWRITE') {
$URL = createScriptURL([
'URL' => 'launch.php',
's' => 'error404',
'search' => $_SERVER['REQUEST_URI'],
]);
}
// pridat absolutni adresovani
if (!preg_match('@^([a-z]{3,6}://|/|\./)@', $URL)) {
$URL = preg_replace('@^/*@', '', $URL);
$URL = $GLOBALS['cfg']['Addr']['rel'].$URL;
}
if (defined('TEST_SUITE')) {
throw new Exception("Redirecting to {$URL}: permament: {$typeOrPermanent}");
}
if ($typeOrPermanent) {
throw new \KupShop\KupShopBundle\Exception\PermanentRedirectException($URL);
} else {
throw new \KupShop\KupShopBundle\Exception\RedirectException($URL);
}
}
// Not using class.Modules because that would require autoloader
if (!findModule('components')) {
spl_autoload_register('autoload');
}