first commit

This commit is contained in:
2024-11-11 18:46:54 +01:00
commit a630d17338
25634 changed files with 4923715 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
class ArSeoProDispatcherResponse
{
public $id = null;
public $property = null;
public $controllerMatched = false;
public $controllerProbably = false;
public $useIfProbably = true;
}

View File

@@ -0,0 +1,200 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
include_once dirname(__FILE__).'/../ArSeoModel.php';
/**
* @property ArSeoProUrls $owner
*/
abstract class ArSeoProURLAbstract extends ArSeoModel
{
const REDIRECT_NONE = 0;
const REDIRECT_PARENT = 1;
const REDIRECT_404 = 2;
const REGEX_ALPHA_NUMERIC = '[_a-zA-Z0-9-\pL]*';
public $schema;
public function __construct($module, $configPrefix = null, $owner = null)
{
parent::__construct($module, $configPrefix);
$this->owner = $owner;
$this->configPrefix = $this->getConfigPrefix();
}
abstract public function getRuleId();
abstract public function getRoute();
abstract public function getDefaultRoute();
abstract public function dispatch();
abstract public function preDispatch($uri, $route_id, $route, $m, $id_lang, $id_shop);
public function keywords()
{
return array();
}
public function keywordLabels()
{
return array();
}
public function getKeywordLabel($keyword)
{
$labels = $this->keywordLabels();
return isset($labels[$keyword])? $labels[$keyword] : null;
}
public function getKeywords()
{
$result = array();
$keywords = $this->keywords();
foreach (array_keys($keywords) as $k) {
$result[$k] = $this->getKeywordLabel($k);
}
return $result;
}
public function regexp($regexp, $param = null, $required = true)
{
if ($param) {
return array('regexp' => $regexp, 'param' => $param);
}
return array('regexp' => $regexp);
}
public static function getConfigTab()
{
return 'url';
}
public function beforeSave()
{
if ($this->schema == $this->getDefaultRoute()) {
$this->schema = null;
}
return parent::beforeSave();
}
public function getRouteRule()
{
$dispatcher = Dispatcher::getInstance();
$defaultRoutes = $dispatcher->default_routes;
$rule = Configuration::get('PS_ROUTE_' . $this->getRuleId());
if (!$rule) {
$rule = $defaultRoutes[$this->getRuleId()]['rule'];
}
return $rule;
}
public function renderSchemaField()
{
return $this->module->render('_partials/url/_schema.tpl', array(
'schema' => $this->getRouteRule(),
'ruleId' => $this->getRuleId(),
'link' => Context::getContext()->link->getAdminLink('AdminMeta'),
'is16' => $this->module->is16(),
'is17' => $this->module->is17(),
'is174' => $this->module->is174()
));
}
public function redirectCodeSelectOptions()
{
return array(
array(
'id' => '301',
'name' => $this->l('301 Moved Permanently', 'ArSeoProURLProduct')
),
array(
'id' => '302',
'name' => $this->l('302 Moved Temporarily', 'ArSeoProURLProduct')
)
);
}
public function getConfigPrefix()
{
return null;
}
public function attributeTypes()
{
return array(
'enable' => 'switch',
'keep_id' => 'switch',
'redirect_code' => 'select',
'keywords' => 'html',
'schema' => 'html',
'disable_old' => 'switch'
);
}
public function htmlFields()
{
return array(
'keywords' => $this->module->render('_partials/url/_keywords.tpl', array(
'keywords' => $this->getKeywords(),
'target' => 'PS_ROUTE_' . $this->getRuleId()
)),
'schema' => $this->renderSchemaField()
);
}
public function attributeLabels()
{
return array(
'enable' => $this->l('Enable', 'ArSeoProURLAbstract'),
'disable_old' => $this->l('Disable old routes', 'ArSeoProURLAbstract'),
'redirect_code' => $this->l('Redirect code', 'ArSeoProURLAbstract'),
'keywords' => ''
);
}
public function hasKeyword($rule, $keyword)
{
return preg_match('#\{([^{}]*:)?' . preg_quote($keyword, '#') . '(:[^{}]*)?\}#', $rule);
}
public function getBaseLink($idShop = null, $ssl = null, $relativeProtocol = false)
{
if (null === $ssl) {
$ssl = (Configuration::get('PS_SSL_ENABLED') && Configuration::get('PS_SSL_ENABLED_EVERYWHERE'));
}
$ssl_enable = Configuration::get('PS_SSL_ENABLED');
if (Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE') && $idShop !== null) {
$shop = new Shop($idShop);
} else {
$shop = Context::getContext()->shop;
}
if ($relativeProtocol) {
$base = '//' . ($ssl && $ssl_enable ? $shop->domain_ssl : $shop->domain);
} else {
$base = (($ssl && $ssl_enable) ? 'https://' . $shop->domain_ssl : 'http://' . $shop->domain);
}
return $base . $shop->getBaseURI();
}
}

View File

@@ -0,0 +1,370 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
include_once dirname(__FILE__).'/ArSeoProURLAbstract.php';
class ArSeoProURLCMS extends ArSeoProURLAbstract
{
const CONFIG_PREFIX = 'arscms_';
public $enable;
public $keep_id;
public $parent_cat;
public $redirect;
public $redirect_code;
public $disable_old;
public function getRuleId()
{
return 'cms_rule';
}
public function getDuplicates()
{
$langs = $this->module->getLanguages();
$return = array();
$limit = ' LIMIT 5';
$sql = 'SELECT cl.`id_cms`, cl.`link_rewrite`, cs.`id_shop`, cl.`id_lang` FROM `'._DB_PREFIX_.'cms_lang` cl ' .
'LEFT JOIN `'._DB_PREFIX_.'cms` c ON cl.`id_cms` = c.`id_cms` ' .
'LEFT JOIN `'._DB_PREFIX_.'cms_shop` cs ON cl.`id_cms` = cs.`id_cms` ' .
'WHERE cl.`id_lang` IN ('.implode(',', $langs).') ' .
'GROUP BY cs.`id_shop`, cl.`id_lang`, cl.`link_rewrite`';
if ($this->parent_cat) {
$sql .= ', c.`id_cms_category`';
}
$sql .= ' HAVING count(cl.`link_rewrite`) > 1 ORDER BY cs.`id_shop` ASC' . pSQL($limit);
$duplicates = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($duplicates) {
foreach ($duplicates as $duplicate) {
$sql2 = 'SELECT cl.`id_cms`, cl.`link_rewrite`, cs.`id_shop`, cl.`id_lang`, cl.`meta_title` FROM `' . _DB_PREFIX_.'cms_lang` cl '
. 'LEFT JOIN `'._DB_PREFIX_.'cms` c ON cl.`id_cms` = c.`id_cms` '
. 'LEFT JOIN `'._DB_PREFIX_.'cms_shop` cs ON cl.`id_cms` = cs.`id_cms` '
. 'WHERE cs.`id_shop` = '.(int)($duplicate['id_shop']).' '
. 'AND cl.`link_rewrite` = "'.pSQL($duplicate['link_rewrite']).'" '
. 'AND cl.`id_lang` = '.(int)($duplicate['id_lang']);
if ($this->parent_cat) {
$sql2 .= ' AND c.`id_cms_category` = '.(int)($duplicate['id_cms_category']);
}
$sql2 .= ' GROUP BY cl.`id_cms`'.pSQL($limit);
$more = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql2);
if (count($more) > 1) {
foreach ($more as $info) {
$row = array();
$row['id'] = 'cms_'.$info['id_cms'];
$row['id_object'] = $info['id_cms'];
$row['id_type'] = 'cms';
$row['type'] = 'CMS';
$row['name'] = $info['meta_title'];
$row['link_rewrite'] = $info['link_rewrite'];
$row['id_lang'] = $info['id_lang'];
$row['lang'] = $this->owner->getIsoLang($info['id_lang']);
$row['shop'] = '';
$shop = Shop::getShop($info['id_shop']);
if ($shop) {
$row['shop'] = $shop['name'];
}
$return[] = $row;
}
}
}
}
return $return;
}
protected function getQuery($rewrite, $id_lang = null, $id_shop = null, $id_cms_category = false)
{
$sql = new DbQuery();
$sql->from('cms_lang', 't');
$sql->join('LEFT JOIN `'._DB_PREFIX_.'cms` c ON t.`id_cms` = c.`id_cms`');
if ($id_shop) {
$sql->join('LEFT JOIN `'._DB_PREFIX_.'cms_shop` cs ON c.`id_cms` = cs.`id_cms`');
}
$where = array("t.`link_rewrite` = '" . pSQL($rewrite) . "'");
if ($id_lang) {
$where[] = "t.`id_lang` = " . (int)$id_lang;
}
if ($id_shop) {
$where[] = "t.`id_shop` = " . (int)$id_shop;
$where[] = "cs.`id_shop` = " . (int)$id_shop;
}
if ($id_cms_category !== false) {
$where[] = "c.id_cms_category = " . (int)$id_cms_category;
}
$where[] = 'c.active = 1';
$sql->where(implode(' AND ', $where));
return $sql;
}
public function preDispatch($uri, $route_id, $route, $m, $id_lang, $id_shop)
{
$return = $this->owner->getEmptyPreDispatcherResponse();
$rewrite = '';
if (isset($m['ars_rewrite_cms'])) {
$rewrite = $m['ars_rewrite_cms'];
}
if ($this->module->is17()) {
$sql = $this->getQuery($rewrite, $id_lang, $id_shop);
} else {
$sql = $this->getQuery($rewrite, $id_lang);
}
$result = Db::getInstance()->getRow($sql);
if (isset($m['ars_id_cms']) && $m['ars_id_cms']) {
$id = $m['ars_id_cms'];
} else {
$id = null;
}
if ($result || $id) {
if ($result) {
$id = $result['id_cms'];
}
$return->controllerMatched = true;
if (!$id) {
$id_cms_category = $this->owner->cmsCategory->getCategoryIdFromCategoriesRewrite(
$this->owner->cmsCategory->getFromParamsCMSCategories($m),
$id_lang,
$id_shop
);
if ($this->parent_cat) {
$id = Db::getInstance()->getValue($this->getQuery($rewrite, $id_lang, null, $id_cms_category));
} else {
$sql = $this->getQuery($rewrite);
}
if (!$id) {
$id = Db::getInstance()->getValue($sql);
}
}
if ($id) {
$return->id = $id;
$return->property = 'id_cms';
} else {
$return->controllerMatched = false;
}
}
if (!$id) {
$id_cms_category = $this->owner->cmsCategory->getCategoryIdFromCategoriesRewrite(
$this->owner->cmsCategory->getFromParamsCMSCategories($m),
$id_lang,
$id_shop
);
if ($id_cms_category > 1) {
$return->controllerProbably = true;
if ($this->redirect == self::REDIRECT_NONE) {
$return->useIfProbably = false;
}
}
}
return $return;
}
public function dispatch()
{
$context = $this->owner->getContext();
$id_shop = $context->shop->id;
$id_lang = $context->language->id;
$id_cms = Tools::getValue('id_cms');
if (!$id_cms) {
if ($this->redirect == self::REDIRECT_PARENT) {
$id_parent = $this->owner->cmsCategory->getCategoryIdFromCategoriesRewrite(
Tools::getValue('ars_rewrite_cms_categories'),
$id_lang,
$id_shop
);
if ($id_parent > 1) {
$redirect_url = $context->link->getCMSCategoryLink($id_parent);
$this->owner->redirect($redirect_url, ArSeoHelpers::getResponseHeader($this->redirect_code? $this->redirect_code : 301));
}
}
$this->owner->redirectToNotFound();
}
$_GET['id_cms'] = $id_cms;
if (ArSeoHelpers::getIsset('ars_rewrite_cms')) {
unset($_GET['ars_rewrite_cms']);
}
if (ArSeoHelpers::getIsset('ars_rewrite_cms_categories')) {
unset($_GET['ars_rewrite_cms_categories']);
}
if (ArSeoHelpers::getIsset('fc')) {
unset($_GET['fc']);
}
}
public function getDefaultRoute()
{
if (!$this->parent_cat) {
if ($this->keep_id) {
return 'content/{id}-{rewrite}.html';
}
return 'content/{rewrite}.html';
}
if ($this->keep_id) {
return 'content/{categories:/}{id}-{rewrite}.html';
}
return 'content/{categories:/}{rewrite}.html';
}
public function getRoute()
{
$route = array(
'controller' => 'cms',
'rule' => $this->getDefaultRoute(),
'keywords' => array(
'id' => $this->keep_id ? $this->regexp('[0-9]+', 'ars_id_cms') : $this->regexp('[0-9]+'),
'rewrite' => $this->regexp('[_a-zA-Z0-9\pL\pS-]*', 'ars_rewrite_cms'),
'categories' => $this->regexp('[/_a-zA-Z0-9-\pL]*', 'ars_rewrite_cms_categories'),
'meta_keywords' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'meta_title' =>$this->regexp(self::REGEX_ALPHA_NUMERIC),
),
'params' => array(
'fc' => 'controller'
)
);
if (!$this->parent_cat) {
unset($route['keywords']['categories']['param']);
}
return $route;
}
public function getConfigPrefix()
{
return self::CONFIG_PREFIX;
}
public function rules()
{
return array(
array(
array(
'enable',
'keep_id',
'parent_cat',
'redirect',
'redirect_code',
'schema',
'keywords',
'disable_old'
), 'safe'
)
);
}
public function redirectSelectOptions()
{
return array(
array(
'id' => self::REDIRECT_NONE,
'name' => $this->l('None', 'ArSeoProURLCMS')
),
array(
'id' => self::REDIRECT_PARENT,
'name' => $this->l('Redirect to category', 'ArSeoProURLCMS')
),
array(
'id' => self::REDIRECT_404,
'name' => $this->l('Redirect to page not found', 'ArSeoProURLCMS')
)
);
}
public function attributeDescriptions()
{
$domain = $this->getBaseLink();
$desc = parent::attributeDescriptions();
return array_merge($desc, array(
'parent_cat' => sprintf($this->l('Example: %scontent/parent-category/children-category/page-rewrite.html', 'ArSeoProURLCMS'), $domain),
'redirect' => $this->l('Redirect type if CMS page not found', 'ArSeoProURLCMS')
));
}
public function attributeLabels()
{
$labels = parent::attributeLabels();
return array_merge($labels, array(
'enable' => $this->l('Enable this tab functionality', 'ArSeoProURLCMS'),
'keep_id' => $this->l('Keep CMS page ID in the URL', 'ArSeoProURLCMS'),
'parent_cat' => $this->l('Include parent category to URL', 'ArSeoProURLCMS'),
'redirect' => $this->l('Redirect type if CMS Page not found', 'ArSeoProURLCMS'),
'schema' => $this->l('Current CMS Page URL scheme', 'ArSeoProURLCMS'),
));
}
public function attributeTypes()
{
$types = parent::attributeTypes();
return array_merge($types, array(
'parent_cat' => 'switch',
'redirect' => 'select',
));
}
public function attributeDefaults()
{
return array(
'enable' => 1,
'redirect' => self::REDIRECT_PARENT
);
}
public function afterSave()
{
if ($rule = Configuration::get('PS_ROUTE_cms_rule')) {
if ($this->hasKeyword($rule, 'categories') && !$this->parent_cat) {
$rule = str_replace('{categories:/}', '', $rule);
} elseif (!$this->hasKeyword($rule, 'categories') && $this->parent_cat) {
if ($this->hasKeyword($rule, 'id')) {
$rule = str_replace('{id}', '{categories:/}{id}', $rule);
} else {
$rule = str_replace('{rewrite}', '{categories:/}{rewrite}', $rule);
}
}
if (!$this->hasKeyword($rule, 'id') && $this->keep_id) {
$rule = str_replace('{rewrite}', '{id}-{rewrite}', $rule);
} elseif ($this->hasKeyword($rule, 'id') && !$this->keep_id) {
$rule = str_replace('{id}-{rewrite}', '{rewrite}', $rule);
}
ConfigurationCore::updateValue('PS_ROUTE_cms_rule', $rule);
}
return parent::afterSave();
}
}

