Как задать разный порядок сортировки товара для каждой из категорий к которому он привязан

категория: , Дорабатываем, Полезности


Опубликовано: 11.02.2018 Обновлено: 18.09.2019 Просмотров: 3794 Комментарии: 6


Как задать разный порядок сортировки товара для каждой из категорий к которому он привязан

В стандарте опенкарт сортирует по умолчанию как p.sort_order а нам же надо для каждой категории своя. Инструкция как сделать.


Приветствую! Недавно мне написал заказчик который попросил меня сделать достаточно интересную доработку. Суть ее в том что надо сделать порядок сортировки товара который можно задать для каждой категории к которой будет привязан этот товар. То есть у него есть категория видеорегистраторы где регистраторы идут по своему порядку, также есть категории видеокамеры где камерам задан параметр sort_order. Так вот на сайте еще есть такие разделы как готовые наборы где выводятся товары из разных категорий и сортируются в зависимости от заданного sort_order.

Чем это неудобно

Тем, что в категории готовые наборы нужна своя сортировка, например камеры идут первыми, регистраторы вторыми и т.д.То есть суть в том что одному и тому же товару можно задать разную сортировку для каждой категории. Для регистраторов будет 45 для наборов 12 - это к примеру.


В чем сложность

Дело в том что прописать сортировку дело не хитрое, но другое дело что надо еще и править выборку из базы. В стандарте опенкарт сортирует по умолчанию как p.sort_order а нам же надо для каждой категории своя.

Для начала нам надо создать в таблице product_to_category после category_order (int 11). После чего идем в файл catalog/model/product/product.php где строку

$sql .= " ORDER BY p.sort_order";

меняем на

$sql .= " ORDER BY p2c.category_order";

Таким образом мы говорим выборке из базы что будет сортировка согласно той что прописана в таблице product_to_category в поле p2c.category_order а туда мы будем писать порядок сортировки для каждой категории.

Далее нам надо править admin/model/catalog/product.php - это модель товара в админке. Там находим строки с

