Добрый день!
Есть ссылка на товар
site.com/catalog/catalog/product.html
На сайте используется штатный seo_url.php + seo_url_mod.php
Нужно что карточка товара работала с парметрами типа ?=key или ?utm
Потому что сейчас срабатывает 301 редирект..
код прилагаю.. Нужна ваша помощь...
Товар должен открываться по такой ссылке
site.com/catalog/catalog/product.html?key=1234
<?php
class ControllerStartupSeoUrlMod extends Controller {
private $cat_tree = [
];
private $keywords = [
];
private $queries = [
];
private $product_categories = [
];
public function __construct($registry) {
parent::__construct($registry);
if (isset($this->request->get['_route_'])) {
$this->request->get['_route_'] = preg_replace('/' . '.html' . '$/', '', (string) $this->request->get['_route_']);
}
$this->cache = $registry->get('cache');
$this->cat_tree = $this->cache->get('seourl.cat_tree');
if (empty($this->cat_tree)) {
$this->cat_tree = [
];
$query = $this->db->query("SELECT category_id, parent_id FROM " . DB_PREFIX . "category ORDER BY parent_id");
$categories = [
];
foreach ($query->rows as $category) {
$categories[$category['category_id']]['parent_id'] = $category['parent_id'];
};
foreach ($categories as $category_id => $category) {
$path = $this->getPath($categories, $category_id);
$this->cat_tree[$category_id]['path'] = $path;
};
}
$this->keywords = $this->cache->get('seourl.keywords');
$this->queries = $this->cache->get('seourl.queries');
if (empty($this->keywords) || empty($this->queries)) {
$sql = "SELECT LCASE(keyword) as keyword, query, store_id, language_id FROM " . DB_PREFIX . "seo_url";
$query = $this->db->query($sql);
if ($query->num_rows) {
foreach ($query->rows as $row) {
$this->keywords[$row['query']][$row['store_id']][$row['language_id']] = $row['keyword'];
$this->queries[$row['keyword']][$row['store_id']][$row['language_id']] = $row['query'];
}
}
}
}
public function index() {
$this->url->addRewrite($this);
if (isset($this->request->get['_route_'])) {
$parts = explode('/', $this->request->get['_route_']);
if (utf8_strlen(end($parts)) == 0) {
array_pop($parts);
}
$store_id = (int) $this->config->get('config_store_id');
$language_id = (int) $this->config->get('config_language_id');
foreach ($parts as $part) {
$query = [
];
$keyword = utf8_strtolower($part);
if (isset($this->queries[$keyword][$store_id][$language_id])) {
$query = $this->queries[$keyword][$store_id][$language_id];
}
if ($query) {
$url = explode('=', $query);
if (!in_array($url[0], [
'category_id',
'product_id',
'manufacturer_id',
'news_id',
'news2_id',
'news3_id',
'information_id'])) {
$this->request->get['route'] = $query;
} elseif ($url[0] == 'category_id') {
if (!isset($this->request->get['path'])) {
$this->request->get['path'] = $url[1];
} else {
$this->request->get['path'] .= '_' . $url[1];
}
} elseif (count($url) > 1) {
$this->request->get[$url[0]] = $url[1];
}
} else {
$this->request->get['route'] = 'error/not_found';
break;
}
}
if (!isset($this->request->get['route'])) {
if (isset($this->request->get['product_id'])) {
$path = $this->getCategoryByProduct($this->request->get['product_id']);
if ($path) {
$this->request->get['path'] = $path;
}
$this->request->get['route'] = 'product/product';
} elseif (isset($this->request->get['path'])) {
$this->request->get['route'] = 'product/category';
} elseif (isset($this->request->get['manufacturer_id'])) {
$this->request->get['route'] = 'product/manufacturer/info';
} elseif (isset($this->request->get['information_id'])) {
$this->request->get['route'] = 'information/information';
}
} elseif (isset($this->request->get['news_id'])) {
$this->request->get['route'] = 'information/news/info';
} elseif (isset($this->request->get['news2_id'])) {
$this->request->get['route'] = 'information/news2/info';
} elseif (isset($this->request->get['news3_id'])) {
$this->request->get['route'] = 'information/news3/info';
}
}
if (empty($this->request->get['route'])) {
$this->request->get['route'] = 'common/home';
}
if (isset($this->request->get['route'])) {
$break_routes = [
'error/not_found',
'extension/feed/google_sitemap',
'extension/feed/google_base',
'extension/feed/sitemap_pro',
'extension/feed/yandex_feed'
];
if (in_array($this->request->get['route'], $break_routes))
return;
}
if (isset($this->request->server['HTTP_X_REQUESTED_WITH']) && strtolower($this->request->server['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
return;
}
if ($_SERVER['HTTPS'] == true) {
$host = substr($this->config->get('config_ssl'), 0, $this->strpos_offset('/', $this->config->get('config_ssl'), 3) + 1);
} else {
$host = substr($this->config->get('config_url'), 0, $this->strpos_offset('/', $this->config->get('config_url'), 3) + 1);
}
$exclude = urldecode(http_build_query(array_diff_key($this->request->get, array_flip(array(
'_route_',
'route')))));
$url_validate = str_replace('&', '&', $host . ltrim($this->request->server['REQUEST_URI'], '/'));
$seo_validate = str_replace('&', '&', $this->url->link($this->request->get['route'], $exclude, $_SERVER['HTTPS']));
if (rawurldecode($url_validate) != rawurldecode($seo_validate)) {
$this->response->redirect($seo_validate, 301);
}
}
private function strpos_offset($needle, $haystack, $occurrence) {
$arr = explode($needle, $haystack);
switch ($occurrence) {
case $occurrence == 0:
return false;
case $occurrence > max(array_keys($arr)):
return false;
default:
return strlen(implode($needle, array_slice($arr, 0, $occurrence)));
}
}
private function getPath($categories, $category_id, $current_path = [
]) {
if (!$current_path)
$current_path = [
(int) $category_id];
$path = $current_path;
$parent_id = 0;
if (isset($categories[$category_id]['parent_id'])) {
$parent_id = (int) $categories[$category_id]['parent_id'];
}
if ($parent_id > 0) {
$new_path = array_merge([
$parent_id], $current_path);
$path = $this->getPath($categories, $parent_id, $new_path);
}
return $path;
}
public function rewrite($link) {
$url_info = parse_url(str_replace('&', '&', $link));
parse_str($url_info['query'], $data);
$ishome = 0;
$url = '';
switch ($data['route']) {
case 'product/product':
if (isset($data['product_id'])) {
$route = 'product/product';
$product_id = $data['product_id'];
unset($data);
$data['route'] = $route;
$path = $this->getCategoryByProduct($product_id);
if ($path) {
$data['path'] = $path;
}
$data['product_id'] = $product_id;
}
break;
case 'product/category':
if (isset($data['path'])) {
$category = explode('_', $data['path']);
$category = end($category);
$data['path'] = $this->getPathByCategory($category);
}
break;
case 'common/home':
$ishome = 1;
break;
case 'information/information/agree':
return $link;
break;
case 'information/information/info':
return $link;
break;
default:
break;
}
if (isset($data['news_id'])) {
$url = '/news';
} elseif (isset($data['news2_id'])) {
$url = '/articles';
} elseif (isset($data['news3_id'])) {
$url = '/services';
}
$route = '';
if (isset($data['route'])) {
$route = $data['route'];
unset($data['route']);
}
$queries = [
];
foreach ($data as $key => $value) {
switch ($key) {
case 'product_id':
case 'manufacturer_id':
case 'category_id':
case 'information_id':
case 'news_id':
case 'news2_id':
case 'news3_id':
$queries[] = $key . '=' . (int) $value;
unset($data[$key]);
break;
case 'path':
$categories = explode('_', $value);
foreach ($categories as $category_id) {
$queries[] = 'category_id=' . (int) $category_id;
}
unset($data[$key]);
break;
default:
break;
}
}
if (empty($queries) && $route) {
$keyword = $this->getKeywordByQuery($route);
if ($keyword !== null) {
if ($keyword !== '') {
$url = '/' . rawurlencode($keyword);
}
}
$data['route'] = $route;
} else {
$rows = [
];
foreach ($queries as $query) {
$keyword = $this->getKeywordByQuery($query);
if ($keyword) {
$rows[] = $keyword;
}
}
if (!empty($rows) && (count($rows) == count($queries))) {
foreach ($rows as $row) {
$url .= '/' . rawurlencode($row);
}
}
}
if ($url) {
$url .= '.html';
unset($data['route']);
$query = '';
if ($data) {
foreach ($data as $key => $value) {
$query .= '&' . rawurlencode((string) $key) . '=' . rawurlencode((is_array($value) ? http_build_query($value) : (string) $value));
}
if ($query) {
$query = '?' . str_replace('&', '&', trim($query, '&'));
}
}
return $url_info['scheme'] . '://' . $url_info['host'] . (isset($url_info['port']) ? ':' . $url_info['port'] : '') . str_replace('/index.php', '', $url_info['path']) . $url . $query;
} elseif ($ishome) {
return str_replace('index.php?route=common/home', '', $link);
} else {
return $link;
}
}
private function getCategoryByProduct($product_id) {
if (!$product_id) {
return false;
}
$this->product_categories = $this->cache->get('seourl.product_categories');
if (isset($this->product_categories[$product_id])) {
return $this->product_categories[$product_id];
}
$query = $this->db->query("SELECT category_id FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int) $product_id . "' ORDER BY main_category DESC LIMIT 1");
$category_id = $this->getPathByCategory($query->num_rows ? (int) $query->row['category_id'] : 0);
$this->product_categories[$product_id] = $category_id;
return $category_id;
}
private function getPathByCategory($category_id) {
$path = '';
if (!$category_id && !isset($this->cat_tree[$category_id]))
return false;
if (!empty($this->cat_tree[$category_id]['path']) && is_array($this->cat_tree[$category_id]['path'])) {
$path = implode('_', $this->cat_tree[$category_id]['path']);
}
return $path;
}
private function getKeywordByQuery($query) {
$keyword = null;
$store_id = (int) $this->config->get('config_store_id');
$language_id = $this->config->get('config_language_id');
if (isset($this->keywords[$query][$store_id][$language_id])) {
$keyword = $this->keywords[$query][$store_id][$language_id];
}
return $keyword;
}
public function __destruct() {
$this->cache->set('seourl.keywords', $this->keywords);
$this->cache->set('seourl.queries', $this->queries);
$this->cache->set('seourl.cat_tree', $this->cat_tree);
$this->cache->set('seourl.product_categories', $this->product_categories);
}
}