Jump to content

Recommended Posts

Установлен Opencart 1.5.4.1, SeoPro, настроены ЧПУ. Как избавиться от таких дублей:

site.ru/index.php

site.ru/index.php?

site.ru/index.php?123

site.ru/index.php?qwe

и т.д.

По всем ответ 200 ОК

Т.е. бесконечное множество дублей... как то можно от них избавиться?

Edited by imushroom

Share this post


Link to post
Share on other sites

А щит от лазера из космоса купили? ведь по сути это является угрозой

Share this post


Link to post
Share on other sites

Привет всем. под ветку 2.2.0.0 есть решение?

Share this post


Link to post
Share on other sites

Приветствую всех!

И у меня тоже возникла проблема с дублями, OP 2.2, seo_pro

Дубли получается вот такие

/category1/sub-category1/tovar1

/category1/tovar1

Почему seo_pro такое не обрабатывает правильно?

И как лучше всего исправить?

Share this post


Link to post
Share on other sites

Ребят помогите пожалуйста уже и не знаю что делать!
такая беда с очень многими товарами
вроде как сео все правильно делает
раньше такого небыло
с недавних пор таким образом пропадают товары
хотя в списке они есть но как заходишь в саму карточку то вот такая лабуда

dcf685a8cafe.png

Share this post


Link to post
Share on other sites
Здравствуйте!

Приобретал Ваш модуль для сайта, модуль работает, всё отлично.

Начали строить второй сайт хотим установить SeoPro.

Вопрос на второй сайт модуль необходимо покупать повторно?

 Просто из описания модуля это не очевидно...  https://opencartforum.com/files/file/1155-модуль-управления-seopro/

 

В личку написать не получается, пишет что у вас нет возможности принимать новые сообщения...

 

 

 

ПС. Valogroup, мы с вами соседи по корпусу в Румянцево :)

Share this post


Link to post
Share on other sites

Доброе время суток.

Кто нибудь решил вопрос с одинаковыми подкатегориями?

То есть структура такая:

-Бумага

--Бумага А4

--Цветная

----

-Картон

--Картон А4

--Цветной

 

У цветной и цветная - url один и тот же. Изменять нельзя!

Соответственно открывается только одна страница, которая первая в выборке.

Писал так в файле catalog\controller\common\seo_pro.php:


foreach ($parts as $keyword) {

if (isset($a) && $a[0]=="category_id") {
$query = $this->db->query("SELECT a.* FROM " . DB_PREFIX . "url_alias a, " . DB_PREFIX . "category c WHERE a.keyword = '" . $this->db->escape($keyword) . "' AND a.query=CONCAT('category_id=', c.category_id) AND c.parent_id='".$a[1]."'");
if ($query->num_rows) {
$rows[] = array('keyword' => $keyword, 'query' => $query->row['query']);
$a = explode("=",$query->row['query']);
}
} else {
if (isset($this->cache_data['keywords'][$keyword])) {
$rows[] = array('keyword' => $keyword, 'query' => $this->cache_data['keywords'][$keyword]);
$a=explode("=",$this->cache_data['keywords'][$keyword]);
}
}

}

 

В результате категории стали открываться как надо, но при клике на товар - Запрашиваемая страница не найдена.

 

Исходный код файла seo_pro.php

class ControllerCommonSeoPro extends Controller {
private $cache_data = null;
private $languages = array();
private $config_language;

public function __construct($registry) {
parent::__construct($registry);
$this->cache_data = $this->cache->get('seo_pro');
if (!$this->cache_data) {
$query = $this->db->query("SELECT LOWER(`keyword`) as 'keyword', `query` FROM " . DB_PREFIX . "url_alias");
$this->cache_data = array();
foreach ($query->rows as $row) {
$this->cache_data['keywords'][$row['keyword']] = $row['query'];
$this->cache_data['queries'][$row['query']] = $row['keyword'];
}
$this->cache->set('seo_pro', $this->cache_data);
}

$query = $this->db->query("SELECT `value` FROM `" . DB_PREFIX . "setting` WHERE `key` = 'config_language'");
$this->config_language = $query->row['value'];

$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "language WHERE status = '1'");

foreach ($query->rows as $result) {
$this->languages[$result['code']] = $result;
}

}