if (isset($data['product_category'])) { до if (isset($data['product_filter'])) {

и все что между ними заменяем на код

if (isset($data['product_category'])) {
  foreach ($data['product_category'] as $category) {
    if(isset($category['category_id'])){
      $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_category SET product_id = '" . (int)$product_id . "', category_id = '" . (int)$category['category_id'] . "', category_order = '" . (int)$category['category_order'] . "'"); //
    }
  }
}
if(isset($data['main_category_id']) && $data['main_category_id'] > 0) {
  $this->db->query("DELETE FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "' AND category_id = '" . (int)$data['main_category_id'] . "'");
  $this->db->query("INSERT INTO " . DB_PREFIX . "product_to_category SET product_id = '" . (int)$product_id . "', category_id = '" . (int)$data['main_category_id'] . "', main_category = 1, category_order = '" . (int)$data['sort_order'] . "'");
}

Еще в этом файле в любое удобное место вставляем функцию выборки сортировок категорий

public function getProductCategorySorts($product_id) {
  $product_category_data = array();
  $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");
  foreach ($query->rows as $result) {
    $product_category_data[$result['category_id']] = $result['category_order'];
  }
  return $product_category_data;
}

Таким образом мы подготовим модель к записи не только категорий товара а и сортировку в той категории. После этого можно открыть контроллер категории admin/controller/catalog/product.php и после строки

if (isset($this->request->post['product_category'])) {

добавить строки

if (isset($this->request->post['product_category'])) {
  $data['product_category_sorts'] = $this->request->post['product_category'];
} elseif (isset($this->request->get['product_id'])) {
  $data['product_category_sorts'] = $this->model_catalog_product->getProductCategorySorts($this->request->get['product_id']);
} else {
  $data['product_category_sorts'] = array();
}

Этим мы передаем в шаблон данные какая сортировка у категории. Далее редактируем шаблон формы редактирования товара он находится по адресу admin/view/template/catalog/product_form.tpl в нем есть строка

<?php if (in_array($category['category_id'], $product_category)) { ?>

там идут эти галочки для выбора категорий <input type="checkbox" и в любое место (рядом в цикле) вставляем поле ввода сортировки

<input type="text" class="hided_text" placeholder="Сорт" name="product_category[<?php echo $category['category_id']; ?>][category_order]" value="<?php echo (isset($product_category_sorts[$category['category_id']]) && $product_category_sorts[$category['category_id']]>0)?$product_category_sorts[$category['category_id']]:''; ?>" />

У меня например это было после закрывающего тега </label> После чего у нас появится возможность задать каждой категории свою сортировку.

Но, как же быть в главных категориях - во всех товарах она не задана. Выход очень простой. Откройте файл admin/controller/common/header.php и после

public function index() {

Вставьте код прописи уже существующий сортировок товара в таблицу product_to_category что бы в главных категориях сортировка не сбилась.

$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_category WHERE main_category = 1");
print_r($query->rows);
foreach($query->rows as $item){
$product_info = $this->db->query("SELECT sort_order FROM " . DB_PREFIX . "product WHERE product_id = '" . $item['product_id'] . "'");
$this->db->query("UPDATE " . DB_PREFIX . "product_to_category SET category_order = '" . $product_info->row['sort_order'] . "' WHERE product_id = '" . $item['product_id'] . "' AND main_category = 1");
}

После чего просто зайдите в админку обновите кеш модификаторов и удалить этот код.

Все, дело сделано, теперь у нас во вкладке Связи есть список категорий в который выводить товары и + поле ввода порядка сортировки для этих категорий.

Но для того что бы так сработало надо еще открыть контроллер категории catalog/controller/product/category.php и заменить

$sort = 'p.sort_order';

на

$sort = 'p2c.category_order';

После этого у нас на сайте будет работать разная сортировка для всех категорий товара.


Комментарии:


Фото комментатора

Павел 03.04.2018

Спасибо. В инструкции еще не указано что нужно в шаблоне категории изменить имя поля в чекбоксах выбранных категорий на name="product_category[<?php echo $category['category_id']; ?>][category_id]"
Администратор

Ответ for-opencart.com 03.04.2018

Может упустил - спасибо за поправку!
Фото комментатора

Андрей 20.07.2018

Подскажите пожалуйста, пытаюсь повторить все на opencart 2.1.0.2. В product_form.tpl нет строки <?php if (in_array($category['category_id'], $product_category)) { ?> Посмотрел в версии 1.5.6, там тоже нет. Для какой версии вы описывали?
Администратор

Ответ for-opencart.com 20.07.2018

Ну посмотрите по аналогии - это начало перебора цикла категорий и проверка присвоен ли товар к конкретной категории. Может строка отличаться, просто найдите этот цикл.
Фото комментатора

Alex 23.12.2018

Спасибо за инструкцию. Как всё это упростить, если не нужно ничего менять в админке, а надо просто выводить товары для посетителей в порядке категорий и порядке их сортировки внутри неё? В базе есть несколько главных категорий, сортировка внутри которых начинается с 1 и далее сквозная для всех входящих подкатегорий (надо было делать сквозную на всю базу, а не внутри каждой из главных, но ошиблись...). Поскольку по умолчанию стоит p.sort_order, то на страницах поиска и товаров производителя получается мешанина... Я правильно ли понимаю, что вместо " ORDER BY p.sort_order"; надо писать $sql .= " ORDER BY p2c.category_id"; и потом прописать в catalog/controller/product/category.php типа $this->data['sorts'][] = array( 'text' => $this->language->get('text_category_asc'), 'value' => 'p.category_id-ASC', 'href' => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.category_id&order=ASC' . $url) ); добавив нужное в языковой файл, и потом добавить в catalog/model/catalog/product.php p2c.category_id ( или p.category_id ??? ) Однако что-то у меня не получается запрос в catalog/model/catalog/product.php Помогите pls как это правильно сделать.
Администратор

Ответ for-opencart.com 23.12.2018

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

Витя 06.09.2019

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

Ответ for-opencart.com 06.09.2019

На 2.3 все работает, смотрите на ошибки и исправьте, все будет работать. Опять же, если магазин не переделан в тех местах что может сделать код неработоспособным
Фото комментатора

Михаил 17.09.2019

Очень нужная функциональность. Но на своей 2.3 не могу разобраться, как сделать. 1. В первом шаге говорится: "в таблице product_to_category после category_sort", а после везде фигурирует имя поля "category_order"... Опечатка? Или я упускаю мысль? 2. "от if (isset($data['product_category'])) { до if (isset($data['product_filter'])) {" - встречается дважды. Оба менять? Или только где-то в одном месте? И не понятна формулировка "от и до". Это значит вставить между ними? Или удалить и вставить "вместо"?! И вот таких непонятных моментов в каждом шаге. Но реализовать ОЧЕНЬ нужно! Прошу участия и помощи!
Администратор

Ответ for-opencart.com 17.09.2019

1) Возможно, сама суть в том что создаем поле и в нем будет сортировка. Пересмотрю текст возможно там ошибка. (Исправил). 2) Да, смотрите ниже написано и все что между ними меняем на тот код. То есть заменяем. Поменяйте и там и там. Еще момент, такого типа доработки рассчитаны для тех кто +/- понимает в коде, лучше все же разобраться чем просто копировать, это важно.
Фото комментатора

Артур 31.10.2019

Здравствуйте, подскажите как сделать для opencart 3? Все подходит кроме файлов tpl , можете дать инструкцию под синтаксис twig ?
Администратор

Ответ for-opencart.com 31.10.2019

Добрый день! Просто надо портировать код под twig. Документация есть в открытых источниках, здесь все не распишу

Быстрый поиск

Похожее

Новое на сайте