Ruslan Brest, rb.labtodo.com
Backend web-developer: CodeIgniter, PHP, MySQL, OpenCart, PrestaShop, MaxSite CMS

Улучшение сортировки на витрине Opencart

Просмотров: 18912 RSS 25
Howto » OpenCart

Поступил вопрос:

можно ли сделать по умолчанию сортировку товаров на витрине, одновременно по двум параметрам: по цене и названию. Тоесть сортируются по цене, а те у кого цены одинаковые уже по имени.
Я сделал по цене, но я заметил что иногда Опенкарт меняет местами товары с одинаковыми параметрами сортировки, например если менять кол-во выводимого товара на одну страницу, ощущение что их тусует в произвольном порядке.

Действительно, лучше это предусмотреть и заодно изменить стандартный способ сортировки по полю "sort_order" (которое мало кто использует в товарах) на сортировку по названию товара (а название у товара есть всегда), чтобы избежать популярной, но иногда незаметной ситуации, когда один и тот же товар может выводиться и на первой, и на второй странице (вообще-то на любых, если использовать стандартный способ сортировки, применяемый в Опенкарт).

Diff приведён ниже, здесь же приведу описание обычными словами, т.к изменение всего одно и небольшое:

Как внести изменения вручную

1. Открываем файл catalog/model/catalog/product.php

2. Ищем функцию function getProducts

3. Пролистываем почти до конца в поисках кода запроса с ORDER BY и следующего за ним LIMIT. Соответствующий участок кода выглядит так:

$sort_data = array(
				'pd.name',
				'p.model',
				'p.quantity',
				'p.price',
				'rating',
				'p.sort_order',
				'p.date_added'
			);
			if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
				if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
					$sql .= " ORDER BY LCASE(" . $data['sort'] . ")";
				} else {
					$sql .= " ORDER BY " . $data['sort'];
				}
			} else {
				$sql .= " ORDER BY p.sort_order";
			}
			if (isset($data['order']) && ($data['order'] == 'DESC')) {
				$sql .= " DESC";
			} else {
				$sql .= " ASC";
			}
			if (isset($data['start']) || isset($data['limit'])) {
				if ($data['start'] < 0) {
					$data['start'] = 0;
				}
				if ($data['limit'] < 1) {
					$data['limit'] = 20;
				}
				$sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit'];
			}

4. Мы сделаем две вещи: для начала изменим способ сортировки товаров на витрине по умолчанию на сортировку по названию:

} else {
				$sql .= " ORDER BY p.sort_order";
 			}

меняем на

} else {
				$sql .= " ORDER BY pd.name";
 			}

5. И теперь добавляем вторичную сортировку по названию:

if (isset($data['order']) && ($data['order'] == 'DESC')) {
				$sql .= " DESC";
			} else {
				$sql .= " ASC";
			}
			// БУДЕМ ВСТАВЛЯТЬ КОД СЮДА
			// БУДЕМ ВСТАВЛЯТЬ КОД СЮДА
			// БУДЕМ ВСТАВЛЯТЬ КОД СЮДА
			// БУДЕМ ВСТАВЛЯТЬ КОД СЮДА
			if (isset($data['start']) || isset($data['limit'])) {

Всталяем в указанное место такой блок кода:

// Additional sort order by product name
			if(isset($data['sort']) && $data['sort'] != 'pd.name') {
				$sql .= ", pd.name ASC";
			}

Вот и всё.

То же самое в виде Diff-файла

commit c12debb0a37ade03e773535ed361a4b96bd54c91
Author: Ruslan Brest <rb@labtodo.com>
Date:   Mon May 21 10:26:39 2012 +0300
    [+] Better catalog sort order: additional sorting by product name
    
    Добавлена вторичная сортировка по имени товара для более аккуратного вывода.
    Без этого товары при выборе других сортировок, например по количеству, могут сортироваться
    в случайном порядке. То же самое при изменении количества товаров на странице: один и тот же
    товар может оказаться и на первой, и на второй странице. Сейчас товары сортируются по выбранному
    признаку, а затем по имени.
    
    [!] CHANGED: По умолчанию -- сортировка по имени, а не по sort_order
diff --git a/upload/catalog/model/catalog/product.php b/upload/catalog/model/catalog/product.php
index 8b15e26..c3dec4f 100644
--- a/upload/catalog/model/catalog/product.php
+++ b/upload/catalog/model/catalog/product.php
@@ -162,7 +162,7 @@ class ModelCatalogProduct extends Model {
 					$sql .= " ORDER BY " . $data['sort'];
 				}
 			} else {
-				$sql .= " ORDER BY p.sort_order";
+				$sql .= " ORDER BY pd.name";
 			}
 
 			if (isset($data['order']) && ($data['order'] == 'DESC')) {
@@ -171,6 +171,11 @@ class ModelCatalogProduct extends Model {
 				$sql .= " ASC";
 			}
 
+			// Additional sort order by product name
+			if(isset($data['sort']) && $data['sort'] != 'pd.name') {
+				$sql .= ", pd.name ASC";
+			}
+
 			if (isset($data['start']) || isset($data['limit'])) {
 				if ($data['start'] < 0) {
 					$data['start'] = 0;
twitter.com facebook.com vkontakte.ru odnoklassniki.ru mail.ru ya.ru digg.com friendfeed.com liveinternet.ru livejournal.ru yandex.ru del.icio.us
Комментариев: 25
  1. 2012-05-26 в 06:05:52 | Евгений

    Руслан,спасибо огромное!

  2. Большое тебе СПАСИБО, милчеловек!

  3. 2012-06-11 в 02:32:44 | Константин

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

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

  4. Как сделать, чтобы дополнительно сортировалось и по наличию?

  5. 2012-09-12 в 08:11:01 | Александр Сова

    Прекрасно! Как всегда - огромное спасибо!

  6. 2012-09-16 в 03:48:04 | Эмильен Де Женуа

    У меня версия 1513 сделал как тут написано, все вроде бы получилось, живу себе радуюсь, а тут решил проверить, как там мой google sitemap поживает. А он работать не хочет пишет ошибка в каталог/модел/каталог/продукт.пхп ну я залез поискал, убрал все что вставил из этой статьи, и заработал мой сайт-мап!) Может есть какое-нибудь решение, чтобы сайтмап не ругался? ото вещь то полезная...

  7. 2012-09-21 в 11:43:04 | Ruslan Brest

    Здесь всего 2 мелкие правки, которые не могут мешать сайтмапу, если всё нормально сделано.

  8. не реагировало никак, ковырял и так и так, чистил кеш и тд., но когда просто отключил-включил один товар в админке, сортировка начала работать как задумывалось.

  9. что делать???? выше у товарища была проблема и вроде сама решилась у меня пока нет!

  10. Аналогично. Изменения заработали после ковыряния товара в админке.

  11. Здравствуйте.

    Подскажите , как сделать в админке сортировку товара по номеру накладной ? 1.5.1.3

    Спасибо.

  12. 2013-03-09 в 18:49:49 | Ruslan Brest
    Подскажите , как сделать в админке сортировку товара по номеру накладной ? 1.5.1.3

    Не знаю, не занимался. Я вообще не понял, о чем речь. Что за номер накладной и откуда он у товара?

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

  14. 2013-03-09 в 19:22:43 | Ruslan Brest

    Вы про SKU (артикул)? Или какое поле? Модель? Я не знаю, где вы храните "номер как в накладной". Скорей всего это подойдёт:

    http://rb.labtodo.com/page/opencart-admin-sku-column

    Если какое-то другое поле - делайте по аналогии.

  15. Это номер модели (номер в накладной),не по SKU.

  16. 2013-03-09 в 20:21:41 | Ruslan Brest

    Тогда я вообще ничего не понимаю. Колонка "модель" УЖЕ есть в списке товаров, по ней есть и сортировка, и фильтрация. Чего не хватает? Нажмите на заголовок колонки - оно и отсортируется.

  17. А не подскажите, как сделать сортировку по цене в корзине товара

  18. Подскажите плизз!

    У меня проблема с сортировкой "OPENCART"

    В ручную добавил 2 поля "↓Мощ. дв." и "↓Пробег"

    Параметры в model и conteoller настроил

    Все работает! вот только есть один нюанс:

    к примеру сортирую по возрастанию:

    (сортировка проходит только по первым двум символам, значение 90 должно быть первым, сортировка определяет как 20,21,21,24,90 а должна 90,204,211,218,249 )

    204 л.с.

    211 л.с.

    218 л.с.

    249 л.с.

    90 л.с.

    перекапал уже весь движок, решений так и не нашел, поля в MSQL значение (INT)

    если кто знает подскажите плииизз!!! Заранее Очень Благодарен!!!

    вот фильтр http://duet-auto.ru/index.php?route=product/category&path=147&sort=p.enginepower&order=ASC

  19. 2014-04-22 в 22:15:00 | Ruslan Brest

    А что подсказать-то? Да, очень похоже на то. Ваши выводы о том, что сортировка производится по первым символам, всё объясняет. Почему, где и как Вы сортируете по первым двум символам - я не знаю. Ответы содержатся где-то в PHP коде или БД. Это наверное всё, что я могу сказать. Даже поглядев на сайт.

  20. Извините, может вопрос глупый, но в других cms не сталкивалась с diff-файлами. Как его использовать?

  21. 2015-07-22 в 19:31:22 | Ruslan Brest

    http://rb.labtodo.com/page/help-diff

  22. Добрый день! Подскажите пожалуйста, как сделать сортировку по атрибутам? Вот у меня есть глубина в атрибутах, ee ID - 82. Можно ли по ней сортировать? Буду премного благодарен за подсказку

  23. 2016-01-15 в 19:35:52 | Аноним

    такой вопрос по правкам, получаеться что сортировка по названию существует всегда в независимости от выбора другой сортировки ?

    Тоесть если мне надо вывести сортировку по рейтингу основной, и другорядную по цене, такие же правки по коду с другими переменными подойдут?

  24. 2016-01-20 в 05:15:35 | Ruslan Brest

    > сортировка по названию существует всегда в независимости от выбора другой сортировки ?

    Да.

    > Тоесть если мне надо вывести сортировку по рейтингу основной, и другорядную по цене, такие же правки по коду с другими переменными подойдут?

    Смотрите запрос, может там и рейтинг-то не выбирается и его предварительно добавить придётся. А в остальном - ну да, как-то так, по аналогии можете делать.

  25. Доброго времени суток!

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

Оставьте комментарий!

Используйте нормальные имена. Ваш комментарий будет опубликован после проверки.

Имя и сайт используются только при регистрации

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

Авторизация  Facebook. MaxSiteAuth. Loginza

(обязательно)