OpenCart — заплатка. Убрать дубли страниц товаров

ПОЯВИЛСЯ ОБНОВЛЕННЫЙ МЕТОД ДЛЯ OpenCart 1.5.5.1.x ВОТ ЗДЕСЬ

Добрый день, уважаемые читатели! Сегодня мы попробуем разобраться с тем, как можно без дополнительных модулей привести все ссылки на товары к единому виду. Этот способ может и не является самым красивым и быстрым решением, но работает достаточно хорошо.

PS: данная заплатка будет работать только при уровне вложенности в 1 или 2 категории (родительская и дочерняя)

Проблема в следующем: при включенном ЧПУ товар становится доступным по нескольким ссылкам, что очень плохо влияет на SEO-оптимизацию, потому что поисковые машины такие страницы либо понижают в рейтинге выдачи или вообще применяет карательные меры (имеется ввиду бан).

Товар доступен по следующим URL:

  • site.ru/product.html
  • site.ru/product.html?manufacturer_id=1
  • site.ru/product.html?filter_name=product
  • site.ru/category_name/product.html
  • site.ru/category_name/sub_category_name/product.html

Вроде все возможные ссылки, но мог и что-нибудь упустить

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

1) Нам потребуется в каждом модуле, который выводит товары, поменять ссылки. Чтобы эти ссылки создать — нужны ID категорий, к которым этот товар привязан.

Открываем

/catalog/controller/product/category.php

и ищем строчку:

