first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View File

@@ -0,0 +1,171 @@
<?php
global $cfg;
// define('SACY_TRANSFORMER_SASS', 1);
define('SACY_DEBUG_TOGGLE', 'SMARTY_DEBUG');
define('SACY_QUERY_STRINGS', 'force-handle');
define('SACY_WRITE_HEADERS', false);
define('SACY_TRANSFORMER_FONTICONS', '/usr/local/bin/fontcustom');
define('ASSET_COMPILE_OUTPUT_DIR', $cfg['Path']['data'].'tmp/cache/');
define('ASSET_COMPILE_URL_ROOT', '/'.$cfg['Path']['data'].'tmp/cache/');
$_SERVER['DOCUMENT_ROOT'] = './';
if (!defined('____SACY_BUNDLED')) {
include_once $cfg['Path']['shared_class'].'sacy/sacy.php';
include_once $cfg['Path']['shared_class'].'sacy/phpsass.php';
include_once $cfg['Path']['shared_class'].'sacy/fragment-cache.php';
}
if (!(defined('ASSET_COMPILE_OUTPUT_DIR') && defined('ASSET_COMPILE_URL_ROOT'))) {
throw new sacy\Exception('Failed to initialize because path configuration is not set (ASSET_COMPILE_OUTPUT_DIR and ASSET_COMPILE_URL_ROOT)');
}
function smarty_block_asset_compile($params, $content, &$template, &$repeat)
{
if (!$repeat) {
// don't shoot me, but all tried using the dom-parser and removing elements
// ended up with problems due to the annoying DOM API and braindead stuff
// like no getDocumentElement() or getElementByID() not working even though
// loadHTML clearly knows that the content is in fact HTML.
//
// So, let's go back to good old regexps :-)
$cfg = new sacy\Config($params);
if ($cfg->getDebugMode() == 1) {
return $content;
}
// Cache whole compile output
$cache_key = 'sacy-cache-'.md5($content);
if ($cfg->getDebugMode() == 0) {
$patched_content = getCache($cache_key);
if ($patched_content) {
return $patched_content;
}
}
$tag_pattern = '#\s*<\s*T(?:\s+(.*))?\s*(?:/>|>(.*)</T>)\s*#Uims';
$tags = [];
$aindex = 0;
// first assembling all work. The idea is that, if sorted by descending
// location offset, we can selectively remove tags.
//
// We'll need that to conditionally handle tags (like jTemplate's
// <script type="text/html" that should remain)
foreach (['link', 'style', 'script'] as $tag) {
$p = str_replace('T', preg_quote($tag), $tag_pattern);
if (preg_match_all($p, $content, $ms, PREG_OFFSET_CAPTURE)) {
foreach ($ms[1] as $i => $m) {
$tags[] = [
'tag' => $tag,
'attrdata' => $m[0],
'index' => $ms[0][$i][1],
'tagdata' => $ms[0][$i][0],
'content' => $ms[2][$i][0] ?? null,
'page_order' => $aindex++,
];
}
}
}
// now sort task list by descending location offset
usort($tags, function ($a, $b) {
if ($a['index'] == $b['index']) {
return 0;
}
return ($a['index'] < $b['index']) ? 1 : -1;
});
$ex = new sacy\WorkUnitExtractor($cfg);
$work_units = $ex->getAcceptedWorkUnits($tags);
$renderer = new sacy\CacheRenderer($cfg, $_SERVER['SCRIPT_FILENAME']);
$patched_content = $content;
$render = [];
$category = function ($work_unit) {
return implode('', [$work_unit['group'], $work_unit['tag'], (bool) $work_unit['file']]);
};
$curr_cat = $work_units ? $category($work_units[0]) : null;
$entry = null;
foreach ($work_units as $i => $entry) {
$cg = $category($entry);
// the moment the category changes, render all we have so far
// this makes it IMPERATIVE to keep links of the same category
// together.
if ($curr_cat != $cg || ($cfg->getDebugMode() == 3 && $i > 0 && $renderer->allowMergedTransformOnly($work_units[$i - 1]['tag']) && count($render))) {
$render_order = array_reverse($render);
$res = $renderer->renderWorkUnits($work_units[$i - 1]['tag'], $work_units[$i - 1]['group'], $render_order);
if ($res === false) {
// rendering failed.
// because we don't know which one, we just enter emergency mode
// and return the initial content unharmed:
return $content;
}
// add rendered stuff to patched content
$m = null;
foreach ($render as $r) {
if ($m == null) {
$m = $r['position'];
}
if ($r['position'] < $m) {
$m = $r['position'];
}
// remove tag
$patched_content = substr_replace($patched_content, '', $r['position'], $r['length']);
}
// splice in replacement
$patched_content = substr_replace($patched_content, $res, $m, 0);
$curr_cat = $cg;
$render = [$entry];
} else {
$render[] = $entry;
}
}
$render_order = array_reverse($render);
$res = '';
if ($work_units) {
$res = $renderer->renderWorkUnits($entry['tag'], $entry['group'], $render_order);
if ($res === false) {
// see last comment
return $content;
}
}
$m = 0;
foreach ($render as $r) {
if ($m == null) {
$m = $r['position'];
}
if ($r['position'] < $m) {
$m = $r['position'];
}
// remove tag
$patched_content = substr_replace($patched_content, '', $r['position'], $r['length']);
}
$patched_content = substr_replace($patched_content, $res, $m, 0);
if ($block_ref = $cfg->get('block_ref')) {
$sacy = $template->smarty->getTemplateVars('sacy') ?: [];
$rendered_assets = $sacy['rendered_assets'] ?: [];
$rendered_assets[$block_ref] = array_merge(
$rendered_assets[$block_ref] ?: [],
$renderer->getRenderedAssets()
);
$sacy['rendered_assets'] = $rendered_assets;
$template->smarty->assign('sacy', $sacy);
}
// Save content to cache
setCache($cache_key, $patched_content);
return $patched_content;
}
}

View File

@@ -0,0 +1,30 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* File: block.change_currency.php
* Type: block
* Name: change_currency
* Purpose: Override active currency for content inside block
* -------------------------------------------------------------
*/
function smarty_block_change_currency($params, $content, Smarty_Internal_Template $template, &$repeat)
{
// Initial call
if ($repeat) {
if (!array_key_exists('currency', $params)) {
user_error('Block change_currency: Missing parameter "currency"');
$params['currency'] = 'CZK';
}
changeCurrency($params['currency']);
}
// Ending call
if (!$repeat) {
changeCurrency();
return $content;
}
}

View File

@@ -0,0 +1,16 @@
<?php
function smarty_block_change_translations_domain($params, $content, Smarty_Internal_Template &$template, &$repeat)
{
// Initial call
if ($repeat) {
Smarty::$global_tpl_vars['TRANSLATIONS_DOMAIN'][] = $params['domain'];
}
// Ending call
if (!$repeat) {
array_pop(Smarty::$global_tpl_vars['TRANSLATIONS_DOMAIN']);
return $content;
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* File: block.ifrights.php
* Type: block
* Name: ifrights
* Purpose: Check user rights
* -------------------------------------------------------------
*/
function smarty_block_ifrights($params, $content, Smarty_Internal_Template $template, &$repeat)
{
if (!isset($params['rights'])) {
throw new InvalidArgumentException('Parameter rights is required');
}
if (!$repeat) {
if (UserRights::hasRights($params['rights'], $params['specific'] ?? '')) {
return $content;
}
}
return '';
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* Smarty Internal Plugin Compile extend
* Compiles the {extends} tag.
*
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile extend Class.
*/
class Smarty_Compiler_Extends_Parent extends Smarty_Internal_Compile_Extends
{
public function getAttributes($compiler, $attributes)
{
return [
'file' => $this->getParent($compiler, $attributes),
];
}
protected function getParent(object $compiler, array $attributes)
{
$_template = $compiler->template;
$source = $compiler->template->source;
$bundle = '';
if (!$bundle) {
if ($source->smarty->_current_file === null && $_template) {
$filePath = $_template->source->filepath;
} else {
$filePath = $source->smarty->_current_file;
}
$directories = $source->smarty->getTemplateDir();
foreach ($directories as $dir_bundle => $_directory) {
if (\KupShop\KupShopBundle\Util\StringUtil::startsWith($filePath, $_directory)) {
$bundle = $dir_bundle;
break;
}
}
if (!$bundle) {
throw new \Exception('Cannot detect current bundle');
}
}
$current_file = preg_replace('/\[(.*)\]/i', '', $_template->source->name);
$directories = $source->smarty->getTemplateDir();
$found = false;
foreach ($directories as $dir_bundle => $_directory) {
if (!$found) {
if ($bundle == $dir_bundle) {
$found = true;
}
} else {
$_filepath = $_directory.$current_file;
// TODO: chybejici metoda fileExists
// if ($this->fileExists($source, $_filepath))
if (file_exists($_filepath)) {
return "'[{$dir_bundle}]{$current_file}'";
}
}
}
throw new \Exception('Extended template doesn\'t found!');
}
}

View File

@@ -0,0 +1,103 @@
<?php
/**
* Class Smarty_Compiler_Ifmodule.
*
* Examples:
* {ifmodule "review"}blablabla{/ifmodule}
*/
class Smarty_Compiler_Ifmodule extends Smarty_Internal_CompileBase
{
public $optional_attributes = ['_any'];
public $shorttag_order = ['module'];
/**
* @var Smarty_Internal_SmartyTemplateCompiler
*/
private $compiler;
/**
* @param $compiler Smarty_Internal_SmartyTemplateCompiler
*
* @return string
*/
public function compile($args, $compiler)
{
$_args = $this->getAttributes($compiler, $args);
$this->openTag($compiler, 'ifmodule');
$key = trim($_args['module'], "\"'");
$parts = explode('__', $key);
$module = $parts[0];
$submodule = getVal(1, $parts);
if (\Modules::check($module, $submodule)) {
return '';
}
eat_code($compiler, $this);
return '';
}
}
class Smarty_Compiler_Elsemodule extends Smarty_Internal_CompileBase
{
public $required_attributes = [];
public $optional_attributes = [];
public $shorttag_order = [];
public function compile($args, $compiler)
{
return '<?php /*';
}
}
class Smarty_Compiler_Ifmoduleclose extends Smarty_Internal_CompileBase
{
public $required_attributes = [];
public $optional_attributes = [];
public $shorttag_order = [];
public function compile($args, $compiler)
{
$this->closeTag($compiler, ['ifmodule']);
return '<?php /**/ ?>';
}
}
function eat_code($compiler, $tag)
{
/** @var Smarty_Internal_Templatelexer $lexer */
$lexer = $compiler->parser->lex;
$counter = 1;
while (true) {
$last = $lexer->value;
if ($lexer->yylex() === false) {
return '';
}
$ifModule = strcasecmp($lexer->value, 'ifmodule') === 0;
if (mb_strtolower($lexer->value) == '{/ifmodule}') {
$counter--;
}
if ($ifModule) {
$counter++;
}
$elseModule = strcasecmp(mb_strtolower($lexer->value), '{elsemodule}') === 0;
if ($elseModule && $counter == 1) {
break;
}
if (mb_strtolower($lexer->value) == '{/ifmodule}' && $counter == 0) {
$tag->closeTag($compiler, ['ifmodule']);
break;
}
}
}

View File

@@ -0,0 +1,245 @@
<?php
/**
* Switch statement plugin for smarty.
* This smarty plugin provides php switch statement functionality in smarty tags.
* To install this plugin drop it into your smarty plugins folder. You will also need to manually
* load the plugin sot hat all the hooks are registered properly. Add the following line after
* you load smarty and create an instance of it in your source code.
*
* <code>
* $this->smartyObj->loadPlugin('smarty_compiler_switch');
* </code>
*
* @author Jeremy Pyne <jeremy.pyne@gmail.com>
* - Donations: Accepted via PayPal at the above address.
* - Updated: 01/25/2016 - Version 3.7
* - File: smarty/plugins/compiler.switch.php
* - Licence: CC:BY/NC/SA http://creativecommons.org/licenses/by-nc-sa/3.0/
*
* - Updates
* Version 2:
* Changed the break attribute to cause a break to be printed before the next case, instead of before this
* case. This way makes more sense and simplifies the code. This change in incompatible with code in
* from version one. This is written to support nested switches and will work as expected.
* Version 2.1:
* Added {/case} tag, this is identical to {break}.
* Version 3:
* Updated switch statment to support Smarty 3. This update is NOT backwards compatible but the old version is still maintained.
* Version 3.1:
* Added a prefilter to re-enable the shorthand {switch $myvar} support. To use the shorthand form you will need to add the following line to your code.
* $smarty->loadPlugin('smarty_compiler_switch');
* Version 3.2:
* Fixed a bug when chaining multiple {case} statements without a {break}.
* Version 3.5:
* Updated to work with Smarty 3.0 release. (Tested and working with 3.0.5, no longer compatible with 3.0rcx releases.)
* Version 3.6:
* Updated to work with Smarty 3.1 release. (Tested and working on 3.1.3, No longer compatible with 3.0 releases.)
* Version 3.7:
* Updated to work with Smarty 3.1.28 release. (Tested and working on 3.1.29,)
*
* - Bugs/Notes:
*/
// $smarty->loadPlugin('smarty_compiler_switch');
$smarty->registerFilter('post', 'smarty_postfilter_switch');
#[AllowDynamicProperties]
class Smarty_Compiler_Switch extends Smarty_Internal_CompileBase
{
public $required_attributes = ['var'];
public $optional_attributes = [];
public $shorttag_order = ['var'];
/**
* Start a new switch statement.
* A variable must be passed to switch on.
* Also, the switch can only directly contain {case} and {default} tags.
*
* @return string
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
$attr = $this->getAttributes($compiler, $args);
$_output = '';
$this->openTag($compiler, 'switch', [$compiler->tag_nocache]);
if (is_array($attr['var'])) {
$_output .= '<?php if (!isset($_smarty_tpl->tpl_vars['.$attr['var']['var'].'])) $_smarty_tpl->tpl_vars['.$attr['var']['var'].'] = new Smarty_Variable;';
$_output .= 'switch ($_smarty_tpl->tpl_vars['.$attr['var']['var'].']->value = '.$attr['var']['value'].'){?>';
} else {
$_output .= '<?php switch ('.$attr['var'].'){?>';
}
return $_output;
}
}
#[AllowDynamicProperties]
class Smarty_Compiler_Case extends Smarty_Internal_CompileBase
{
public $required_attributes = ['value'];
public $optional_attributes = ['break'];
public $shorttag_order = ['value', 'break'];
/**
* Print out a case line for this switch.
* A condition must be passed to match on.
* This can only go in {switch} tags.
* If break is passed, a {break} will be rendered before the next case.
*
* @return string
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
$attr = $this->getAttributes($compiler, $args);
$_output = '';
list($last_tag, $last_attr) = $this->compiler->_tag_stack[count($this->compiler->_tag_stack) - 1];
if ($last_tag == 'case') {
list($break, $compiler->tag_nocache) = $this->closeTag($compiler, ['case']);
if ($last_attr[0]) {
$_output .= '<?php break;?>';
}
}
$this->openTag($compiler, 'case', [isset($attr['break']) ? $attr['break'] : false, $compiler->tag_nocache]);
if (is_array($attr['value'])) {
$_output .= '<?php if (!isset($_smarty_tpl->tpl_vars['.$attr['value']['var'].'])) $_smarty_tpl->tpl_vars['.$attr['value']['var'].'] = new Smarty_Variable;';
$_output .= 'case $_smarty_tpl->tpl_vars['.$attr['value']['var'].']->value = '.$attr['value']['value'].':?>';
} else {
$_output .= '<?php case '.$attr['value'].':?>';
}
return $_output;
}
}
#[AllowDynamicProperties]
class Smarty_Compiler_Default extends Smarty_Internal_CompileBase
{
public $required_attributes = [];
public $optional_attributes = ['break'];
public $shorttag_order = ['break'];
/**
* Print out a default line for this switch.
* This can only go in {switch} tags.
* If break is passed, a {break} will be rendered before the next case.
*
* @return string
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
$attr = $this->getAttributes($compiler, $args);
$_output = '';
list($last_tag, $last_attr) = $this->compiler->_tag_stack[count($this->compiler->_tag_stack) - 1];
if ($last_tag == 'case') {
list($break, $compiler->tag_nocache) = $this->closeTag($compiler, ['case']);
if ($last_attr[0]) {
$_output .= '<?php break;?>';
}
}
$this->openTag($compiler, 'case', [isset($attr['break']) ? $attr['break'] : false, $compiler->tag_nocache]);
$_output .= '<?php default:?>';
return $_output;
}
}
#[AllowDynamicProperties]
class Smarty_Compiler_Break extends Smarty_Internal_CompileBase
{
public $required_attributes = [];
public $optional_attributes = [];
public $shorttag_order = [];
/**
* Print out a break command for the switch.
* This can only go inside of {case} tags.
*
* @return string
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
$attr = $this->getAttributes($compiler, $args);
list($break, $compiler->tag_nocache) = $this->closeTag($compiler, ['case']);
return '<?php break;?>';
}
}
#[AllowDynamicProperties]
class Smarty_Compiler_Caseclose extends Smarty_Internal_CompileBase
{
public $required_attributes = [];
public $optional_attributes = [];
public $shorttag_order = [];
/**
* Print out a break command for the switch.
* This can only go inside of {case} tags.
*
* @return string
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
$attr = $this->getAttributes($compiler, $args);
list($break, $compiler->tag_nocache) = $this->closeTag($compiler, ['case']);
return '<?php break;?>';
}
}
#[AllowDynamicProperties]
class Smarty_Compiler_Switchclose extends Smarty_Internal_CompileBase
{
public $required_attributes = [];
public $optional_attributes = [];
public $shorttag_order = [];
/**
* End a switch statement.
*
* @return string
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
$attr = $this->getAttributes($compiler, $args);
list($last_tag, $last_attr) = $this->compiler->_tag_stack[count($this->compiler->_tag_stack) - 1];
if ($last_tag == 'case' || $last_tag == 'default') {
list($break, $compiler->tag_nocache) = $this->closeTag($compiler, ['case']);
}
list($compiler->tag_nocache) = $this->closeTag($compiler, ['switch']);
return '<?php }?>';
}
}
/**
* Filter the template after it is generated to fix switch bugs.
* Remove any spaces after the 'switch () {' code and before the first case. Any tabs or spaces
* for layout would cause php errors witch this reged will fix.
*
* @param string $compiled
*
* @return string
*/
function smarty_postfilter_switch($compiled, Smarty_Internal_Template $template)
{
// Remove the extra spaces after the start of the switch tag and before the first case statement.
return preg_replace('/({ ?\?>)\s+(<\?php case)/', "$1\n$2", $compiled);
}

View File

@@ -0,0 +1,126 @@
<?php
/**
* {t}{/t} compile tags for Smarty WITHOUT translations.
*
* Examples:
* {t}Test{/t}
* {t promenna="prekladovy"}Testovaci {promenna} text{/t} => vygeneruje "Testovaci prekladovy text"
* {t escape=false}<b>test</b>{/t} => povolit HTML tagy ve vystupu
* {t count=$pocet plural="Products"}Produkt{/t} => "Produkt" pokud count=1, Produkty pokud 1 < count < 5, Produktů pokud count > 5
*/
class Smarty_Compiler_T extends Smarty_Internal_CompileBase
{
public $optional_attributes = ['_any'];
/**
* @var Smarty_Internal_SmartyTemplateCompiler
*/
private $compiler;
/**
* @param $compiler Smarty_Internal_SmartyTemplateCompiler
*
* @return string
*/
public function compile($args, $compiler)
{
$_args = $this->getAttributes($compiler, $args);
$this->compiler = $compiler;
$lexer = $compiler->parser->lex;
if ($lexer->value == '}') {
$lexer->yylex();
}
$term = '';
do {
$term .= $lexer->value;
$lexer->yylex();
} while ($lexer->value != '{/t}');
unset($_args['1']);
return $this->translate($term, $_args);
}
public function export_params($params)
{
return '['.
join(',',
array_map(
function ($name) use ($params) {
return "'{$name}' => {$params[$name]}";
},
array_diff(array_keys($params), ['nocache', 'domain', 'count', 'plural', 'plural5', 'escape'])
)
)
.']';
}
public function translate($text, $params)
{
if (empty($text)) {
return $text;
}
$defaults = [
'escape' => 'html',
'domain' => null,
];
$params = array_merge($defaults, $params);
switch ($params['escape']) {
case 'html':
$text = nl2br(htmlspecialchars($text));
break;
case 'javascript':
case 'js':
// javascript escape
$text = strtr($text, ['\\' => '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n', '</' => '<\/']);
break;
case 'url':
// url escape
$text = urlencode($text);
break;
}
// Can do partial static translation if parameters are present
$hasPlural = isset($params['count']) || isset($params['plural']);
$hasParams = array_diff(array_keys($params), ['nocache', 'domain', 'escape']);
if ($hasPlural || $hasParams) {
// Do plural form translation
if ($hasPlural) {
$plural = getVal('plural', $params, $text);
$plural5 = getVal('plural5', $params, $plural);
$text = str_replace("'", "\\'", $text);
$text = "(({$params['count']}) == 1) ? '{$text}' : ((({$params['count']}) > 1 && ({$params['count']}) < 5) ? {$plural} : {$plural5})";
} else {
$text = "'".str_replace("'", "\\'", $text)."'";
}
if ($hasParams) {
$params = $this->export_params($params);
$text = "\KupShop\KupShopBundle\Util\StringUtil::replacePlaceholders({$text}, {$params})";
}
return "<?php echo {$text}; ?>";
}
return $text;
}
}
class Smarty_Compiler_Tclose extends Smarty_Internal_CompileBase
{
public $required_attributes = [];
public $optional_attributes = [];
public $shorttag_order = [];
public function compile($args, $compiler)
{
return '';
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* Class Smarty_Compiler_Webpack.
*
* Examples:
* {webpack file="icons.css"} => "Vygeneruje absolutní cesku k souboru z manifest.json"
*/
class Smarty_Compiler_Webpack extends Smarty_Internal_CompileBase
{
public $optional_attributes = ['_any'];
public string $manifestLocation = __DIR__.'../../../../shop/web/build/manifest.json';
public string $prefixPath = 'web/build/';
/**
* Triggruje error když během buildu dojde k chybě.
*/
private function triggerError(string $title): void
{
trigger_error($title, E_USER_ERROR);
}
/**
* @param $compiler Smarty_Internal_SmartyTemplateCompiler
*
* @return string
*/
public function compile($args, $compiler)
{
$_args = $this->getAttributes($compiler, $args);
$manifest = $this->parseManifest();
if ($manifest === null) {
$this->triggerError("Manifest.json file does not exists in location {$this->manifestLocation}");
}
$file = $_args['file'] ?? null;
if ($file === null) {
$this->triggerError("Parameter file in macro {webpack} is required. \n For example: {webpack file='example.css'}");
}
$file = str_replace(["'", '"'], '', $file);
$text = $manifest[$this->prefixPath.$file] ?? null;
if ($text === null) {
$keys = array_map(fn ($v) => substr($v, strlen($this->prefixPath)), array_keys($manifest));
$this->triggerError("File: {$text} does not exists. Compiler counts with default prefix 'web/build/'. Select valid one: \n".implode("\n", $keys));
}
return $text;
}
public function parseManifest(): ?array
{
$file = file_get_contents($this->manifestLocation);
return $file === false ? null : json_decode($file, true);
}
}

View File

@@ -0,0 +1,63 @@
<?php
function array_remove(&$array, $key, $default = null)
{
$value = getVal($key, $array, $default);
unset($array[$key]);
return $value;
}
function smarty_function_admin_url($params, &$smarty)
{
global $cfg;
$adminUrl = trim($cfg['Path']['admin'], '/');
$url = array_remove($params, 'url', $adminUrl.'/launch.php');
if (array_remove($params, 'absolute')) {
$url = $cfg['Addr']['full'].$url;
} else {
$url = $cfg['Addr']['rel'].$url;
}
$s = array_remove($params, 's');
if (!$s) {
$type = array_remove($params, 'type');
if (empty($type)) {
throw new InvalidArgumentException("Missing parameter 'type' in smarty function 'admin_url'!");
}
switch ($type) {
case 'user':
case 'users':
$s = 'users';
$email = array_remove($params, 'email');
if ($email) {
$user = sqlFetchAssoc(sqlQueryBuilder()->select('id')
->from('users')
->where(\Query\Operator::equals(['email' => $email]))
->execute());
if ($user) {
$params['ID'] = $user['id'];
}
}
break;
case 'order':
case 'orders':
$s = 'orders';
break;
default:
$s = $type;
}
if (empty($params['acn'])) {
$params['acn'] = 'edit';
}
}
$params = ['s' => "{$s}.php"] + $params;
return $url.'?'.http_build_query($params);
}

View File

@@ -0,0 +1,10 @@
<?php
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function smarty_function_asset($params, &$smarty)
{
$packages = ServiceContainer::getService('assets.packages');
return $packages->getPackage('webpack')->getUrl($params['url']);
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_product_total_discount
* Purpose: returns product discount (% sleva, nebo % rozdíl mezi škrtlou cenou a prodejní cenou, podle toho co je vyšší),
* priceOriginal (cena před slevou nebo škrtlá cena, podle toho co je vyšší)
* -------------------------------------------------------------
*/
use KupShop\CatalogBundle\Util\Product\CalculateProductDiscountUtil;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function smarty_function_calc_product_discount($params, &$smarty)
{
if (!isset($params['product'])) {
user_error('calc_product_discount: parametr "product" je povinný.');
}
static $calculateProductDiscountUtil;
if (!$calculateProductDiscountUtil) {
/** @var CalculateProductDiscountUtil $calculateProductDiscountUtil */
$calculateProductDiscountUtil = ServiceContainer::getService(CalculateProductDiscountUtil::class);
}
$result = $calculateProductDiscountUtil->calculate($params);
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,35 @@
<?php
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\System\UrlFinder;
function smarty_function_encore_entry_link_tags($params, &$smarty)
{
if (empty($params['entry'])) {
trigger_error("encore_entry_link_tags: missing 'entry' parameter");
return '';
}
$defaults = [
'package' => null,
'build' => '_default',
];
$params = array_merge($defaults, $params);
static $renderer = null;
static $urlFinder = null;
if (is_null($renderer)) {
$urlFinder = ServiceContainer::getService(UrlFinder::class);
$renderer = ServiceContainer::getService('webpack_encore.tag_renderer');
}
// Package "cdn" serves assets from configured CDN prefix
if ($urlFinder->hasCDN()) {
$params['package'] = 'cdn';
}
return $renderer->renderWebpackLinkTags($params['entry'], $params['package'], $params['build']);
}

View File

@@ -0,0 +1,45 @@
<?php
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\System\UrlFinder;
function smarty_function_encore_entry_script_tags($params, &$smarty)
{
if (empty($params['entry'])) {
trigger_error("encore_entry_script_tags: missing 'entry' parameter");
return '';
}
$defaults = [
'package' => null,
'build' => '_default',
];
$params = array_merge($defaults, $params);
static $renderer = null;
static $urlFinder = null;
if (is_null($renderer)) {
$urlFinder = ServiceContainer::getService(UrlFinder::class);
$renderer = ServiceContainer::getService('webpack_encore.tag_renderer');
}
// Package "cdn" serves assets from configured CDN prefix
if ($urlFinder->hasCDN()) {
$params['package'] = 'cdn';
}
$params['extra_attr'] = [];
$dbcfg = Settings::getDefault();
if (!empty($dbcfg->analytics['cookiebot']['ID'])) {
$params['extra_attr']['data-cookieconsent'] = 'ignore';
}
$params['extra_attr']['defer'] = false;
return $renderer->renderWebpackScriptTags($params['entry'], $params['package'], $params['build'], $params['extra_attr']);
}

View File

@@ -0,0 +1,10 @@
<?php
function smarty_function_flush($params, $template)
{
echo ob_get_clean();
// flush();
ob_start();
return;
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {getAnalytics} plugin.
*
* Type: function<br>
* Name: url<br>
* Purpose: getAnalytics
*
* @param array $params parameters
* @param Smarty_Internal_Template $smarty
*
* @return string
*/
function smarty_function_getAnalytics($params, &$smarty)
{
global $dbcfg;
if (!empty($dbcfg['analytics'][$params['name']])) {
$analytics_dbcfg = array_filter($dbcfg['analytics'][$params['name']]);
} else {
$analytics_dbcfg = [];
}
if (!empty($analytics_dbcfg)) {
$smarty->assign(['analytics' => [$params['name'] => $dbcfg['analytics'][$params['name']]]]);
} else {
$smarty->assign(['analytics' => []]);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_slider
* Purpose: get a slider of known name or id
* -------------------------------------------------------------
*/
function smarty_function_get_active_category($params, &$smarty)
{
$category = null;
$breadcrumb = null;
$exact = false;
$returnNav = [];
extract($params);
if (empty($returnNav)) {
return;
}
$activeCategory = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\CatalogBundle\Util\ActiveCategory::class);
$result = [
'category' => $activeCategory->getCategory(),
'breadcrumb' => $activeCategory->findBreadcrumb($returnNav),
];
if (!empty($assign)) {
$smarty->assign($assign, $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_analytics_pagetype
* Purpose: get pagetype for google analytics
* -------------------------------------------------------------
*/
/**
* @param array $params
* @param Smarty $smarty
*
* @return array
*/
function smarty_function_get_analytics_pagetype($params, &$smarty)
{
if (empty($smarty->tpl_vars['view']->value) || !is_object($smarty->tpl_vars['view']->value)) {
return 'home';
}
$class = (new \ReflectionClass($smarty->tpl_vars['view']->value))->getShortName();
switch ($class) {
case 'CategoryView':
return 'category';
case 'SearchView':
return 'searchresults';
case 'ProductView':
return 'product';
case 'CartView':
return 'cart';
case 'OrderView':
if (getVal('status') == 1) {
return 'purchase';
}
// no break
default:
return 'other';
}
}

View File

@@ -0,0 +1,74 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_analytics_price
* Purpose: get prices for google analytics
* -------------------------------------------------------------
*/
/**
* @param array $params
* @param Smarty $smarty
*
* @return array
*/
function smarty_function_get_analytics_products($params, &$smarty)
{
if (empty($_GET['s'])) {
return '';
}
$prodids = [];
$item_group_ids = [];
switch ($_GET['s']) {
case 'product':
$prices = $params['body']['product']['price_array']['price_with_vat'];
$items_group_id = "['{$params['body']['product']['id']}']";
break;
case 'orderView':
$prices = toDecimal(0);
foreach ($params['body']['orderObj']['items'] as $item) {
if (!empty($item['id_product']) && !$item['value_with_vat']->isZero()) {
$prodids[] = $item['id_variation'];
$item_group_ids[] = $item['id_product'];
$prices = $prices->add($item['total_price']['value_with_vat']);
}
}
break;
case 'ordering':
foreach ($params['body']['cart']['products'] as $product) {
$item_group_ids[] = $product['id'];
$prodids[] = $product['id_variation'];
}
$prices = $params['body']['totalPriceWithVat'];
// no break
default:
}
$return = '';
if (!empty($prices)) {
$return .= "ecomm_totalvalue: '".str_replace(' ', '', roundPrice(unapplyCurrency($prices))->printValue(0))."',";
}
if (!empty($prodids)) {
$prodid = "['".join("','", $prodids)."']";
}
if (!empty($prodid)) {
$return .= "ecomm_prodid: {$prodid},";
}
if (!empty($item_group_ids)) {
$items_group_id = "['".join("','", $item_group_ids)."']";
}
if (!empty($items_group_id)) {
$return .= "item_group_id: {$items_group_id},";
}
return $return;
}

View File

@@ -0,0 +1,14 @@
<?php
function smarty_function_get_and_cache($params, Smarty_Internal_Template $template)
{
$key = 'get_and_cache_'.md5(join('-', $params));
$data = getCache($key, $found);
if (!$found) {
$data = json_decode(file_get_contents($params['url']), true);
setCache($key, $data, $params['ttl'] ?? 7200);
}
$template->assign($params['assign'], $data);
}

View File

@@ -0,0 +1,30 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_slider
* Purpose: get a slider of known name or id
* -------------------------------------------------------------
*/
use KupShop\ContentBundle\Util\ArticlesUtil;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
/**
* @param array $params
* @param Smarty $smarty
*
* @return array
*/
function smarty_function_get_articles($params, &$smarty)
{
$articleUtil = ServiceContainer::getService(ArticlesUtil::class);
$ret = $articleUtil->getArticles($params);
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $ret);
} else {
return $ret;
}
}

View File

@@ -0,0 +1,31 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_slider
* Purpose: get a slider of known name or id
* -------------------------------------------------------------
*/
/**
* @param array $params
* @param Smarty $smarty
*
* @return array
*/
function smarty_function_get_datetime($params, &$smarty)
{
$assign = null;
$value = 'now';
extract($params);
$ret = new DateTime($value);
if (!empty($assign)) {
$smarty->assign($assign, $ret);
} else {
return $ret;
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* @note If you need deliveries by delivery type or class name or id.
*
* @param id - filter deliveries by id
* @param type - filter deliveries by Delivery::$type
* @param class_name - filter deliveries by Delivery::$className
* @param figure - get only figure deliveries - default is true
*
* @return array|void
*/
function smarty_function_get_deliveries($params, &$smarty)
{
$deliveries = Delivery::getAll($params['figure'] ?? true);
if ($id = ($params['id'] ?? false)) {
$deliveries = array_filter($deliveries ?? [], function ($delivery) use ($id) {
return $delivery->id == $id;
});
}
if ($type = ($params['type'] ?? false)) {
$deliveries = array_filter($deliveries ?? [], function ($delivery) use ($type) {
return $delivery->getType() == $type;
});
}
if ($className = ($params['class_name'] ?? false)) {
$deliveries = array_filter($deliveries ?? [], function ($delivery) use ($className) {
return $delivery->getClassName() == $className;
});
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $deliveries);
} else {
return $deliveries;
}
}

View File

@@ -0,0 +1,82 @@
<?php
use KupShop\CatalogBundle\Entity\Wrapper\ProductWrapper;
use KupShop\ContentBundle\Entity\Wrapper\ProductUnifiedWrapper;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\OrderingBundle\Util\Delivery\DeliveryDatesService;
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
/**
* Return array with two items:
* - 'list' - List of deliveries. Each delivery has new property 'date'.
* - 'min' - Array of precomputed minimal values across the deliveries.
*
* @note If you need delivery dates of the variations, use tag `get_variations_delivery_dates`.
*
* @param product product that is used to restrict list of deliveries and delivery dates
* @param only_supported if true, deliveries are filtered by the restrictions of the shop settings and `product` properties (default: true)
* @param price price that is used to restrict list of deliveries
*
* @return array|void
*/
function smarty_function_get_delivery_dates($params, &$smarty)
{
/** @var DeliveryDatesService $deliveryDates */
$deliveryDates = ServiceContainer::getService(DeliveryDatesService::class);
$purchaseUtil = ServiceContainer::getService(PurchaseUtil::class);
$only_supported = true;
$product = null;
extract($params);
$purchaseState = null;
$productCollection = null;
/** @var Product $product */
if ($product) {
if ($product instanceof ProductWrapper) {
$product = $product->getObject();
}
if ($product instanceof ProductUnifiedWrapper) {
/** @var \KupShop\ContentBundle\Entity\ProductUnified $productUnified */
$productUnified = $product->getObject();
$product = $productUnified->getProduct();
if ($productUnified->getVariationId()) {
$product = new \Variation($productUnified->getId(), $productUnified->getVariationId());
$product->createFromDB();
}
}
$currencyContext = Contexts::get(CurrencyContext::class);
$purchaseState = $deliveryDates->initPurchaseState(
$product,
// price should be in active currency
PriceCalculator::convert(
$product->getProductPrice(),
$currencyContext->getActive()
)
);
$productCollection = $deliveryDates->initializeProductCollection($product, false);
}
if ($params['purchaseState'] ?? false) {
/** @var \KupShop\OrderingBundle\Entity\Purchase\PurchaseState $purchaseState */
$purchaseState = $params['purchaseState'];
}
$totalResult = $purchaseUtil->getShippingInfo($purchaseState, $productCollection, $only_supported);
if (!empty($assign)) {
$smarty->assign($assign, $totalResult);
} else {
return $totalResult;
}
}

View File

@@ -0,0 +1,19 @@
<?php
function smarty_function_get_delivery_dispatch_date($params, &$smarty)
{
if (empty($params['delivery'])) {
throw new InvalidArgumentException('Missing parameter \'delivery\'');
}
/** @var Delivery $delivery */
$delivery = $params['delivery'];
$dispatchDate = $delivery->getDispatchDate();
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $dispatchDate);
} else {
return $dispatchDate;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: getFormatedPrice
* Purpose: get formated price for google analytics
* -------------------------------------------------------------
*/
/**
* @param array $params
* @param Smarty $smarty
*
* @return array
*/
function smarty_function_get_formated_price($params, &$smarty)
{
if (empty($params['price'])) {
return '';
}
$params['price'] = unapplyCurrency($params['price']);
if (!empty($params['sub'])) {
$params['price'] = $params['price']->sub($params['sub']);
}
if ($params['price']->isZero()) {
return '0';
}
return str_replace(',', '.', str_replace(' ', '', $params['price']->printValue(2)));
}

View File

@@ -0,0 +1,19 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_free_delivery
* Purpose: returns minimum order price to get a free delivery.
* Example: {get_free_delivery assign=freeDelivery} {$freeDelivery|format_price}
* -------------------------------------------------------------
*/
function smarty_function_get_free_delivery($params, &$smarty)
{
$params['type'] = 'free_delivery';
$smarty->loadPlugin('Smarty_function_get_stats');
return smarty_function_get_stats($params, $smarty);
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_greeting
* Purpose: get a greeting for given name/surname
* -------------------------------------------------------------
*/
/**
* @param array $params
* @param Smarty $smarty
*
* @return array
*/
function smarty_function_get_greeting($params, &$smarty)
{
$name = null;
$surname = null;
$prioritize = 'name';
extract($params);
if (empty($name) && empty($surname)) {
echo 'Chybí jméno/příjmení';
}
$ret = User::getGreeting($name, $surname, $prioritize);
if (!empty($assign)) {
$smarty->assign($assign, $ret);
} else {
return $ret;
}
}

View File

@@ -0,0 +1,75 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_html_page
* Purpose: get HTML page of given: name, id or label
* -------------------------------------------------------------
*/
use KupShop\ContentBundle\Entity\Wrapper\PageWrapper;
use KupShop\ContentBundle\Util\MenuLinksPage;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use Query\Operator;
/**
* @param $smarty \Smarty
*
* @return string
*/
function smarty_function_get_html_page($params, &$smarty)
{
if (empty($params['name']) && empty($params['id']) && empty($params['label'])) {
return 'get_html_page: Have to specify one of parameters: id, name or label';
}
$menuLinkId = null;
if (isset($params['name']) && !$menuLinkId) {
$menuLinkId = findMenuLinkBySpec(Operator::equals(['name' => $params['name']]));
}
if (isset($params['id']) && is_numeric($params['id']) && !$menuLinkId) {
$menuLinkId = findMenuLinkBySpec(Operator::equals(['old_id_page' => $params['id']]));
}
if (isset($params['label']) && !$menuLinkId) {
$menuLinkId = findMenuLinkBySpec(Operator::equals(['code' => $params['label']]));
}
/** @var MenuLinksPage $menuLinksPage */
$menuLinksPage = ServiceContainer::getService(MenuLinksPage::class);
$pageWrapper = ServiceContainer::getService(PageWrapper::class);
if ($menuLinkId) {
$page = [];
if ($pageEntity = $menuLinksPage->getPage((int) $menuLinkId)) {
$page = $pageWrapper->setObject($pageEntity);
}
} else {
return 'Neexistuje stránka: '.print_r($params, true);
}
if (empty($params['assign'])) {
foreach ($page['blocks'] as $block) {
$firstBlockContent = $block['content'];
break;
}
return isset($firstBlockContent) ? $firstBlockContent : '';
}
$smarty->assign($params['assign'], $page);
return '';
}
function findMenuLinkBySpec($spec)
{
return sqlQueryBuilder()->select('id')
->from('menu_links')
->where($spec)
->execute()
->fetchColumn();
}

View File

@@ -0,0 +1,47 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_slider
* Purpose: get a slider of known name or id
* -------------------------------------------------------------
*/
use KupShop\ContentBundle\Util\InfoPanelLoader;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
/**
* @param array $params
* @param Smarty $smarty
*
* @return array
*/
function smarty_function_get_infopanel($params, &$smarty)
{
$assign = null;
$ret = false;
extract($params);
$infoPanelLoader = ServiceContainer::getService(InfoPanelLoader::class);
$infoPanel = $infoPanelLoader->loadInfoPanel($type ?? null);
if (str_contains($infoPanel['body'] ?? '', '{DOPRAVA_ZDARMA_OD}')) {
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$smarty->loadPlugin('Smarty_function_get_stats');
$freeDelivery = smarty_function_get_stats(['type' => 'free_delivery'], $smarty);
$infoPanel['body'] = str_replace('{DOPRAVA_ZDARMA_OD}', "{$freeDelivery->asInteger()} {$currencyContext->getActive()->getSymbol()}", $infoPanel['body']);
}
if (!empty($infoPanel)) {
$ret = $infoPanel;
$ret['text'] = $infoPanel['body'];
}
if (!empty($assign)) {
$smarty->assign($assign, $ret);
} else {
return $ret;
}
}

View File

@@ -0,0 +1,24 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_slider
* Purpose: get a slider of known name or id
* -------------------------------------------------------------
*/
function smarty_function_get_news($params, &$smarty)
{
$default = [
'count' => 5,
'section' => 'Novinky',
'section_id' => 2,
];
$params = array_merge($default, $params);
$smarty->loadPlugin('Smarty_function_get_articles');
return smarty_function_get_articles($params, $smarty);
}

View File

@@ -0,0 +1,65 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_product_info
* Purpose: returns various information about order
* -------------------------------------------------------------
*/
use KupShop\OrderingBundle\Util\Order\OrderInfo;
function smarty_function_get_order_info($params, &$smarty)
{
$type = null;
$id = null;
/** @var Order $order */
$order = null;
$result = null;
extract($params);
if (empty($type)) {
trigger_error("Chybějící parametr 'type'");
}
if (empty($id) && empty($order)) {
trigger_error("Chybějící parametr 'id' nebo 'order'");
}
if (empty($id)) {
$id = $order->id;
}
switch ($type) {
case 'conversion_sent':
if ($order->getData('conversion_sent')) {
$result = false;
} else {
$order->setData('conversion_sent', 1);
$result = true;
}
break;
case 'heurekaDisagree':
$result = $order->getData('heurekaDisagree');
break;
case 'getUsedCoupons':
if ($coupons = OrderInfo::getUsedCoupons($order)) {
$result = $coupons;
}
break;
default:
trigger_error("Neexistující 'type': {$type}");
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,39 @@
<?php
use KupShop\I18nBundle\Translations\ParametersListTranslation;
use KupShop\I18nBundle\Translations\ParametersTranslation;
function smarty_function_get_parameter_info($params, &$smarty)
{
if (empty($params['id'])) {
trigger_error("Chybějící parametr 'id'");
}
$result = sqlQueryBuilder()
->select('pa.*')
->from('parameters', 'pa')
->where(\Query\Operator::equals(['pa.id' => $params['id']]))
->andWhere(\Query\Translation::coalesceTranslatedFields(ParametersTranslation::class))
->execute()
->fetch();
$result['values'] = sqlFetchAll(sqlQueryBuilder()
->select('pl.*')
->from('parameters_list', 'pl')
->where(\Query\Operator::equals(['pl.id_parameter' => $params['id']]))
->andWhere(\Query\Translation::coalesceTranslatedFields(ParametersListTranslation::class))
->orderBy('position')
->execute(), 'id');
$result['values'] = array_map(function ($parameter) {
$parameter['data'] = json_decode($parameter['data'], true);
return $parameter;
}, $result['values']);
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,26 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_payment_method
* Purpose: get a class representing payment method
* -------------------------------------------------------------
*/
function smarty_function_get_payment_method($params, &$smarty)
{
$name = false;
extract($params);
$payment = Payment::getClass($name);
if (!$payment) {
echo "Neexistující platebni metoda '{$name}'";
}
if (!empty($assign)) {
$smarty->assign($assign, $payment);
}
}

View File

@@ -0,0 +1,237 @@
<?php
/**
* Smarty plugin.
*/
use KupShop\ContentBundle\Entity\Wrapper\PhotoWrapper;
use KupShop\ContentBundle\Util\ImageLocator;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\System\UrlFinder;
use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext;
/**
* Smarty {url} plugin.
*
* Type: function<br>
* Name: get_photo<br>
* Purpose: return array describing image
*
* @param array $params parameters
* @param Smarty_Internal_Template $smarty template object
*
* @return string
*/
function smarty_function_get_photo($params, &$smarty)
{
$photo = null;
$type = 'product';
$id = null;
$photoId = null;
$size = null;
$assign = null;
$lang = null;
$absolute = null;
$time = null;
$version = 'desktop';
extract($params);
// validate version (desktop, tablet, mobile)
if (!in_array($version, ['desktop', Photos::PHOTO_VERSION_MOBILE, Photos::PHOTO_VERSION_TABLET])) {
throw new InvalidArgumentException('Invalid version of image!');
}
if ($version === 'desktop') {
$version = Photos::PHOTO_VERSION_DESKTOP;
}
static $imageLocator = null;
if (!$imageLocator) {
$imageLocator = ServiceContainer::getService(ImageLocator::class);
}
// HACK: Dočasná zpetná kompatibilita kvůli přejmenování 'image' parametru na 'size'
if (is_null($size) && !is_null($params['image'])) {
$size = $params['image'];
}
$smartyReturn = function ($ret) use (&$smarty, $assign, $absolute, $params) {
static $urlFinder = null;
if (!$urlFinder) {
$urlFinder = ServiceContainer::getService(UrlFinder::class);
}
if ($params['gifs'] ?? false) {
if (!$absolute) {
$ret = $urlFinder->shopUrl($ret);
} else {
$ret = $urlFinder->shopUrlAbsolute($ret);
}
} else {
if (!$absolute) {
$ret = $urlFinder->staticUrl($ret);
} else {
$ret = $urlFinder->staticUrlAbsolute($ret);
}
}
if (!empty($assign)) {
$smarty->assign($assign, $ret);
} else {
return $ret;
}
return null;
};
// HACK: Dočasně podporujeme v 'id' parametru pole, stejně jako v 'photo' parametru
if (is_array($id) && is_null($photo)) {
$photo = $id;
}
if (is_array($photo)) {
if (empty($photo)) {
$id = 0;
} elseif (isset($photo['type']) && $photo['type'] == $imageLocator->getTypeName($size)) {
return $smartyReturn($photo['src']);
} else {
if (!array_key_exists('date_update', $photo)) {
$sentry = getRaven();
$sentry->captureMessage(
"get_photo: chybí parametr 'date_update' v poli s obrázkem"
);
user_error("get_photo: chybí parametr 'date_update' v poli s obrázkem");
}
$id = $photo['id'];
$time = $photo['date_update'];
$photo = null;
}
} elseif ($photo instanceof PhotoWrapper) {
$photo = $photo->getObject();
$id = $photo->getId();
$time = $photo->getDate()->getTimestamp();
$photo = null;
} elseif ($photo instanceof \KupShop\ContentBundle\Entity\Image) {
$id = $photo->getId();
$time = $photo->getDateUpdated()->getTimestamp();
$photo = null;
} else {
$id = (int) $id;
}
if (!$photo) {
if (is_null($id) || is_null($size)) {
$sentry = getRaven();
$sentry->captureMessage(
"get_photo: pokud chybi parametr 'photo', musi byt aspon parametr 'id' (id obrázku) a 'size' (velikost obrázku)"
);
user_error("get_photo: pokud chybi parametr 'photo', musi byt aspon parametr 'id' (id obrázku) a 'size' (velikost obrázku)");
return null;
}
$settings = $imageLocator->getTypeConfig($size);
if (empty($lang)) {
$cfg = \KupShop\KupShopBundle\Config::get();
if (!empty($settings['lang']) || ($id == 0 && !empty($cfg['Photo']['placeholder']['lang']))) {
$lang = Contexts::get(LanguageContext::class)->getActiveId();
}
}
$imagePath = $imageLocator->getPath($id, $size, 'jpg', $lang, $version);
$ret = $imagePath;
// Add cache busting timestamp
if (!$time && isLocalDevelopment()) {
$logger = ServiceContainer::getService('logger');
$logger->error('get_photo bez data poslední změny '.$size, array_merge(['id' => $id], ['exception' => new SilencedErrorContext(1, '', 0, debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 5), 1)]));
}
$imageVersion = Settings::getDefault()->image_version ?? 1;
$ret = "{$ret}?{$time}_{$imageVersion}";
return $smartyReturn($ret);
}
if (!$type) {
$sentry = getRaven();
$sentry->captureMessage("get_photo: missing parameter 'type'");
user_error("get_photo: missing parameter 'type'");
return;
}
if (!$id) {
$sentry = getRaven();
$sentry->captureMessage("get_photo: missing parameter 'id'");
user_error("get_photo: missing parameter 'id'");
return;
}
$ret = null;
switch ($type) {
case 'section':
if (!$size) {
$size = 6;
}
$ret = getImage($id, $photo, '../section/', $size);
break;
case 'producer':
if (!$size) {
$size = 7;
}
$ret = getImage($id, $photo, '../producer/', $size);
break;
case 'payment':
if (!$size) {
$size = 8;
}
$ret = getImage($id, $photo, '../payment/', $size);
break;
case 'delivery':
if (!$size) {
$size = 9;
}
$ret = getImage($id, $photo, '../delivery/', $size);
break;
case 'article':
if (!$size) {
$size = 1;
}
if (empty($photoId) || ($ret = getImage($photoId, null, null, $size)) === false) {
$ret = leadImage($id, $size, 'ARTICLE');
}
break;
case 'product':
if (!$size) {
$size = 1;
}
if (empty($photoId) || ($ret = getImage($photoId, null, null, $size)) === false) {
$ret = leadImage($id, $size);
}
break;
default:
echo "Non-existing photo type: {$type}";
return;
}
return $smartyReturn($ret);
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* Smarty plugin.
*/
use KupShop\I18nBundle\Translations\PhotosTranslation;
use Query\Translation;
/**
* Smarty {url} plugin.
*
* Type: function<br>
* Name: get_photos<br>
* Purpose: return array of photos for product/article/page
*
* @param array $params parameters
* @param Smarty_Internal_Template $smarty template object
*
* @return string
*/
function smarty_function_get_photos($params, &$smarty)
{
$type = 'null';
$id = null;
$image = null;
extract($params);
$photos = [];
switch ($type) {
case 'pages':
$field = 'id_menu';
if (!$image) {
$image = 1;
}
$menu_id = returnSQLResult('SELECT id FROM menu_links WHERE old_id_page=:id', ['id' => $id]);
// Pokud staré ID neexistuje, tváříme se, že jsme dostali nové ID stránky kvůli kompatibilitě.
if ($menu_id) {
$id = $menu_id;
}
$type = 'menu';
break;
case 'articles':
$field = 'id_art';
if (!$image) {
$image = 1;
}
break;
case 'products':
$image = 1;
break;
case 'sections':
if (!$image) {
$image = 1;
}
break;
case 'producers':
$field = 'id_producer';
if (!$image) {
$image = 1;
}
break;
default:
echo "Non-existing type: {$type}";
return;
}
if (empty($field)) {
$field = 'id_'.substr($type, 0, -1);
}
$SQL = sqlQueryBuilder()
->select('ph.*, pr.id_photo')
->from('photos_'.$type.'_relation', 'pr')
->leftJoin('pr', 'photos', 'ph', 'pr.id_photo = ph.id')
->where(Translation::coalesceTranslatedFields(PhotosTranslation::class))
->andWhere(\Query\Operator::equals(['pr.'.$field => $id]))
->orderBy('position', 'ASC')
->execute();
if (!empty($SQL)) {
foreach ($SQL as $photo) {
$photo['img'] = getImage($photo['id_photo'], $photo['image_2'], $photo['source'], $image, $photo['descr'], strtotime($photo['date_update']));
$photos[] = $photo;
}
}
if (!empty($assign)) {
$smarty->assign($assign, $photos);
} else {
return [];
}
}

View File

@@ -0,0 +1,31 @@
<?php
function smarty_function_get_product_gifts($params, &$smarty)
{
$product = $params['product'] ?? false;
if (!$product) {
return null;
}
$gifts = [];
if (findModule(Modules::ORDERS, Modules::SUB_ORDERS_FROM_PURCHASE_STATE)) {
// Gifts loaded from PurchaseItem from additionalItems
foreach ($product->getAdditionalItems() as $item) {
if ($item->note['item_type'] === 'gift') {
$gifts[] = $item->getProduct();
}
}
} else {
if (is_array($product)) {
$gifts = $product['product']['gifts'] ?? [];
} else {
$gifts = $product->getProduct()['gifts'] ?? [];
}
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $gifts);
} else {
return $gifts;
}
}

View File

@@ -0,0 +1,71 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_product_info
* Purpose: returns various information about product
* -------------------------------------------------------------
*/
use KupShop\CatalogBundle\Util\FavoriteProductsUtil;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
function smarty_function_get_product_info($params, &$smarty)
{
$type = null;
$id = null;
/** @var Product $product */
$product = null;
$result = null;
extract($params);
if (empty($type)) {
trigger_error("Chybějící parametr 'type'");
}
if (empty($id) && empty($product)) {
trigger_error("Chybějící parametr 'id' nebo 'product'");
}
if (empty($id)) {
$id = $product->id;
}
switch ($type) {
case 'is_favorite':
$userContext = Contexts::get(UserContext::class);
$favoriteProductsUtil = ServiceContainer::getService(FavoriteProductsUtil::class);
$userId = null;
if ($userContext->getActiveId()) {
$userId = (int) $userContext->getActiveId();
}
$result = $favoriteProductsUtil->isProductFavorite((int) $id, $userId, FavoriteProductsUtil::getCookieProducts());
break;
case 'is_watchdog':
$userContext = Contexts::get(UserContext::class);
$watchdog = ServiceContainer::getService(\KupShop\WatchdogBundle\Util\Watchdog::class);
if (!$userContext->getActiveId()) {
return false;
}
$result = $watchdog->isWatchdog((int) $userContext->getActiveId(), (int) $id, $id_variation ? (int) $id_variation : null);
break;
default:
trigger_error("Neexistující 'type': {$type}");
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,65 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_product_total_discount
* Purpose: returns product discount (% sleva, nebo % rozdíl mezi škrtlou cenou a prodejní cenou, podle toho co je vyšší),
* priceOriginal (cena před slevou nebo škrtlá cena, podle toho co je vyšší)
* -------------------------------------------------------------
*/
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\KupShopBundle\Wrapper\PriceWrapper;
function smarty_function_get_product_total_discount($params, &$smarty)
{
if (!isset($params['productPrice'])) {
return null;
}
$productPrice = $params['productPrice'];
if ($productPrice instanceof PriceWrapper) {
$productPrice = $productPrice->getObject();
}
$discount = DecimalConstants::zero();
if (!$productPrice->getValue()->isZero()) {
$originalPrice = $productPrice->getOriginalPrice()->getPriceWithoutDiscount();
if (!empty($params['priceCommon'])) {
$priceCommon = $params['priceCommon'];
if ($priceCommon instanceof PriceWrapper) {
$priceCommon = $priceCommon->getObject();
}
if (PriceCalculator::firstLower($originalPrice, $priceCommon)) {
$originalPrice = $priceCommon;
}
}
if (!empty($params['priceForDiscount'])) {
$priceForDiscount = $params['priceForDiscount'];
if ($priceForDiscount instanceof PriceWrapper) {
$priceForDiscount = $priceForDiscount->getObject();
}
if (PriceCalculator::firstLower($priceForDiscount, $originalPrice)) {
$originalPrice = $priceForDiscount;
}
}
if (PriceCalculator::firstLower($productPrice, $originalPrice)) {
$discount = DecimalConstants::one()->sub($productPrice->getPriceWithVat()->div($originalPrice->getPriceWithVat()))->mul(DecimalConstants::hundred());
if (!empty($params['assignPriceOriginal'])) {
$smarty->assign($params['assignPriceOriginal'], $originalPrice);
}
}
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $discount);
} else {
return $discount;
}
}

View File

@@ -0,0 +1,75 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_slider
* Purpose: get a slider of known name or id
* -------------------------------------------------------------
*/
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Contexts;
/**
* @param array $params
* @param Smarty $smarty
*
* @return array
*/
function smarty_function_get_ratings($params, &$smarty)
{
$activeLanguage = null;
$rating = false;
$tmpSum = 0;
$ratingCount = 0;
if (findModule(Modules::TRANSLATIONS)) {
$languagesContext = Contexts::get(LanguageContext::class);
$activeLanguage = $languagesContext->getActiveId();
}
$review = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\CatalogBundle\Util\ReviewsUtil::class);
$reviews = $review->getForProduct($params['id_product'], $activeLanguage);
foreach ($reviews as $index => $item) {
if (isset($item['rating'])) {
$tmpSum += $item['rating'];
$ratingCount++;
}
if (!empty($params['skip_empty']) && empty($item['user_name']) && empty($item['name'])) {
unset($reviews[$index]);
}
if (!$review->hasComment($item)) {
unset($reviews[$index]);
}
if (findModule(Modules::TRANSLATIONS) && $activeLanguage != $item['id_language']) {
if (empty($params['languages'][$activeLanguage]) || !in_array($item['id_language'], $params['languages'][$activeLanguage])) {
if (!$review->hasTranslatedComment($item)) {
unset($reviews[$index]);
}
}
}
}
if ($ratingCount > 0) {
$rating = $tmpSum / $ratingCount;
}
$ret = [
'rating' => $rating,
'rating_count' => $ratingCount,
'reviews' => $reviews,
'user_already_rated' => $review->hasUserAlreadyRated($params['id_product']),
];
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $ret);
} else {
return $ret;
}
}

View File

@@ -0,0 +1,12 @@
<?php
function smarty_function_get_referer($params, &$smarty)
{
$referer = getVal('HTTP_REFERER', $_SERVER);
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $referer);
} else {
return $referer;
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_section
* Purpose: get a section of given id
* -------------------------------------------------------------
*/
use KupShop\CatalogBundle\Entity\Wrapper\CategoryWrapper;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function smarty_function_get_section($params, &$smarty)
{
if (!isset($params['id'])) {
return null;
}
$sectionTree = ServiceContainer::getService(\KupShop\CatalogBundle\Section\SectionTree::class);
$section = $sectionTree->getSectionById($params['id']);
if ($section) {
$section = ServiceContainer::getService(CategoryWrapper::class)->setObject($section);
} else {
$section = [];
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $section);
}
}

View File

@@ -0,0 +1,80 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_session_value
* Purpose: returns value stored in session
* -------------------------------------------------------------
*/
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function smarty_function_get_session_value($params, &$smarty)
{
/** @var \Symfony\Component\HttpFoundation\Session\Session $session */
$session = ServiceContainer::getService('session');
$type = null;
$result = null;
$multiple = null;
$remove = null;
extract($params);
if (empty($type)) {
trigger_error("Chybějící parametr 'type'");
}
switch ($type) {
case 'added_to_cart':
$addedToCart = $session->get('addedToCart');
if ($addedToCart) {
$session->remove('addedToCart');
$ids = array_map(f_field('id_cart'), $addedToCart['items']);
$result = CartItem::createFromSpec(\Query\Operator::inIntArray($ids, 'id'));
foreach ($result as &$item) {
$item->pieces_added = $addedToCart['items'][$item['id']]['quantity'];
}
if (!$multiple) {
$result = reset($result);
}
}
break;
case 'user_messages':
static $flash_messages = null;
if (is_null($flash_messages)) {
$flash_messages = [];
foreach ($session->getFlashBag()->all() as $type => $msg) {
foreach ($msg as $message) {
$flash_messages[] = array_merge(['severity' => $type], $message);
}
}
}
$result = $flash_messages;
break;
case 'added_to_favorites':
$type = 'addedToFavorites';
$remove = true;
// no break
default:
$result = $session->get($type);
if ($remove && $result) {
$session->remove($type);
}
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,38 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_slider
* Purpose: get a slider of known name or id
* -------------------------------------------------------------
*/
use KupShop\ContentBundle\Util\SliderUtil;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function smarty_function_get_slider($params, &$smarty)
{
$random = false;
extract($params);
$sliderUtil = ServiceContainer::getService(SliderUtil::class);
$slider = null;
if (isset($id)) {
$slider = $sliderUtil->get((int) $id, (bool) $random);
} elseif (isset($name)) {
$slider = $sliderUtil->getByName($name, (bool) $random);
}
if (!$slider) {
echo "Neexistující slider '{$name}'";
}
if (!empty($assign)) {
$smarty->assign($assign, $slider);
}
}

View File

@@ -0,0 +1,19 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: eval
* Purpose: evaluate a template variable as a template
* -------------------------------------------------------------
*/
function smarty_function_get_smarty($params, &$smarty)
{
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $smarty);
} else {
return $smarty;
}
}

View File

@@ -0,0 +1,413 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_stats
* Purpose: returns various statistic numbers
* -------------------------------------------------------------
*/
use KupShop\CatalogBundle\Util\FavoriteProductsUtil;
use KupShop\I18nBundle\Util\PriceConverter;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\CountryContext;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
function smarty_function_get_stats($params, &$smarty)
{
$type = null;
$result = null;
extract($params);
if (empty($type)) {
trigger_error("Chybějící parametr 'type'");
}
switch ($type) {
case 'products_count':
$key = join('_', $params);
$result = getCache($key);
if (!$result) {
$from = getTableName('products').' p';
$where = 'figure="Y"';
$data = [];
if (!empty($params['in_store'])) {
$where .= ' AND p.in_store > 0 ';
}
if (!empty($params['category'])) {
$from .= ' LEFT JOIN '.getTableName('products-sections').' ps ON p.id=ps.id_product';
$where .= ' AND ps.id_section = :section ';
$data['section'] = $params['category'];
}
$result = returnSQLResult("SELECT COUNT(*) FROM {$from} WHERE {$where}", $data);
setCache($key, $result);
}
break;
case 'cart_free_delivery':
case 'free_delivery':
$with_empty_purchasestate = $type == 'free_delivery';
if (!$with_empty_purchasestate) {
/** @var Cart $cart */
$cart = ServiceContainer::getService(\KupShop\OrderingBundle\Cart::class);
if ($cart->hasOnlyVirtualProducts() && !($params['alllow_only_virtual_products'] ?? false)) {
return null;
}
}
$purchaseUtil = ServiceContainer::getService(PurchaseUtil::class);
$freeDeliveryFrom = $purchaseUtil->getFreeDeliveryFrom($with_empty_purchasestate);
if (Contexts::get(UserContext::class)->isActive() || ($params['registered'] ?? false)) {
$freeDeliveryFrom = $freeDeliveryFrom['registered'];
} else {
$freeDeliveryFrom = $freeDeliveryFrom['unregistered'];
}
if ($freeDeliveryFrom) {
$converter = ServiceContainer::getService(PriceConverter::class);
$currencyContext = Contexts::get(CurrencyContext::class);
$result = $converter->convert($freeDeliveryFrom->getCurrency(), $currencyContext->getActive(), $freeDeliveryFrom->getValue());
}
break;
case 'user_spending':
if (Contexts::get(UserContext::class)->isActive()) {
$where = 'o.id_user = :user_id';
$data = [
'user_id' => Contexts::get(UserContext::class)->getActiveId(),
];
if (!empty($params['year'])) {
$where .= ' AND YEAR(o.date_created) = :year ';
$data['year'] = $params['year'];
}
if (!empty($params['last_year'])) {
$year = intval($params['last_year']);
$where .= " AND date_created > DATE_SUB( NOW(), INTERVAL {$year} YEAR) ";
}
// Pokud chtějí zobrazovat přesný součet objednávek v dané měně
if (isset($params['currency'])) {
$spendActiveCurrency = sqlQueryBuilder()
->select('SUM(o.total_price) as total')
->from(getTableName('orders'), 'o')
->andWhere(\Query\Operator::equals(['id_user' => $data['user_id'], 'o.currency' => $params['currency']]))
->execute()->fetchOne();
$result = toDecimal($spendActiveCurrency);
} else {
$result = applyCurrency(returnSQLResult('SELECT SUM(o.total_price'.(findModule('currencies') ? '* o.currency_rate' : '').') FROM orders AS o WHERE '.$where, $data));
}
} else {
$result = null;
}
break;
case 'user_orders':
global $ctrl;
$result = sqlQueryBuilder()
->select('COUNT(*) as orders_num')
->from('orders', 'o')
->where('id_user=:id_user')
->setParameter('id_user', $ctrl['id'])
->execute()->fetchColumn();
break;
case 'user_points':
global $ctrl;
if (!$ctrl['id']) {
$result = null;
break;
}
$last_date = sqlQueryBuilder()
->select('date_created')
->from('bonus_points', 'b')
->where('id_user=:id_user')
->andWhere(\Query\Operator::equals(['b.status' => 'active']))
->setParameter('id_user', $ctrl['id'])
->orderBy('date_created', 'DESC')
->setMaxResults(1)
->execute()->fetchColumn();
if (!$last_date) {
$result = null;
break;
}
$insert_date = (new \DateTime())->setTimestamp(strtotime($last_date));
if (!empty($expire_date)) {
$dbcfg = Settings::getDefault();
$result = $insert_date->modify("+ {$dbcfg->bonus_program['remove_time']} day");
} else {
$result = $insert_date;
}
break;
case 'user_unsolved_orders':
global $ctrl;
$result = sqlQueryBuilder()
->select('COUNT(*) as orders_num')
->from('orders', 'o')
->where('id_user=:id_user')
->andWhere('o.status_storno = 0')
->andWhere(\Query\Operator::inIntArray(getStatuses('nothandled'), 'o.status'))
->setParameter('id_user', $ctrl['id'])
->execute()->fetchColumn();
break;
case 'user_favorite_goods':
$userContext = Contexts::get(UserContext::class);
$productList = new ProductList();
$productList->applyDefaultFilterParams();
$productList->andSpec(function (Query\QueryBuilder $qb) use ($userContext) {
if ($userContext->getActiveId()) {
$qb->join('p', 'products_favorites', 'pf', 'pf.id_product = p.id');
$qb->andWhere(\Query\Operator::equals(['pf.id_user' => $userContext->getActiveId()]));
} else {
$qb->andWhere(\Query\Operator::inIntArray(FavoriteProductsUtil::getCookieProducts(), 'p.id'));
}
});
$result = $productList->getProductsCount();
break;
case 'user_watchdog':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as watchdog')
->from('products_watchdog', 'pw')
->where(\Query\Operator::equals(['id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'user_shopping_list':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as shopping_list')
->from('shopping_list', 'sl')
->where(\Query\Operator::equals(['id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'user_reclamations':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as reclamations')
->from('reclamations', 'r')
->join('r', 'order_items', 'oi', 'oi.id=r.id_item')
->join('oi', 'orders', 'o', 'oi.id_order=o.id')
->where(\Query\Operator::equals(['o.id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'elnino_reclamations':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as reclamations_elnino')
->from('reclamations_elnino', 'r')
->join('r', 'reclamation_items_elnino', 'ri', 'r.id=ri.id_reclamation')
->join('ri', 'order_items', 'oi', 'oi.id=ri.id_item')
->join('oi', 'orders', 'o', 'oi.id_order=o.id')
->where(\Query\Operator::equals(['o.id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'user_returns':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as returns')
->from('returns', 'r')
->join('r', 'return_items', 'ri', 'r.id = ri.id_return')
->join('ri', 'order_items', 'oi', 'oi.id = ri.id_item')
->join('oi', 'orders', 'o', 'oi.id_order=o.id')
->where(\Query\Operator::equals(['o.id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'product_compare':
/** @var \Symfony\Component\HttpFoundation\Session\SessionInterface $session */
$session = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService('session');
$result = count($session->get('productCompare', []));
break;
case 'delivery_dates':
$country = Contexts::get(CountryContext::class);
$cache_key = "delivery_dates_{$country->getActiveId()}";
$result = getCache($cache_key);
if ($result) {
break;
}
$deliveries = Delivery::getAll();
$dateMinInPerson = null;
$dateMinDelivery = null;
$list = [];
foreach ($deliveries as $id => $delivery) {
$date = $delivery->getDeliveryDate();
if (!$date) {
continue;
}
$list[$id] = [
'name' => $delivery->name,
'delivery_date' => $date,
];
if ($delivery->isInPerson()) {
if (is_null($dateMinInPerson) || $dateMinInPerson > $date) {
$dateMinInPerson = $date;
}
} elseif (is_null($dateMinDelivery) || $dateMinDelivery > $date) {
$dateMinDelivery = $date;
}
}
$result = [
'list' => $list,
'min' => [
'in_person' => $dateMinInPerson,
'delivery' => $dateMinDelivery,
],
];
setCache($cache_key, $result, 600);
break;
case 'max_dimensions':
if (empty($cart)) {
trigger_error('Chybí košík v parametru cart!');
}
$result = $cart->getPurchaseState()->getDeliveryRestrictionParams()->getMaxDimensions();
break;
case 'sum_of_dimensions':
if (empty($cart)) {
trigger_error('Chybí košík v parametru cart!');
}
$result = $cart->getPurchaseState()->getDeliveryRestrictionParams()->getMaxSumOfEachDimension();
break;
case 'cheapest_delivery':
$countryContext = Contexts::get(CountryContext::class);
$contextManager = ServiceContainer::getService(ContextManager::class);
$country = $params['country'] ?? $countryContext->getActiveId();
$result = $contextManager->activateContexts([CountryContext::class => $country], function () use ($params, $country) {
/** @var Cart $cart */
$cart = ServiceContainer::getService(\KupShop\OrderingBundle\Cart::class);
if ($cart->hasOnlyVirtualProducts() && !($params['alllow_only_virtual_products'] ?? false)) {
return null;
}
$cacheName = 'cheapestDelivery_'.$country;
if (!empty($params['key'])) {
$cacheName .= $params['key'];
}
if (User::getCurrentUser() || ($params['registered'] ?? false)) {
$cacheName .= '_reg';
}
if (!isset($params['registered'])) {
$params['registered'] = null;
}
$cache = getCache($cacheName, $found);
if (!$found) {
$cache = null;
$types = DeliveryType::getAll();
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$defaultCurrency = $currencyContext->getDefault();
$min = null;
$vat = getVat();
$deliveries = [];
foreach ($types as $type) {
if ($type->delivery_class == 'OsobniOdber') {
continue;
}
if ($type->accept(new Price(toDecimal(0), $defaultCurrency, 0), false)) {
if ($type->getDelivery()->getPrice()) {
$price = $type->getDelivery()->getPrice();
$vat = $price->getVat();
$price = PriceCalculator::convert($price, $defaultCurrency);
$deliveries[] = $price->getValue();
}
}
}
if (!empty($deliveries)) {
$min = min($deliveries);
}
if ($min !== null) {
$cache = new Price(toDecimal($min), $defaultCurrency, $vat);
}
setCache($cacheName, $cache);
}
if ($cache != false) {
$result = $cache;
} else {
$result = null;
}
return $result;
});
break;
case 'reviews_count':
$result = 0;
if (findModule(\Modules::REVIEWS)) {
$result = sqlQueryBuilder()
->select('COUNT(*) as reviews_count')
->from('reviews', 'r')
->execute()->fetchColumn();
}
break;
case 'average_rating':
$result = 0;
if (findModule(\Modules::REVIEWS)) {
$result = sqlQueryBuilder()
->select('AVG(r.rating) as average_rating')
->from('reviews', 'r')
->execute()->fetchColumn();
}
break;
default:
trigger_error("Neexistující 'type': {$type}");
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,205 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_templates
* Purpose: returns templates
* -------------------------------------------------------------
*/
use Doctrine\DBAL\Connection;
use KupShop\CatalogBundle\Entity\Wrapper\ProductWrapper;
use KupShop\ContentBundle\Entity\Placeholder;
use KupShop\ContentBundle\Util\Block;
use KupShop\ContentBundle\Util\InlineEdit;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use Query\Operator;
use Query\Translation;
function smarty_function_get_templates($params, &$smarty)
{
$include = [];
$exclude = [];
$label = [];
$id = [];
$product = null;
$productId = null;
$assign = null;
extract($params);
$product = ProductWrapper::unwrap($product);
if ($product instanceof \Product) {
$productId = $product->id;
} elseif (is_numeric($product)) {
$productId = $product;
$product = null;
}
if (empty($params['assign'])) {
trigger_error("Chybějící parametr 'assign'");
}
if (!is_array($label)) {
$label = [$label];
}
if (!is_array($include)) {
$include = [$include];
}
if (!is_array($exclude)) {
$exclude = [$exclude];
}
if (!is_array($id)) {
$id = [$id];
}
$qb = sqlQueryBuilder()
->select('t.id_category, t.id, t.name, tc.name as category, tc.product_detail_position, t.id_block, t.data, t.figure')
->from('templates', 't')
->leftJoin('t', 'templates_categories', 'tc', 't.id_category = tc.id')
->orderBy('tc.position')
->addOrderBy('t.position')
->addOrderBy('t.name');
if ($productId) {
$qb->leftJoin('t', 'templates_products', 'tp', 't.id = tp.id_template')
->andWhere(Operator::equals(['tp.id_product' => $productId]));
}
if ($label) {
$qb->andWhere(Operator::findInSet($label, 'tc.label', 'OR'));
}
if ($include) {
$qb->andWhere(Operator::inIntArray($include, 'tc.id'));
}
if ($exclude) {
$qb->andWhere(Operator::not(Operator::inIntArray($exclude, 'tc.id')));
}
if ($id) {
$qb->andWhere(Operator::inIntArray($id, 't.id'));
}
if ($product && ($labels = $product->labels) && ($labelTemplateIds = array_column($labels, 'id_template'))) {
$qb->setParameter('labelsIntArray', array_keys($labels), Connection::PARAM_INT_ARRAY);
$qb->orWhere(Operator::inIntArray($labelTemplateIds, 't.id'))
->leftJoin('t', 'labels', 'l', 'l.id_template = t.id AND l.id IN (:labelsIntArray)')
->addSelect('l.id AS from_label');
$productLabelUtil = ServiceContainer::getService(\KupShop\LabelsBundle\Util\ProductLabelUtil::class);
}
$qb->andWhere(Translation::coalesceTranslatedFields(\KupShop\I18nBundle\Translations\TemplatesTranslation::class));
$qb->andWhere(Translation::coalesceTranslatedFields(\KupShop\I18nBundle\Translations\TemplatesCategoriesTranslation::class, ['name' => 'category']));
$qb->having('figure!="N"');
$result = $qb->execute();
$blockUtils = ServiceContainer::getService(Block::class);
$inlineEdit = ServiceContainer::getService(InlineEdit::class);
$ret = [];
foreach ($result as $row) {
$key = $row['id_category'];
if (!isset($ret[$key])) {
$ret[$key] = [
'id' => $row['id_category'],
'title' => $row['category'],
'position' => $row['product_detail_position'],
'values' => [],
];
}
$row['data'] = json_decode($row['data'] ?? '', true) ?? [];
$placeholders = $placeholders ?? [];
if ($placeholders) {
foreach ($placeholders as &$placeholder) {
if ($placeholder instanceof Placeholder) {
continue;
}
$placeholder = new Placeholder(
key($placeholder), '', function () use ($placeholder) {
return array_pop($placeholder);
});
}
}
// Label templates
if ($row['from_label']) {
$labelPlaceholders = $productLabelUtil->getLabelPlaceholders($product, $row['from_label']);
if (empty($labelPlaceholders[0]?->getValue())) {
continue;
}
// add labelPlaceholders to existing placeholders
array_push($placeholders, ...$labelPlaceholders);
}
if ($blockID = $row['id_block']) {
$blockList = $blockUtils->getBlocks($blockID);
if ($placeholders) {
$blockUtils->replacePlaceholders($blockList, [], $placeholders);
}
$object_info = json_encode([
'type' => 'templates',
'id' => $row['id'],
'name' => (translate('objects', 'blocks', false, true)['template'] ?? 'template').': '.$row['name'],
'placeholders' => $placeholders,
]);
$row['blocks'] = [];
foreach ($blockList as $block) {
$block['object_info'] = $object_info;
$row['blocks'][] = $inlineEdit->wrapBlock($block);
}
$row['text'] = join('', array_column($row['blocks'], 'content'));
} else {
$row['blocks'] = [];
$row['text'] = '';
}
// Label templates
if ($row['from_label'] && empty($placeholders)) {
$unwrapped_content = join('', array_column($row['blocks'], 'unwrapped_content')) ?: $row['text'];
$hasPlaceholders = preg_match('/{(.+?)}/', $unwrapped_content);
if ($hasPlaceholders) {
// label template text contains placeholders that were not replaced,
// because getLabelPlaceholders returned an empty array,
// meaning that none of the selected discounts could be applied
// in this case we don't want to display the template at all
continue;
}
}
$valueKey = $row['id'];
if ($row['from_label']) {
$valueKey .= "-{$row['from_label']}";
}
$ret[$key]['values'][$valueKey] = $row;
if ($position = $row['product_detail_position'] ?? null) {
if (empty($ret[$position])) {
$ret[$position] = [];
}
$ret[$position][$key] = &$ret[$key];
}
}
$smarty->assign($params['assign'], $ret);
}

View File

@@ -0,0 +1,78 @@
<?php
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\OrderingBundle\Util\Delivery\DeliveryDatesService;
use KupShop\OrderingBundle\Util\Order\DeliveryInfo;
/**
* Return array with three items:
* - 'list' - List of deliveries. Each delivery has new property 'date'.
* - 'min' - Array of precomputed minimal values across the deliveries.
* - 'variations' - List of the variations of the `products`. Each variation is the array with the properties 'list' and 'min' related to the variation.
*
* @note If you don't need variations, use tag `get_delivery_dates`.
*
* @param product product that is used to restrict list of deliveries and delivery dates
* @param only_supported if true, deliveries are filtered by the restrictions of the shop settings and `product` properties (default: true)
* @param price price that is used to restrict list of deliveries
*
* @return array|void
*/
function smarty_function_get_variations_delivery_dates($params, &$smarty)
{
if (empty($params['product'])) {
throw new InvalidArgumentException('Missing required parameter \'product\'');
}
/** @var DeliveryDatesService $deliveryDates */
$deliveryDates = ServiceContainer::getService(DeliveryDatesService::class);
/** @var DeliveryInfo $deliveryInfo */
$deliveryInfo = ServiceContainer::getService(DeliveryInfo::class);
$only_supported = true;
$product = null;
$price = null;
extract($params);
$price = $product->getProductPrice();
$purchaseState = $deliveryDates->initPurchaseState($product, $price);
$activeDeliveries = $deliveryDates->filterDeliveries(Delivery::getAll(), $only_supported, $price, $purchaseState);
$minDeliveryPrice = $deliveryDates->calcMinDeliveryPrice($activeDeliveries);
$productList = $deliveryDates->initializeProductCollection($product, true);
$deliveriesDates = $deliveryInfo->getProductsDeliveriesDeliveryDates($productList, $activeDeliveries);
$variationResults = [];
$dateMinInPerson = null;
$dateMinDelivery = null;
list($variationResults, $dateMinInPerson, $dateMinDelivery) = $deliveryDates->calcResultsForEachVariation($deliveriesDates,
$activeDeliveries,
$minDeliveryPrice,
$variationResults,
$dateMinInPerson,
$dateMinDelivery);
$deliveriesList = $deliveryDates->calcTotalDeliveryListForVariations($activeDeliveries, $deliveriesDates);
$totalResult = [
'list' => $deliveriesList,
'min' => [
'in_person' => $dateMinInPerson,
'delivery' => $dateMinDelivery,
'total' => min($dateMinDelivery, $dateMinInPerson),
'deliveryPrice' => $minDeliveryPrice,
],
'variations' => $variationResults,
];
if (!empty($assign)) {
$smarty->assign($assign, $totalResult);
} else {
return $totalResult;
}
}

View File

@@ -0,0 +1,38 @@
<?php
use KupShop\CDNBundle\CDN;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
/**
* Smarty {url} plugin.
*
* Type: function<br>
* Name: get_video<br>
* Purpose: return array describing video
*
* @param array $params parameters
* @param Smarty_Internal_Template $smarty template object
*
* @return array
*/
function smarty_function_get_video($params, &$smarty)
{
if (!isset($params['id'])) {
throw new InvalidArgumentException("Missing parameter 'id' in smarty function 'get_video'!");
}
$id = $params['id'];
$resolution = $params['resolution'] ?? '240p';
$autoplay = $params['autoplay'] ?? true;
$cdn = ServiceContainer::getService(CDN::class);
$result = [
'mp4' => $cdn->getMP4Video($id, $resolution),
'hls' => $cdn->getHLSPlaylist($id),
'direct' => $cdn->getIframeUrl($id, $autoplay),
];
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,29 @@
<?php
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
function smarty_function_get_watchdog($params, &$smarty)
{
$result = null;
if (empty($params['product'])) {
throw new InvalidArgumentException('Missing required parameter \'product\'');
}
$id = (int) $params['product']['id'];
$variationId = !empty($params['id_variation']) ? (int) $params['id_variation'] : null;
$userContext = Contexts::get(UserContext::class);
if ($userContext->getActiveId()) {
$watchdog = ServiceContainer::getService(\KupShop\WatchdogBundle\Util\Watchdog::class);
$result = $watchdog->getWatchdog((int) $userContext->getActiveId(), $id, $variationId);
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,149 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: eval
* Purpose: evaluate a template variable as a template
* -------------------------------------------------------------
*/
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function html_compress(&$html)
{
preg_match_all('!(<(?:code|pre).*>[^<]+</(?:code|pre)>)!', $html, $pre); // exclude pre or code tags
$html = preg_replace('!<(?:code|pre).*>[^<]+</(?:code|pre)>!', '#pre#', $html); // removing all pre or code tags
$html = preg_replace('#<![^\[].+>#', '', $html); // removing HTML comments
$html = preg_replace('/[\r\n\t]+/', ' ', $html); // remove new lines, spaces, tabs
$html = preg_replace('/>[\s]+</', '><', $html); // remove new lines, spaces, tabs
$html = preg_replace('/[\s]+/', ' ', $html); // remove new lines, spaces, tabs
if (!empty($pre[0])) {
foreach ($pre[0] as $tag) {
$html = preg_replace('!#pre#!', $tag, $html, 1);
}
}// putting back pre|code tags
}
function smarty_function_include_cached($params, &$smarty)
{
$key = null;
$file = null;
$force = false;
$debug = false;
$skip_cache = false;
$get_data_function = null;
$last_updated = null;
extract($params);
if ($skip_cache) {
$debug = true;
}
if (empty($key)) {
trigger_error("include_cached: missing 'key' parameter");
return;
}
if (empty($file)) {
trigger_error("include_cached: missing 'file' parameter");
return;
}
$html = getCache($key);
if (is_array($html) && !empty($html['time_cached'])) {
if ($last_updated && $last_updated > $html['time_cached']) {
$html = false;
} else {
$html = $html['html'] ?? '';
}
}
if ($debug || !$html) {
ob_start();
$_smarty_tpl_vars = $smarty->tpl_vars;
if ($get_data_function) {
call_user_func_array($get_data_function, [&$params]);
}
echo $smarty->_subTemplateRender($file, $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
$smarty->tpl_vars = $_smarty_tpl_vars;
unset($_smarty_tpl_vars);
$html = ob_get_contents();
if (!$debug) {
html_compress($html);
}
$cache = ['html' => $html, 'time_cached' => time()];
// Umožňujeme $get_data_function nastavit TTL, když třeba selže fetch, tak se zacachuje na krátko
setCache($key, $cache, $params['ttl'] ?? 7200);
ob_end_clean();
}
echo $html;
if ($force) {
$params['fromCache'] = true;
$_smarty_tpl_vars = $smarty->tpl_vars;
echo $smarty->_subTemplateRender($file, $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
$smarty->tpl_vars = $_smarty_tpl_vars;
}
}
function smarty_function_include_cached_optional(&$params, &$smarty)
{
if (!empty($params['cache'])) {
// Use caching, generate key
$params['key'] = $params['cache_key'];
if (is_callable($params['cache_key'])) {
$params['key'] = $params['cache_key']($params);
}
if (is_array($params['key'])) {
$params['key'][] = ServiceContainer::getService(LanguageContext::class)->getActiveId();
$params['key'] = join('-', $params['key']);
}
if (empty($params['file'])) {
$params['file'] = $params['template'];
}
smarty_function_include_cached($params, $smarty);
return;
}
// Fallback without caching
if (!empty($params['get_data_function'])) {
call_user_func_array($params['get_data_function'], [&$params]);
}
$_smarty_tpl_vars = $smarty->tpl_vars;
echo $smarty->_subTemplateRender($params['template'], $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
$smarty->tpl_vars = $_smarty_tpl_vars;
}
/* vim: set expandtab: */

View File

@@ -0,0 +1,39 @@
<?php
function smarty_function_insert_articles($params, &$smarty)
{
$defaults = [
'count' => null,
'section' => null,
'section_id' => null,
'product_id' => null,
'related' => [],
'related_symmetric' => false,
'related_type' => false,
'tag' => null,
'assign' => null,
'order' => 'DESC',
'image' => 1,
'require_tag' => null,
'template' => 'block.articles.tpl',
];
$params = array_merge($defaults, $params);
$tmpParams = $params;
unset($tmpParams['assign']);
$smarty->loadPlugin('smarty_function_get_articles');
$data = smarty_function_get_articles($tmpParams, $smarty);
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $data);
} elseif (!empty($params['template'])) {
$_smarty_tpl_vars = $smarty->tpl_vars;
echo $smarty->_subTemplateRender($params['template'], $smarty->cache_id, $smarty->compile_id, 0, null, $data, 0, false);
$smarty->tpl_vars = $_smarty_tpl_vars;
} else {
return $data;
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {insert_barcode} plugin.
*
* Type: function<br>
* Name: insert_barcode<br>
* Purpose: inserts inline SVG barcode
*
* @param array $params parameters
* @param Smarty_Internal_Template $smarty
*
* @return string
*/
function smarty_function_insert_barcode($params, &$smarty)
{
if (($params['type'] ?? '') == 'EAN13') {
$params['code'] = formatEAN($params['code']);
}
try {
$generator = new Picqer\Barcode\BarcodeGeneratorSVG();
$result = $generator->getBarcode($params['code'] ?? '', $params['type'] ?? $generator::TYPE_CODE_128, $params['width'] ?? 2, $params['height'] ?? 30);
} catch (\Picqer\Barcode\Exceptions\BarcodeException $e) {
$result = '';
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: eval
* Purpose: evaluate a template variable as a template
* -------------------------------------------------------------
*/
function smarty_function_insert_cart_info($params, &$smarty)
{
global $cfg;
require_once $cfg['Path']['shared_version'].'web/block.cartInfo.php';
$default = [
'template' => 'block.cartInfo.tpl',
'cartInfo' => block_cartInfo(),
];
$params = array_merge($default, $params);
if (!empty($params['return'])) {
$smarty->assign($params['return'], $params);
return;
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $params);
}
$_smarty_tpl_vars = $smarty->tpl_vars;
echo $smarty->_subTemplateRender($params['template'], $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
$smarty->tpl_vars = $_smarty_tpl_vars;
}

View File

@@ -0,0 +1,95 @@
<?php
function smarty_function_insert_external_feed($params, &$smarty)
{
if (empty($params['url']) || empty($params['count'])) {
throw new InvalidArgumentException('Missing required parameter \'url\' or \'count\'');
}
$default = [
'template' => 'block.external_feed.rss.tpl',
'cache' => 1,
'type' => 'rss',
'ttl' => 7200,
'cache_key' => function ($params) {
return ['insert_external_feed', $params['template'], $params['type'], $params['url'], $params['count']];
},
];
$params = array_merge($default, $params);
$params['get_data_function'] = function (&$params) {
$feed = simplexml_load_file($params['url'], null, LIBXML_NOCDATA);
if ($feed === false) {
$params['ttl'] = 5;
}
$params['items'] = [];
switch ($params['type']) {
case 'rss':
foreach ($feed->channel->item as $item) {
$params['items'][] = xml2array($item);
}
break;
case 'atom':
foreach ($feed->entry as $item) {
$params['items'][] = xml2array($item);
}
break;
case 'heureka_review':
foreach ($feed->review as $item) {
$params['items'][] = xml2array($item);
}
break;
default:
throw new InvalidArgumentException('Type \''.$params['type'].'\' is not supported');
}
$params['items'] = array_slice($params['items'], 0, $params['count']);
};
if (!empty($params['template'])) {
$smarty->loadPlugin('Smarty_function_include_cached');
smarty_function_include_cached_optional($params, $smarty);
}
if (!empty($params['assign'])) {
if (empty($params['template'])) {
$params['get_data_function']($params);
}
$smarty->assign($params['assign'], $params);
}
return null;
}
function xml2array($xmlObject, $out = [])
{
foreach ((array) $xmlObject as $index => $node) {
$out[$index] = (is_object($node) || is_array($node)) ? xml2array($node) : (string) $node;
}
if (is_object($xmlObject)) {
foreach ($xmlObject->attributes() as $name => $attribute) {
$out["@{$name}"] = (string) $attribute;
}
foreach ($xmlObject->getDocNamespaces() as $namespace) {
foreach ($xmlObject->children($namespace) as $index => $node) {
$out[$index] = (is_object($node) || is_array($node)) ? xml2array($node) : (string) $node;
}
foreach ($xmlObject->attributes($namespace) as $name => $attribute) {
$out["@{$name}"] = (string) $attribute;
}
}
}
foreach ($out as $key => $item) {
if (is_array($item) && count($item) === 1 && key($item) == 0) {
$out[$key] = reset($item);
}
}
return $out;
}

View File

@@ -0,0 +1,76 @@
<?php
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function smarty_function_insert_filtered_sections($params, &$smarty)
{
$default = [
'level' => 0,
'level_max' => 99,
'template' => 'block.sections.tpl',
'skip_cache' => false,
'get_data_function' => 'smarty_function_insert_filtered_sections_get_data',
];
$params = array_merge($default, $params);
if (empty($params['template'])) {
throw new Exception('missing template');
}
$params['file'] = $params['template'];
$languageID = ServiceContainer::getService(\KupShop\KupShopBundle\Context\LanguageContext::class)
->getActive()->getId();
if (empty($params['key'])) {
$currencyContext = ServiceContainer::getService(\KupShop\KupShopBundle\Context\CurrencyContext::class);
$params['key'] = "sections-{$languageID}-{$params['template']}";
if (count($currencyContext->getSupported()) > 1) {
$params['key'] .= '-'.$currencyContext->getActiveId();
}
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $params);
return '';
}
$smarty->loadPlugin('Smarty_function_include_cached');
return smarty_function_include_cached($params, $smarty);
}
function smarty_function_insert_filtered_sections_get_data(&$params)
{
$menuSectionTree = ServiceContainer::getService(\KupShop\CatalogBundle\Section\SectionTree::class)->get();
$qb = sqlQueryBuilder()->select('id')
->from('sections')
->groupBy('id');
if (!empty($params['flags'])) {
$qb->andWhere(\Query\Operator::findInSet($params['flags'], 'flags'));
}
if (!empty($params['id'])) {
$qb->andWhere(\Query\Operator::inIntArray((array) $params['id'], 'id'));
}
if (!empty($params['order_by'])) {
if (is_array($params['order_by'])) {
$qb->orderBy('FIELD(id, :orderBySectionsId)')
->setParameter('orderBySectionsId', $params['order_by'], \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);
} else {
$qb->orderBy($params['order_by'], $params['order'] ?? 'DESC');
}
}
$cats = $qb->execute()->fetchAll();
$params['categories'] = [];
foreach ($cats as $cat) {
$params['categories'][] = $menuSectionTree->getSectionById($cat['id']);
}
}

View File

@@ -0,0 +1,212 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: eval
* Purpose: evaluate a template variable as a template
* -------------------------------------------------------------
*/
use KupShop\ContentBundle\Util\MenuUtil;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function fetchMenuLinks($parent_id = 0, $level = 0)
{
$menuLinks = [];
$languageContext = ServiceContainer::getService(LanguageContext::class);
$qb = sqlQueryBuilder()
->select('ml.*')
->from('menu_links', 'ml')
->andWhere(
\Query\Translation::joinTranslatedFields(
\KupShop\I18nBundle\Translations\MenuLinksTranslation::class,
function ($qb, $columnName, $translatedField, $langID) use ($languageContext) {
if ($columnName === 'name_short' && $langID != $languageContext->getDefaultId()) {
$translatedField = $translatedField ?? 'ml.'.$columnName; // no translations
$qb->addSelect("{$translatedField} AS `{$columnName}`");
return false;
}
return;
},
['name', 'name_short', 'link', 'url', 'figure']
)
)
->orderBy('list_order', 'ASC');
if ($parent_id > 0) {
$qb->andWhere(\Query\Operator::equals(['parent' => $parent_id]));
} else {
$qb->andWhere('ml.parent IS NULL AND ml.id=ml.id_menu');
}
$SQL = $qb->execute();
foreach ($SQL as $row) {
if ($row['figure'] == 'N') {
continue;
}
$url = ($row['type'] == MenuUtil::TYPE_PAGE) ? createScriptURL(['URL' => $row['url']]) : $row['link'];
$url = htmlspecialchars($url);
if ($parent_id === 0 && $level === 0) {
$item = fetchMenuLinks($row['id'], $level);
} else {
$item = [
'id' => $row['id'],
'title' => !empty($row['name_short']) ? $row['name_short'] : $row['name'],
'url' => $url,
'target' => $row['target'],
'children' => fetchMenuLinks($row['id'], $level + 1),
'level' => $level,
'selected' => false,
'data' => json_decode($row['data'] ?? '', true) ?? [],
];
}
$menuLinks[$row['id']] = $item;
}
unset($row);
sqlFreeResult($SQL);
return $menuLinks;
}
function updateMenuLinks(&$menu)
{
global $ctrl;
$selected = false;
$currUrl = html_entity_decode($ctrl['currUrl']['Abs']);
$currUrlRel = html_entity_decode($ctrl['currUrl']['Rel']);
foreach ($menu as &$submenu) {
$itemSelected = false;
// Select if subitem selected
if (!empty($submenu['children'])) {
$itemSelected |= updateMenuLinks($submenu['children']);
}
// Select if url matches
$decodedUrl = html_entity_decode($submenu['url']);
$itemSelected |= $decodedUrl == $currUrl || $decodedUrl == $currUrlRel;
$submenu['selected'] = $itemSelected;
$selected |= $itemSelected;
}
return $selected;
}
function smarty_function_insert_menu($params, &$smarty)
{
$default = [
'level' => 0,
'level_max' => 99,
'template' => 'block.menu.tpl',
'menu_id' => 1,
'submenu' => [],
];
$params = array_merge($default, $params);
// Get Own Menu structures
static $menuLinks = null;
$languageContext = ServiceContainer::getService(LanguageContext::class);
$cacheName = 'menu-'.$languageContext->getActiveId();
if (empty($menuLinks)) {
$menuLinks = getCache($cacheName);
}
if (empty($menuLinks)) {
$menuLinks = fetchMenuLinks();
setCache($cacheName, $menuLinks);
}
// discover menu_id by label
static $menuLabels = null;
if (is_null($menuLabels)) {
$menuLabels = getCache('menu-groupLabels');
if (empty($menuLabels)) {
$menuLabels = sqlFetchAll(
sqlQueryBuilder()->select('id, code')->from('menu_links')
->where('type=:type AND code IS NOT NULL')
->setParameter('type', MenuUtil::TYPE_GROUP)->execute(),
['code' => 'id']
);
setCache('menu-groupLabels', $menuLabels);
}
}
if (!empty($params['label']) && isset($menuLabels[$params['label']])) {
$params['menu_id'] = $menuLabels[$params['label']];
} elseif (!empty($params['label'])) {
return "Neznámý label: {$params['label']}";
}
if (!isset($menuLinks[$params['menu_id']])) {
return "Neznámé menu_id: {$params['menu_id']}";
}
// Get correct menu
$menu = $menuLinks[$params['menu_id']];
$parent = null;
updateMenuLinks($menu);
if (!empty($params['submenu'])) {
foreach ($params['submenu'] as $item) {
$parent = $menu[$item];
$menu = $parent['children'];
}
} elseif ($params['level'] > 0) {
for ($i = 0; $i < $params['level']; $i++) {
$selected = null;
foreach ($menu as $submenu) {
if ($submenu['selected']) {
$selected = $submenu;
break;
}
}
if (empty($selected)) {
return;
}
$parent = $selected;
$menu = $selected['children'];
}
}
$params['file'] = $params['template'];
$params['menu'] = $menu;
$params['parent'] = $parent;
$_smarty_tpl_vars = $smarty->tpl_vars;
echo $smarty->_subTemplateRender(
$params['file'],
$smarty->cache_id,
$smarty->compile_id,
0,
null,
$params,
0,
false
);
$smarty->tpl_vars = $_smarty_tpl_vars;
}
/* vim: set expandtab: */

View File

@@ -0,0 +1,155 @@
<?php
use KupShop\CatalogBundle\Util\ActiveCategory;
use KupShop\I18nBundle\Translations\ProducersTranslation;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\RestrictionsBundle\Utils\Restrictions;
use Query\Operator;
function smarty_function_insert_producers_get_data(&$params)
{
$dbcfg = Settings::getDefault();
$qb = sqlQueryBuilder()
->select('pr.id, pr.name, pr.photo, pr.data, pr.date_updated')
->andWhere(\Query\Translation::coalesceTranslatedFields(
ProducersTranslation::class,
['name' => 'name', 'web' => 'web', 'data' => 'data_translated']
))
->from('products', 'p')
->leftJoin('p', 'producers', 'pr', 'p.producer = pr.id')
->andWhere(Operator::equals(['pr.active' => 'Y', 'p.figure' => 'Y']))
->andWhere('p.id IS NOT NULL')
->groupBy('pr.id');
if ($params['count']) {
$qb->setMaxResults($params['count']);
}
if ($params['top'] ?? false) {
$qb->andWhere(Operator::equals(['pr.top' => 'Y']));
}
if ($dbcfg->prod_show_not_in_store == 'N') {
$qb->andWhere('p.in_store > 0');
}
if ($params['totals']) {
if ($params['totals'] == 'in_store') {
$qb->addSelect('SUM(IF(p.in_store > 0, 1, 0)) as total');
} else {
$qb->addSelect('COUNT(p.id) as total');
}
}
if (findModule('elnino')) {
$select = join(', ', $qb->getQueryPart('select'));
$inStoreSpec = findModule('products', 'in_store_spec');
if ($inStoreSpec && is_callable($inStoreSpec)) {
$select = str_replace('p.in_store', call_user_func($inStoreSpec, false, $qb), $select);
if ($dbcfg->prod_show_not_in_store == 'N') {
$qb->andWhere(call_user_func($inStoreSpec, false, $qb).' > 0');
}
}
$qb->select($select)
->leftJoin('p', 'products_in_sections', 'ps', 'p.id=ps.id_product')
->join('ps', 'sections', 's', 's.id = ps.id_section');
}
if (findModule(\Modules::RESTRICTIONS)) {
$qb->andWhere(ServiceContainer::getService(Restrictions::class)->getRestrictionSpec());
}
$qb->orderBy('COALESCE(pr.position, 9999), pr.name', 'ASC');
if (!empty($params['best_sellers'])) {
$qb->orderBy('SUM(p.pieces_sold)', 'DESC');
}
if (!empty($params['category'])) {
$categories = getDescendantCategories($params['category']);
$qb->leftJoin('p', 'products_in_sections', 'ps', 'p.id=ps.id_product')
->andWhere(Operator::inIntArray($categories, 'ps.id_section'));
}
$SQL = $qb->execute();
$producers = [];
foreach ($SQL as $producer) {
if (!empty($producer['photo'])) {
$producer['image'] = getImage($producer['id'], $producer['photo'], '../producer/', 7, $producer['name'], strtotime($producer['date_updated']));
}
$producer['data'] = array_replace_recursive(json_decode($producer['data'], true) ?: [], json_decode($producer['data_translated'], true) ?: []);
$producers[$producer['id']] = $producer;
}
// Fetch producer photos
if (isset($params['fetchPhotos'])) {
$photoSize = $params['fetchPhotos'];
$producerIds = array_keys($producers);
$photos = sqlQueryBuilder()->select('ppr.id_producer, p.id, p.descr, p.source, p.image_2')
->from('photos', 'p')
->join('p', 'photos_producers_relation', 'ppr', 'ppr.id_photo = p.id')
->andWhere(Operator::inIntArray($producerIds, 'ppr.id_producer'))
->orderBy('ppr.position')
->execute();
foreach ($photos as $photo) {
$producers[$photo['id_producer']]['photos'][] = getImage($photo['id'], $photo['image_2'], $photo['source'], $photoSize, $photo['descr']);
}
}
$params['producers'] = $producers;
}
function smarty_function_insert_producers($params, &$smarty)
{
/** @var ActiveCategory $activeCategory */
$activeCategory = ServiceContainer::getService(ActiveCategory::class);
if (getVal('IDproduct')) {
$selection = $activeCategory->loadProducerId();
} else {
$selection = $activeCategory->getProducerId();
}
$default = [
'template' => 'block.producers.tpl',
'count' => null,
'totals' => null,
'key' => 'producers-html',
'get_data_function' => 'smarty_function_insert_producers_get_data',
'selection' => [intval($selection)],
'subsections' => $activeCategory->getOpenedTreePath(),
];
$params = array_merge($default, $params);
$key = [
$params['key'],
$params['template'],
ServiceContainer::getService(LanguageContext::class)->getActiveId(),
];
$params['key'] = join('-', $key);
$params['file'] = $params['template'];
if (!empty($params['assign'])) {
smarty_function_insert_producers_get_data($params);
$smarty->assign($params['assign'], $params);
return;
}
$smarty->loadPlugin('Smarty_function_include_cached');
return smarty_function_include_cached($params, $smarty);
}
/* vim: set expandtab: */

View File

@@ -0,0 +1,63 @@
<?php
use KupShop\CatalogBundle\ProductList\ProductCollectionWrapper;
use KupShop\KupShopBundle\Context\CacheContext;
use KupShop\KupShopBundle\Util\Contexts;
/**
* @param array $params
* @param Smarty_Internal_Template $smarty
*
* @return array|null
*/
function smarty_function_insert_products($params, $smarty)
{
$input_params = $params;
$param_defaults = [
'template' => 'block.products.tpl',
'variations' => false,
'cache' => null,
'cache_key' => function ($params) use ($input_params) {
return array_merge(
['insert_products'],
array_values(array_filter($input_params, fn ($value) => !is_callable($value))),
[Contexts::get(CacheContext::class)->getKey([CacheContext::TYPE_TEXT, CacheContext::TYPE_PRICE])]
);
},
];
$params = array_merge($param_defaults, $params);
$params['get_data_function'] = function (&$params) {
$params['products'] = ProductCollectionWrapper::wrap((new InsertProductsTypes())->getProducts($params));
};
if (!empty($params['return'])) {
$params['get_data_function']($params);
return $params;
}
if (!empty($params['template'])) {
$smarty->loadPlugin('Smarty_function_include_cached');
smarty_function_include_cached_optional($params, $smarty);
}
if (!empty($params['assign'])) {
if (!empty($params['cache'])) {
trigger_error("include_products: 'cache' is not compatible with 'assign'");
}
if (empty($params['template'])) {
// Bohuzel tohle musim spustit, protoze bez template se to nespustilo
$params['get_data_function']($params);
}
$smarty->assign($params['assign'], $params);
}
return null;
}
/* vim: set expandtab: */

View File

@@ -0,0 +1,161 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: eval
* Purpose: evaluate a template variable as a template
* -------------------------------------------------------------
*/
use KupShop\CatalogBundle\Util\SectionUtil;
use KupShop\KupShopBundle\Context\CacheContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
function smarty_function_insert_sections_get_categories()
{
$menuSectionTree = ServiceContainer::getService(\KupShop\CatalogBundle\Section\SectionTree::class)->get();
$selection = smarty_function_insert_sections_get_selection();
$menuSectionTree->updateSelection($selection);
return $menuSectionTree->getTree();
}
function smarty_function_insert_sections_get_time_cached()
{
$menuSectionTree = ServiceContainer::getService(\KupShop\CatalogBundle\Section\SectionTree::class)->get();
return $menuSectionTree->getTimeCached();
}
function smarty_function_insert_sections_get_selection($breadcrumbs = null)
{
$selection = [];
$activeCategory = ServiceContainer::getService(\KupShop\CatalogBundle\Util\ActiveCategory::class);
$openedTree = $activeCategory->getOpenedTreePath();
if ($breadcrumbs != null) {
$selection = array_values(array_filter(array_map(function ($x) {
return getVal('ID', $x);
},
$breadcrumbs)));
} // nastavit rozevreny strom sekci ulozeny v SESSION
elseif ($openedTree != null) {
$selection = $openedTree;
}
$id_cat = $activeCategory->getCategoryId();
if ($id_cat > 0 && end($selection) != $id_cat) {
$selection[] = $id_cat;
}
return $selection;
}
function smarty_function_insert_sections($params, &$smarty)
{
$default = [
'level' => 0,
'level_max' => 99,
'template' => 'block.sections.tpl',
'force' => true,
'skip_cache' => false,
'categories' => smarty_function_insert_sections_get_categories(),
'selection' => smarty_function_insert_sections_get_selection(getVal('breadcrumbs', $params)),
'get_data_function' => 'smarty_function_insert_sections_get_data',
];
$params = array_merge($default, $params);
if (!empty($params['skip_cache'])) {
$params['force'] = false;
}
$key_id = '0';
if ($params['level'] > 0) {
$sectionList = $params['categories'];
$sectionSelection = $params['selection'];
for ($i = 0; $i < $params['level']; $i++) {
if (empty($sectionSelection[$i])) {
return;
}
if (!isset($sectionList[$sectionSelection[$i]])) {
break;
}
$sectionList = $sectionList[$sectionSelection[$i]]['submenu'];
$key_id = $sectionSelection[$i];
}
$params['categories'] = $sectionList;
}
if (empty($params['key'])) {
$cacheContext = Contexts::get(CacheContext::class);
$params['key'] = implode(
'-',
[
'sections',
$key_id,
$params['template'],
$cacheContext->getKey([CacheContext::TYPE_TEXT, CacheContext::TYPE_AVAILABILITY, CacheContext::TYPE_PRICE]),
]
);
}
$params['file'] = $params['template'];
$params['categories'] = array_filter($params['categories'] ?? [], function ($x) {
return $x->isVisible();
});
// chci nafetchovat slidery do sekci
if ($params['sliders'] ?? false) {
$sectionUtil = ServiceContainer::getService(SectionUtil::class);
$sectionUtil->fetchSlidersIntoSectionsCache();
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $params);
return '';
}
$params['last_updated'] = smarty_function_insert_sections_get_time_cached();
$smarty->loadPlugin('Smarty_function_include_cached');
return smarty_function_include_cached($params, $smarty);
}
function smarty_function_insert_sections_get_data(&$params)
{
if (findModule(\Modules::RESTRICTIONS)) {
$params['categories'] = ServiceContainer::getService(\KupShop\RestrictionsBundle\Utils\RestrictionUtil::class)->restrictSections($params['categories']);
}
if (!empty($params['IDpv'])) {
$qb = sqlQueryBuilder()->select('s.id')
->from('sections', 's')
->join('s', 'products_in_sections', 'ps', 's.id = ps.id_section')
->join('ps', 'products', 'p', 'p.id = ps.id_product')
->join('p', 'parameters_products', 'pap', 'p.id=pap.id_product AND pap.value_list=:value_list')
->setParameter('value_list', $params['IDpv']);
$qb->andWhere((new FilterParams())->getSpec());
$sectionIds = sqlFetchAll($qb, 'id');
SectionUtil::recurseDeleteSections($params['categories'], $sectionIds);
}
}

View File

@@ -0,0 +1,68 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: eval
* Purpose: evaluate a template variable as a template
* -------------------------------------------------------------
*/
use KupShop\ContentBundle\Util\SliderUtil;
use KupShop\KupShopBundle\Context\CacheContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
function smarty_function_insert_slider($params, &$smarty)
{
if (!findModule('sliders')) {
return;
}
$default = [
'template' => 'block.slider.tpl',
'id' => null,
'cache' => null,
'cache_key' => function ($params) {
$cacheContext = Contexts::get(CacheContext::class);
return ['sliders', $params['id'], $cacheContext->getKey([CacheContext::TYPE_FULL_PAGE])];
},
];
if (empty($params['id']) && empty($params['label']) && empty($params['slider'])) {
trigger_error("insert_slider: missing 'id', 'label' or 'slider'");
return;
}
$smarty->loadPlugin('Smarty_function_include_cached');
if (!empty($params['slider'])) {
$params = array_merge($default, $params);
smarty_function_include_cached_optional($params, $smarty);
return;
}
if (empty($params['id']) && !empty($params['label'])) {
$params['id'] = sqlQueryBuilder()->select('id')->from('sliders')
->where(\Query\Operator::equals(['label' => $params['label']]))
->execute()->fetchColumn();
}
$params = array_merge($default, $params);
$params['get_data_function'] = function (&$params) {
if (empty($params['id'])) {
$params['slider'] = false;
} else {
$sliderUtil = ServiceContainer::getService(SliderUtil::class);
$params['slider'] = $sliderUtil->get((int) $params['id']);
}
};
smarty_function_include_cached_optional($params, $smarty);
}

View File

@@ -0,0 +1,234 @@
<?php
use KupShop\CatalogBundle\Section\SectionTree;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
function getSectionsBlock($params)
{
/** @var \KupShop\CatalogBundle\Util\ActiveCategory $activeCategory */
$activeCategory = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\CatalogBundle\Util\ActiveCategory::class);
$sections = [];
$catProducer = intval(getVal('IDpd'));
if (isset($params['producer'])) {
$catProducer = intval($params['producer']);
}
if (!$catProducer) {
$catProducer = $activeCategory->getProducerId();
}
$cat = $params['category'];
$categoryTree = ServiceContainer::getService(SectionTree::class);
if ($catProducer > 0) {
$dbcfg = Settings::getDefault();
/** @var \Query\QueryBuilder $query */
$query = sqlQueryBuilder()
->select('s.id')
->from('sections', 's')
->leftJoin('s', 'products_in_sections', 'ps', 's.id=ps.id_section')
->leftJoin('s', 'products', 'p', 'ps.id_product=p.id AND p.figure="Y" ')
->where('s.figure="Y"')
->andWhere('p.producer=:producer')
->setParameter('producer', $catProducer)
->groupBy('s.id');
if ($dbcfg->prod_show_not_in_store == 'N') {
$query->andWhere(\Query\Filter::byInStore(Filter::IN_STORE_SUPPLIER));
}
$result = $query->execute();
$selected = [];
foreach ($result as $row) {
$selected[$row['id']] = true;
}
if (!isset($cat['id'])) {
$categories = $activeCategory->getCategory();
} else {
$categories = $categoryTree->getSectionById($cat['id']);
}
if (!empty($categories)) {
$end = false;
do {
$sectionsFallback = $sections;
$sections = recurseSelectCategories($categories, $selected);
// avoid infinite
if (empty($sections)) {
$end = true;
$sections = $sectionsFallback;
}
// if there is only one section
$categories = $categoryTree->getSectionById(reset($sections)['id']);
} while (count($sections) < 2 && $end == false);
}
} elseif (isset($cat['id']) && $cat['id'] >= 0) {
$root = $params['root'] ?? false;
$topsection = ($root && $cat['id'] == 0 ? null : $cat['id']);
if ($topsection == 0 && !$root) {
return [];
}
$SQL = sqlQueryBuilder()
->select('s.*')
->from('sections', 's')
->leftJoin('s', 'sections_relation', 'sr', 's.id=sr.id_section')
->where(
\Query\Operator::equalsNullable(['s.figure' => 'Y', 'sr.id_topsection' => $topsection])
)
->andWhere('s.id != 0')
->andWhere(
\Query\Translation::coalesceTranslatedFields(
\KupShop\I18nBundle\Translations\SectionsTranslation::class
)
)
->orderBy('sr.position, s.name', 'ASC')
->execute();
foreach ($SQL as $row) {
$category = $categoryTree->getSectionById($row['id']);
// Skip subcategory if not visible
if ($category && !$category->isVisible()) {
continue;
}
$row['title'] = $row['name'];
$row['title_short'] = $row['name_short'] ? $row['name_short'] : $row['name'];
if ($row['photo']) {
$row['photo'] = getImage($row['id'], $row['photo'], '../section/', $params['image'], $row['name'], strtotime($row['date_updated']));
}
if (!empty($cat['id']['campaign'])) {
$row['id'] .= $cat['id']['campaign'];
}
$row['data'] = ($row['data'] === null) ? [] : json_decode($row['data'], true);
if ($category == null) {
$logger = ServiceContainer::getService('logger');
$logger->notice('[Proxy Cache] Category is null', ['row' => $row, 'category' => $category]);
}
$row['count'] = $category?->getCount() ?: 0;
$row['in_stock_count'] = $category?->getInStockCount() ?: 0;
$row['data'] = $category?->getData() ?: [];
$sections[] = $row;
}
if (!empty($params['IDpv'])) {
$qb = sqlQueryBuilder()->select('s.id')
->from('sections', 's')
->join('s', 'products_in_sections', 'ps', 's.id = ps.id_section')
->join('ps', 'products', 'p', 'p.id = ps.id_product')
->join('p', 'parameters_products', 'pap', 'p.id=pap.id_product AND pap.value_list=:value_list')
->setParameter('value_list', $params['IDpv']);
$qb->andWhere((new FilterParams())->getSpec());
$sectionIds = sqlFetchAll($qb, 'id');
foreach ($sections as $key => $section) {
if (!in_array($section['id'], array_keys($sectionIds))) {
unset($sections[$key]);
}
}
}
if (!empty($params['campaign'])) {
$qb = sqlQueryBuilder()->select('s.id')
->from('sections', 's')
->join('s', 'products_in_sections', 'ps', 's.id = ps.id_section')
->join('ps', 'products', 'p', 'p.id = ps.id_product AND FIND_IN_SET(:campaign, p.campaign)')
->setParameter('campaign', $params['campaign']);
$qb->andWhere((new FilterParams())->getSpec());
$sectionIds = sqlFetchAll($qb, 'id');
foreach ($sections as $key => $section) {
if (!in_array($section['id'], array_keys($sectionIds))) {
unset($sections[$key]);
}
}
}
unset($divide, $tblWidth);
}
return $sections;
}
function smarty_function_insert_subsections($params, &$smarty)
{
/** @var \KupShop\CatalogBundle\Util\ActiveCategory $activeCategory */
$activeCategory = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\CatalogBundle\Util\ActiveCategory::class);
$tree = $activeCategory->getOpenedTreePath();
$default = [
'template' => 'block.subsections.tpl',
'category' => null,
'up' => true,
'selection' => $tree,
];
$params = array_merge($default, $params);
if (empty($params['category'])) {
throw new InvalidArgumentException('Missing \'category\' parameter - array describing category');
}
if (empty($params['image'])) {
$params['image'] = 6;
}
if (empty($params['count'])) {
$params['count'] = 9999;
}
$params['sections'] = getSectionsBlock($params);
if (!empty($params['template'])) {
$_smarty_tpl_vars = $smarty->tpl_vars;
echo $smarty->_subTemplateRender($params['template'], $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
$smarty->tpl_vars = $_smarty_tpl_vars;
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $params);
}
}
function recurseSelectCategories($categories, $selected)
{
$result = [];
if (isset($categories['submenu'])) {
$categories = $categories['submenu'];
}
foreach ($categories as $category) {
$children = [];
if (isset($selected[$category['id']]) || $children = recurseSelectCategories($category['submenu'], $selected)) {
if (!empty($category['submenu']) && empty($children)) {
$children = recurseSelectCategories($category['submenu'], $selected);
}
$result[] = [
'id' => $category['id'],
'title' => $category['title'],
'title_short' => $category['title_short'] ?: $category['title'],
'photo' => $category['photo'] ?? null,
'parents' => $category['parents'],
'children' => $children,
];
}
}
return $result;
}

View File

@@ -0,0 +1,14 @@
<?php
function smarty_function_load_active_category($params, &$smarty)
{
$activeCategory = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService(\KupShop\CatalogBundle\Util\ActiveCategory::class);
$result = $activeCategory->loadCategoryId();
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}

View File

@@ -0,0 +1,54 @@
<?php
/**
* Smarty plugin.
*/
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\System\UrlFinder;
/**
* Smarty {url} plugin.
*
* Type: function<br>
* Name: photo<br>
* Purpose: insert <img> tag
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string
*/
function smarty_function_photo($params, $template)
{
$photo = null;
$link = false;
$type = null;
$id = null;
$image = null;
$alt = '';
extract($params);
if (!$photo) {
return null;
}
static $urlFinder = null;
if (!$urlFinder) {
$urlFinder = ServiceContainer::getService(UrlFinder::class);
}
if ($alt !== '' && $alt) {
$alt = ' alt="'.htmlspecialchars($alt).'"';
}
$res = "<img src='{$urlFinder->staticUrl($photo['src'])}'{$alt}>";
if ($link) {
$res = "<a href='{$urlFinder->staticUrl($photo['src_big'])}'>{$res}</a>'";
}
return $res;
}

View File

@@ -0,0 +1,54 @@
<?php
use KupShop\OrderingBundle\Util\Order\OrderItemInfo;
/**
* @param array $params
* @param Smarty $smarty
*
* @return string
*/
function smarty_function_pohoda_get_vat_level($params, &$smarty)
{
// TODO: předělat na VatContext + ContextManager @h.prokop
static $vats = null;
if (is_null($vats)) {
$vats = [];
$vatsSQL = sqlQueryBuilder()->select('*')->from('vats');
foreach ($vatsSQL->execute() as $vat) {
$data = json_decode($vat['data'], true);
$vats[$vat['id_country'] ?? 'CZ'][$vat['vat']] = $data['level'] ?? 'high';
}
}
/** @var \Order $order */
$order = $params['order'];
$item = $params['item'];
$country = strtoupper($order['delivery_country'] ?? 'CZ');
$oss = $order->getFlags()['OSS'] ?? false;
$POHODA_OSS_VAT_LEVELS = [
OrderItemInfo::VAT_HIGH => 'historyHigh',
OrderItemInfo::VAT_LOW => 'historyLow',
OrderItemInfo::VAT_LOW2 => 'historyThird',
OrderItemInfo::VAT_NONE => 'none',
];
$POHODA_VAT_LEVELS = [
OrderItemInfo::VAT_HIGH => 'high',
OrderItemInfo::VAT_LOW => 'low',
OrderItemInfo::VAT_LOW2 => 'third',
OrderItemInfo::VAT_NONE => 'none',
];
if ($item['vat'] == 0) {
return 'none';
}
$level = $vats[$country][$item['vat']] ?? 'high';
$levels = $oss ? $POHODA_OSS_VAT_LEVELS : $POHODA_VAT_LEVELS;
return $levels[$level];
}

View File

@@ -0,0 +1,44 @@
<?php
use KupShop\CatalogBundle\ProductList\ProductCollection;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Template\BaseWrapper;
use KupShop\KupShopBundle\Util\Contexts;
function smarty_function_prepare_product_discount($params, &$smarty)
{
if (isset($params['product'])) {
$product = $params['product'];
if ($product instanceof \KupShop\ContentBundle\Entity\Wrapper\ProductUnifiedWrapper) {
$product = $product->getProduct();
}
$productCollection = new ProductCollection([$product->id => $product]);
$params['products'] = $productCollection;
}
if (!isset($params['products'])) {
user_error('prepare_product_discount: parametr "products" je povinný.');
}
$productCollection = $params['products'];
$productCollection = BaseWrapper::unwrap($productCollection);
assert($productCollection instanceof ProductCollection);
// TODO: Je možný to udělat super-lazy.
// Tím že by se na ProductCollection uložil něco jako ProductDiscountResultWrapper,
// který by v sobě měl odkaz na productCollection a až když by si někdo řekl o common/retail price,
// tak by se zavolal prefetch a vrátil výsledek.
$userContext = Contexts::get(UserContext::class);
$retailType = $userContext->getRetailPriceType();
$retailType->prefetchProductCollection($productCollection);
$originalType = $userContext->getOriginalPriceType();
$originalType->prefetchProductCollection($productCollection);
return null;
}

View File

@@ -0,0 +1,21 @@
<?php
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\System\UrlFinder;
function smarty_function_static_url($params)
{
$url = $params['url'] ?? '';
static $urlFinder = null;
if (!$urlFinder) {
$urlFinder = ServiceContainer::getService(UrlFinder::class);
}
if ($params['absolute'] ?? false) {
return $urlFinder->staticUrlAbsolute($url);
}
return $urlFinder->staticUrl($url);
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {url} plugin.
*
* Type: function<br>
* Name: url<br>
* Purpose: insert seo-friendly url
*
* @param array $params parameters
*
* @return string
*/
function smarty_function_url($params, &$smarty)
{
$assign = getVal('assign', $params);
if ($assign) {
unset($params['assign']);
}
$url = createScriptURL($params);
if ($assign) {
$smarty->assign($assign, $url);
return '';
}
if (isset($params['ESCAPE'])) {
return $url;
}
return htmlspecialchars($url, ENT_QUOTES);
}

View File

@@ -0,0 +1,15 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* File: insert.seo_url.php
* Type:
* Name:
* Purpose: je vyvolana z sablony a ma za ukol vytvorit spravnou SEO friendly adresu
* -------------------------------------------------------------
*/
function smarty_insert_seo_url($params, &$smarty)
{
return createScriptURL($params);
}

View File

@@ -0,0 +1,30 @@
<?php
function smarty_modifier_add_price_level_print_names(PriceLevel $priceLevel)
{
if (!empty($priceLevel->sections)) {
$sections = sqlFetchAll(sqlQuery('SELECT id, name FROM sections'), ['id' => 'name']);
foreach ($priceLevel->sections as $id => &$section) {
$section['name'] = $sections[$id];
}
}
if (!empty($priceLevel->producers)) {
$producers = sqlFetchAll(sqlQuery('SELECT id, name FROM producers'), ['id' => 'name']);
foreach ($priceLevel->producers as $id => &$producer) {
$producer['name'] = $producers[$id];
}
}
if (!empty($priceLevel->products)) {
$products = sqlFetchAll(sqlQuery('SELECT id, title FROM products WHERE id IN (:ids)', ['ids' => array_keys($priceLevel->products)], ['ids' => \Doctrine\DBAL\Connection::PARAM_INT_ARRAY]), ['id' => 'title']);
foreach ($priceLevel->products as $id => &$product) {
$product['name'] = $products[$id];
}
}
return $priceLevel;
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {translate} function plugin.
*/
function smarty_modifier_checked($string, $value = null)
{
if (is_null($value)) {
return ($string) ? " checked='checked' " : '';
}
return ($string == $value) ? " checked='checked' " : '';
}

View File

@@ -0,0 +1,125 @@
<?php
/**
* Smarty plugin.
*/
function hex2rgb($hex)
{
$hex = str_replace('#', '', $hex);
if (strlen($hex) == 3) {
$r = hexdec(substr($hex, 0, 1).substr($hex, 0, 1));
$g = hexdec(substr($hex, 1, 1).substr($hex, 1, 1));
$b = hexdec(substr($hex, 2, 1).substr($hex, 2, 1));
} else {
$r = hexdec(substr($hex, 0, 2));
$g = hexdec(substr($hex, 2, 2));
$b = hexdec(substr($hex, 4, 2));
}
$rgb = [$r, $g, $b];
// return implode(",", $rgb); // returns the rgb values separated by commas
return $rgb; // returns an array with the rgb values
}
function rgb2hex($rgb)
{
$hex = '#';
$hex .= str_pad(dechex($rgb[0]), 2, '0', STR_PAD_LEFT);
$hex .= str_pad(dechex($rgb[1]), 2, '0', STR_PAD_LEFT);
$hex .= str_pad(dechex($rgb[2]), 2, '0', STR_PAD_LEFT);
return $hex; // returns the hex value including the number sign (#)
}
function rgbToHsl($r, $g, $b)
{
$r /= 255;
$g /= 255;
$b /= 255;
$max = max($r, $g, $b);
$min = min($r, $g, $b);
$l = ($max + $min) / 2;
$d = $max - $min;
if ($d == 0) {
$h = $s = 0; // achromatic
} else {
$s = $d / (1 - abs(2 * $l - 1));
switch ($max) {
case $r:
$h = 60 * fmod(($g - $b) / $d, 6);
if ($b > $g) {
$h += 360;
}
break;
case $g:
$h = 60 * (($b - $r) / $d + 2);
break;
case $b:
$h = 60 * (($r - $g) / $d + 4);
break;
}
}
return [round($h, 2), round($s, 2), round($l, 2)];
}
function hslToRgb($h, $s, $l)
{
$c = (1 - abs(2 * $l - 1)) * $s;
$x = $c * (1 - abs(fmod($h / 60, 2) - 1));
$m = $l - ($c / 2);
if ($h < 60) {
$r = $c;
$g = $x;
$b = 0;
} elseif ($h < 120) {
$r = $x;
$g = $c;
$b = 0;
} elseif ($h < 180) {
$r = 0;
$g = $c;
$b = $x;
} elseif ($h < 240) {
$r = 0;
$g = $x;
$b = $c;
} elseif ($h < 300) {
$r = $x;
$g = 0;
$b = $c;
} else {
$r = $c;
$g = 0;
$b = $x;
}
$r = ($r + $m) * 255;
$g = ($g + $m) * 255;
$b = ($b + $m) * 255;
return [floor($r), floor($g), floor($b)];
}
/**
* Smarty {color_lighter} modifier makes given color $amount % lighter.
*
* useage: {"#AABBCC"|color_lighter:10}
*/
function smarty_modifier_color_lighter($color, $amount = 10)
{
$color = hex2rgb($color);
$hsl = rgbToHsl($color[0], $color[1], $color[2]);
$rgb = hslToRgb($hsl[0], $hsl[1], min(max($hsl[2] + $amount / 100, 0), 1));
return rgb2hex($rgb);
}

View File

@@ -0,0 +1,35 @@
<?php
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\KupShopBundle\Util\Price\PriceUtil;
/**
* @param string $toCurrency
*
* @return Decimal|mixed|string
*/
function smarty_modifier_convert_price($price, $toCurrency = '')
{
/** @var CurrencyContext $currency */
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
if (!($price instanceof Price)) {
if (is_array($price)) {
$priceUtil = ServiceContainer::getService(PriceUtil::class);
$price = $priceUtil->getFromPriceArray($price);
} else {
$price = new Price(toDecimal($price), $currencyContext->getActive(), 0);
}
}
if (array_key_exists($toCurrency, $currencyContext->getSupported())) {
$toCurrency = $currencyContext->getSupported()[$toCurrency];
$price = PriceCalculator::convert($price, $toCurrency);
return printPrice($price->getPriceWithVat(), ['currency' => $toCurrency]);
} else {
user_error('Modifier convert_price: Unsupported currency '.$toCurrency);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty filesize modifier plugin.
*
* Type: modifier
* Name: filesize
* Purpose: show the filesize of a file in kb, mb, gb etc...
*
* @param string $
*
* @return string
*/
function smarty_modifier_filesize($size)
{
$size = max(0, (int) $size);
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
$power = $size > 0 ? floor(log($size, 1024)) : 0;
return number_format($size / pow(1024, $power), 2, '.', ',').' '.$units[$power];
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {translate} function plugin.
*/
function smarty_modifier_format_date($string, $format = null, $default_date = '', $formatter = 'auto')
{
if ($format == 'admin') {
if ($string == '-0001-11-30') {
return '00-00-0000';
}
if (empty($string)) {
return '';
}
$datetime = new DateTime($string);
return $datetime->format(Settings::getDateFormat());
}
if ($string instanceof DateTime) {
if (!$format) {
$format = Settings::getDateFormat();
}
return $string->format($format);
}
require_once SMARTY_PLUGINS_DIR.'modifier.date_format.php';
return smarty_modifier_date_format($string, $format, $default_date, $formatter);
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {translate} function plugin.
*
* @param $date DateTime
* @param null $format
* @param string $default_date
* @param string $formatter
*
* @return string
*/
function smarty_modifier_format_date_pretty($date, $format = null, $default_date = '', $formatter = 'auto')
{
if ($format === null) {
$format = 'd. m. Y';
}
if (!($date instanceof DateTime)) {
$date = new DateTime($date);
}
$today = new DateTime('midnight');
$tomorrow = new DateTime('+1 day midnight');
$dayAfterTomorrow = new DateTime('+2 day midnight');
if ($date > $today && $date < $tomorrow) {
return 'dnes';
}
if ($date > $tomorrow && $date < $dayAfterTomorrow) {
return 'zítra';
}
$format_date = $date->format($format);
$en_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
$cz_days = ['Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota', 'Neděle', 'leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'];
$format_date = str_replace($en_days, $cz_days, $format_date);
return $format_date;
}

View File

@@ -0,0 +1,13 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {format_ean} function plugin.
*/
function smarty_modifier_format_ean($ean, $params = '')
{
return formatEAN($ean);
}

View File

@@ -0,0 +1,28 @@
<?php
function smarty_modifier_format_filter_range($range)
{
if (!$range) {
return '';
}
$convertValue = function ($value) {
if ($value === null) {
return 'null';
}
return (float) $value;
};
$min = null;
$max = null;
if ($range instanceof Range) {
$min = $range->min();
$max = $range->max();
} elseif (is_array($range)) {
$min = $range['min'];
$max = $range['max'];
}
return 'data-filter-value=['.$convertValue($min).','.$convertValue($max).']';
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {format_price} function plugin.
*
* @param float $value Float to format
* @param int $decimals number of decimal places
*
* @return string
*/
function smarty_modifier_format_float($value, $decimals = 2)
{
if ($value == '') {
return '';
}
$value = (float) $value;
$decimals = (int) $decimals;
$value = number_format($value, abs($decimals), ',', ' ');
if ($decimals < 0) {
$value = trim($value, '0,');
}
return $value;
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {format_price} function plugin.
*
* @param int|array $price integer or array containing price
* @param string $params String describing
* parameters and default values:
* "withVat" => true,
* "ceil" => "default",
* "format" => true,
* "printcurrency" => true,
* "printdealerdiscount" => false,
* "dealerdiscount" => true,
*
* @return int|string
*/
function smarty_modifier_format_price($price, $params = '')
{
if ($price instanceof \KupShop\KupShopBundle\Wrapper\PriceWrapper) {
$price = $price->getObject();
}
// TODO remove: Fix float formated using czech locale
if (is_string($price) && strpos($price, ',') !== false) {
$price = str_replace(',', '.', $price);
}
$cond = [];
$part = preg_split('/;|,/', $params);
for ($i = 0; $i < count($part); $i++) {
$pair = explode('=', $part[$i]);
if ($pair[0] == '') {
continue;
}
if ($pair[1] == 'true' || $pair[1] == 'yes') {
$cond[$pair[0]] = true;
} elseif ($pair[1] == 'false' || $pair[1] == 'no') {
$cond[$pair[0]] = false;
} else {
$cond[$pair[0]] = (string) $pair[1];
}
}
return printPrice($price, $cond);
}

View File

@@ -0,0 +1,15 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {translate} function plugin.
*
* @return mixed|string
*/
function smarty_modifier_highlight($string, $words)
{
return emphasizeString($string, $words);
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* Smarty plugin.
*/
use KupShop\ContentBundle\Util\InlineEdit;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
/**
* Smarty {translate} function plugin.
*/
function smarty_modifier_inline_edit($block, $editable = true)
{
if (is_string($block) || is_null($block)) {
return $block;
}
/** @var InlineEdit $inlineEdit */
$inlineEdit = ServiceContainer::getService(InlineEdit::class);
$wrapped = $inlineEdit->wrapBlock($block);
if (!$editable && getAdminUser()) {
return $wrapped['unwrapped_content'];
}
if (isset($wrapped['content'])) {
return $wrapped['content'];
}
}

View File

@@ -0,0 +1,19 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {range_to_step} function plugin.
*
* @param $range array
*
* @return array new range
*/
function smarty_modifier_range_to_step($range, $step)
{
var_dump([$range, $step]);
// Math.pow(10, Math.floor(Math.log10(313)))
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {translate} function plugin.
*/
function smarty_modifier_selected($string, $value = null)
{
if (is_array($value)) {
return array_search($string, $value) !== false ? " selected='selected' " : '';
}
return ($string == $value) ? " selected='selected' " : '';
}

View File

@@ -0,0 +1,13 @@
<?php
/**
* Smarty plugin.
*/
/**
* Ignores result, do not print anything.
*/
function smarty_modifier_silent($string, $value = null)
{
return '';
}

View File

@@ -0,0 +1,82 @@
<?php
//
// sorts an array of named arrays by the supplied fields
// code by dholmes at jccc d0t net
// taken from http://au.php.net/function.uasort
// modified by cablehead, messju and pscs at http://www.phpinsider.com/smarty-forum
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Contexts;
function array_sort_by_fields(&$data, $sortby)
{
static $sort_funcs = [];
if ($data === '') {
return;
}
if (empty($sort_funcs[$sortby])) {
$sortData = [];
// prepare sort
foreach (explode(',', $sortby) as $key) {
$d = 1;
$c = 0;
if (substr($key, 0, 1) == '-') {
$d = -1;
$key = substr($key, 1);
}
if (substr($key, 0, 1) == '#') {
$key = substr($key, 1);
$sortCallable = function ($a, $b) use ($key, $d, $c) {
if ($a[$key] > $b[$key]) {
return $d * 1;
}
if ($a[$key] < $b[$key]) {
return $d * -1;
}
return $c;
};
} else {
$collator = new Collator(Contexts::get(LanguageContext::class)->getActive()->getLocale());
$sortCallable = function ($a, $b) use ($key, $d, $c, $collator) {
if (($c = $collator->compare($a[$key], $b[$key])) != 0) {
return $d * $c;
}
return $c;
};
}
$sortData[$key] = $sortCallable;
}
// create sort func
$sort_func = $sort_funcs[$sortby] = function ($a, $b) use ($sortData) {
foreach ($sortData as $key => $callable) {
return $callable($a, $b);
}
return 0;
};
} else {
$sort_func = $sort_funcs[$sortby];
}
uasort($data, $sort_func);
}
//
// Modifier: sortby - allows arrays of named arrays to be sorted by a given field
//
function smarty_modifier_sortby($arrData, $sortfields)
{
array_sort_by_fields($arrData, $sortfields);
return $arrData;
}
// $smarty->register_modifier( "sortby", "smarty_modifier_sortby" );

View File

@@ -0,0 +1,13 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {translate} function plugin.
*/
function smarty_modifier_strip_accent($string)
{
return createScriptURL_Text($string);
}

View File

@@ -0,0 +1,26 @@
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: date_format
* Purpose: format datestamps via strftime
* Input: string: input date string
* format: strftime format for output
* default_date: default date if $string is empty
* -------------------------------------------------------------
*/
function smarty_modifier_timestamp_format($string, $format = '%b %e, %Y', $default_date = null)
{
if ($string != '') {
return strftime($format, $string);
} elseif (isset($default_date) && $default_date != '') {
return strftime($format, $default_date);
} else {
return;
}
}
/* vim: set expandtab: */

View File

@@ -0,0 +1,18 @@
<?php
/**
* Smarty plugin.
*/
/**
* Smarty {translate} function plugin.
*/
function smarty_modifier_translate($string, $category = null, $silent = false, $isAdministration = null)
{
if (is_null($category) && !empty(Smarty::$global_tpl_vars['TRANSLATIONS_DOMAIN'])) {
$category = end(Smarty::$global_tpl_vars['TRANSLATIONS_DOMAIN']);
}
// echo "Kategorie: $category -- ";
return translate($string, $category, $silent, $isAdministration);
}

View File

@@ -0,0 +1,12 @@
<?php
function smarty_modifier_xml_string($string)
{
$string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');
// beware of the order of search@replace values
// str_replace() replaces left to right, it might replace a previously inserted value when doing multiple replacements
$string = str_replace(['&', '<', '>'], ['&amp;', '&lt;', '&gt;'], $string);
$string = preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $string);
return $string;
}

View File

@@ -0,0 +1,24 @@
<?php
/**
* Smarty Internal Plugin Resource File.
*
* Implements the file system as resource for Smarty templates
*/
class Smarty_Resource_Fallback extends Smarty_Internal_Resource_File
{
public function populate(Smarty_Template_Source $source, ?Smarty_Internal_Template $_template = null)
{
$files = $source->name;
foreach (explode(':', $files) as $part) {
$source->name = $part;
parent::populate($source, $_template);
if ($source->filepath !== false) {
return;
}
}
}
}

View File

@@ -0,0 +1,10 @@
<?php
/**
* Smarty Internal Plugin Resource File.
*
* Implements the file system as resource for Smarty templates
*/
class Smarty_Resource_Sharedtpl extends Smarty_Internal_Resource_File
{
}