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

275 lines
7.6 KiB
PHP

<?php
namespace KupShop\RewriteBundle\Util;
use KupShop\ContentBundle\Util\MenuUtil;
use KupShop\KupShopBundle\Context\DomainContext;
use KupShop\KupShopBundle\Util\StringUtil;
use Query\Operator;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\RouterInterface;
class Rewrite
{
use \DatabaseCommunication;
public const TYPE_PRODUCT = 0;
public const TYPE_PRODUCER = 1;
public const TYPE_CATEGORY = 3;
public const TYPE_CUSTOM = 4;
public const TYPE_PAGE = 5;
public const TYPE_VARIATION = 6;
public const TYPE_RAW = 7;
/**
* TYPE_ID => NAME.
*
* @var array
*/
public $config = [
self::TYPE_PRODUCT => 'product',
self::TYPE_PRODUCER => 'producer',
self::TYPE_CATEGORY => 'category',
self::TYPE_CUSTOM => 'custom',
self::TYPE_PAGE => 'page',
self::TYPE_VARIATION => 'variation',
self::TYPE_RAW => 'raw',
];
private $router;
private $domainContext;
public function __construct(RouterInterface $router, DomainContext $domainContext)
{
$this->router = $router;
$this->domainContext = $domainContext;
}
/**
* Resolve given url.
*/
public function resolve($url, &$type = null)
{
$url = $this->trimUrl($url);
$urlDecoded = $this->trimUrl(urldecode($url));
$row = sqlQueryBuilder()
->select('related_id, type')
->from('rewrite')
->where('url=:url')->setParameter('url', $urlDecoded)
->orWhere('url=:url4')->setParameter('url4', $url)
->orWhere('url=:url2')->setParameter('url2', rtrim($urlDecoded, '/'))
->orWhere('url=:url3')->setParameter('url3', $this->getActiveDomain().$urlDecoded)
->setMaxResults(1)->execute()->fetch();
if ($row) {
if (!empty($this->config[$row['type']])) {
$type = $row['type'];
return call_user_func([$this, 'resolve'.ucfirst($this->config[$row['type']])], $row['related_id']);
}
}
return false;
}
/**
* Add new rewrite.
*/
public function addRewrite($url, $type, $related_id)
{
$url = $this->trimUrl($url);
$check = $this->selectSQL('rewrite', ['url' => $url])->fetch();
if ($check) {
sqlQueryBuilder()->update('rewrite')
->directValues(['type' => $type, 'related_id' => $related_id])
->where(Operator::equals(['id' => $check['id']]))
->execute();
} else {
sqlQuery('INSERT IGNORE INTO rewrite (url, type, related_id) VALUES (:url, :type, :related_id)', [
'url' => $url,
'type' => $type,
'related_id' => $related_id,
]);
}
}
/**
* Return rewrite type and related id by given url.
*
* @return array
*/
public function getTypeByUrl($url)
{
$originalUrl = $url;
$url = $this->trimUrl($url);
if ($url !== '/') {
$url = '/'.$url.'/';
}
try {
$match = $this->router->match($url);
} catch (ResourceNotFoundException $e) {
$match = false;
}
// Controller::Action => [TYPE, id field in $match result]
$mappingType = [
'KupShop\CatalogBundle\Controller\CatalogController::sectionAction' => [self::TYPE_CATEGORY, 'id_section'],
'KupShop\CatalogBundle\Controller\CatalogController::producerAction' => [self::TYPE_PRODUCER, 'id_producer'],
'KupShop\ContentBundle\Controller\ProductController::productAction' => [self::TYPE_PRODUCT, 'id'],
];
if ($match && isset($mappingType[$match['_controller']])) {
return [
'type' => $mappingType[$match['_controller']][0],
'related' => $match[$mappingType[$match['_controller']][1]],
];
}
return [
'type' => self::TYPE_CUSTOM,
'related' => trim($originalUrl),
];
}
public function getTargetUrlByType($type, $related_id)
{
$targetURL = null;
switch ($type) {
case Rewrite::TYPE_PRODUCT:
$targetURL = $this->resolveProduct($related_id);
break;
case static::TYPE_PRODUCER:
$targetURL = $this->resolveProducer($related_id);
break;
case static::TYPE_CATEGORY:
$targetURL = $this->resolveCategory($related_id);
break;
case static::TYPE_PAGE:
$targetURL = $this->resolvePage($related_id);
break;
default:
$targetURL = $related_id;
}
return ltrim($targetURL, '/');
}
/**
* @return mixed|string
*/
public function trimUrl($url)
{
$url = trim($url);
if ($url === '/') {
return $url;
}
$url = trim($url, '/');
$url = rtrim($url, '?');
$url = str_replace(' ', '+', $url);
return $url;
}
protected function resolvePage($relatedId)
{
$page = sqlQueryBuilder()->select('id')
->from('menu_links')
->where(Operator::equals(['id' => $relatedId, 'type' => MenuUtil::TYPE_PAGE]))
->execute()->fetch();
if ($page) {
return createScriptURL([
's' => 'menuitem',
'ID' => $page['id'],
]);
}
return false;
}
/**
* @return bool|string
*/
protected function resolveProduct($relatedId)
{
$product = sqlQueryBuilder()->select('id')->from('products')
->where('id = :id')->setParameter('id', $relatedId)
->setMaxResults(1)->execute()->fetch();
if ($product && isset($product['id'])) {
return createScriptURL([
's' => 'product',
'IDproduct' => $product['id'],
]);
}
return false;
}
/**
* @return bool|string
*/
protected function resolveVariation($relatedId)
{
$product = sqlQueryBuilder()->select('id', 'id_product')->from('products_variations')
->where('id = :id')->setParameter('id', $relatedId)
->setMaxResults(1)->execute()->fetch();
if ($product && isset($product['id'])) {
return createScriptURL([
's' => 'product',
'IDproduct' => $product['id_product'],
]).'#'.$relatedId;
}
return false;
}
/**
* @return string
*/
protected function resolveProducer($relatedId)
{
return createScriptURL([
's' => 'category',
'IDpd' => $relatedId,
]);
}
/**
* @return string
*/
protected function resolveCategory($relatedId)
{
return createScriptURL([
's' => 'category',
'IDcat' => $relatedId,
]);
}
protected function resolveCustom($relatedId)
{
if (StringUtil::startsWith($relatedId, $this->getActiveDomain())) {
$result = str_replace($this->getActiveDomain(), '', $relatedId);
if (empty($result)) {
return '/';
}
return $result;
}
return $relatedId;
}
protected function resolveRaw($raw)
{
// RAW type returns "url" as content - usable for various site-validation files
return $raw;
}
private function getActiveDomain()
{
return 'https://'.trim($this->domainContext->getActiveId(), '/').'/';
}
}