Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)

#
Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
Добрый день.

Представляю Вашему вниманию реализацию расширенного контроллера показов магазина Shop_Controller_Show_Extended с фильтрами "как в Яндекс.Маркете".

Комплект поставки:
архив с кодом, в составе
- собственно контроллер отображения магазина с поддержкой расширенных фильтров,
- измененная ТДС "Интернет-магазин", которая использует этот контроллер
- измененный XSL-шаблон "МагазинКаталогТоваров", который умеет выводить расширенный фильтр
- измененный XSL-шаблон "МагазинФильтр", который умеет выводить расширенный фильтр в боковой колонке
- измененный макет "Шаблон для Интернет-магазина" с подключением клиентских стилей и скриптов, а также с измененным кодом показа фильтров в боковой колонке
- клиентский js, который добавляет возможность работать с расширенными фильтрами через ajax;
а также описание, в виде подробных комментариев к коду.

В стоимость также входит ограниченная техническая поддержка (ошибки в работе модуля связанные с моим кодом анализируются и исправляются бесплатно, в течение 1-3 рабочих дней) и доступ к обновлениям модуля (всего таких обновлений за полтора года было около 20).

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

Серверная часть полностью готова, оттестирована и используется в реальных проектах, в клиентском js не до конца реализован контрол, управляющий диапазонными значениями (использован стандартный от jQueryUI, а в Маркете он несколько более наворочанный, но я не осилил), ну и в целом js еще можно шлифовать до достижения идеала, но обычно его нужно затачивать уже под конкретный дизайн, так что недостатком это не является.

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

Есть возможность при обработке фильтров учитывать модификации товаров.

Официальный демо-пример http://test.strigo.ru/shop/camcorder/ (доп.свойства настроены только в группе "Видеокамеры"

Код контроллера расширенных фильтров специально спроектирован в расчете на высокую нагрузку и работу с большими объемами данных, особое внимание уделялось оптимизации SQL-запросов и исключению повторной обработки одних и тех же данных.
Для оптимизации производительности, XML, генерируемый контроллером, в части описания фильтров не совместим с аналогичным XML от штатного контроллера, прилагаемые к разработке XSL-шаблоны это учитывают.
Кроме того, оптимизирована и работа XSL-шаблонов.

Концепция и код расширенного управления фильтрами прошли code-review у главного разработчика системы Бориса Теряева, и были им одобрен, по высказанным замечаниям были внесены правки.

Установка

Установка кода в систему очень проста -  нужно просто развернуть архив в корневую папку системы.

Архив с кодом нужно просто развернуть в корень системы.
Обратите внимание, что при этом затрутся исходные ТДС Интернет-магазин (id=6) и XSL-шаблоны МагазинКаталогТоваров (id=55) и МагазинФильтр (id=230) а также html-часть макета "Шаблон для Интернет-магазина" (id=11)

Важно
  • Контроллер расширенных фильтров не поддерживает построение выборок по доп.свойствам типа "Строка". Поддерживаются доп.свойства типа "Список", "Число" и "Число с плавающей точкой". Таким образом, контроллер интересен, в первую очередь, пользователям коммерческих редакций системы. от "Малый Бизнес" и выше.
    Пользователи редакций "Халява" и "Мой сайт" смогут использовать его только для числовых доп.свойств с режимом отображения "От...до..."
  • Вся обработка фильтров переехала из ТДС "Интернет магазин" в файл расширенного контроллера /modules/shop/controller/show/extended.php, запуск обработки, а также все условия, влияющие на изначальную выборку товаров описываются во вкладке "Настройки ТДС".
  • Описание схемы работы модуля находится в комментариях в файле /modules/shop/controller/show/extended.php, использование модуля описано в комментариях в ТДС Интернет-магазин и в макете "Шаблон для Интернет-магазина".


Цена разработки 4000 рублей, к оплате принимаются WMR, ЯД, Киви и банковские карты.
Заказов не беру. Консультирую редко.
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
Описание метода работы

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

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

