Улучшение сортировки на витрине 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;