View File

@@ -0,0 +1,416 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
include_once dirname(__FILE__).'/ArSeoProURLAbstract.php';
class ArSeoProURLCMSCategory extends ArSeoProURLAbstract
{
const CONFIG_PREFIX = 'arscmsc_';
public $enable;
public $keep_id;
public $parent_cat;
public $redirect;
public $redirect_code;
public $disable_old;
public function getRuleId()
{
return 'cms_category_rule';
}
public function getDuplicates()
{
$langs = $this->module->getLanguages();
$return = array();
$limit = ' LIMIT 5';
$sql = 'SELECT ccl.`id_cms_category`, ccl.`link_rewrite`, ccl.`id_lang`'
. ' FROM `' . _DB_PREFIX_.'cms_category_lang` ccl'
. ' LEFT JOIN `'._DB_PREFIX_.'cms_category` cc ON ccl.`id_cms_category` = cc.`id_cms_category`'
. ' WHERE ccl.`id_lang` IN ('.implode(',', $langs).')'
. ' GROUP BY ccl.`id_lang`, ccl.`link_rewrite`';
if ($this->parent_cat) {
$sql .= ', cc.`id_parent`';
}
$sql .= ' HAVING count(ccl.`link_rewrite`) > 1' . pSQL($limit);
$duplicates = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($duplicates) {
foreach ($duplicates as $duplicate) {
$sql2 = 'SELECT ccl.`id_cms_category`, ccl.`link_rewrite`, ccl.`id_lang`, ccl.`name`'
. ' FROM `' . _DB_PREFIX_ . 'cms_category_lang` ccl LEFT JOIN `'._DB_PREFIX_.'cms_category`'
. ' cc ON ccl.`id_cms_category` = cc.`id_cms_category`'
. ' WHERE ccl.`link_rewrite` = "'.pSQL($duplicate['link_rewrite']).'"'
. ' AND ccl.`id_lang` = '.(int)$duplicate['id_lang'];
if ($this->parent_cat) {
$sql2 .= ' AND cc.`id_parent` = '.(int)$duplicate['id_parent'];
}
$sql2 .= ' GROUP BY ccl.`id_cms_category`' . pSQL($limit);
$more = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql2);
if (count($more) > 1) {
foreach ($more as $info) {
$row = array();
$row['id'] = 'cmscategory_'.$info['id_cms_category'];
$row['id_object'] = $info['id_cms_category'];
$row['id_type'] = 'cms_category';
$row['type'] = 'CMS Category';
$row['name'] = $info['name'];
$row['link_rewrite'] = $info['link_rewrite'];
$row['id_lang'] = $info['id_lang'];
$row['lang'] = $this->owner->getIsoLang($info['id_lang']);
$return[] = $row;
}
}
}
}
return $return;
}
public function getQuery($rewrite, $id_lang = null, $id_parent = false)
{
$sql = new DbQuery();
$sql->from('cms_category_lang', 't');
$sql->join("LEFT JOIN `" . _DB_PREFIX_ . "cms_category` cc ON t.`id_cms_category` = cc.`id_cms_category`");
$where = array(
"t.`link_rewrite` = '" . pSQL($rewrite) . "'"
);
if ($id_lang) {
$where[] = "t.`id_lang` = " . (int)$id_lang;
}
if ($id_parent !== false) {
$where[] = "cc.id_parent = " . (int)$id_parent;
}
$sql->where(implode(' AND ', $where));
return $sql;
}
public function preDispatch($uri, $route_id, $route, $m, $id_lang, $id_shop)
{
$return = $this->owner->getEmptyPreDispatcherResponse();
$rewrite = '';
if (isset($m['ars_rewrite_cms_category'])) {
$rewrite = $m['ars_rewrite_cms_category'];
}
$sql = $this->getQuery($rewrite, $id_lang);
$result = Db::getInstance()->getRow($sql);
$id_cms_category = null;
if (isset($m['ars_id_cms_cat']) && $m['ars_id_cms_cat']) {
$id_cms_category = $m['ars_id_cms_cat'];
} else {
$id_cms_category = null;
}
if ($result || $id_cms_category) {
$return->controllerMatched = true;
if (!$id_cms_category) {
$id_parent = $this->getCategoryIdFromCategoriesRewrite(
$this->getFromParamsCMSCategories($m),
$id_lang,
$id_shop
);
if ($this->parent_cat) {
$sql = $this->getQuery($rewrite, $id_lang, $id_parent);
} else {
$sql = $this->getQuery($rewrite, $id_lang);
}
$id_cms_category = Db::getInstance()->getValue($sql);
if (!$id_cms_category) {
if ($this->parent_cat) {
$id_cms_category = Db::getInstance()->getValue($this->getQuery($rewrite, null, $id_parent));
} else {
$id_cms_category = Db::getInstance()->getValue($this->getQuery($rewrite, null));
}
}
}
if ($id_cms_category) {
$return->id = $id_cms_category;
$return->property = 'id_cms_category';
} else {
$return->controllerMatched = false;
}
}
if (!$id_cms_category) {
$id_cms_category = $this->getCategoryIdFromCategoriesRewrite(
$this->getFromParamsCMSCategories($m),
$id_lang,
$id_shop
);
if ($id_cms_category > 1) {
$return->controllerProbably = true;
if ($this->redirect == self::REDIRECT_NONE) {
$return->useIfProbably = false;
}
}
}
return $return;
}
public function dispatch()
{
$context = $this->owner->getContext();
$id_shop = $context->shop->id;
$id_lang = $context->language->id;
$id_cms_category = Tools::getValue('id_cms_category');
if (!$id_cms_category) {
if ($this->redirect == self::REDIRECT_PARENT) {
$id_parent = $this->getCategoryIdFromCategoriesRewrite(
Tools::getValue('ars_rewrite_cms_categories'),
$id_lang,
$id_shop
);
if ($id_parent > 1) {
$redirect_url = $context->link->getCMSCategoryLink($id_parent);
$this->owner->redirect($redirect_url, ArSeoHelpers::getResponseHeader($this->redirect_code? $this->redirect_code : 301));
}
}
$this->owner->redirectToNotFound();
}
$_GET['id_cms_category'] = $id_cms_category;
if (ArSeoHelpers::getIsset('ars_rewrite_cms_category')) {
unset($_GET['ars_rewrite_cms_category']);
}
if (ArSeoHelpers::getIsset('ars_rewrite_cms_categories')) {
unset($_GET['ars_rewrite_cms_categories']);
}
if (ArSeoHelpers::getIsset('fc')) {
unset($_GET['fc']);
}
}
public function getCMSCategoryParentCategories($id_cms_category, $id_lang = null)
{
if (is_null($id_lang)) {
$id_lang = Context::getContext()->language->id;
}
$categories = array();
$id_current = $id_cms_category;
while (true) {
$sql = 'SELECT c.*, cl.* FROM `'._DB_PREFIX_.'cms_category` c '
. 'LEFT JOIN `'._DB_PREFIX_.'cms_category_lang` cl ON (c.`id_cms_category` = cl.`id_cms_category` '
. 'AND `id_lang` = '.(int)$id_lang.') '
. 'WHERE c.`id_cms_category` = '.(int)$id_current.' AND c.`id_parent` != 0';
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);
if ($result) {
$categories[] = $result;
if (!$result || $result['id_parent'] == 1) {
return $categories;
}
$id_current = $result['id_parent'];
} else {
return $categories;
}
}
}
public function getCategoryIdFromCategoriesRewrite($rewrite_categories, $id_lang, $id_shop)
{
$id_cms_category = 1;
if ($rewrite_categories) {
$rewrite_categories_array = explode('/', $rewrite_categories);
foreach ($rewrite_categories_array as $rewrite_category) {
$sql = 'SELECT ccl.`id_cms_category` FROM `'._DB_PREFIX_.'cms_category_lang` ccl '
. 'LEFT JOIN `'._DB_PREFIX_.'cms_category` cc ON ccl.id_cms_category = cc.id_cms_category '
. 'WHERE ccl.`link_rewrite` = "'.pSQL($rewrite_category).'" '
. 'AND cc.id_parent = '.(int)($id_cms_category).'';
$result = Db::getInstance()->getValue($sql . ' AND ccl.`id_lang` = '.(int)($id_lang));
if ($result) {
$id_cms_category = $result;
}
if (!$id_cms_category) {
$result = Db::getInstance()->getValue($sql);
if ($result) {
$id_cms_category = $result;
}
}
}
$this->owner->doNothing($id_shop);
}
return $id_cms_category;
}
public function getFromParamsCMSCategories($m)
{
return isset($m['ars_rewrite_cms_categories'])? $m['ars_rewrite_cms_categories'] : '';
}
public function getDefaultRoute()
{
if (!$this->parent_cat) {
if ($this->keep_id) {
return 'content/{id}-{rewrite}/';
}
return 'content/{rewrite}/';
}
if ($this->keep_id) {
return 'content/{categories:/}{id}-{rewrite}/';
}
return 'content/{categories:/}{rewrite}/';
}
public function getRoute()
{
$route = array(
'controller' => 'cms',
'rule' => $this->getDefaultRoute(),
'keywords' => array(
'id' => $this->keep_id ? $this->regexp('[0-9]+', 'ars_id_cms_cat') : $this->regexp('[0-9]+'),
'rewrite' => $this->regexp('[_a-zA-Z0-9\pL\pS-]*', 'ars_rewrite_cms_category'),
'categories' => $this->regexp('[/_a-zA-Z0-9-\pL]*', 'ars_rewrite_cms_categories'),
'meta_keywords' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'meta_title' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
),
'params' => array(
'fc' => 'controller'
)
);
if (!$this->parent_cat) {
unset($route['keywords']['categories']['param']);
}
return $route;
}
public function getConfigPrefix()
{
return self::CONFIG_PREFIX;
}
public function rules()
{
return array(
array(
array(
'enable',
'keep_id',
'parent_cat',
'redirect',
'redirect_code',
'schema',
'keywords',
'disable_old'
), 'safe'
)
);
}
public function redirectSelectOptions()
{
return array(
array(
'id' => self::REDIRECT_NONE,
'name' => $this->l('None', 'ArSeoProURLCMS')
),
array(
'id' => self::REDIRECT_PARENT,
'name' => $this->l('Redirect to category', 'ArSeoProURLCMS')
),
array(
'id' => self::REDIRECT_404,
'name' => $this->l('Redirect to page not found', 'ArSeoProURLCMS')
)
);
}
public function attributeDescriptions()
{
$domain = $this->getBaseLink();
$desc = parent::attributeDescriptions();
return array_merge($desc, array(
'parent_cat' => sprintf($this->l('Example: %scontent/parent-category/children-category/page-rewrite.html', 'ArSeoProURLCMSCategory'), $domain),
'redirect' => $this->l('Redirect type if category not found', 'ArSeoProURLCMSCategory')
));
}
public function attributeLabels()
{
$labels = parent::attributeLabels();
return array_merge($labels, array(
'enable' => $this->l('Enable this tab functionality', 'ArSeoProURLCMSCategory'),
'keep_id' => $this->l('Keep CMS category ID in the URL', 'ArSeoProURLCMSCategory'),
'parent_cat' => $this->l('Include parent category to URL', 'ArSeoProURLCMSCategory'),
'redirect' => $this->l('Redirect type if CMS category not found', 'ArSeoProURLCMSCategory'),
'schema' => $this->l('Current CMS Category URL scheme', 'ArSeoProURLCMSCategory'),
));
}
public function attributeTypes()
{
$types = parent::attributeTypes();
return array_merge($types, array(
'parent_cat' => 'switch',
'redirect' => 'select',
));
}
public function attributeDefaults()
{
return array(
'enable' => 1,
'redirect' => self::REDIRECT_PARENT
);
}
public function afterSave()
{
if ($rule = Configuration::get('PS_ROUTE_cms_category_rule')) {
if ($this->hasKeyword($rule, 'categories') && !$this->parent_cat) {
$rule = str_replace('{categories:/}', '', $rule);
} elseif (!$this->hasKeyword($rule, 'categories') && $this->parent_cat) {
if ($this->hasKeyword($rule, 'id')) {
$rule = str_replace('{id}', '{categories:/}{id}', $rule);
} else {
$rule = str_replace('{rewrite}', '{categories:/}{rewrite}', $rule);
}
}
if (!$this->hasKeyword($rule, 'id') && $this->keep_id) {
$rule = str_replace('{rewrite}', '{id}-{rewrite}', $rule);
} elseif ($this->hasKeyword($rule, 'id') && !$this->keep_id) {
$rule = str_replace('{id}-{rewrite}', '{rewrite}', $rule);
}
ConfigurationCore::updateValue('PS_ROUTE_cms_category_rule', $rule);
}
return parent::afterSave();
}
}

