275 lines
7.6 KiB
PHP
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(), '/').'/';
|
|
}
|
|
}
|