Files
kupshop/bundles/KupShop/KupShopBundle/Util/LegacyUrlGenerator.php
2025-08-02 16:30:27 +02:00

427 lines
17 KiB
PHP

<?php
namespace KupShop\KupShopBundle\Util;
use KupShop\CatalogBundle\Section\SectionTree;
use KupShop\I18nBundle\Translations\ArticlesTagsTranslation;
use KupShop\I18nBundle\Translations\MenuLinksTranslation;
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Context\DomainContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\OrderingBundle\Util\CartFactory;
use Query\Operator;
use Query\Translation;
class LegacyUrlGenerator
{
protected $cfg;
/**
* @var SectionTree
*/
private $sectionTree;
private array $pageDataCache = [];
private array $producersCache = [];
public function __construct(SectionTree $sectionTree)
{
$this->cfg = Config::get();
$this->sectionTree = $sectionTree;
}
public function generate($params): string
{
$domainContext = ServiceContainer::getService(DomainContext::class);
unset($params['name']);
if (empty($params['absolute'])) {
$SERVER_URL = $this->cfg['Addr']['rel'];
} else {
$SERVER_URL = "https://{$domainContext->getActiveId()}/";
}
unset($params['absolute']);
if (!array_key_exists('URL', $params)) {
$params['URL'] = 'launch.php';
}
$SEO_URL = '';
$SEO_TITLE = '';
if (!empty($params['TITLE'])) {
$SEO_TITLE = createScriptURL_Text($params['TITLE']);
}
$SEO_URL = $this->processAll($params, $SERVER_URL, $SEO_URL, $SEO_TITLE);
unset($params['s']);
if (array_key_exists('search', $params) && !$params['search']) {
unset($params['search']);
}
$SEO_URL = createScriptURL_Next_Params($SEO_URL, $params);
if ($SEO_URL[0] == '/') {
$SEO_URL = $SERVER_URL.substr($SEO_URL, 1);
} elseif (!StringUtil::isAbsoluteUrl($SEO_URL)) {
$SEO_URL = $SERVER_URL.$SEO_URL;
}
return $SEO_URL;
}
protected function processAll(&$params, &$SERVER_URL, $SEO_URL, $SEO_TITLE): string
{
switch (@$params['s']) {
case 'category':
$SEO_URL = '/';
$IDcat = intval(getVal('IDcat', $params, 0));
$IDp = intval(getVal('IDpd', $params, 0));
$label = '';
$urlFlags = $this->cfg['Products']['UrlFlags'] ?? null;
if (preg_match("/^[[:digit:]]+({$urlFlags})$/i", getVal('IDcat', $params), $arr)) {
$label = strtoupper($arr[1]);
}
if (isset($params['campaign'])) {
$label = $params['campaign'];
}
if ($IDp) {
if (!empty($params['producerTitle'])) {
$SEO_URL .= createScriptURL_Text($params['producerTitle']);
} else {
if ($producerName = $this->getProducerName($IDp)) {
$SEO_URL .= createScriptURL_Text($producerName);
} else {
$SEO_URL .= translate_shop('producer', 'SEO_URL');
}
}
$SEO_URL .= "_v{$IDp}/";
}
$IDpv = intval(getVal('IDpv', $params, 0));
if ($IDpv) {
if (!empty($params['parameterValueTitle'])) {
$SEO_URL .= createScriptURL_Text($params['parameterValueTitle']);
} else {
$paramValue = sqlQueryBuilder()->select('value')->from('parameters_list')
->where('id=:id')->setParameter('id', $IDpv)->setMaxResults(1)->execute()->fetch();
if ($paramValue) {
$SEO_URL .= createScriptURL_Text($paramValue['value']);
}
}
$SEO_URL .= "_pv{$IDpv}/";
}
if ($IDcat > 0) {
if ($section = $this->sectionTree->getSectionById($IDcat)) {
if (!$IDp) {
if (($redirectUrl = $section->getRedirectUrl()) && StringUtil::isAbsoluteUrl($redirectUrl)) {
$SEO_URL = $redirectUrl;
} else {
$SEO_URL .= $section->getUrl();
}
} else {
$SEO_URL .= $section->getAutogeneratedUrl();
}
} else {
if (!empty($SEO_TITLE)) {
$SEO_URL .= $SEO_TITLE;
} else {
$SEO_URL .= translate_shop('category', 'SEO_URL');
}
$SEO_URL .= '_k'.$IDcat.'/';
}
}
if (!empty($label)) {
switch ($label) {
case 'F':
$SEO_URL .= translate_shop('favourite', 'SEO_URL');
break;
case 'W':
$SEO_URL .= translate_shop('watchdog-list', 'SEO_URL');
break;
default:
$SEO_URL .= getCampaigns()[$label]['url'];
}
$SEO_URL .= '/';
} elseif (!$IDp && !$IDcat) {
$SEO_URL .= translate_shop('category', 'SEO_URL').'/';
}
unset($params['IDcat'], $params['IDpd'], $params['producerTitle'], $params['parents'], $params['TM'], $params['campaign'],$params['IDpv'], $params['parameterValueTitle']);
break;
case 'product':
if (!empty($params['currency'])) {
$SERVER_URL .= "mena/{$params['currency']}/";
unset($params['currency']);
}
if (isset($params['category']) && isset($params['IDcat'])) {
unset($params['category']);
unset($params['IDcat']);
}
$params['IDproduct'] = intval(getVal('IDproduct', $params, 0));
if (empty($SEO_TITLE) && $params['IDproduct']) {
$SEO_TITLE = createScriptURL_Text(returnSQLResult("SELECT title FROM products WHERE id='{$params['IDproduct']}' LIMIT 1"));
}
$SEO_URL .= '/'.$SEO_TITLE;
$SEO_URL .= '_z'.$params['IDproduct'];
$SEO_URL .= '/';
unset($params['IDproduct']);
break;
case 'articles':
$SEO_URL = '/'.translate_shop($params['s'], 'SEO_URL').'/';
if (!empty($params['IDb'])) {
$SEO_URL .= $params['IDb'];
if (!empty($SEO_TITLE)) {
$SEO_URL .= '/'.$SEO_TITLE;
}
$SEO_URL .= '/';
}
unset($params['IDb']);
break;
case 'articles_tags':
$SEO_URL = '/'.translate_shop('articles', 'SEO_URL').'/'.translate_shop('tag', 'SEO_URL').'/';
if (!empty($params['ID'])) {
$SEO_URL .= $params['ID'];
if (empty($SEO_TITLE) && $params['ID']) {
$tag = sqlQueryBuilder()
->from('articles_tags', 'at')
->where(Operator::equals(['at.id' => $params['ID']]))
->andWhere(Translation::coalesceTranslatedFields(ArticlesTagsTranslation::class, ['tag']))
->execute()->fetch();
$SEO_TITLE = createScriptURL_Text($tag['tag'] ?? '');
}
$SEO_URL .= '/'.$SEO_TITLE.'/';
}
unset($params['ID']);
break;
case 'article':
$SEO_URL = '/'.translate_shop($params['s'], 'SEO_URL').'/';
$SEO_URL .= $params['IDa'];
if (!empty($SEO_TITLE)) {
$SEO_URL .= '/'.$SEO_TITLE;
}
$SEO_URL .= '/';
unset($params['IDa']);
break;
case 'author':
$SEO_URL = '/'.translate_shop('articles', 'SEO_URL').'/'.translate_shop($params['s'], 'SEO_URL').'/';
$SEO_URL .= $params['IDa'];
if (!empty($SEO_TITLE)) {
$SEO_URL .= '/'.$SEO_TITLE;
}
$SEO_URL .= '/';
unset($params['IDa']);
break;
case 'image':
$SEO_URL = '/'.translate_shop($params['s'], 'SEO_URL').'/';
$SEO_URL .= $params['IDph'];
if (!empty($SEO_TITLE)) {
$SEO_URL .= '/'.$SEO_TITLE;
}
$SEO_URL .= '/';
unset($params['IDph']);
break;
case 'watchdog':
$acn = $params['acn'] ?? 'add';
$route = $acn == 'add' ? 'kupshop_watchdog_watchdog_add' : 'kupshop_watchdog_watchdog_remove';
unset($params['acn'], $params['URL'], $params['s']);
$SEO_URL .= path($route, $params);
break;
case 'page':
if (empty($SEO_TITLE)) {
$page = $this->getPageData($params);
if (!$page && isDevelopment() && !translate_shop($params['label'] ?? '', 'SEO_URL', true)) {
throw new \Exception('Neexistuje stranka s label:'.($params['label'] ?? '').' nebo ID:'.($params['ID'] ?? ''));
}
$SEO_TITLE = createScriptURL_Text($page['name'] ?? '');
if (!empty($params['label'])) {
$params['ID'] = $page['id'] ?? null;
}
if ($page['url'] ?? false) {
$SEO_URL = '/'.$page['url'];
}
}
if (empty($SEO_URL) && !empty($params['label']) && translate_shop($params['label'], 'SEO_URL', true)) {
// Translated url - use fixed string
$SEO_URL = '/'.translate_shop($params['label'], 'SEO_URL', true).'/';
}
if (!$SEO_URL) {
$SEO_URL = "/{$SEO_TITLE}_p{$params['ID']}.html";
}
unset($params['label']);
unset($params['ID']);
break;
case 'menuitem':
$menuLinkId = $params['ID'];
$menuLink = sqlQueryBuilder()
->from('menu_links', 'ml')
->andWhere(Operator::equals(['ml.id' => $menuLinkId]))
->andWhere(Translation::coalesceTranslatedFields(MenuLinksTranslation::class, ['url']))
->execute()->fetch();
if (isDevelopment() && (!$menuLink || !$menuLink['url'])) {
throw new \Exception("Neexistuje stranka s ID {$params['ID']} nebo nemá URL");
}
$SEO_URL = $menuLink['url'] ?? '/';
unset($params['ID']);
break;
case 'index':
$SEO_URL = '/';
break;
case 'user':
$SEO_URL = (getVal('act', $params) == 'new') ?
'/'.translate_shop('user_new', 'SEO_URL').'/' : '/'.translate_shop('user_edit', 'SEO_URL').'/';
unset($params['act']);
break;
case 'login':
if (@$params['act'] == 'passw') {
$SEO_URL = '/'.translate_shop('login-passw', 'SEO_URL').'/';
unset($params['act']);
} else {
$SEO_URL = '/'.translate_shop('login', 'SEO_URL').'/';
if (!empty($params['redir'])) {
$SEO_URL .= '?'.$params['redir'];
}
unset($params['redir']);
}
break;
case 'orderView':
$SEO_URL = '/'.translate_shop($params['s'], 'SEO_URL').'/';
$SEO_URL .= $params['IDo'].'/';
if (empty($params['cf'])) {
unset($params['cf']);
}
if (!empty($params['edit'])) {
$SEO_URL .= translate_shop('orderEdit', 'SEO_URL').'/';
}
unset($params['edit']);
unset($params['IDo']);
break;
/*case "orderHistory":
$SEO_URL = "/".translate_shop($params['s'], 'SEO_URL')."/";
$SEO_URL .= $params['IDo'] . "/";
if(empty($params['cf']))
unset($params['cf']);
unset($params['IDo']);
break;*/
case 'compare':
$SEO_URL = '/'.translate_shop($params['s'], 'SEO_URL').'/';
if (!empty($params['linkProducts'])) {
$SEO_URL .= '?'.$params['linkProducts'];
}
unset($params['s'], $params['linkProducts']);
break;
case 'newsletter':
$SEO_URL = '/'.$params['s'].'/';
if (!empty($params['ID']) && !empty($params['date'])) {
$SEO_URL .= $params['date'].'/'.$params['ID'].'/';
unset($params['date'], $params['ID']);
}
break;
case 'ordering':
$cart = ServiceContainer::getService(CartFactory::class)->create();
if (isset($cart->steps[$params['step']])) {
$step = $cart->steps[$params['step']];
} else {
// fallback, kdyz chybi step, aby to nespadlo na tom, ze return type neni string
$step = reset($cart->steps);
}
$SEO_URL = $step['url'];
unset($params['step']);
break;
case 'currency':
$SEO_URL = '/';
if (!empty($params['change'])) {
$SERVER_URL .= "mena/{$params['change']}/";
unset($params['change']);
}
break;
case 'captcha':
default:
if (isset($params['s']) && translate_shop($params['s'], 'SEO_URL', true)) {
$SEO_URL .= '/'.translate_shop($params['s'], 'SEO_URL').'/';
} else {
$SEO_URL = '/'.ltrim($params['URL'], '/');
if (!empty($params['s'])) {
$SEO_URL .= '?s='.$params['s'];
}
}
break;
}
unset($params['s']);
return $SEO_URL;
}
private function getPageData(array $params): ?array
{
$language = Contexts::get(LanguageContext::class)->getActiveId();
if (!($this->pageDataCache[$language] ?? false)) {
$qb = sqlQueryBuilder()
->select('ml.id, ml.name, ml.url, ml.code, ml.old_id_page')
->from('menu_links', 'ml')
->andWhere(Translation::coalesceTranslatedFields(MenuLinksTranslation::class, ['id', 'name', 'url']))
->andWhere('ml.code IS NOT NULL OR ml.old_id_page IS NOT NULL');
$this->pageDataCache[$language]['byCode'] = [];
$this->pageDataCache[$language]['byOldIdPage'] = [];
foreach ($qb->execute() as $item) {
if (!empty($item['old_id_page'])) {
$this->pageDataCache[$language]['byOldIdPage'][$item['old_id_page']] = $item;
}
if (!empty($item['code'])) {
$this->pageDataCache[$language]['byCode'][$item['code']] = $item;
}
}
}
if (!empty($params['label'])) {
$data = $this->pageDataCache[$language]['byCode'][$params['label']] ?? null;
} else {
$data = $this->pageDataCache[$language]['byOldIdPage'][$params['ID']] ?? null;
}
return $data;
}
private function getProducerName(int $producerId): ?string
{
if (!isset($this->producersCache[$producerId])) {
$query = sqlQueryBuilder()
->select('name')
->from('producers')
->andWhere(Operator::equals(['id' => $producerId]))
->setMaxResults(1);
$this->producersCache[$producerId] = $query->execute()->fetchOne() ?: null;
}
return $this->producersCache[$producerId];
}
}