foreach ($results as $result) {

и после нее вставляем следующий код:

 // получаем ID категории для генерации правильного URL
 // и сортируем по родительской категории, чтобы родительская шла всегда первой
 $categories_for_url = $this->db->query("
 SELECT `t1`.`category_id` FROM `" . DB_PREFIX . "product_to_category` as `t1`
 LEFT JOIN `" . DB_PREFIX . "category` as `t2` ON `t1`.`category_id` = `t2`.`category_id`
 WHERE `t1`.`product_id`='" . $result['product_id'] . "'
 ORDER BY `t2`.`parent_id` ASC
 ");

if($categories_for_url->num_rows > 0) {

$category_path = '';

foreach($categories_for_url->rows as $category) {

$category_path .= $category['category_id'] . '_';

}

$category_path = trim($category_path, '_');

}

В этом коде мы получаем ID категорий в нужной нам последовательности: сначала ID родительской, затем дочерней. Это нужно для того, чтобы построить правильный путь. В стандартном виде ссылка в OpenCart выглядит как index.php?route=product/product&path=categoriesid&product_id=1, к такому виду мы и приводим.

Далее ищем строчку

$this->data['products'][] = array(
...
...
'href'        => $this->url->link('product/product', 'path=' . $this->request->get['path'] . '&product_id=' . $result['product_id'])

и меняем значение ключа массива ‘href’ на

'href'        => $this->url->link('product/product', 'path=' . $category_path . '&product_id=' . $result['product_id'])

После этого на странице категорий товары будут иметь полные ссылки.

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

В некоторых модулях переменные цикла foreach ($results as $result) { могут отличаться! Будьте внимательны

Вот и все. Спасибо за внимание

43 комментария

  1. Здравствуйте! Попробовал сделать как Вы написали, но начали появляться ошибки, при переходе из главного меню, так-же правил дополнительные модули по выводу товаров, ошибки только увеличиваются. Шаблон не дефолтный, и видимо происходят конфликты. В openCart не силен чтобы исправить такие проблемы.

    Notice: Undefined index: product_id in /home/r/rozygrysh/oopsda.ru/public_html/catalog/controller/product/category.php on line 184Notice

    Ошибка не одна, их много.
    Метод очень нужный, хотелось бы разобраться. Помогите пожалуйста!

  2. https://yadi.sk/i/6l4s3ZwMW9gEq

    foreach ($results as $result) {
    $this->url->link(‘product/product’, ‘path=’ . $category_path . ‘&product_id=’ . $result[‘product_id’])

    $data = array(
    ‘filter_category_id’ => $result[‘category_id’],
    ‘filter_sub_category’ => true
    );

    $product_total = $this->model_catalog_product->getTotalProducts($data);

    $this->data[‘categories’][] = array(
    ‘name’ => $result[‘name’] . ($this->config->get(‘config_product_count’) ? ‘ (‘ . $product_total . ‘)’ : »),
    ‘href’ => $this->url->link(‘product/category’, ‘path=’ . $this->request->get[‘path’] . ‘_’ . $result[‘category_id’] . $url)
    );
    }

    1. Все верно, вы не в том цикле перебираете. Массив $results — в вашей строке содержит информацию о категориях, а не о продуктах. Ниже у вас есть строчка 212, там $results — это товары

      1. это foreach categories

        $results = $this->model_catalog_category->getCategories($category_id);

        foreach ($results as $result) {
        $data = array(
        ‘filter_category_id’ => $result[‘category_id’],
        ‘filter_sub_category’ => true
        );

        $product_total = $this->model_catalog_product->getTotalProducts($data);

        $this->data[‘categories’][] = array(
        ‘name’ => $result[‘name’] . ‘ (‘ . $product_total . ‘)’,
        ‘href’ => $this->url->link(‘product/category’, ‘path=’ . $this->request->get[‘path’] . ‘_’ . $result[‘category_id’] . $url)
        );
        }

      2. А это foreach products

        $results = $this->model_catalog_product->getProducts($data);

        foreach ($results as $result) {
        // Код OpenCart …

        $this->data[‘products’][] = array(
        ‘product_id’ => $result[‘product_id’],

        // …

        //’href’ => $this->url->link(‘product/product’, ‘path=’ . $this->request->get[‘path’] . ‘&product_id=’ . $result[‘product_id’])
        );
        }

  3. Здравствуйте. Помог ваш метод, но есть один недочёт — перестали отображаться подкатегории 1 уровня. Страница отображается просто белым экраном.

    1. я походу не понял сразу вопроса 🙂
      там точно также в контроллере нужно получить список категорий (родительская + главная)

      и заменить ссылки в результате выдачи товаров

  4. Notice: Undefined index: product_id in /home/amzroigh/public_html/catalog/controller/product/category.php on line 212Notice: Undefined index: product_id in /home/amzroigh/public_html/catalog/controller/product/category.php on line 212Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308Notice: Undefined variable: category_path in /home/amzroigh/public_html/catalog/controller/product/category.php on line 308

    1. не тот цикл) посмотрите новую статью, там указано в каком цикле нужно перебирать

      ссылка на статью в предыдущем комментарии или в начале этой статьи

  5. Спасибо, ссылки стали то что надо. Но сверху страницы пишет:
    Notice: Undefined variable: category_path in /var/www/domainname/domain.ru/vqmod/vqcache/vq2-catalog_controller_product_category.php on line 275

  6. День добрый. Сделал как описано выше, всё получилось, но не могу проделать тоже самое в модуле рекомендуемое, там вместо foreach ($results as $result), стоит foreach ($products as $product_id), и ссылка получает вид /index.php?route=product/product&path=&product_id= которая ведет к несуществующему товару, подскажите пожалуйста где что подправить.

    1. после foreach ($products as $product_id) {

      $product_info = $this->model_catalog_product->getProduct($product_id);

      // получаем ID категории для генерации правильного URL
      // и сортируем по родительской категории, чтобы родительская шла всегда первой
      $categories_for_url = $this->db->query(»
      SELECT `t1`.`category_id` FROM `» . DB_PREFIX . «product_to_category` as `t1`
      LEFT JOIN `category` as `t2` ON `t1`.`category_id` = `t2`.`category_id`
      WHERE `t1`.`product_id`='» . $product_id . «‘
      ORDER BY `t2`.`parent_id` ASC
      «);

      if($categories_for_url->num_rows > 0) {

      $category_path = »;

      foreach($categories_for_url->rows as $category) {

      $category_path .= $category[‘category_id’] . ‘_’;

      }

      $category_path = trim($category_path, ‘_’);

      }

      и вот тут так:

      $this->data[‘products’][] = array(
      ‘product_id’ => $product_info[‘product_id’],

      ‘href’ => $this->url->link(‘product/product’, ‘path=’ . $category_path . ‘&product_id=’ . $product_info[‘product_id’])

          1. а в логе ошибок что пишет?
            или скиньте файл сам, посмотрю

          2. LEFT JOIN `category` as `t2` ON `t1`.`category_id` = `t2`.`category_id`

            исправьте на

            LEFT JOIN `» . DB_PREFIX . «category` as `t2` ON `t1`.`category_id` = `t2`.`category_id`

          3. Спасибо я так пробовал, и получилось, но был небольшой нюанс, в одной переменной не заметил кавычки которые надо было изменить)
            Всё работает спасибо за помощь.

  7. Добрый день!

    перелопатил весь интернет, но ответа так ине нашел…

    У меня проблема в следующем:

    Стоит Deadcow Seo ЧПУ генерится, всё работает, но дублируются адреса на товары с ЧПУ и БЕЗ ЧПУ, т.е.

    В яндекс.вебмастере стоят ссылки:
    мой-сайт/index.php?route=product/product&path=5&product_id=20

    Но они же доступны и с ЧПУ:
    мой-сайт/dlya-lica/aktivnaya-syvorotka-mgnovennyy-lifting-markell-anti-age-program-20ml.html
    ——
    Как избавится от дублей и как заставить яндекс выводить в поиск адреса с ЧПУ?

    Буду очень признателен за ответ!

    1. судя по всему вы настроили ЧПУ после индексации яндексом.. некоторые страницы яндекс воспринимает правильно, но товары по прежнему с get-запросом. Подождите, пока яндекс переиндексирует на ЧПУ.

      Они доступны на всех сайтах, это не совсем дубль, просто нужно обеспечить, чтобы ПС не видели таких ссылок.
      К тому же канонические страницы у вас настроены правильно, так что остается только ждать, в среднем около месяца

      Посмотрите ГУГЛ — он проиндексировал уже ЧПУ ссылки.

    1. не много не в тему, но не могу не сказать.
      исправьте пожалуйста на своем сайте «Брэнды» на «бренды»))
      с производителями сама мучаюсь сейчас.

  8. Долго не получалось убрать дубли из производителей, потому что там много похожих ссылок.
    1. foreach ($results as $result) {
    должно относится к ссылке на открывающиеся модели (у меня это была строчка 208)
    т.е. после getProducts

    $results = $this->model_catalog_product->getProducts($data);

    foreach ($results as $result) {

    тут мы вставляем » получаем ID категории для генерации правильного URL…»

    и чуть ниже (примерно 273 строчка), где получаем массив $this->data[‘products’][] = array(
    меняем на ссылку, которая дана автором статьи!!

    кстати, на версии 1.5.4.1 тоже работает! огромнейшее спасибо))

  9. а разве имеет значение по скольким ссылкам доступен товар, если во всех этих ссылках указано, что одна из них каноническая. то есть ПС будут вес со всех других ссылок передавать на каноническую, тем самым дубли есть, но проблемы нет

Leave a Reply