Вот и столкнулся я с тем, чтобы написать расширение функционала для SimplaCMS. Какой же интернет-магазин не поддерживает сортировку и фильтрацию? Так вот почему то в одной из лучших систем управления отсутствует фильтр по цене! Есть все что угодно, кроме цены. Сегодня попробуем решить эту проблему, без покупки платных модулей.

Итак, поехали!

Фильтр будем делать красивый и удобный, для этого воспользуемся jquery-ui.

Клиентскую часть можно править как угодно, у меня в дизайне ползунок, но можно и обойтись без javascript, просто сделать два поля с типом «text», и получать оттуда максимум и минимум цены, в рамках которых должен быть запрос.

Теперь собственно самое главное. Для начала надо разобраться как работает фильтр вообще. Как он ищет другие товары? За этим обратимся к той части системы управления, которая отвечает за отображение публичной части, а именно view/Products.php

Все 136 строк до этого формируется массив с данными фильтра. Какой товар, какой категории, сохранена ли сортировка в сессии, есть ли ключевое слово и т. п.

В выделенной 139 строке происходит обращение к классу из api/Products.php и его методу get_products, которому мы передаем все параметры фильтра. Там формируется запрос к базе данных и мы получаем именно тот список товаров, который нам нужен. Ни одного лишнего.

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

Все тот же файл. Выделенное — добавленное.

Соответственно мы будем получать цену из GET параметров. В строке запроса получим что-то типа /goods?price_min=0&price_max=9000

Вот и поля, которые будут эту задачу выполнять в верстке сайта.

После проверки на пустоту $category_url и $brand_url вставляем код, который будет в фильтр добавлять значения минимальной и максимальной цены.

Далее работаем с API. Нужно:

  1. Добавить условие того, что если есть цена — добавляем к запросу условие, что цена в границах минимума и максимума;
  2. Собственно цена то как раз у нас в таблице с вариантами (__variants), а в запросе опрашиваются только __products и __brands. Надо добавить еще одну таблицу в запрос.

Файл api/products.php. Начнем со второго вопроса, а именно добавим в запрос еще одну таблицу

А теперь подробнее по выделенным строкам:

  • 124 — добавить строку, не забудьте добавить запятую в конце 123 строки
  • 128 — добавить строку;
  • 139-140 — переменные с условием;
  • 141 — заменить строку. Там должна быть переменная $group_by, так вот, она нам не понадобится

До этого в этом же методе можете удалить строку где есть

А что в $price_min_filter и $price_max_filter?

А, ну да, чуть главное не забыл

До самого запроса необходимо вставить следующий код

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

Ну вот собственно и все.

Итого

Вид функции получения списка товаров с фильтром по цене:

Обновление 21 января 2016

Благодарим нашего читателя Романа за проявленную бдительность и внимательность.

Мы совсем упустили из виду постраничную навигацию. После внесенных изменений, количество страниц остается неизменным.

За постраничную навигацию отвечает функция count_products().

Вот как она должна выглядеть для работы с фильтром по цене:

 

  1. Свойств товара много. Есть и числовые и строки. Думается, если числовой параметр, то выводить двухстороннюю линейку, а если строка, то просто чекбоксы. Вопрос, если автоматизировать , то как лучше, по вашему мнению, добавить колонку в s_features, в котором отмечать как выводить или же делать это в другом месте, например, создать еще одну таблицу, вроде s_features_type?

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

      Дмитрий
  2. Работает, но не правильно считает страницы.

    Роман
    • Спасибо за Ваш комментарий! В самое ближайшее время, как только найду причину ошибки с постраничной навигацией, статья будет обновлена.

      Дмитрий (Автор)
  3. Нужно в count_products($filter = array())
    Добавить после visible
    // Фильтр по цене
    if(!empty($filter[‘price_min’]))
    $price_min_filter = $this->db->placehold(‘ AND v.price > ?’, intval($filter[‘price_min’]));
    if(!empty($filter[‘price_max’]))
    $price_max_filter = $this->db->placehold(‘ AND v.price < ?', intval($filter['price_max']));

    и после $query = "SELECT count(distinct p.id) as count
    FROM __products AS p
    $category_id_filter

    добавить
    LEFT JOIN __variants v ON p.id = v.product_id

    И еще после
    $visible_filter

    Добавить
    $price_min_filter
    $price_max_filter

    Тогда заработает как надо 🙂

    Роман
  4. Здравствуйте,

    Скажите пожалуйста, а в сам шаблон как правильно разместить код и функции чтобы слайдер по цене все же работал как надо?

    Установив html из первого пункта мы лишь подключили библиотеку, но функций там нет и в своем примере вы их не озвучиваете.

    Можно ли дополнить статью полным кодом для шаблона.

    Виктор
  5. Не работает слайдер вообще, он даже не отражается, просто голые инпуты, как будто бы стили и библиотеки не подгружены, хотя всё подгружено. Что с этим делать?

    Алексей
    • Искать ошибки и конфликты. Для начала, можно оставить без слайдера. Невозможно установить причину проблемы, не видя кода.

      Дмитрий Ильичев (Автор)

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