View File

@@ -0,0 +1,570 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
include_once dirname(__FILE__).'/ArSeoProURLAbstract.php';
class ArSeoProURLCategory extends ArSeoProURLAbstract
{
const CONFIG_PREFIX = 'arsc_';
public $enable;
public $keep_id;
public $enable_layered;
public $parent_cat;
public $redirect;
public $redirect_code;
public $disable_old;
public function getRuleId()
{
return 'category_rule';
}
public function getDuplicates()
{
$langs = $this->module->getLanguages();
$return = array();
$limit = ' LIMIT 5';
$id_shop = Context::getContext()->shop->id;
$sql = 'SELECT cl.`id_category`, cl.`link_rewrite`, cl.`id_shop`, cl.`id_lang`, c.`id_parent` FROM `'._DB_PREFIX_.'category_lang` cl '
. 'LEFT JOIN `' . _DB_PREFIX_ . 'category` c ON cl.`id_category` = c.`id_category` '
. 'LEFT JOIN `' . _DB_PREFIX_ . 'category_shop` cs ON cs.id_category = c.id_category '
. 'WHERE cl.`id_lang` IN ('.implode(',', $langs).') AND cl.id_shop = ' . (int)$id_shop . ' AND cs.id_shop = ' . (int)$id_shop . ' '
. 'GROUP BY cl.`id_shop`, cl.`id_lang`, cl.`link_rewrite`';
if ($this->parent_cat) {
$sql .= ', c.`id_parent`';
}
$sql .= ' HAVING count(cl.`link_rewrite`) > 1 ORDER BY cl.`id_shop` ASC' . pSQL($limit);
$duplicates = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($duplicates) {
foreach ($duplicates as $duplicate) {
$sql2 = 'SELECT cl.`id_category`, cl.`link_rewrite`, cl.`id_shop`, cl.`id_lang`, c.`id_parent`, cl.`name` FROM `'._DB_PREFIX_.'category_lang` cl '
. 'LEFT JOIN `' . _DB_PREFIX_ . 'category` c ON cl.`id_category` = c.`id_category` '
. 'LEFT JOIN `' . _DB_PREFIX_ . 'category_shop` cs ON cs.id_category = c.id_category '
. 'WHERE cl.`id_shop` = ' . (int)($duplicate['id_shop']) . ' AND cl.id_shop = ' . (int)$id_shop . ' AND cs.id_shop = ' . (int)$id_shop . ' '
. 'AND cl.`link_rewrite` = "' . pSQL($duplicate['link_rewrite']) . '" '
. 'AND cl.`id_lang` = ' . (int)($duplicate['id_lang']);
if ($this->parent_cat) {
$sql2 .= ' AND c.`id_parent` = ' . (int)($duplicate['id_parent']);
}
$sql2 .= ' GROUP BY cl.`id_category`' . pSQL($limit);
$more = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql2);
foreach ($more as $info) {
$row = array();
$row['id'] = 'category_'.$info['id_category'];
$row['id_arseopro'] = 'category_'.$info['id_category'];
$row['id_object'] = $info['id_category'];
$row['id_type'] = 'category';
$row['type'] = 'Category';
$row['name'] = $info['name'];
$row['link_rewrite'] = $info['link_rewrite'];
$row['id_lang'] = $info['id_lang'];
$row['lang'] = $this->owner->getIsoLang($info['id_lang']);
$row['shop'] = '';
if ($shop = Shop::getShop($info['id_shop'])) {
$row['shop'] = $shop['name'];
}
$return[] = $row;
}
}
}
return $return;
}
public function preDispatch($uri, $route_id, $route, $m, $id_lang, $id_shop)
{
$return = $this->owner->getEmptyPreDispatcherResponse();
$context = $this->owner->getContext();
$routes = Dispatcher::getInstance()->getRoutes();
$rewrite = '';
if (isset($m['ars_rewrite_category'])) {
$rewrite = $m['ars_rewrite_category'];
}
$sql = 'SELECT cl.`id_category`, c.is_root_category FROM `'._DB_PREFIX_.'category_lang` cl '
. 'LEFT JOIN `'._DB_PREFIX_.'category` c ON cl.id_category = c.id_category '
. 'LEFT JOIN `' . _DB_PREFIX_ . 'category_shop` cs ON cs.id_category = c.id_category '
. 'WHERE cl.`id_shop` = '.(int)($id_shop) . ' AND cs.id_shop = ' . (int)$id_shop . ' '
. 'AND cl.`link_rewrite` = "'.pSQL($rewrite).'"';
$result = Db::getInstance()->getRow($sql.' AND cl.`id_lang` = ' . (int)$id_lang);
$id_category = null;
if (isset($m['ars_id_category']) && $m['ars_id_category']) {
$id_category = $m['ars_id_category'];
} else {
$id_category = null;
}
if ($result || $id_category) {
$return->controllerMatched = true;
if (!$id_category) {
$sql = 'SELECT cl.`id_category` FROM `'._DB_PREFIX_.'category_lang` cl '
. 'LEFT JOIN `'._DB_PREFIX_.'category` c ON cl.id_category = c.id_category '
. 'LEFT JOIN `' . _DB_PREFIX_ . 'category_shop` cs ON cs.id_category = c.id_category '
. 'WHERE cl.`id_shop` = ' . (int)($id_shop) . ' AND cs.id_shop = ' . (int)$id_shop . ' '
. 'AND cl.`link_rewrite` = "' . pSQL($rewrite) . '" ';
if ($this->parent_cat && !$result['is_root_category']) {
$id_parent = $this->getLastIdFromCategoriesRewrite(
$this->getFromParamsCategories($m),
$context->shop->id_category,
$id_lang,
$id_shop,
false
);
if ($id_parent && is_array($id_parent)) {
$sql .= ' AND c.id_parent IN (' . implode(',', $id_parent) . ')';
} elseif ($id_parent && !is_array($id_parent)) {
$sql .= ' AND c.id_parent = ' . (int)$id_parent;
}
}
$id_category = Db::getInstance()->getValue($sql . ' AND cl.`id_lang` = '.(int)($id_lang));
if (!$id_category) {
$id_category = Db::getInstance()->getValue($sql);
}
}
if (!$id_category) {
if (isset($routes[$id_shop][$id_lang]['old_category_rule'])) {
$dispatcher = Dispatcher::getInstance();
$request_uri = $dispatcher->getRequestUri();
if (Tools::substr($request_uri, -1) == '/') {
$request_uri = Tools::substr($dispatcher->getRequestUri(), 0, -1);
}
if (preg_match(
$routes[$id_shop][$id_lang]['old_category_rule']['regexp'],
$request_uri,
$m_sub
)) {
if (isset($m_sub['id_category'])) {
$id_category = $m_sub['id_category'];
}
}
}
}
if ($id_category) {
$c = new Category($id_category);
if (!$c->active) {
$id_category = 0;
}
}
if ($id_category) {
$return->id = $id_category;
$return->property = 'id_category';
} else {
$return->controllerMatched = false;
}
}
if (!$id_category) {
$id_category = $this->getLastIdFromCategoriesRewrite(
$this->getFromParamsCategories($m),
$context->shop->id_category,
$id_lang,
$id_shop
);
if ($this->redirect == self::REDIRECT_NONE) {
$return->useIfProbably = false;
}
if ($id_category && $id_category != $context->shop->id_category) {
$return->controllerProbably = true;
if ((in_array($route_id, array('layered_rule', 'layered_rule_2'))) && $this->redirect == 'best') {
$selected_filters = $this->getLayeredParamFromUri($uri, $id_category);
if ($selected_filters) {
$_GET['selected_filters_maybe'] = $selected_filters;
}
$return->id = $id_category;
$return->property = 'id_category';
$return->controllerMatched = true;
}
}
} else {
if ((in_array($route_id, array('layered_rule', 'layered_rule_2'))) && $this->redirect == 'best') {
$selected_filters = $this->getLayeredParamFromUri($uri, $id_category);
if ($selected_filters) {
$_GET['selected_filters_maybe'] = $selected_filters;
}
}
}
return $return;
}
public function getLayeredParamFromUri($uri, $id_category)
{
$common_part = $this->getLongestMatchingSubstring($this->context->link->getCategoryLink($id_category), $uri);
$selected_filters = '';
if ($common_part) {
$selected_filters = str_replace($common_part, '', $uri);
}
if ($selected_filters) {
if (ArSeoHelpers::endWith(trim($selected_filters), '/')) {
$selected_filters = Tools::substr($selected_filters, 0, -1);
}
if (ArSeoHelpers::startWith(trim($selected_filters), '/')) {
$selected_filters = Tools::substr($selected_filters, 1);
}
$filter_helper = array();
$selected_filters_array = explode('/', $selected_filters);
foreach ($selected_filters_array as $selected_filter) {
if (ArSeoHelpers::contains($selected_filter, '-')) {
$filter_helper[] = $selected_filter;
}
}
if ($filter_helper) {
$selected_filters = implode('/', $filter_helper);
}
}
return $selected_filters;
}
public function getLongestMatchingSubstring($str1, $str2)
{
$len_1 = Tools::strlen($str1);
$longest = '';
for ($i = 0; $i < $len_1; $i++) {
for ($j = $len_1 - $i; $j > 0; $j--) {
$sub = Tools::substr($str1, $i, $j);
if (Tools::strpos($str2, $sub) !== false && Tools::strlen($sub) > Tools::strlen($longest)) {
$longest = $sub;
break;
}
}
}
return $longest;
}
public function dispatch()
{
$context = $this->owner->getContext();
$id_shop = $context->shop->id;
$id_lang = $context->language->id;
if (Tools::getValue('ars_rewrite_category')) {
$id_category = Tools::getValue('id_category');
if (!$id_category) {
if ($this->redirect == ArSeoProURLCategory::REDIRECT_PARENT) {
$id_parent = $this->getLastIdFromCategoriesRewrite(
Tools::getValue('ars_rewrite_categories'),
$context->shop->id_category,
$id_lang,
$id_shop
);
if ($id_parent != $context->shop->id_category) {
$redirect_url = $context->link->getCategoryLink($id_parent);
$this->owner->redirect($redirect_url, ArSeoHelpers::getResponseHeader($this->redirect_code? $this->redirect_code : 301));
}
$this->owner->redirect($context->link->getPageLink('index'), ArSeoHelpers::getResponseHeader($this->redirect_code? $this->redirect_code : 301));
} elseif ($this->redirect == self::REDIRECT_404) {
$this->owner->redirectToNotFound();
}
$this->owner->redirectToNotFound();
}
if (Tools::getValue('selected_filters_maybe')) {
$_GET['selected_filters'] = Tools::getValue('selected_filters_maybe');
unset($_GET['selected_filters_maybe']);
}
if ($this->module->is17() && Tools::getValue('selected_filters')) {
$_GET['q'] = Tools::getValue('selected_filters');
}
$_GET['id_category'] = $id_category;
if (ArSeoHelpers::getIsset('ars_rewrite_category')) {
unset($_GET['ars_rewrite_category']);
}
if (ArSeoHelpers::getIsset('ars_rewrite_categories')) {
unset($_GET['ars_rewrite_categories']);
}
if (ArSeoHelpers::getIsset('fc')) {
unset($_GET['fc']);
}
}
}
public function getLastIdFromCategoriesRewrite($rewrite_categories, $id_parent, $id_lang, $id_shop, $returnAll = false)
{
$res = array();
if ($rewrite_categories) {
$rewrite_categories = explode('/', $rewrite_categories);
foreach ($rewrite_categories as $rewrite_category) {
$sql = 'SELECT cl.`id_category` FROM `'._DB_PREFIX_.'category_lang` cl '
. 'LEFT JOIN `'._DB_PREFIX_.'category` c ON cl.id_category = c.id_category '
. 'WHERE cl.`id_shop` = '.(int)($id_shop) . ' '
. 'AND cl.`link_rewrite` = "' . pSQL($rewrite_category) . '" '
. 'AND c.id_parent = '.(int)($id_parent);
if ($returnAll) {
$result = Db::getInstance()->executeS($sql.' AND cl.`id_lang` = '.(int)($id_lang));
foreach ($result as $row) {
$res[] = $row['id_category'];
}
}
$result = Db::getInstance()->getValue($sql.' AND cl.`id_lang` = '.(int)($id_lang));
if ($result) {
$id_parent = $result;
}
if (!$id_parent) {
$result = Db::getInstance()->getValue($sql);
if ($result) {
$id_parent = $result;
}
}
}
}
if ($returnAll) {
return $res;
}
return $id_parent;
}
public function getFromParamsCategories($m)
{
return isset($m['ars_rewrite_categories'])? $m['ars_rewrite_categories'] : '';
}
public function getIdFromCategoryRewrite($rewrite_category, $id_category, $id_lang, $id_shop, $returnAll = false)
{
$res = array();
if ($rewrite_category) {
$sql = 'SELECT cl.`id_category` FROM `'._DB_PREFIX_.'category_lang` cl '
. 'LEFT JOIN `'._DB_PREFIX_.'category` c ON cl.id_category = c.id_category '
. 'WHERE cl.`id_shop` = '.(int)($id_shop).' '
. 'AND cl.`link_rewrite` = "'.pSQL($rewrite_category).'"';
if ($returnAll) {
$result = Db::getInstance()->executeS($sql.' AND cl.`id_lang` = '.(int)($id_lang));
foreach ($result as $row) {
$res[] = $row['id_category'];
}
return $res;
} else {
$result = Db::getInstance()->getValue($sql.' AND cl.`id_lang` = '.(int)($id_lang));
}
if ($result) {
$id_category = $result;
}
if (!$id_category) {
if ($result = Db::getInstance()->getValue($sql)) {
$id_category = $result;
}
}
}
return $id_category;
}
public function getFromParamsCategory($m)
{
return isset($m['ars_rewrite_category'])? $m['ars_rewrite_category'] : '';
}
public function getDefaultRoute()
{
$route = array();
if ($this->parent_cat) {
$route[] = '{categories:/}';
}
if ($this->keep_id) {
$route[] = '{id}-';
}
$route[] = '{rewrite}';
return implode('', $route) . '/';
}
public function getRoute()
{
$route = array(
'controller' => 'category',
'rule' => $this->getDefaultRoute(),
'keywords' => array(
'id' => $this->keep_id? $this->regexp('[0-9]+', 'ars_id_category') : $this->regexp('[0-9]+'),
'rewrite' => $this->regexp('[_a-zA-Z0-9\pL\pS-]*', 'ars_rewrite_category'),
'categories' => $this->regexp('[/_a-zA-Z0-9-\pL]*', 'ars_rewrite_categories'),
'meta_keywords' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'meta_title' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
),
'params' => array(
'fc' => 'controller'
)
);
if (!$this->parent_cat) {
unset($route['keywords']['categories']['param']);
}
return $route;
}
public function getLayeredRoute()
{
$route = array(
'controller' => 'category',
'rule' => '{categories:/}{rewrite}/{/:selected_filters}/',
'keywords' => array(
'id' => $this->keep_id? $this->regexp('[0-9]+', 'ars_id_category') : $this->regexp('[0-9]+'),
'selected_filters' => $this->regexp('.*', 'selected_filters'),
'rewrite' => $this->regexp('[_a-zA-Z0-9\pL\pS-]*', 'ars_rewrite_category'),
'categories' => $this->regexp('[/_a-zA-Z0-9-\pL]*', 'ars_rewrite_categories'),
'meta_keywords' => $this->regexp('[_a-zA-Z0-9-\pL]*'),
'meta_title' => $this->regexp('[_a-zA-Z0-9-\pL]*'),
),
'params' => array(
'fc' => 'controller'
)
);
if (!$this->parent_cat) {
$route['rule'] = '{rewrite}{/:selected_filters}';
unset($route['keywords']['categories']['param']);
}
return $route;
}
public function getConfigPrefix()
{
return self::CONFIG_PREFIX;
}
public function rules()
{
return array(
array(
array(
'enable',
'keep_id',
'enable_layered',
'parent_cat',
'redirect',
'redirect_code',
'schema',
'keywords',
'disable_old'
), 'safe'
)
);
}
public function redirectSelectOptions()
{
return array(
array(
'id' => self::REDIRECT_NONE,
'name' => $this->l('None', 'ArSeoProURLCategory')
),
array(
'id' => self::REDIRECT_PARENT,
'name' => $this->l('Redirect to parent category', 'ArSeoProURLCategory')
),
array(
'id' => self::REDIRECT_404,
'name' => $this->l('Redirect to page not found', 'ArSeoProURLCategory')
)
);
}
public function attributeDescriptions()
{
$domain = $this->getBaseLink();
$desc = parent::attributeDescriptions();
return array_merge($desc, array(
'parent_cat' => sprintf($this->l('Example: %sparent-category/children-category/category-rewrite/', 'ArSeoProURLCategory'), $domain),
'redirect' => $this->l('Redirect type if category not found', 'ArSeoProURLCategory')
));
}
public function attributeLabels()
{
$labels = parent::attributeLabels();
return array_merge($labels, array(
'enable' => $this->l('Enable this tab functionality', 'ArSeoProURLCategory'),
'keep_id' => $this->l('Keep category ID in the URL', 'ArSeoProURLCategory'),
'enable_layered' => $this->l('Handle faceted search URLs', 'ArSeoProURLCategory'),
'parent_cat' => $this->l('Include parent category to URL', 'ArSeoProURLCategory'),
'redirect' => $this->l('Redirect type if category not found', 'ArSeoProURLCategory'),
'schema' => $this->l('Current Category URL scheme', 'ArSeoProURLCategory'),
));
}
public function attributeTypes()
{
$types = parent::attributeTypes();
return array_merge($types, array(
'enable_layered' => 'switch',
'parent_cat' => 'switch',
'redirect' => 'select',
));
}
public function attributeDefaults()
{
return array(
'enable' => 1,
'enable_layered' => 0,
'parent_cat' => 1,
'redirect' => self::REDIRECT_PARENT
);
}
public function afterSave()
{
if ($rule = Configuration::get('PS_ROUTE_category_rule')) {
if ($this->hasKeyword($rule, 'categories') && !$this->parent_cat) {
$rule = str_replace('{categories:/}', '', $rule);
} elseif (!$this->hasKeyword($rule, 'categories') && $this->parent_cat) {
$rule = '{categories:/}' . $rule;
}
if (!$this->hasKeyword($rule, 'id') && $this->keep_id) {
$rule = str_replace('{rewrite}', '{id}-{rewrite}', $rule);
} elseif ($this->hasKeyword($rule, 'id') && !$this->keep_id) {
$rule = str_replace('{id}-{rewrite}', '{rewrite}', $rule);
}
ConfigurationCore::updateValue('PS_ROUTE_category_rule', $rule);
}
return parent::afterSave();
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
include_once dirname(__FILE__).'/../ArSeoModel.php';
class ArSeoProURLGeneral extends ArSeoModel
{
const CONFIG_PREFIX = 'ars_';
public $remove_def_lang;
public function rules()
{
return array(
array(
array(
'remove_def_lang'
), 'safe'
)
);
}
public function attributeLabels()
{
return array(
'remove_def_lang' => $this->l('Remove default language from URL', 'ArSeoProURLGeneral')
);
}
public function __construct($module, $configPrefix = null, $owner = null)
{
parent::__construct($module, $configPrefix);
$this->owner = $owner;
$this->configPrefix = $this->getConfigPrefix();
}
public function getConfigPrefix()
{
return self::CONFIG_PREFIX;
}
public static function getConfigTab()
{
return 'url';
}
public function attributeTypes()
{
return array(
'remove_def_lang' => 'switch'
);
}
}

View File

@@ -0,0 +1,268 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
include_once dirname(__FILE__).'/ArSeoProURLAbstract.php';
class ArSeoProURLManufacturer extends ArSeoProURLAbstract
{
const CONFIG_PREFIX = 'arsm_';
public $enable;
public $keep_id;
public $redirect;
public $redirect_code;
public $disable_old;
public function getRuleId()
{
return 'manufacturer_rule';
}
public function getDuplicates()
{
$return = array();
$limit = ' LIMIT 5';
$sql = 'SELECT m.`id_manufacturer`, ms.`id_shop`, m.`name` FROM `'._DB_PREFIX_.'manufacturer` m '
. 'LEFT JOIN `'._DB_PREFIX_.'manufacturer_shop` ms ON m.`id_manufacturer` = ms.`id_manufacturer` '
. 'GROUP BY ms.`id_shop`, m.`name` '
. 'HAVING count(m.`name`) > 1 ORDER BY ms.`id_shop` ASC' . pSQL($limit);
$duplicates = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($duplicates) {
foreach ($duplicates as $duplicate) {
$sql2 = 'SELECT m.`id_manufacturer`, ms.`id_shop`, m.`name` FROM `'._DB_PREFIX_.'manufacturer` m '
. 'LEFT JOIN `'._DB_PREFIX_.'manufacturer_shop` ms ON m.`id_manufacturer` = ms.`id_manufacturer` '
. 'WHERE ms.`id_shop` = '.(int)($duplicate['id_shop']).' '
. 'AND m.`name` = "'.pSQL($duplicate['name']).'" '
. 'GROUP BY m.`id_manufacturer`' . pSQL($limit);
$more = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql2);
foreach ($more as $info) {
$row = array();
$row['id'] = 'manufacturer_'.$info['id_manufacturer'];
$row['id_object'] = $info['id_manufacturer'];
$row['id_type'] = 'manufacturer';
$row['type'] = 'Manufacturer';
$row['name'] = $info['name'];
$row['shop'] = '';
if ($shop = Shop::getShop($info['id_shop'])) {
$row['shop'] = $shop['name'];
}
$return[] = $row;
}
}
}
return $return;
}
public function preDispatch($uri, $route_id, $route, $m, $id_lang, $id_shop)
{
$return = $this->owner->getEmptyPreDispatcherResponse();
$rewrite = '';
if (isset($m['ars_rewrite_manufacturer'])) {
$rewrite = $m['ars_rewrite_manufacturer'];
}
if (isset($m['ars_id_manufacturer']) && $m['ars_id_manufacturer']) {
$id_manufacturer = $m['ars_id_manufacturer'];
} else {
$id_manufacturer = null;
}
if (!$id_manufacturer) {
$id_manufacturer = Db::getInstance()->getValue(
'SELECT m.`id_manufacturer` FROM `'._DB_PREFIX_.'manufacturer` m '
. 'LEFT JOIN `'._DB_PREFIX_.'manufacturer_shop` ms ON m.id_manufacturer = ms.id_manufacturer '
. 'WHERE ms.`id_shop` = '.(int)($id_shop).' AND REPLACE(LOWER(m.`name`), " ", "-") = "'.pSQL($rewrite).'"'
);
}
if (!$id_manufacturer) {
$manufacturers = Db::getInstance()->executeS(
'SELECT m.`id_manufacturer`, m.`name` FROM `'._DB_PREFIX_.'manufacturer` m '
. 'LEFT JOIN `'._DB_PREFIX_.'manufacturer_shop` ms ON m.id_manufacturer = ms.id_manufacturer '
. 'WHERE ms.`id_shop` = '.(int)($id_shop)
);
if ($manufacturers) {
foreach ($manufacturers as $manufacturer) {
if ($rewrite == Tools::str2url($manufacturer['name'])) {
$id_manufacturer = $manufacturer['id_manufacturer'];
break;
}
}
}
}
if ($id_manufacturer) {
$return->controllerMatched = true;
$return->id = $id_manufacturer;
$return->property = 'id_manufacturer';
} else {
if (!ArSeoHelpers::startWith(trim($route['rule']), '{')) {
$return->controllerProbably = true;
if ($this->redirect == self::REDIRECT_NONE) {
$return->useIfProbably = false;
}
}
}
return $return;
}
public function dispatch()
{
$context = $this->owner->getContext();
if (Tools::getValue('ars_rewrite_manufacturer')) {
$id_manufacturer = Tools::getValue('id_manufacturer');
if (!$id_manufacturer) {
if ($this->redirect == ArSeoProURLManufacturer::REDIRECT_PARENT) {
$this->owner->redirect($context->link->getPageLink('manufacturer'), ArSeoHelpers::getResponseHeader($this->redirect_code? $this->redirect_code : 301));
}
$this->owner->redirectToNotFound();
}
$_GET['id_manufacturer'] = $id_manufacturer;
if (ArSeoHelpers::getIsset('ars_rewrite_manufacturer')) {
unset($_GET['ars_rewrite_manufacturer']);
}
if (ArSeoHelpers::getIsset('fc')) {
unset($_GET['fc']);
}
}
}
public function getDefaultRoute()
{
if ($this->keep_id) {
return 'manufacturer/{id}-{rewrite}.html';
}
return 'manufacturer/{rewrite}.html';
}
public function getRoute()
{
return array(
'controller' => 'manufacturer',
'rule' => $this->getDefaultRoute(),
'keywords' => array(
'id' => $this->keep_id ? $this->regexp('[0-9]+', 'ars_id_manufacturer') : $this->regexp('[0-9]+'),
'rewrite' => $this->regexp('[_a-zA-Z0-9\pL\pS-]*', 'ars_rewrite_manufacturer'),
'meta_keywords' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'meta_title' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
),
'params' => array(
'fc' => 'controller'
)
);
}
public function getConfigPrefix()
{
return self::CONFIG_PREFIX;
}
public function rules()
{
return array(
array(
array(
'enable',
'keep_id',
'redirect',
'redirect_code',
'schema',
'keywords',
'disable_old'
), 'safe'
)
);
}
public function redirectSelectOptions()
{
return array(
array(
'id' => self::REDIRECT_NONE,
'name' => $this->l('None', 'ArSeoProURLManufacturer')
),
array(
'id' => self::REDIRECT_PARENT,
'name' => $this->l('Redirect to manufacturer list', 'ArSeoProURLManufacturer')
),
array(
'id' => self::REDIRECT_404,
'name' => $this->l('Redirect to page not found', 'ArSeoProURLManufacturer')
)
);
}
public function attributeDescriptions()
{
return array_merge(parent::attributeDescriptions(), array(
'redirect' => $this->l('Redirect type if category not found', 'ArSeoProURLManufacturer')
));
}
public function attributeLabels()
{
return array_merge(parent::attributeLabels(), array(
'enable' => $this->l('Enable this tab functionality', 'ArSeoProURLManufacturer'),
'keep_id' => $this->l('Keep manufacturer ID in the URL', 'ArSeoProURLManufacturer'),
'redirect' => $this->l('Redirect type if manufacturer not found', 'ArSeoProURLManufacturer'),
'schema' => $this->l('Current Manufacturer URL scheme', 'ArSeoProURLManufacturer'),
));
}
public function attributeTypes()
{
return array_merge(parent::attributeTypes(), array(
'redirect' => 'select'
));
}
public function attributeDefaults()
{
return array(
'enable' => 1,
'redirect' => self::REDIRECT_PARENT
);
}
public function afterSave()
{
if ($rule = Configuration::get('PS_ROUTE_manufacturer_rule')) {
if (!$this->hasKeyword($rule, 'id') && $this->keep_id) {
$rule = str_replace('{rewrite}', '{id}-{rewrite}', $rule);
} elseif ($this->hasKeyword($rule, 'id') && !$this->keep_id) {
$rule = str_replace('{id}-{rewrite}', '{rewrite}', $rule);
}
ConfigurationCore::updateValue('PS_ROUTE_manufacturer_rule', $rule);
}
return parent::afterSave();
}
}

View File

@@ -0,0 +1,555 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
include_once dirname(__FILE__).'/ArSeoProURLAbstract.php';
class ArSeoProURLProduct extends ArSeoProURLAbstract
{
const CONFIG_PREFIX = 'arsp_';
public $enable;
public $keep_id;
public $default_cat;
public $parent_cat;
public $redirect;
public $redirect_code;
public $redirect_not_active;
public $redirect_not_active_code;
public $disable_old;
public $disable_anchor;
public $disable_default_attr_anchor;
public $remove_anchor_id;
public $enable_attr;
public $disable_default_attr;
public function getRuleId()
{
return 'product_rule';
}
public function getDuplicates()
{
$langs = $this->module->getLanguages();
$return = array();
$limit = ' LIMIT 5';
$id_shop = Context::getContext()->shop->id;
$sql = 'SELECT pl.`id_product`, pl.`link_rewrite`, pl.`id_shop`, pl.`id_lang`, p.`id_category_default`, COUNT(pl.`id_product`) as count FROM `'._DB_PREFIX_.'product_lang` pl '
. 'LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON pl.`id_product` = p.`id_product` '
. 'WHERE pl.`id_lang` IN ('.implode(',', $langs).') AND p.active = 1 AND pl.id_shop = ' . (int)$id_shop . ' '
. 'GROUP BY pl.`id_shop`, pl.`id_lang`, pl.`link_rewrite`';
if ($this->default_cat || $this->parent_cat) {
$sql .= ', p.`id_category_default`';
}
$sql .= ' HAVING count(pl.`link_rewrite`) > 1 ORDER BY pl.`id_shop` ASC' . pSQL($limit);
$duplicates = Db::getInstance()->executeS($sql);
if ($duplicates) {
foreach ($duplicates as $duplicate) {
$sql2 = 'SELECT pl.`id_product`, pl.`link_rewrite`, pl.`id_shop`, pl.`id_lang`, p.`id_category_default`, pl.`name` FROM `'._DB_PREFIX_.'product_lang` pl '
. 'LEFT JOIN `' . _DB_PREFIX_.'product` p ON pl.`id_product` = p.`id_product` WHERE pl.`id_shop` = ' . (int)$duplicate['id_shop'] . ' '
. 'AND pl.`link_rewrite` = "' . pSQL($duplicate['link_rewrite']) . '" '
. 'AND pl.`id_lang` = ' . (int)$duplicate['id_lang'];
if ($this->default_cat || $this->parent_cat) {
$sql2 .= ' AND p.`id_category_default` = ' . (int)($duplicate['id_category_default']);
}
$sql2 .= ' GROUP BY pl.`id_product` ORDER BY pl.`id_product` ASC' . pSQL($limit);
$more = Db::getInstance()->executeS($sql2);
foreach ($more as $info) {
$row = array();
$row['id_arseopro'] = 'product_'.$info['id_product'];
$row['id'] = 'product_'.$info['id_product'];
$row['id_object'] = $info['id_product'];
$row['id_type'] = 'product';
$row['type'] = 'Product';
$row['name'] = $info['name'];
$row['link_rewrite'] = $info['link_rewrite'];
$row['id_lang'] = $info['id_lang'];
$row['lang'] = $this->owner->getIsoLang($info['id_lang']);
$row['shop'] = '';
if ($shop = Shop::getShop($info['id_shop'])) {
$row['shop'] = $shop['name'];
}
$return[] = $row;
}
}
}
return $return;
}
public function getQuery($rewrite, $id_lang = null, $id_shop = null, $id_parent = false, $activeOnly = false)
{
$sql = new DbQuery();
$sql->from('product_lang', 't');
$sql->join("LEFT JOIN `" . _DB_PREFIX_ . "product_shop` ps ON t.`id_product` = ps.`id_product` AND t.`id_shop` = ps.`id_shop`");
$where = array("t.`link_rewrite` = '" . pSQL($rewrite) . "'");
if ($id_lang) {
$where[] = "t.`id_lang` = " . (int)$id_lang;
}
if ($id_shop) {
$where[] = "ps.`id_shop` = " . (int)$id_shop;
}
if (!empty($id_parent)) {
if (is_array($id_parent)) {
$where[] = "ps.`id_category_default` IN (" . implode(',', $id_parent) . ")";
} else {
$where[] = "ps.`id_category_default` = " . (int)$id_parent;
}
}
if ($activeOnly) {
$where[] = "ps.`active` = 1";
}
$sql->where(implode(' AND ', $where));
return $sql;
}
public function preDispatch($uri, $route_id, $route, $m, $id_lang, $id_shop, $activeOnly = true)
{
$return = $this->owner->getEmptyPreDispatcherResponse();
$context = $this->owner->getContext();
$routes = Dispatcher::getInstance()->getRoutes();
$rewrite = '';
if (isset($m['ars_rewrite_product'])) {
$rewrite = $m['ars_rewrite_product'];
}
$result = Db::getInstance()->getRow($this->getQuery($rewrite, $id_lang, $id_shop, false, $activeOnly));
if (isset($m['ars_id_product']) && $m['ars_id_product']) {
$id_product = $m['ars_id_product'];
} else {
$id_product = null;
}
if ($result || $id_product) {
$return->controllerMatched = true;
if (!$id_product) {
$id_parent = $this->owner->category->getLastIdFromCategoriesRewrite(
$this->owner->category->getFromParamsCategories($m),
$context->shop->id_category,
$id_lang,
$id_shop,
true
);
$id_parent = $this->owner->category->getIdFromCategoryRewrite(
$this->owner->category->getFromParamsCategory($m),
$id_parent,
$id_lang,
$id_shop,
true
);
if ($this->default_cat || $this->parent_cat) {
$sql = $this->getQuery($rewrite, $id_lang, $id_shop, $id_parent, $activeOnly);
} else {
$sql = $this->getQuery($rewrite, $id_lang, $id_shop, false, $activeOnly);
}
$id_product = Db::getInstance()->getValue($sql);
if (!$id_product) {
if ($this->default_cat || $this->parent_cat) {
$id_product = Db::getInstance()->getValue($this->getQuery($rewrite, null, $id_shop, $id_parent, $activeOnly));
} else {
$id_product = Db::getInstance()->getValue($this->getQuery($rewrite, null, $id_shop, false, $activeOnly));
}
}
}
if (!$id_product) {
if (isset($routes[$id_shop][$id_lang]['old_product_rule'])) {
$dispatcher = Dispatcher::getInstance();
if (preg_match($routes[$id_shop][$id_lang]['old_product_rule']['regexp'], $dispatcher->getRequestUri(), $m_sub)) {
if (isset($m_sub['id_product'])) {
$id_product = $m_sub['id_product'];
}
}
}
}
if ($id_product) {
$p = new Product($id_product);
if (!$p->active && $this->redirect_not_active != self::REDIRECT_NONE) {
if (Tools::getValue('adtoken', false)) {
$gt = Tools::getAdminToken(
'AdminProducts'.(int)Tab::getIdFromClassName('AdminProducts').
(int)Tools::getValue('id_employee')
);
if (Tools::getValue('adtoken') != $gt) {
$id_product = 0;
}
} else {
$id_product = 0;
}
if ($this->redirect_not_active == self::REDIRECT_PARENT) {
$id_category = $p->id_category_default;
$cat = new Category($id_category, $id_lang);
return $this->owner->redirect($cat->getLink(), ArSeoHelpers::getResponseHeader($this->redirect_not_active_code? $this->redirect_not_active_code : 301));
} elseif ($this->redirect_not_active == self::REDIRECT_404) {
return $this->owner->redirectToNotFound();
}
}
}
if ($id_product) {
$return->id = $id_product;
$return->property = 'id_product';
} else {
$return->controllerMatched = false;
}
}
if (!$id_product) {
if ($activeOnly) {
return $this->preDispatch($uri, $route_id, $route, $m, $id_lang, $id_shop, false);
}
$id_category = $this->owner->category->getLastIdFromCategoriesRewrite(
$this->owner->category->getFromParamsCategories($m),
$context->shop->id_category,
$id_lang,
$id_shop
);
$id_category = $this->owner->category->getIdFromCategoryRewrite(
$this->owner->category->getFromParamsCategory($m),
$id_category,
$id_lang,
$id_shop
);
if ($id_category && $id_category != $context->shop->id_category) {
$return->controllerProbably = true;
if ($this->redirect == self::REDIRECT_NONE) {
$return->useIfProbably = false;
}
}
}
return $return;
}
public function dispatch()
{
$context = $this->owner->getContext();
$id_shop = $context->shop->id;
$id_lang = $context->language->id;
if (Tools::getValue('ars_rewrite_product')) {
$id_product = Tools::getValue('id_product');
if (!$id_product) {
if ($this->redirect == self::REDIRECT_PARENT) {
$id_category = $this->owner->category->getLastIdFromCategoriesRewrite(
Tools::getValue('ars_rewrite_categories'),
$context->shop->id_category,
$id_lang,
$id_shop
);
$id_category = $this->owner->category->getIdFromCategoryRewrite(
Tools::getValue('ars_rewrite_category'),
$id_category,
$id_lang,
$id_shop
);
if ($id_category != $context->shop->id_category) {
$redirect_url = $context->link->getCategoryLink($id_category);
$this->owner->redirect($redirect_url, ArSeoHelpers::getResponseHeader($this->redirect_code? $this->redirect_code : 301));
}
$this->owner->redirect($context->link->getPageLink('index'), ArSeoHelpers::getResponseHeader($this->redirect_code? $this->redirect_code : 301));
} else {
$this->owner->redirectToNotFound();
}
}
$_GET['id_product'] = $id_product;
if (ArSeoHelpers::getIsset('ars_rewrite_product')) {
$_GET['rewrite'] = Tools::getValue('ars_rewrite_product');
unset($_GET['ars_rewrite_product']);
}
if (ArSeoHelpers::getIsset('ars_rewrite_categories')) {
unset($_GET['ars_rewrite_categories']);
}
if (ArSeoHelpers::getIsset('ars_rewrite_category')) {
unset($_GET['ars_rewrite_category']);
}
if (ArSeoHelpers::getIsset('fc')) {
unset($_GET['fc']);
}
if (ArSeoHelpers::getIsset('ars_id_attribute')) {
$_GET['id_product_attribute'] = Tools::getValue('ars_id_attribute');
unset($_GET['ars_id_attribute']);
}
}
}
public function getDefaultRoute()
{
$route = array();
if ($this->default_cat) {
$route[] = '{category:/}';
} elseif ($this->parent_cat) {
$route[] = '{categories:/}';
}
if ($this->keep_id) {
$route[] = '{id}-';
}
$route[] = '{rewrite}';
if ($this->enable_attr) {
$route[] = '{::id_product_attribute}';
}
return implode('', $route) . '.html';
}
public function keywords()
{
$keywords = array(
'id' => $this->keep_id? $this->regexp('[0-9]+', 'ars_id_product') : $this->regexp('[0-9]+'),
'rewrite' => $this->regexp('[_a-zA-Z0-9\pL\pS-]*', 'ars_rewrite_product'),
'ean13' => $this->regexp('[0-9\pL]*'),
'category' => $this->default_cat? $this->regexp('[_a-zA-Z0-9-\pL]*', 'ars_rewrite_category') : $this->regexp(self::REGEX_ALPHA_NUMERIC),
'categories' => $this->parent_cat? $this->regexp('[/_a-zA-Z0-9-\pL]*', 'ars_rewrite_categories') : $this->regexp('[/_a-zA-Z0-9-\pL]*'),
'reference' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'meta_keywords' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'meta_title' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'manufacturer' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'supplier' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'price' => $this->regexp('[0-9\.,]*'),
'tags' => $this->regexp('[a-zA-Z0-9-\pL]*'),
);
$force_id_product_attribute = false;
if ((Tools::getValue('action', 'none') == 'productrefresh')
&& Tools::getValue('ajax', false)
&& Tools::getValue('id_product', false)
&& Tools::getValue('qty', false)
&& Tools::isSubmit('group')) {
$force_id_product_attribute = true;
}
if ($this->module->is17() && !$force_id_product_attribute && !defined('PS_ADMIN_DIR')) {
$keywords['id_product_attribute'] = $this->regexp('[0-9]+', 'ars_id_attribute');
$keywords['id_product_attribute']['required'] = false;
}
return $keywords;
}
public function keywordLabels()
{
return array(
'id' => $this->l('Product ID'),
'rewrite' => $this->l('rewrite'),
'ean13' => $this->l('EAN 13'),
'category' => $this->l('Default product category'),
'categories' => $this->l('Parent product categories'),
'reference' => $this->l('Product reference'),
'meta_keywords' => $this->l('Meta keywords'),
'meta_title' => $this->l('Meta title'),
'manufacturer' => $this->l('Manufacturer name'),
'supplier' => $this->l('Supplier name'),
'price' => $this->l('Product price'),
'tags' => $this->l('Product tags'),
'id_product_attribute' => $this->l('Product attribute ID')
);
}
public function getRoute()
{
$route = array(
'controller' => 'product',
'rule' => $this->getDefaultRoute(),
'keywords' => $this->keywords(),
'params' => array(
'fc' => 'controller'
)
);
return $route;
}
public function getConfigPrefix()
{
return self::CONFIG_PREFIX;
}
public function rules()
{
$safe = array(
'enable',
'keep_id',
'default_cat',
'parent_cat',
'redirect',
'redirect_code',
'redirect_not_active',
'redirect_not_active_code',
'schema',
'keywords',
'disable_old',
'remove_anchor_id'
);
if ($this->module->is17()) {
$safe[] = 'disable_anchor';
$safe[] = 'disable_default_attr_anchor';
$safe[] = 'enable_attr';
$safe[] = 'disable_default_attr';
}
return array(
array(
$safe, 'safe'
)
);
}
public function redirectSelectOptions()
{
return array(
array(
'id' => self::REDIRECT_NONE,
'name' => $this->l('None', 'ArSeoProURLAbstract')
),
array(
'id' => self::REDIRECT_PARENT,
'name' => $this->l('Redirect to category', 'ArSeoProURLAbstract')
),
array(
'id' => self::REDIRECT_404,
'name' => $this->l('Redirect to page not found', 'ArSeoProURLAbstract')
)
);
}
public function redirectNotActiveSelectOptions()
{
return $this->redirectSelectOptions();
}
public function redirectNotActiveCodeSelectOptions()
{
return $this->redirectCodeSelectOptions();
}
public function attributeDescriptions()
{
$domain = $this->getBaseLink();
$desc = parent::attributeDescriptions();
return array_merge($desc, array(
'default_cat' => sprintf($this->l('Example: %sdefault-category/product-rewriten-url.html', 'ArSeoProURLProduct'), $domain),
'parent_cat' => sprintf($this->l('Example: %sparent-category/children-category/product-rewriten-url.html', 'ArSeoProURLProduct'), $domain),
));
}
public function htmlFields()
{
$html = parent::htmlFields();
return array_merge($html, array(
//'schema' => $this->renderSchemaField()
));
}
public function attributeLabels()
{
$labels = parent::attributeLabels();
return array_merge($labels, array(
'enable' => $this->l('Enable this tab functionality', 'ArSeoProURLProduct'),
'keep_id' => $this->l('Keep product ID in the URL', 'ArSeoProURLProduct'),
'default_cat' => $this->l('Include default category to URL', 'ArSeoProURLProduct'),
'parent_cat' => $this->l('Include parent category to URL', 'ArSeoProURLProduct'),
'redirect' => $this->l('Redirect type if product not found', 'ArSeoProURLProduct'),
'redirect_code' => $this->l('Redirect code if product not found', 'ArSeoProURLProduct'),
'redirect_not_active' => $this->l('Redirect type if product is not active', 'ArSeoProURLProduct'),
'schema' => $this->l('Current Product URL scheme', 'ArSeoProURLProduct'),
'disable_anchor' => $this->l('Disable combination anchors for product URL', 'ArSeoProURLProduct'),
'disable_default_attr_anchor' => $this->l('Disable combination anchors for default attribute only', 'ArSeoProURLProduct'),
'enable_attr' => $this->l('Include combination ID to product URL', 'ArSeoProURLProduct'),
'disable_default_attr' => $this->l('Disable default combination ID in product URL', 'ArSeoProURLProduct'),
'redirect_not_active_code' => $this->l('Redirect code if product not active', 'ArSeoProURLProduct'),
'remove_anchor_id' => $this->l('Disable IDs in the hashed part of the URL', 'ArSeoProURLProduct')
));
}
public function attributeTypes()
{
$types = parent::attributeTypes();
return array_merge($types, array(
'default_cat' => 'switch',
'parent_cat' => 'switch',
'redirect' => 'select',
'redirect_code' => 'select',
'redirect_not_active' => 'select',
'redirect_not_active_code' => 'select',
'disable_anchor' => 'switch',
'disable_default_attr_anchor' => 'switch',
'enable_attr' => 'switch',
'disable_default_attr' => 'switch',
'remove_anchor_id' => 'switch'
));
}
public function attributeDefaults()
{
return array(
'enable' => 1,
'keep_id' => 0,
'default_cat' => 1,
'redirect' => self::REDIRECT_PARENT,
'redirect_code' => 301,
'redirect_not_active' => 0,
'redirect_not_active_code' => 301,
'disable_default_attr' => 1,
'disable_default_attr_anchor' => 1,
'remove_anchor_id' => 1
);
}
public function afterSave()
{
if ($rule = Configuration::get('PS_ROUTE_product_rule')) {
if ($this->hasKeyword($rule, 'category') && $this->parent_cat) {
$rule = str_replace('category', 'categories', $rule);
} elseif ($this->hasKeyword($rule, 'categories') && $this->default_cat) {
$rule = str_replace('categories', 'category', $rule);
} elseif ($this->hasKeyword($rule, 'category') && !$this->default_cat) {
$rule = str_replace('{category:/}', '', $rule);
} elseif ($this->hasKeyword($rule, 'categories') && !$this->parent_cat) {
$rule = str_replace('{categories:/}', '', $rule);
} elseif (!$this->hasKeyword($rule, 'category') && $this->default_cat) {
$rule = '{category:/}' . $rule;
} elseif (!$this->hasKeyword($rule, 'categories') && $this->parent_cat) {
$rule = '{categories:/}' . $rule;
}
if (!$this->hasKeyword($rule, 'id') && $this->keep_id) {
$rule = str_replace('{rewrite}', '{id}-{rewrite}', $rule);
} elseif ($this->hasKeyword($rule, 'id') && !$this->keep_id) {
$rule = str_replace('{id}-{rewrite}', '{rewrite}', $rule);
}
if (!$this->hasKeyword($rule, 'id_product_attribute') && $this->enable_attr) {
$rule = str_replace('{rewrite}', '{rewrite}{::id_product_attribute}', $rule);
} elseif ($this->hasKeyword($rule, 'id_product_attribute') && !$this->enable_attr) {
$rule = str_replace('{::id_product_attribute}', '', $rule);
}
ConfigurationCore::updateValue('PS_ROUTE_product_rule', $rule);
}
return parent::afterSave();
}
}

