Сопутствующие товары OpenCart в одну сторону

В штатном OpenCart «сопутствующие» — это не «к удочке леска», а взаимная дружба навек. Повесил на товар A товар B — и B сразу орёт «смотрите, я с A». Для SEO и для честного апсейла это часто вредно: чехол к телефону должен светиться на телефоне, а не наоборот.

Модуль за 500 рублей покупать не будем. Вечер, чай, один файл админки. Делаем связь в одну сторону: A знает про B, B про A молчит, пока сами не скажете.

Файл: admin/model/catalog/product.php. Ищем методы добавления и правки товара — там пачка запросов в product_related.

Было (двусторонняя любовь, OpenCart 2.x / ocStore, кусок editProduct):

if (isset($data['product_related'])) {
    foreach ($data['product_related'] as $related_id) {
        $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "' AND related_id = '" . (int)$related_id . "'");
        $this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$product_id . "', related_id = '" . (int)$related_id . "'");
        $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$related_id . "' AND related_id = '" . (int)$product_id . "'");
        $this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$related_id . "', related_id = '" . (int)$product_id . "'");
    }
}

Стало — оставляем только прямую запись. Две нижние строки комментируем, не вырезаем: через полгода вспомните, зачем они были.

if (isset($data['product_related'])) {
    foreach ($data['product_related'] as $related_id) {
        $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "' AND related_id = '" . (int)$related_id . "'");
        $this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$product_id . "', related_id = '" . (int)$related_id . "'");
        // односторонняя связь: обратную не пишем
        // $this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$related_id . "' AND related_id = '" . (int)$product_id . "'");
        // $this->db->query("INSERT INTO " . DB_PREFIX . "product_related SET product_id = '" . (int)$related_id . "', related_id = '" . (int)$product_id . "'");
    }
}

То же самое повторите в addProduct — иначе новые товары опять начнут дружить взаимно, а старые будут «как повезёт».

Удаление товара. Если снести карточку A, OpenCart подчищает и чужие связи «на меня». Это ок. Блок обычно такой:

$this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE product_id = '" . (int)$product_id . "'");
$this->db->query("DELETE FROM " . DB_PREFIX . "product_related WHERE related_id = '" . (int)$product_id . "'");

Второй запрос лучше оставить: иначе мёртвый id будет торчать в чужих карточках. Речь только про создание обратной связи, не про уборку мусора.

Где править в OpenCart 3: тот же файл, те же четыре запроса, только код чуть разъехался по строкам. Ищите product_related по файлу — попаданий немного.

Фронт трогать не надо. Шаблон catalog/view/theme/.../template/product/product.twig (или .tpl в двойке) как выводил $products из $product_related, так и выводит. Меняется только то, что лежит в таблице.

Проверить за 30 секунд:

  1. Товар A → вкладка «Связи» → прикрутили B → сохранили.
  2. В карточке A на витрине B есть.
  3. В карточке B товара A нет. Если есть — значит правили не тот метод или кэш модификаций (OCMOD/vQmod) перехватывает модель. Тогда правьте не ядро, а модификатор, либо отключите чужой «related».

SQL для параноиков, вдруг руками в базе наковыряли двусторонние хвосты:

SELECT product_id, related_id FROM oc_product_related
WHERE product_id = 15 OR related_id = 15;

Префикс oc_ подставьте свой. Нужна одна строка 15 → 88, а не пара 15 → 88 и 88 → 15.

На этом всё. Чехол продаём к телефону, а не телефон к чехлу. Бесплатно, без модуля и без «рекомендуем ещё вот это случайное».

Комментарии


Комментарии (1)

  1. Алексей:
    16 Jul 2017г. в 11:38

    Спасибо огромное!!! Очень напрягали эти ответные связи. А теперь все ОК!



Разрешённые теги: <b><i><br>Добавить новый комментарий: