3632 lines
112 KiB
PHP
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(' ', ' ', $String);
|
|
$String = str_replace('"', '"', $String);
|
|
$String = str_replace('>', '>', $String);
|
|
$String = str_replace('<', '<', $String);
|
|
$String = str_replace('&', '&', $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');
|
|
}
|