View File

@@ -0,0 +1,272 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
include_once dirname(__FILE__).'/ArSeoProURLAbstract.php';
class ArSeoProURLSupplier extends ArSeoProURLAbstract
{
const CONFIG_PREFIX = 'arss_';
public $enable;
public $keep_id;
public $redirect;
public $redirect_code;
public $disable_old;
public function getRuleId()
{
return 'supplier_rule';
}
public function getDuplicates()
{
$return = array();
$limit = ' LIMIT 5';
$sql = 'SELECT s.`id_supplier`, ss.`id_shop`, s.`name` FROM `'._DB_PREFIX_.'supplier` s '
. 'LEFT JOIN `'._DB_PREFIX_.'supplier_shop` ss ON s.`id_supplier` = ss.`id_supplier` '
. 'GROUP BY ss.`id_shop`, s.`name` '
. 'HAVING count(s.`name`) > 1 ORDER BY ss.`id_shop` ASC' . pSQL($limit);
$duplicates = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
if ($duplicates) {
foreach ($duplicates as $duplicate) {
$sql2 = 'SELECT s.`id_supplier`, ss.`id_shop`, s.`name` FROM `'._DB_PREFIX_.'supplier` s '
. 'LEFT JOIN `'._DB_PREFIX_.'supplier_shop` ss ON s.`id_supplier` = ss.`id_supplier` '
. 'WHERE ss.`id_shop` = '.(int)($duplicate['id_shop']).' '
. 'AND s.`name` = '.(int)($duplicate['name']).' '
. 'GROUP BY s.`id_supplier`' . pSQL($limit);
$more = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql2);
foreach ($more as $info) {
$row = array();
$row['id'] = 'supplier_'.$info['id_supplier'];
$row['id_object'] = $info['id_supplier'];
$row['id_type'] = 'supplier';
$row['type'] = 'Supplier';
$row['name'] = $info['name'];
$row['shop'] = '';
if ($shop = Shop::getShop($info['id_shop'])) {
$row['shop'] = $shop['name'];
}
$return[] = $row;
}
}
}
return $return;
}
public function preDispatch($uri, $route_id, $route, $m, $id_lang, $id_shop)
{
$return = $this->owner->getEmptyPreDispatcherResponse();
$rewrite = '';
if (isset($m['ars_rewrite_supplier'])) {
$rewrite = $m['ars_rewrite_supplier'];
}
if (isset($m['ars_id_supplier']) && $m['ars_id_supplier']) {
$id_supplier = $m['ars_id_supplier'];
} else {
$id_supplier = null;
}
if (!$id_supplier) {
$id_supplier = Db::getInstance()->getValue(
'SELECT s.`id_supplier` FROM `'._DB_PREFIX_.'supplier` s '
. 'LEFT JOIN `'._DB_PREFIX_.'supplier_shop` ss ON s.id_supplier = ss.id_supplier '
. 'WHERE ss.`id_shop` = '.(int)$id_shop.' '
. 'AND REPLACE(LOWER(s.`name`), " ", "-") = "'.pSQL($rewrite).'"'
);
}
if (!$id_supplier) {
$suppliers = Db::getInstance()->executeS(
'SELECT s.`id_supplier`, s.`name` FROM `'._DB_PREFIX_.'supplier` s '
. 'LEFT JOIN `'._DB_PREFIX_.'supplier_shop` ss ON s.id_supplier = ss.id_supplier '
. 'WHERE ss.`id_shop` = '.(int)$id_shop
);
if ($suppliers) {
foreach ($suppliers as $supplier) {
if ($rewrite == Tools::str2url($supplier['name'])) {
$id_supplier = $supplier['id_supplier'];
break;
}
}
}
}
if ($id_supplier) {
$return->controllerMatched = true;
$return->id = $id_supplier;
$return->property = 'id_supplier';
} else {
if (!ArSeoHelpers::startWith(trim($route['rule']), '{')) {
$return->controllerProbably = true;
if ($this->redirect == self::REDIRECT_NONE) {
$return->useIfProbably = false;
}
}
}
return $return;
}
public function dispatch()
{
$context = $this->owner->getContext();
if (Tools::getValue('ars_rewrite_supplier')) {
$id_supplier = Tools::getValue('id_supplier');
if (!$id_supplier) {
if ($this->redirect == self::REDIRECT_PARENT) {
$this->owner->redirect($context->link->getPageLink('supplier'), ArSeoHelpers::getResponseHeader($this->redirect_code? $this->redirect_code : 301));
}
$this->owner->redirectToNotFound();
}
$_GET['id_supplier'] = $id_supplier;
if (ArSeoHelpers::getIsset('ars_rewrite_supplier')) {
unset($_GET['ars_rewrite_supplier']);
}
if (ArSeoHelpers::getIsset('fc')) {
unset($_GET['fc']);
}
}
}
public function getDefaultRoute()
{
if ($this->keep_id) {
return 'supplier/{id}-{rewrite}.html';
}
return 'supplier/{rewrite}.html';
}
public function getRoute()
{
return array(
'controller' => 'supplier',
'rule' => $this->getDefaultRoute(),
'keywords' => array(
'id' => $this->keep_id ? $this->regexp('[0-9]+', 'ars_id_supplier') : $this->regexp('[0-9]+'),
'rewrite' => $this->regexp('[_a-zA-Z0-9\pL\pS-]*', 'ars_rewrite_supplier'),
'meta_keywords' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
'meta_title' => $this->regexp(self::REGEX_ALPHA_NUMERIC),
),
'params' => array(
'fc' => 'controller'
)
);
}
public function getConfigPrefix()
{
return self::CONFIG_PREFIX;
}
public function rules()
{
return array(
array(
array(
'enable',
'keep_id',
'redirect',
'redirect_code',
'schema',
'keywords',
'disable_old'
), 'safe'
)
);
}
public function redirectSelectOptions()
{
return array(
array(
'id' => self::REDIRECT_NONE,
'name' => $this->l('None', 'ArSeoProURLSupplier')
),
array(
'id' => self::REDIRECT_PARENT,
'name' => $this->l('Redirect to supplier list', 'ArSeoProURLSupplier')
),
array(
'id' => self::REDIRECT_404,
'name' => $this->l('Redirect to page not found', 'ArSeoProURLSupplier')
)
);
}
public function attributeDescriptions()
{
$desc = parent::attributeDescriptions();
return array_merge($desc, array(
'redirect' => $this->l('Redirect type if category not found', 'ArSeoProURLSupplier')
));
}
public function attributeLabels()
{
$labels = parent::attributeLabels();
return array_merge($labels, array(
'enable' => $this->l('Enable this tab functionality', 'ArSeoProURLSupplier'),
'keep_id' => $this->l('Keep supplier ID in the URL', 'ArSeoProURLSupplier'),
'redirect' => $this->l('Redirect type if supplier not found', 'ArSeoProURLSupplier'),
'schema' => $this->l('Current Supplier URL scheme', 'ArSeoProURLSupplier'),
));
}
public function attributeTypes()
{
$types = parent::attributeTypes();
return array_merge($types, array(
'redirect' => 'select'
));
}
public function attributeDefaults()
{
return array(
'enable' => 1,
'redirect' => self::REDIRECT_PARENT
);
}
public function afterSave()
{
if ($rule = Configuration::get('PS_ROUTE_supplier_rule')) {
if (!$this->hasKeyword($rule, 'id') && $this->keep_id) {
$rule = str_replace('{rewrite}', '{id}-{rewrite}', $rule);
} elseif ($this->hasKeyword($rule, 'id') && !$this->keep_id) {
$rule = str_replace('{id}-{rewrite}', '{rewrite}', $rule);
}
ConfigurationCore::updateValue('PS_ROUTE_supplier_rule', $rule);
}
return parent::afterSave();
}
}