В текущей базовой логике HostCMS это потребовало бы тройной нагрузки на базу данных -
а) сначала мы в рамках работы с расширенной работы со свойствами выполнили бы запрос первой выборки,
б) затем, с той же целью -  второй выборки,
в) а после этого show-метод внутри себя выполнил бы запрос второй выборки еще раз, уточнив его сортировкой и лимитом.
При этом, из-за уточнения на сортировку и лимит, кеш БД равно как и кеш системы, при повторном выполнении запроса не эффективен.
Собственно, так и было в аналогичной разработке для HostCMS v.5
При этом надо учесть, что второй и третий запрос довольно тяжелые и существенно замедляют генерацию страницы

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

Схема работы данного контроллера с базой данных следующая:
1. Когда мы вызываем метод processFilters(), то в первую очередь выполняем запрос исходной выборки, получая только id товаров попадающих в нее. Этот запрос легкий, с точки зрения нагрузки на БД
2. Далее мы удаляем все условия в Shop_Items->QueryBuilder и заменяем их на единственное условие shop_items.id IN (<идентификаторы товаров, попавших в исходную выборку>
3. После этого мы вносим в Shop_Items->QueryBuilder все условия, которые обусловлены пользовательскими фильтрами Поскольку при этом не надо предварительно отбирать сами товары по сложным условиям, то запрос выполняется быстро, заметно быстрее, чем "классический" запрос с фильтрами в методе show() вызванном из ТДС. Здесь мы тоже получаем только id товаров, но это уже вторая выборка, с учетом фильтров
4. Затем мы снова удаляем все условия в Shop_Items->QueryBuilder и опять заменяем их на единственное условие shop_items.id IN (<но уже идентификаторы товаров, попавших в конечную выборку> и восстанавливаем сортировку и лимит.
Таким образом, мы избегаем повторного выполнения тяжелого запроса внутри show-метода.

Контроллер поддерживает два способа выдачи результатов обработки фильтров:
- в виде json-строки;
- в виде XML-фрагмента, который автоматически добавляется к XML-документу контроллера.
В обоих случаях, результаты имеют одинаковую структуру.
Результат состоит из трех секций:
- used - значения фильтров, переданные через get-запрос от пользователя сайта
- initial - значения цен, свойств и доп.свойств для начальной выборки
- filtered - значения цен, свойств и доп.свойств для фильтрованной выборки

Внутри каждой секции могут быть следующие элементы:
- count - общее число товаров в выборке (без учета модификаций)
- count_total - общее число товаров в выборке с учетом модификаций (UPD для v1.4g+)
- sorting - содержит текущую сортировку
- producer_id - содержит идентификатор(ы) производителей
- seller_id - содержит идентификатор(ы) продавцов
- price - границы диапазона цен товаров (содержит массив как минимум с одним из элементов from или to)
- property_values - значения доп.свойств (содержит массив, ключами которого являются id доп.свойств, а значениями - массивы значений этих доп.свойств)
- property_ranges - границы диапазонов значений доп.свойств для диапазонных доп.свойств (содержит массив, ключами которого являются id доп.свойств, а значениями - массивы как минимум с одним из элементов from или to)
Заказов не беру. Консультирую редко.
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
Пример настройки контроллера:

* UPD: При добавлении условий в $Shop_Controller_Show->shopItems()->queryBuilder()
* ОБЯЗАТЕЛЬНО включите флаг $Shop_Controller_Show->dontResetItems(true)
* Пример: отбор товаров, дороже 100 рублей.
* $Shop_Controller_Show
*   ->dontResetItems(TRUE)
*    ->shopItems()
*       ->queryBuilder()
*          ->where('price', '>', '100');
**/

/* настройки вычисления значений фильтров */
$Shop_Controller_Show

   // для начальной выборки товаров
   ->initialPriceRange(true) // вычислять диапазон цен для начальной выборки
   ->initialMainPropertiesRange(true) // вычислять допустимые значения основных свойств для начальной выборки
   ->initialRangedPropertiesRange(true) // вычислять крайние значения диапазонных доп.свойств для начальной выборки
   ->initialAllowedListPropertiesValues(true) // вычислять допустимые значения списочных доп.свойств для начальной выборки
   
   // для выборки товаров с учетом примененных фильтров
   ->filteredPriceRange(true) // вычислять диапазон цен для фильтрованной выборки
   ->filteredMainPropertiesRange(true) // вычислять допустимые значения основных свойств для фильтрованной выборки
   ->filteredRangedPropertiesRange(true) // вычислять крайние значения диапазонных доп.свойств для фильтрованной выборки
   ->filteredAllowedListPropertiesValues(true) // вычислять допустимые значения списочных доп.свойств для фильтрованной выборки
   
   // для обеих выборок
   ->filterModifications(true) // включать в расчет модификации основных товаров
   
   // Управление блоками фильтров, отображаемыми в основной части страницы
   // Для включения нужного блока - уберите коментарий  у соответствующей строки,
   // для выключения - закомментируйте соответствующей строку
   ->showFilters(array(
      'sorting',
      'price',
      'producer',
      //'seller',
      'properties',
   ))
;
Заказов не беру. Консультирую редко.
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
а что мешает самим разработчикам такой хороший фильтр сделать доступным в платных редакциях из коробки?
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
ZubriDom, рискну предположить, что отсутствие свободного ресурса разработчиков, и длинный бэклог не менее важных задач... )
Заказов не беру. Консультирую редко.
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
Kotoff,
В демке при изменении диапозона цены ничего не происходит
HostDev.pw - модули для HostCMS, Telegram: @hostdev
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
Фильтр работает в системе, обновленной с 5 на 6 версию, как есть, без отключения "режима совместимости" ?
При изменении диапазона цен новая выборка берет значение среди текущей выборки и сбросить выборку не нашел возможности. То есть логичней было бы оставить рамки диапазона изначальными, а ползунок поставить на выбранное значение внутри него.
http://www.aiventa.ru
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
EugenyP, hell0men, прошу прощения за задержку с ответом - забыл подписаться на тему Видимо сработала привычка к тому, что на большинстве популярных форумных движков подписка автора на его собственные темы происходит автоматически.
Заказов не беру. Консультирую редко.
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
hell0men писал(а):
Фильтр работает в системе, обновленной с 5 на 6 версию, как есть, без отключения "режима совместимости" ?

Фильтры написаны на API6. Зависимостей от режима совместимости с API5 нет, одинаково работает как с включенной так и с отключенной совместимостью. Но ТДС Магазина нужно использовать новые, написанные на API6.
Заказов не беру. Консультирую редко.
#
Re: Расширенные фильтры для HostCMS 6 (как в Яндекс.Маркете)
EugenyP писал(а):
В демке при изменении диапозона цены ничего не происходит

Немного пофиксил.

hell0men писал(а):
При изменении диапазона цен новая выборка берет значение среди текущей выборки и сбросить выборку не нашел возможности. То есть логичней было бы оставить рамки диапазона изначальными, а ползунок поставить на выбранное значение внутри него.

Тут тоже немного пофиксил.


Впрочем, должен честно признаться, что в интерфейсах на клиентском js я не силен, и написать нормальный слайдер с поддержкой трех диапазонов (исходный, фильтрованный и пользовательский), подобный тому, который используется в Яндекс.Маркет, я не осилил. А единственная найденная мною более-менее подходящая библиотека jQuery.AdvancedRangeInput работает криво.
Поэтому баги в работе слайдеров гарантийным случаем не являются )

Впрочем, основной смысл фильтров - как раз в серверном коде, и по большому счету весь ajax и клиентский js написаны лишь для демонстрации того что фильтры в принципе работают. Предполагается, что каждый разработчик, устанавливающий фильтры, будет затачивать этот js-код под свои нужны и особенности.

Кстати, если найдется такой разработчик, который осилит написание нормального диапазонного слайдера для этого проекта, то я буду ему весьма благодарен.
Заказов не беру. Консультирую редко.
Авторизация