4 апреля 2013 г.

По умолчанию сортировка в OpenCart доступна по названию, модели, цене, количеству (если в панели администрирования включена опция "Показывать остаток") и рейтингу продукта. Можно расширить этот список, добавив сортировку, например, по дате публикации, по количеству отзывов и по количеству просмотров. Однако все возможные способы сортировки применяются независимо друг от друга, т.е. они не связаны между собой. Это не совсем удобно, когда в магазине много товаров с одинаковыми ценами и наименованиями, но разными моделями. Здесь нужна одновременная сортировка в нескольких направлениях, в этой статье будет описано как её реализовать.

Начнём с добавления дополнительных способов сортировки:

1. Сортировка по дате размещения. Удобно отслеживать новые поступления или наоборот, "залежавшиеся" товары.
2. Сортировка по количеству отзывов. Отзывы это немаловажный атрибут как успешно продаваемого продукта, так и (в некоторых случаях) проблемного продукта с точки зрения, например, эксплуатации.
3. Сортировка по количеству просмотров. Этот способ сортировки покажет насколько товар популярен.

Изменения необходимо внести в модель продукта ./catalog/model/catalog/product.php, в функции getProducts и getProductSpecials. В этих функциях в массив, присваеваемый переменной $sort_data, необходимо добавить поля p.date_added (в функции getProducts это поле уже есть), p.viewed и reviews. Таким образом мы получим:

$sort_data = array('pd.name',
  'p.model',
  'p.quantity',
  'p.price',
  'rating',
  'p.sort_order',
  'p.date_added',
  'p.viewed',
  'reviews');

Теперь необходимо изменить текст запросов к базе данных. Для функции getProducts переменную $sql и её содержимое замените на следующий код:

if (isset($data['sort']) && array_intersect( (array)$data['sort'], array('rating', 'reviews') ) ) {
$sql = "SELECT p.product_id, AVG(r1.rating) AS rating, COUNT(r1.rating) AS reviews 
             FROM " . DB_PREFIX . "product p 
             LEFT JOIN " . DB_PREFIX . "product_description pd 
             ON (p.product_id = pd.product_id) 
             LEFT JOIN " . DB_PREFIX . "product_to_store p2s 
             ON (p.product_id = p2s.product_id) 
             LEFT OUTER JOIN " . DB_PREFIX . "review r1 
             ON (r1.product_id = p.product_id AND r1.status = 1)"; 
} else {

$sql = "SELECT p.product_id 
             FROM " . DB_PREFIX . "product p 
             LEFT JOIN " . DB_PREFIX . "product_description pd 
             ON (p.product_id = pd.product_id) 
             LEFT JOIN " . DB_PREFIX . "product_to_store p2s 
             ON (p.product_id = p2s.product_id)"; 
}

Обратите внимание, условие вводится для того, чтобы не выполнять объединения таблиц в запросе, если нет сортировки по рейтингу и количеству обзоров. Это ещё один шаг в области оптимизации OpenCart.

Далее в контроллере категории ./catalog/controller/product/category.php после строки $this->data['sorts'] = array(); необходимо добавить следующее:

$this->data['sorts'][] = array(
  'text'  => $this->language->get('text_date_added_asc'),
  'value' => 'p.date_added-ASC',
  'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.date_added&order=ASC' . $url)
);

$this->data['sorts'][] = array(
  'text'  => $this->language->get('text_date_added_desc'),
  'value' => 'p.date_added-DESC',
  'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.date_added&order=DESC' . $url)
);

$this->data['sorts'][] = array(
  'text'  => $this->language->get('text_viewed_asc'),
  'value' => 'p.viewed-ASC',
  'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.viewed&order=ASC' . $url)
);

$this->data['sorts'][] = array(
  'text'  => $this->language->get('text_viewed_desc'),
  'value' => 'p.viewed-DESC',
  'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=p.viewed&order=DESC' . $url)
);

$this->data['sorts'][] = array(
  'text'  => $this->language->get('text_reviews_asc'),
  'value' => 'reviews-ASC',
  'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=reviews&order=ASC' . $url)
);

$this->data['sorts'][] = array(
  'text'  => $this->language->get('text_reviews_desc'),
  'value' => 'reviews-DESC',
  'href'  => $this->url->link('product/category', 'path=' . $this->request->get['path'] . '&sort=reviews&order=DESC' . $url)
);

Последнюю пару элементов массива заключите в тело условия if ($this->config->get('config_review_status')) { ... }, которое скроет сортировку по количеству отзывов, если они будут отключены в настройках магазина.

Не забудьте определить значения языковых констант (text_date_added_asc, text_date_added_desc, text_viewed_asc, text_viewed_desc, text_reviews_asc, text_reviews_desc) для локалей интерфейса:

./catalog/language/russian/product/category.php
./catalog/language/english/product/category.php
. . .

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

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

2 комментария:

  1. В старой версии (1,5,3) у меня все работа отлично. Перешел на 1,5,5,1,2 и сортировка по количеству просмотров делается по имени. Можете помочь разобраться?

    ОтветитьУдалить
    Ответы
    1. Здравствуйте! Продублируйте ваше сообщение на контактный e-mail, который указан на странице Услуги.

      Удалить

  • RSS
  • Twitter
  • Youtube