public function index() {

// language
$code = $this->config_language;

if(isset($this->request->get['route'])) {
$routes=explode('/',$this->request->get['route']);
}

if(isset($this->request->get['_route_'])) {

$route_ = $this->request->get['_route_'];

$tokens = explode('/', $this->request->get['_route_']);

if(array_key_exists($tokens[0], $this->languages)) {
$code = $tokens[0];
$this->request->get['_route_'] = substr($this->request->get['_route_'], strlen($code) + 1);
}

if(trim($this->request->get['_route_']) == '' || trim($this->request->get['_route_']) == 'index.php') {
unset($this->request->get['_route_']);
}
}

if ($code == $this->config_language &&
isset($this->request->cookie['language']) &&
$this->request->cookie['language'] != $code &&
isset($this->request->server['HTTP_X_REQUESTED_WITH']) &&
strtolower($this->request->server['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$code = $this->request->cookie['language'];
}

if (isset($this->request->cookie['language']) &&
$this->request->cookie['language'] != $code &&
isset($routes) &&
trim($routes[0]=='module')) {
$code = $this->request->cookie['language'];
}

if(!isset($this->session->data['language']) || $this->session->data['language'] != $code) {
$this->session->data['language'] = $code;
}


$xhttprequested = isset($this->request->server['HTTP_X_REQUESTED_WITH']) && $this->request->server['HTTP_X_REQUESTED_WITH'] == 'xmlhttprequest';

$captcha = isset($this->request->get['route']) && $this->request->get['route']=='product/product/captcha';

if(!$xhttprequested && !$captcha) {
setcookie('language', $code, time() + 60 * 60 * 24 * 30, '/', $this->request->server['HTTP_HOST']);
}


$this->config->set('config_language_id', $this->languages[$code]['language_id']);
$this->config->set('config_language', $this->languages[$code]['code']);

$language = new Language($this->languages[$code]['directory']);
$language->load($this->languages[$code]['filename']);
$this->registry->set('language', $language);


// Add rewrite to url class
if ($this->config->get('config_seo_url')) {
$this->url->addRewrite($this);
} else {
return;
}

// Decode URL
if (!isset($this->request->get['_route_'])) {
$this->validate();
} else {
$route = $this->request->get['_route_'];
unset($this->request->get['_route_']);
$parts = explode('/', trim(utf8_strtolower($route), '/'));
list($last_part) = explode('.', array_pop($parts));
array_push($parts, $last_part);

$rows = array();
foreach ($parts as $keyword) {
if (isset($this->cache_data['keywords'][$keyword])) {
$rows[] = array('keyword' => $keyword, 'query' => $this->cache_data['keywords'][$keyword]);
}
}

if (count($rows) == sizeof($parts)) {
$queries = array();
foreach ($rows as $row) {
$queries[utf8_strtolower($row['keyword'])] = $row['query'];
}

reset($parts);
foreach ($parts as $part) {
$url = explode('=', $queries[$part], 2);

if ($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';
}

if (isset($this->request->get['product_id'])) {
$this->request->get['route'] = 'product/product';
if (!isset($this->request->get['path'])) {
$path = $this->getPathByProduct($this->request->get['product_id']);
if ($path) $this->request->get['path'] = $path;
}
} 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/product';
if(in_array(substr(VERSION, 0, 5), array('1.5.4', '1.5.5'))) {
$this->request->get['route'] = 'product/manufacturer/info';
}
} elseif (isset($this->request->get['information_id'])) {
$this->request->get['route'] = 'information/information';
} elseif(isset($this->cache_data['queries'][$route_])) {
header($this->request->server['SERVER_PROTOCOL'] . ' 301 Moved Permanently');
$this->response->redirect($this->cache_data['queries'][$route_]);
} else {
if (isset($queries[$parts[0]])) {
$this->request->get['route'] = $queries[$parts[0]];
}
}


$this->validate();

if (isset($this->request->get['route'])) {
return $this->forward($this->request->get['route']);
}
}
}

public function rewrite($link, $code = '') {
if(!$code) {
$code = $this->session->data['language'];
}
if (!$this->config->get('config_seo_url')) return $link;

$seo_url = '';

$component = parse_url(str_replace('&', '&', $link));

$data = array();
parse_str($component['query'], $data);

$route = $data['route'];
unset($data['route']);

switch ($route) {
case 'product/product':
if (isset($data['product_id'])) {
$tmp = $data;
$data = array();
if ($this->config->get('config_seo_url_include_path')) {
$data['path'] = $this->getPathByProduct($tmp['product_id']);
if (!$data['path']) return $link;
}
$data['product_id'] = $tmp['product_id'];
if (isset($tmp['tracking'])) {
$data['tracking'] = $tmp['tracking'];
}
}
break;

case 'product/category':
if (isset($data['path'])) {
$category = explode('_', $data['path']);
$category = end($category);
$data['path'] = $this->getPathByCategory($category);
if (!$data['path']) return $link;
}
break;

case 'product/product/review':
case 'information/information/info':
return $link;
break;

default:
break;
}

if ($component['scheme'] == 'https') {
$link = $this->config->get('config_ssl');
} else {
$link = $this->config->get('config_url');
}

if ($code != $this->config_language){
$link .= $code . '/index.php?route=' . $route;
} else{
$link .= 'index.php?route=' . $route;
}

if (count($data)) {
$link .= '&' . urldecode(http_build_query($data, '', '&'));
}

$queries = array();
foreach ($data as $key => $value) {
switch ($key) {
case 'product_id':
case 'manufacturer_id':
case 'category_id':
case 'information_id':
$queries[] = $key . '=' . $value;
unset($data[$key]);
$postfix = 1;
break;

case 'path':
$categories = explode('_', $value);
foreach ($categories as $category) {
$queries[] = 'category_id=' . $category;
}
unset($data[$key]);
break;

default:
break;
}
}

if(empty($queries)) {
$queries[] = $route;
}

$rows = array();
foreach($queries as $query) {
if(isset($this->cache_data['queries'][$query])) {
$rows[] = array('query' => $query, 'keyword' => $this->cache_data['queries'][$query]);
}
}

if(count($rows) == count($queries)) {
$aliases = array();
foreach($rows as $row) {
$aliases[$row['query']] = $row['keyword'];
}
foreach($queries as $query) {
$seo_url .= '/' . rawurlencode($aliases[$query]);
}
}

if ($seo_url == '') return $link;

if($code != $this->config_language) {
$seo_url = $code . '/' . trim($seo_url, '/');
} else {
$seo_url = trim($seo_url, '/');
}

if ($component['scheme'] == 'https') {
$seo_url = $this->config->get('config_ssl') . $seo_url;
} else {
$seo_url = $this->config->get('config_url') . $seo_url;
}

if (isset($postfix)) {
$seo_url .= trim($this->config->get('config_seo_url_postfix'));
} else {
$seo_url .= '/';
}

if(substr($seo_url, -2) == '//') {
$seo_url = substr($seo_url, 0, -1);
}


if (count($data)) {
$seo_url .= '?' . urldecode(http_build_query($data, '', '&'));
}

return $seo_url;
}

private function getPathByProduct($product_id) {
$product_id = (int)$product_id;
if ($product_id < 1) return false;

static $path = null;
if (!is_array($path)) {
$path = $this->cache->get('product.seopath');
if (!is_array($path)) $path = array();
}

if (!isset($path[$product_id])) {
$query = $this->db->query("SELECT category_id FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . $product_id . "' ORDER BY main_category DESC LIMIT 1");

$path[$product_id] = $this->getPathByCategory($query->num_rows ? (int)$query->row['category_id'] : 0);

$this->cache->set('product.seopath', $path);
}

return $path[$product_id];
}

private function getPathByCategory($category_id) {
$category_id = (int)$category_id;
if ($category_id < 1) return false;

static $path = null;
if (!is_array($path)) {
$path = $this->cache->get('category.seopath');
if (!is_array($path)) $path = array();
}

if (!isset($path[$category_id])) {
$max_level = 10;

$sql = "SELECT CONCAT_WS('_'";
for ($i = $max_level-1; $i >= 0; --$i) {
$sql .= ",t$i.category_id";
}
$sql .= ") AS path FROM " . DB_PREFIX . "category t0";
for ($i = 1; $i < $max_level; ++$i) {
$sql .= " LEFT JOIN " . DB_PREFIX . "category t$i ON (t$i.category_id = t" . ($i-1) . ".parent_id)";
}
$sql .= " WHERE t0.category_id = '" . $category_id . "'";

$query = $this->db->query($sql);

$path[$category_id] = $query->num_rows ? $query->row['path'] : false;

$this->cache->set('category.seopath', $path);
}

return $path[$category_id];
}

private function validate() {
if (isset($this->request->get['route']) && $this->request->get['route'] == 'error/not_found') {
return;
}
if(empty($this->request->get['route'])) {
$this->request->get['route'] = 'common/home';
}

if (isset($this->request->server['HTTP_X_REQUESTED_WITH']) && strtolower($this->request->server['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
return;
}

if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) {
$url = str_replace('&', '&', $this->config->get('config_ssl') . ltrim($this->request->server['REQUEST_URI'], '/'));
$seo = str_replace('&', '&', $this->url->link($this->request->get['route'], $this->getQueryString(array('route')), 'SSL'));
} else {
$url = str_replace('&', '&', $this->config->get('config_url') . ltrim($this->request->server['REQUEST_URI'], '/'));
$seo = str_replace('&', '&', $this->url->link($this->request->get['route'], $this->getQueryString(array('route')), 'NONSSL'));
}

if (rawurldecode($url) != rawurldecode($seo)) {

header($this->request->server['SERVER_PROTOCOL'] . ' 301 Moved Permanently');

$this->response->redirect($seo);
}
}

private function getQueryString($exclude = array()) {
if (!is_array($exclude)) {
$exclude = array();
}

return urldecode(http_build_query(array_diff_key($this->request->get, array_flip($exclude))));
}
}
?>

 

Может кто подсказать как дальше пилить? Или какое то другое решение сложившейся проблемы.

 

OC 1.5.6.4

Share this post


Link to post
Share on other sites

Доброе время суток.

Кто нибудь решил вопрос с одинаковыми подкатегориями?

То есть структура такая:

-Бумага

--Бумага А4

--Цветная

----

-Картон

--Картон А4

--Цветной

 

У цветной и цветная - url один и тот же. Изменять нельзя!

Соответственно открывается только одна страница, которая первая в выборке.

Писал так в файле catalog\controller\common\seo_pro.php:

foreach ($parts as $keyword) {

if (isset($a) && $a[0]=="category_id") {

$query = $this->db->query("SELECT a.* FROM " . DB_PREFIX . "url_alias a, " . DB_PREFIX . "category c WHERE a.keyword = '" . $this->db->escape($keyword) . "' AND a.query=CONCAT('category_id=', c.category_id) AND c.parent_id='".$a[1]."'");

if ($query->num_rows) {

$rows[] = array('keyword' => $keyword, 'query' => $query->row['query']);

$a = explode("=",$query->row['query']);

}

} else {

if (isset($this->cache_data['keywords'][$keyword])) {

$rows[] = array('keyword' => $keyword, 'query' => $this->cache_data['keywords'][$keyword]);

$a=explode("=",$this->cache_data['keywords'][$keyword]);

}

}

}

 

В результате категории стали открываться как надо, но при клике на товар - Запрашиваемая страница не найдена.

 

Исходный код файла seo_pro.php

class ControllerCommonSeoPro extends Controller {

private $cache_data = null;

private $languages = array();

private $config_language;

public function __construct($registry) {

parent::__construct($registry);

$this->cache_data = $this->cache->get('seo_pro');

if (!$this->cache_data) {

$query = $this->db->query("SELECT LOWER(`keyword`) as 'keyword', `query` FROM " . DB_PREFIX . "url_alias");

$this->cache_data = array();

foreach ($query->rows as $row) {

$this->cache_data['keywords'][$row['keyword']] = $row['query'];

$this->cache_data['queries'][$row['query']] = $row['keyword'];

}

$this->cache->set('seo_pro', $this->cache_data);

}

$query = $this->db->query("SELECT `value` FROM `" . DB_PREFIX . "setting` WHERE `key` = 'config_language'");

$this->config_language = $query->row['value'];

$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "language WHERE status = '1'");

foreach ($query->rows as $result) {

$this->languages[$result['code']] = $result;

}

}

public function index() {

// language

$code = $this->config_language;

if(isset($this->request->get['route'])) {

$routes=explode('/',$this->request->get['route']);

}

if(isset($this->request->get['_route_'])) {

$route_ = $this->request->get['_route_'];

$tokens = explode('/', $this->request->get['_route_']);

if(array_key_exists($tokens[0], $this->languages)) {

$code = $tokens[0];

$this->request->get['_route_'] = substr($this->request->get['_route_'], strlen($code) + 1);

}

if(trim($this->request->get['_route_']) == '' || trim($this->request->get['_route_']) == 'index.php') {

unset($this->request->get['_route_']);

}

}

if ($code == $this->config_language &&

isset($this->request->cookie['language']) &&

$this->request->cookie['language'] != $code &&

isset($this->request->server['HTTP_X_REQUESTED_WITH']) &&

strtolower($this->request->server['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {

$code = $this->request->cookie['language'];

}

if (isset($this->request->cookie['language']) &&

$this->request->cookie['language'] != $code &&

isset($routes) &&

trim($routes[0]=='module')) {

$code = $this->request->cookie['language'];

}

if(!isset($this->session->data['language']) || $this->session->data['language'] != $code) {

$this->session->data['language'] = $code;

}

$xhttprequested = isset($this->request->server['HTTP_X_REQUESTED_WITH']) && $this->request->server['HTTP_X_REQUESTED_WITH'] == 'xmlhttprequest';

$captcha = isset($this->request->get['route']) && $this->request->get['route']=='product/product/captcha';

if(!$xhttprequested && !$captcha) {

setcookie('language', $code, time() + 60 * 60 * 24 * 30, '/', $this->request->server['HTTP_HOST']);

}

$this->config->set('config_language_id', $this->languages[$code]['language_id']);

$this->config->set('config_language', $this->languages[$code]['code']);

$language = new Language($this->languages[$code]['directory']);

$language->load($this->languages[$code]['filename']);

$this->registry->set('language', $language);

// Add rewrite to url class

if ($this->config->get('config_seo_url')) {

$this->url->addRewrite($this);

} else {

return;

}

// Decode URL

if (!isset($this->request->get['_route_'])) {

$this->validate();

} else {

$route = $this->request->get['_route_'];

unset($this->request->get['_route_']);

$parts = explode('/', trim(utf8_strtolower($route), '/'));

list($last_part) = explode('.', array_pop($parts));

array_push($parts, $last_part);

$rows = array();

foreach ($parts as $keyword) {

if (isset($this->cache_data['keywords'][$keyword])) {

$rows[] = array('keyword' => $keyword, 'query' => $this->cache_data['keywords'][$keyword]);

}

}

if (count($rows) == sizeof($parts)) {

$queries = array();

foreach ($rows as $row) {

$queries[utf8_strtolower($row['keyword'])] = $row['query'];

}

reset($parts);

foreach ($parts as $part) {

$url = explode('=', $queries[$part], 2);

if ($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';

}

if (isset($this->request->get['product_id'])) {

$this->request->get['route'] = 'product/product';

if (!isset($this->request->get['path'])) {

$path = $this->getPathByProduct($this->request->get['product_id']);

if ($path) $this->request->get['path'] = $path;

}

} 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/product';

if(in_array(substr(VERSION, 0, 5), array('1.5.4', '1.5.5'))) {

$this->request->get['route'] = 'product/manufacturer/info';

}

} elseif (isset($this->request->get['information_id'])) {

$this->request->get['route'] = 'information/information';

} elseif(isset($this->cache_data['queries'][$route_])) {

header($this->request->server['SERVER_PROTOCOL'] . ' 301 Moved Permanently');

$this->response->redirect($this->cache_data['queries'][$route_]);

} else {

if (isset($queries[$parts[0]])) {

$this->request->get['route'] = $queries[$parts[0]];

}

}

$this->validate();

if (isset($this->request->get['route'])) {

return $this->forward($this->request->get['route']);

}

}

}

public function rewrite($link, $code = '') {

if(!$code) {

$code = $this->session->data['language'];

}

if (!$this->config->get('config_seo_url')) return $link;

$seo_url = '';

$component = parse_url(str_replace('&', '&', $link));

$data = array();

parse_str($component['query'], $data);

$route = $data['route'];

unset($data['route']);

switch ($route) {

case 'product/product':

if (isset($data['product_id'])) {

$tmp = $data;

$data = array();

if ($this->config->get('config_seo_url_include_path')) {

$data['path'] = $this->getPathByProduct($tmp['product_id']);

if (!$data['path']) return $link;

}

$data['product_id'] = $tmp['product_id'];

if (isset($tmp['tracking'])) {

$data['tracking'] = $tmp['tracking'];

}

}

break;

case 'product/category':

if (isset($data['path'])) {

$category = explode('_', $data['path']);

$category = end($category);

$data['path'] = $this->getPathByCategory($category);

if (!$data['path']) return $link;

}

break;

case 'product/product/review':

case 'information/information/info':

return $link;

break;

default:

break;

}

if ($component['scheme'] == 'https') {

$link = $this->config->get('config_ssl');

} else {

$link = $this->config->get('config_url');

}

if ($code != $this->config_language){

$link .= $code . '/index.php?route=' . $route;

} else{

$link .= 'index.php?route=' . $route;

}

if (count($data)) {

$link .= '&' . urldecode(http_build_query($data, '', '&'));

}

$queries = array();

foreach ($data as $key => $value) {

switch ($key) {

case 'product_id':

case 'manufacturer_id':

case 'category_id':

case 'information_id':

$queries[] = $key . '=' . $value;

unset($data[$key]);

$postfix = 1;

break;

case 'path':

$categories = explode('_', $value);

foreach ($categories as $category) {

$queries[] = 'category_id=' . $category;

}

unset($data[$key]);

break;

default:

break;

}

}

if(empty($queries)) {

$queries[] = $route;

}

$rows = array();

foreach($queries as $query) {

if(isset($this->cache_data['queries'][$query])) {

$rows[] = array('query' => $query, 'keyword' => $this->cache_data['queries'][$query]);

}

}

if(count($rows) == count($queries)) {

$aliases = array();

foreach($rows as $row) {

$aliases[$row['query']] = $row['keyword'];

}

foreach($queries as $query) {

$seo_url .= '/' . rawurlencode($aliases[$query]);

}

}

if ($seo_url == '') return $link;

if($code != $this->config_language) {

$seo_url = $code . '/' . trim($seo_url, '/');

} else {

$seo_url = trim($seo_url, '/');

}

if ($component['scheme'] == 'https') {

$seo_url = $this->config->get('config_ssl') . $seo_url;

} else {

$seo_url = $this->config->get('config_url') . $seo_url;

}

if (isset($postfix)) {

$seo_url .= trim($this->config->get('config_seo_url_postfix'));

} else {

$seo_url .= '/';

}

if(substr($seo_url, -2) == '//') {

$seo_url = substr($seo_url, 0, -1);

}

if (count($data)) {

$seo_url .= '?' . urldecode(http_build_query($data, '', '&'));

}

return $seo_url;

}

private function getPathByProduct($product_id) {

$product_id = (int)$product_id;

if ($product_id < 1) return false;

static $path = null;

if (!is_array($path)) {

$path = $this->cache->get('product.seopath');

if (!is_array($path)) $path = array();

}

if (!isset($path[$product_id])) {

$query = $this->db->query("SELECT category_id FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . $product_id . "' ORDER BY main_category DESC LIMIT 1");

$path[$product_id] = $this->getPathByCategory($query->num_rows ? (int)$query->row['category_id'] : 0);

$this->cache->set('product.seopath', $path);

}

return $path[$product_id];

}

private function getPathByCategory($category_id) {

$category_id = (int)$category_id;

if ($category_id < 1) return false;

static $path = null;

if (!is_array($path)) {

$path = $this->cache->get('category.seopath');

if (!is_array($path)) $path = array();

}

if (!isset($path[$category_id])) {

$max_level = 10;

$sql = "SELECT CONCAT_WS('_'";

for ($i = $max_level-1; $i >= 0; --$i) {

$sql .= ",t$i.category_id";

}

$sql .= ") AS path FROM " . DB_PREFIX . "category t0";

for ($i = 1; $i < $max_level; ++$i) {

$sql .= " LEFT JOIN " . DB_PREFIX . "category t$i ON (t$i.category_id = t" . ($i-1) . ".parent_id)";

}

$sql .= " WHERE t0.category_id = '" . $category_id . "'";

$query = $this->db->query($sql);

$path[$category_id] = $query->num_rows ? $query->row['path'] : false;

$this->cache->set('category.seopath', $path);

}

return $path[$category_id];

}

private function validate() {

if (isset($this->request->get['route']) && $this->request->get['route'] == 'error/not_found') {

return;

}

if(empty($this->request->get['route'])) {

$this->request->get['route'] = 'common/home';

}

if (isset($this->request->server['HTTP_X_REQUESTED_WITH']) && strtolower($this->request->server['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {

return;

}

if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) {

$url = str_replace('&', '&', $this->config->get('config_ssl') . ltrim($this->request->server['REQUEST_URI'], '/'));

$seo = str_replace('&', '&', $this->url->link($this->request->get['route'], $this->getQueryString(array('route')), 'SSL'));

} else {

$url = str_replace('&', '&', $this->config->get('config_url') . ltrim($this->request->server['REQUEST_URI'], '/'));

$seo = str_replace('&', '&', $this->url->link($this->request->get['route'], $this->getQueryString(array('route')), 'NONSSL'));

}

if (rawurldecode($url) != rawurldecode($seo)) {

header($this->request->server['SERVER_PROTOCOL'] . ' 301 Moved Permanently');

$this->response->redirect($seo);

}

}

private function getQueryString($exclude = array()) {

if (!is_array($exclude)) {

$exclude = array();

}

return urldecode(http_build_query(array_diff_key($this->request->get, array_flip($exclude))));

}

}

?>

 

Может кто подсказать как дальше пилить? Или какое то другое решение сложившейся проблемы.

 

OC 1.5.6.4

Разобрался с этим - работает все правильно.

Вот код, кому-то может пригодиться 

class ControllerCommonSeoPro extends Controller {

private $cache_data = null;

public function __construct($registry) {

parent::__construct($registry);

$this->cache_data = $this->cache->get('seo_pro');

if (!$this->cache_data) {

$query = $this->db->query("SELECT LOWER(`keyword`) as 'keyword', `query` FROM " . DB_PREFIX . "url_alias");

$this->cache_data = array();

foreach ($query->rows as $row) {

$this->cache_data['keywords'][$row['keyword']] = $row['query'];

$this->cache_data['queries'][$row['query']] = $row['keyword'];

}

$this->cache->set('seo_pro', $this->cache_data);

}

}

public function index() {

// Add rewrite to url class

if ($this->config->get('config_seo_url')) {

$this->url->addRewrite($this);

} else {

return;

}

// Decode URL

if (isset($this->request->get['_route_'])) {

$parts = explode('/', $this->request->get['_route_']);

foreach ($parts as $part) {

if( $this->config->get('config_seo_url_replace') ) {

$part = str_replace('_', ' ', $part);

}

if (isset($url[2])) {

$query = $this->db->query("SELECT a.* FROM " . DB_PREFIX . "url_alias a, " . DB_PREFIX . "category c WHERE a.keyword = '" . $this->db->escape($part) . "' AND a.query=CONCAT('category_id=', c.category_id) AND c.parent_id='$url[1]'");

} else {

$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($part) . "'");

}

if ($query->num_rows) {

$url = explode('=', $query->row['query']);

if ($url[0] == 'product_id') {

$this->request->get['product_id'] = $url[1];

}

if ($url[0] == 'category_id') {

if (!isset($this->request->get['path'])) {

$this->request->get['path'] = $url[1];

} else {

$this->request->get['path'] .= '_' . $url[1];

}

}

if ($url[0] == 'manufacturer_id') {

$this->request->get['manufacturer_id'] = $url[1];

}

if ($url[0] == 'information_id') {

$this->request->get['information_id'] = $url[1];

}

} else {

$this->request->get['route'] = 'error/not_found';

}

}

if (isset($this->request->get['product_id'])) {

$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/product';

} elseif (isset($this->request->get['information_id'])) {

$this->request->get['route'] = 'information/information';

}

if (isset($this->request->get['route'])) {

return $this->forward($this->request->get['route']);

}

}

}

public function rewrite($link) {

if (!$this->config->get('config_seo_url')) return $link;

$seo_url = '';

$component = parse_url(str_replace('&', '&', $link));

$data = array();

parse_str($component['query'], $data);

$route = $data['route'];

unset($data['route']);

switch ($route) {

case 'product/product':

if (isset($data['product_id'])) {

$tmp = $data;

$data = array();

if ($this->config->get('config_seo_url_include_path')) {

$data['path'] = $this->getPathByProduct($tmp['product_id']);

if (!$data['path']) return $link;

}

$data['product_id'] = $tmp['product_id'];

if (isset($tmp['tracking'])) {

$data['tracking'] = $tmp['tracking'];

}

}

break;

case 'product/category':

if (isset($data['path'])) {

$category = explode('_', $data['path']);

$category = end($category);

$data['path'] = $this->getPathByCategory($category);

if (!$data['path']) return $link;

}

break;

case 'product/product/review':

case 'information/information/info':

return $link;

break;

default:

break;

}

if ($component['scheme'] == 'https') {

$link = $this->config->get('config_ssl');

} else {

$link = $this->config->get('config_url');

}

$link .= 'index.php?route=' . $route;

if (count($data)) {

$link .= '&' . urldecode(http_build_query($data, '', '&'));

}

$queries = array();

foreach ($data as $key => $value) {

switch ($key) {

case 'product_id':

case 'manufacturer_id':

case 'category_id':

case 'information_id':

case 'infocategory_id':

$queries[] = $key . '=' . $value;

unset($data[$key]);

$postfix = 1;

break;

case 'path':

$categories = explode('_', $value);

foreach ($categories as $category) {

$queries[] = 'category_id=' . $category;

}

unset($data[$key]);

break;

default:

break;

}

}

if(empty($queries)) {

$queries[] = $route;

}

$rows = array();

foreach($queries as $query) {

if(isset($this->cache_data['queries'][$query])) {

$rows[] = array('query' => $query, 'keyword' => $this->cache_data['queries'][$query]);

}

}

if(count($rows) == count($queries)) {

$aliases = array();

foreach($rows as $row) {

$aliases[$row['query']] = $row['keyword'];

}

foreach($queries as $query) {

$seo_url .= '/' . rawurlencode($aliases[$query]);

}

}

if ($seo_url == '') return $link;

$seo_url = trim($seo_url, '/');

if ($component['scheme'] == 'https') {

$seo_url = $this->config->get('config_ssl') . $seo_url;

} else {

$seo_url = $this->config->get('config_url') . $seo_url;

}

if (isset($postfix)) {

$seo_url .= trim($this->config->get('config_seo_url_postfix'));

} else {

$seo_url .= '/';

}

$seo_url = trim($seo_url, '//');

if (count($data)) {

$seo_url .= '?' . urldecode(http_build_query($data, '', '&'));

}

return $seo_url;

}

private function getPathByProduct($product_id) {

$product_id = (int)$product_id;

if ($product_id < 1) return false;

static $path = null;

if (!is_array($path)) {

$path = $this->cache->get('product.seopath');

if (!is_array($path)) $path = array();

}

if (!isset($path[$product_id])) {

$query = $this->db->query("SELECT category_id FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . $product_id . "' ORDER BY main_category DESC LIMIT 1");

$path[$product_id] = $this->getPathByCategory($query->num_rows ? (int)$query->row['category_id'] : 0);

$this->cache->set('product.seopath', $path);

}

return $path[$product_id];

}

private function getPathByCategory($category_id) {

$category_id = (int)$category_id;

if ($category_id < 1) return false;

static $path = null;

if (!is_array($path)) {

$path = $this->cache->get('category.seopath');

if (!is_array($path)) $path = array();

}

if (!isset($path[$category_id])) {

$max_level = 4;

$sql = "SELECT CONCAT_WS('_'";

for ($i = $max_level-1; $i >= 0; --$i) {

$sql .= ",t$i.category_id";

}

$sql .= ") AS path FROM " . DB_PREFIX . "category t0";

for ($i = 1; $i < $max_level; ++$i) {

$sql .= " LEFT JOIN " . DB_PREFIX . "category t$i ON (t$i.category_id = t" . ($i-1) . ".parent_id)";

}

$sql .= " WHERE t0.category_id = '" . $category_id . "'";

$query = $this->db->query($sql);

$path[$category_id] = $query->num_rows ? $query->row['path'] : false;

$this->cache->set('category.seopath', $path);

}

return $path[$category_id];

}

private function validate() {

if (empty($this->request->get['route']) || $this->request->get['route'] == 'error/not_found') {

return;

}

if (isset($this->request->server['HTTP_X_REQUESTED_WITH']) && strtolower($this->request->server['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {

return;

}

if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1'))) {

$url = str_replace('&', '&', $this->config->get('config_ssl') . ltrim($this->request->server['REQUEST_URI'], '/'));

$seo = str_replace('&', '&', $this->url->link($this->request->get['route'], $this->getQueryString(array('route')), 'SSL'));

} else {

$url = str_replace('&', '&', $this->config->get('config_url') . ltrim($this->request->server['REQUEST_URI'], '/'));

$seo = str_replace('&', '&', $this->url->link($this->request->get['route'], $this->getQueryString(array('route')), 'NONSSL'));

}

if (rawurldecode($url) != rawurldecode($seo)) {

header($this->request->server['SERVER_PROTOCOL'] . ' 301 Moved Permanently');

$this->response->redirect($seo);

}

}

private function getQueryString($exclude = array()) {

if (!is_array($exclude)) {

$exclude = array();

}

return urldecode(http_build_query(array_diff_key($this->request->get, array_flip($exclude))));

}

}

?>

Вопрос только один - как слеш добавить в конец урл - через .htaccess не подходит - сверху сидит злой СЕОшник)

Share this post


Link to post
Share on other sites

Не работало ЧПУ, на локальном компе. Проблема крылась в htaccess. Спасибо всем кто отписался в теме.

Edited by nextvid

Share this post


Link to post
Share on other sites

Здравствуйте, установил чистый осСтор, включил сео про и алиасы товара которые были "ЧПУ-шные", превратились в index.php?route=product/product&product_id=52 , когда включаю стандарный чпу, алиасы приходят в норму. И все бы хорошо, только при стандартном ЧПУ появляются дубли страниц. В чем дело? Как настроить чпу алиасов товаров с включенным сео про?

Edited by Jays0n

Share this post


Link to post
Share on other sites

видимо нет у категорий ЧПУ

Share this post


Link to post
Share on other sites

или ждать час 

Share this post


Link to post
Share on other sites

Чисти кэш в system - storeage - cache (удаляй все, кроме index!!!) и результат через секунды.

А так все там работает. 

Вот тебе пример на ocStore 2.1.0.2.1

https://###.ru/control-modules/lighting-control/

                домен              категория        под категория

 

А когда на карточку товара выходишь, то покажет 

https://###.ru/control-modules/zipato-rgbw-lamp.php

               домен               категория           товар

 

И на будущее, пока начинаешь делать, url делай транскрипцией ###.ru/moduli-upravleniya/upravlenie-svetom/

Для Яндекса это гуд, в выдаче url тоже подсечивает. Для Гугла по барабану. Гугл в выдаче с англ на русский переводит url автоматом, только почему то не везде.

Но я ставку на яшу больше делаю.

Edited by SuperCoach

Share this post


Link to post
Share on other sites

Добрый день!

Я знаю, что вопрос поднимался не единожды, но найти решения за 3 часа поиска я не смог. Поэтому взываю к вашей помощи.

 

Как прописать страница пагинации "index, nofollow" ? Может кто-мини инструкцию расписать?

Share this post


Link to post
Share on other sites

Не могу найти такое же решение на OCstore 2

Это и есть под 2

Share this post


Link to post
Share on other sites

Народ а SEO pro для opencart 2.3.0.2 существует??? Просто есть вот такая проблемка с дублями

http://climat-store.com.ua/conditioner/kondicionery-nastennie/ftxs35k-rxs35k

http://climat-store.com.ua/conditioner/kondicionery-nastennie/ftxs35k-rxs35k?filter=131

Как бы два одинаковых товара но выводятся разными страницами, я понимаю что это стандартный фильтр, есть в планах покупка нормального фильтра, но хотелось бы проблему решить уже.

Share this post


Link to post
Share on other sites

Народ а SEO pro для opencart 2.3.0.2 существует??? Просто есть вот такая проблемка с дублями

http://climat-store.com.ua/conditioner/kondicionery-nastennie/ftxs35k-rxs35k

http://climat-store.com.ua/conditioner/kondicionery-nastennie/ftxs35k-rxs35k?filter=131

Как бы два одинаковых товара но выводятся разными страницами, я понимаю что это стандартный фильтр, есть в планах покупка нормального фильтра, но хотелось бы проблему решить уже.

У Вас вторая ссылка закрыта от индексации через robots.txt, проблем с ней не должно быть.

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Народ, остаётся открытым вопрос про дубли страниц на голом OpenCart 2.3.0.2.

Есть ли какое-то решение?

 

Уйти на OcStore 2.3 не будет возможности из-за поддержки нужных модулей.

Share this post


Link to post
Share on other sites

интеграция seo_pro

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
You are posting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Similar Content

    • By legioner26
      899.00 руб
      Скачать/Купить дополнение


      SEO Генератор мета тегов (категории, товары), SEO URL - Мультиязык
      Модуль SEO генератор мета описания(тегов), URL, дубли,  позволяет провести оптимизацию всех категорий и товаров с поддержкой языков магазина. Очень прост в эксплуатации
      При первом прохождении  перезаписывает meta по все товарам, категориям, и сохраняет информацию о заполнении проставляя метки. 
      Все что от Вас требуется, это задать шаблон для заполнения meta.
       
      Внедрен Мультиязык производящий генерацию метатегов и URL, а также поиск дублей на всех подключенных языках магазина !!!
       
      Также добавлена возможность автоматической массовой генерации отсутствующих SEO URL в товарах и категориях на всех языках магазина,
      при нажатии на кнопку Обновить ЧПУ (SEO URL)  модуль проставить URL во всех товарах и категориях в которых они отсутствуют.
       
      Возможность устранения дублей SEO URL
       
      ПРИМЕР заполнения прилагается в скриншоте.
       
      УСТАНОВКА
      1. Установить модификатор через Установку дополнения, очистить кешь.
      2. Скопировать папку admin в корень сайта.
      УСТАНОВКА для ОС 3.х
       Устанавливаем архив Uodate-Meta3x.ocmod.zip через Установку расширений, чистим кеш.
      ПРИМЕЧАНИЕ
      Модуль не закублен с открытым исходным кодом, не требует ключа активации.
      Тех. поддержка осуществляется для клиентов купившим модуль для конкретного ресурса, поэтому при покупке обязательно указываем Ваш домен.
       

       
      СЕО СОПРОВОЖДЕНИЕ <<<
       
      РЕКОМЕНДУЕМЫЕ МОДУЛИ
       
      Генератор АКЦИЙ Special PRO
      Смс авторизация и регистрация 
      Модуль Зумма
      Модуль подарков
      Конструктор форм обратной связи
      ___________________
       
      Также советую приобрести модуль от разработчика @chukcha Редирект Универсал 
      Незаменимый инструмент для редиректов, имеется 410 жизненно важный для удаленных товаров.
       
      Добавил legioner26 Добавлено 31.03.2019 Категория SEO, карта сайта, оптимизация Системные требования Метод активации Без активации Ioncube Loader Нет OpenCart 3.0
      2.3
      2.2
      2.1
      2.0 ocStore 3.0
      2.3
      2.2
      2.1 OpenCart.Pro, ocShop Opencart.pro 2.3
      Opencart.pro 2.1 Обращение к серверу разработчика Нет Старая цена 1200  
    • By legioner26
      Модуль SEO генератор мета описания(тегов), URL, дубли,  позволяет провести оптимизацию всех категорий и товаров с поддержкой языков магазина. Очень прост в эксплуатации
      При первом прохождении  перезаписывает meta по все товарам, категориям, и сохраняет информацию о заполнении проставляя метки. 
      Все что от Вас требуется, это задать шаблон для заполнения meta.
       
      Внедрен Мультиязык производящий генерацию метатегов и URL, а также поиск дублей на всех подключенных языках магазина !!!
       
      Также добавлена возможность автоматической массовой генерации отсутствующих SEO URL в товарах и категориях на всех языках магазина,
      при нажатии на кнопку Обновить ЧПУ (SEO URL)  модуль проставить URL во всех товарах и категориях в которых они отсутствуют.
       
      Возможность устранения дублей SEO URL
       
      ПРИМЕР заполнения прилагается в скриншоте.
       
      УСТАНОВКА
      1. Установить модификатор через Установку дополнения, очистить кешь.
      2. Скопировать папку admin в корень сайта.
      УСТАНОВКА для ОС 3.х
       Устанавливаем архив Uodate-Meta3x.ocmod.zip через Установку расширений, чистим кеш.
      ПРИМЕЧАНИЕ
      Модуль не закублен с открытым исходным кодом, не требует ключа активации.
      Тех. поддержка осуществляется для клиентов купившим модуль для конкретного ресурса, поэтому при покупке обязательно указываем Ваш домен.
       

       
      СЕО СОПРОВОЖДЕНИЕ <<<
       
      РЕКОМЕНДУЕМЫЕ МОДУЛИ
       
      Генератор АКЦИЙ Special PRO
      Смс авторизация и регистрация 
      Модуль Зумма
      Модуль подарков
      Конструктор форм обратной связи
      ___________________
       
      Также советую приобрести модуль от разработчика @chukcha Редирект Универсал 
      Незаменимый инструмент для редиректов, имеется 410 жизненно важный для удаленных товаров.
       
    • By Poxod86
      Доброго времени суток. Подскажите как решить проблему или это не является проблемой.
      Дело в том что на сайте https://texnoprofsnabrti.ru/ одна и та же страница доступна по нескольким адресам
      к примеру:
      1. https://texnoprofsnabrti.ru/rezinotehnicheskie-izdeliya/kolca-manzhety-salniki-vtulki-gryazesemniki/kolca-uplotnitelnye/kolca-uplotnitelnye-din-o-ring/Kolco_0,74_1,02_NBR_DIN_3771
      2. https://texnoprofsnabrti.ru/Kolco_0,74_1,02_NBR_DIN_3771
      3. https://texnoprofsnabrti.ru/Kolco_0,74_1,02_NBR_DIN_3771?search=Кольцо 0%2C74 - 1%2C02 NBR DIN 3771
      При этом отображение модуля (меню) на каждом URL разные. (см. боковое меню)
      Отсюда есть подозрение что это дубли. 
      Как это можно исправить?
      Нужно ли это исправлять?
    • By ScartFM
      При копировании товара (функционал в админке) - создаются 2 копии, вместо 1.
       
      Сначала думал из-за какого-то модуля. Поставил чистый ocStore 3.0.2. Проблема сохранилась.
      Подскажите в чем может быть проблема, куда смотреть?
       
       
       
    • By ibond
      Столкнулся с проблемой, что Опера делает дубли при добавлении новых модулей. Например, создаешь новый html-блок, и после сохранения появляется дубликат с новым id.
      https://monosnap.com/file/CAWNzoJOkjVzECqtrJpxqTXScLPJ25
       
      Поставил в лог запись и вижу, что контроллер отрабатывает два раза:
      2019-05-18 8:23:11 - extension 2019-05-18 8:23:25 - index() 2019-05-18 8:23:35 - index() 2019-05-18 8:23:35 - POST 2019-05-18 8:23:35 - addModule 2019-05-18 8:23:35 - index() 2019-05-18 8:23:35 - POST 2019-05-18 8:23:35 - addModule 2019-05-18 8:23:35 - extension  
      Замечено в версии OPR/62.0.3319.0 (Edition developer). На обычной Опере нормально и в других браузерах тоже. Проверял на opencart 2.x, 3.x.  В приватном окне тоже самое.
      Возможно добавилось что-то в настройках самой Оперы?
       
      Появилось наверное после последнего обновления, но точно не скажу.
       
      Есть у кого возможность проверить?
       
      UPDATE: Сделал полный реинсталл. Проблема пропала при версии 59.0.3218.0. Сразу после обновления проблема появилась.
  • Recently Browsing   0 members

    No registered users viewing this page.

×

Important Information

On our site, cookies are used and personal data is processed to improve the user interface. To find out what and what personal data we are processing, please go to the link. If you click "I agree," it means that you understand and accept all the conditions specified in this Privacy Notice.