View File

@@ -0,0 +1,31 @@
<?php
/*
* 2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../../../');
exit;

View File

@@ -0,0 +1,284 @@
<?php
/**
* 2012-2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
include_once dirname(__FILE__).'/../../ArSeoProTableAbstract.php';
class ArSeoProRuleTable extends ArSeoProTableAbstract
{
const TABLE_NAME = 'arseopro_rule';
const REL_TABLE_NAME = 'arseopro_rule_category';
public $id;
public $id_lang;
public $id_shop;
public $name;
public $rule;
public $status;
public $created_at;
public $updated_at;
public $last_applied_at;
public $id_category;
public $categories;
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => self::TABLE_NAME,
'primary' => 'id_rule',
'multilang' => false,
'fields' => array(
'id_lang' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'id_shop' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true),
'rule' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true),
'status' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'created_at' => array('type' => self::TYPE_STRING),
'updated_at' => array('type' => self::TYPE_STRING),
'last_applied_at' => array('type' => self::TYPE_STRING),
),
);
public static function uninstallTable()
{
$res = Db::getInstance()->execute('DROP TABLE IF EXISTS `' . self::getTableName() . '`');
return $res && Db::getInstance()->execute('DROP TABLE IF EXISTS `' . self::getTableName(true) . '`');
}
public static function installTable()
{
$sql = "CREATE TABLE IF NOT EXISTS `" . self::getTableName() . "` (
`id_rule` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`id_lang` INT(11) UNSIGNED NOT NULL,
`id_shop` INT(11) UNSIGNED NOT NULL,
`name` VARCHAR(50) NOT NULL,
`rule` VARCHAR(255) NOT NULL,
`status` TINYINT(1) UNSIGNED NULL DEFAULT NULL,
`created_at` DATETIME NULL DEFAULT NULL,
`updated_at` DATETIME NULL DEFAULT NULL,
`last_applied_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id_rule`),
INDEX `id_lang` (`id_lang`),
INDEX `id_shop` (`id_shop`)
)
COLLATE='utf8_general_ci'";
$res = Db::getInstance()->execute($sql);
$sql = "CREATE TABLE IF NOT EXISTS `" . self::getTableName(true) . "` (
`id_rule` INT(10) UNSIGNED NOT NULL,
`id_category` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id_rule`, `id_category`)
)
COLLATE='utf8_general_ci'";
return $res && Db::getInstance()->execute($sql);
}
public function validateFields($die = true, $error_return = false)
{
$parent = parent::validateFields($die, $error_return);
$ruleValidation = $this->validateRuleField();
if ($ruleValidation && $ruleValidation !== true) {
if (is_array($parent)) {
$parent['rule'] = $ruleValidation;
} else {
$parent = array(
'rule' => $ruleValidation
);
}
}
return $parent;
}
public function validateRuleField()
{
$allowedTags = array_keys(ArSeoPro::getProductKeywords());
$matches = array();
$errors = array();
if (preg_match_all('/{[_a-zA-Z0-9-\pL]+}/is', $this->rule, $matches)) {
if (isset($matches[0]) && is_array($matches[0])) {
foreach ($matches[0] as $tag) {
$keyword = str_replace(array('{', '}'), '', $tag);
if (!in_array($keyword, $allowedTags)) {
$errors[] = sprintf('Tag "%s" is not exists', $tag);
}
}
}
}
return $errors? $errors : true;
}
public static function generateRuleName()
{
$count = self::getCount();
return 'Rule ' . ($count + 1);
}
public static function getCount($params = array())
{
$query = new DbQuery();
$query->from(self::TABLE_NAME);
$query->select('COUNT(1) c');
if (isset($params['filter'])) {
$where = self::processFilters($params['filter']);
$query->where($where);
}
$res = Db::getInstance()->getRow($query);
return $res['c'];
}
public static function getAll($params = array())
{
$pageSize = isset($params['selected_pagination'])? $params['selected_pagination'] : 50;
$page = isset($params['page'])? $params['page'] - 1 : 0;
$offset = isset($params['page'])? $pageSize * $page : 0;
$query = new DbQuery();
$query->from(self::TABLE_NAME);
$query->limit((int)$pageSize, (int)$offset);
if (isset($params['filter'])) {
$where = self::processFilters($params['filter']);
$query->where($where);
}
return Db::getInstance()->executeS($query);
}
public static function processFilters($params)
{
$where = array();
$model = new self();
foreach ($params as $k => $value) {
if (property_exists($model, $k) && $value != '') {
if ($k == 'id') {
$k = 'id_rule';
}
if (strpos($value, '%') !== false) {
$where[] = "`" . $k . "` LIKE '" . pSQL($value) . "'";
} else {
$where[] = "`" . $k . "` = '" . pSQL($value) . "'";
}
}
}
return implode(' AND ', $where);
}
public static function truncate()
{
Db::getInstance()->execute('TRUNCATE `' . self::getTableName(true) . '`');
return Db::getInstance()->execute('TRUNCATE `' . self::getTableName() . '`');
}
public function clearCategories()
{
return Db::getInstance()->execute('DELETE FROM `' . self::getTableName(true) . '` WHERE id_rule=' . (int)$this->id);
}
public function addCategory($id_category)
{
return Db::getInstance()->execute('INSERT INTO `' . self::getTableName(true) . '` (`id_rule`, `id_category`) VALUES (' . (int)$this->id . ', ' . (int)$id_category .')');
}
public function getCategories($nonZero = false)
{
$sql = new DbQuery();
$sql->from(self::getTableName(true, false), 't');
$sql->select('t.id_category');
$sql->where('id_rule=' . (int)$this->id);
if ($nonZero) {
$sql->where('id_rule=' . (int)$this->id . ' AND id_category != 0');
}
$return = array();
if ($res = Db::getInstance()->executeS($sql)) {
foreach ($res as $row) {
$return[] = $row['id_category'];
}
}
return $return;
}
public function getRelatedProductsCount()
{
$categories = array();
foreach ($this->getCategories() as $rel) {
if ($rel != 0) {
$categories[] = (int)$rel;
}
}
if ($categories) {
$sql = 'SELECT COUNT(id_product) FROM `' . _DB_PREFIX_ . 'product_shop` WHERE id_category_default IN (' . implode(',', $categories) . ') AND id_shop = ' . (int)$this->id_shop;
} else {
$sql = 'SELECT COUNT(id_product) FROM `' . _DB_PREFIX_ . 'product_shop` WHERE id_shop = ' . (int)$this->id_shop;
}
return (int)Db::getInstance()->getValue($sql);
}
public function getRelatedProductIds($limit, $offset, $id_product = null)
{
$categories = array();
foreach ($this->getCategories() as $rel) {
if ($rel != 0) {
$categories[] = $rel;
}
}
$where = array();
if ($categories) {
$where[] = 'id_category_default IN (' . implode(',', $categories) . ')';
}
$where[] = 'id_shop = ' . (int)$this->id_shop;
if ($id_product) {
$where[] = ' id_product = ' . (int)$id_product;
}
$sql = 'SELECT id_product FROM `' . _DB_PREFIX_ . 'product_shop` WHERE ' . implode(' AND ', $where) . ' LIMIT ' . (int)$offset . ', ' . (int)$limit;
$return = array();
if ($res = Db::getInstance()->executeS($sql)) {
foreach ($res as $row) {
$return[] = $row['id_product'];
}
}
return $return;
}
public static function getRules($id_category, $id_lang, $id_shop)
{
$where = array();
if ($id_category) {
$where[] = 'arc.id_category IN (0, ' . (int)$id_category . ')';
}
if ($id_lang) {
$where[] = 'ar.id_lang IN (0, ' . (int)$id_lang . ')';
}
if ($id_shop) {
$where[] = 'ar.id_shop = ' . (int)$id_shop;
}
$sql = 'SELECT ar.* FROM `' . self::getTableName() . '` ar ' .
'LEFT JOIN `' . self::getTableName(true) . '` arc ON arc.id_rule = ar.id_rule ' .
'WHERE ' . implode(' AND ', $where);
return Db::getInstance()->executeS($sql);
}
public static function getTableName($relTable = false, $withPrefix = true)
{
if ($withPrefix) {
return $relTable? (_DB_PREFIX_ . self::REL_TABLE_NAME) : (_DB_PREFIX_ . self::TABLE_NAME);
}
return $relTable? self::REL_TABLE_NAME : self::TABLE_NAME;
}
}

View File

@@ -0,0 +1,31 @@
<?php
/*
* 2018 Areama
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@areama.net so we can send you a copy immediately.
*
*
* @author Areama <contact@areama.net>
* @copyright 2018 Areama
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Areama
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../../../');
exit;