Skip to content
  1. Компоненты
  2. mSearch2
  3. Типовые решения
  4. Фильтрация категорий

Фильтрация категорий

Готовое решение фильтрации категорий товаров по дочерним товарам. В фильтрах выводятся параметры товаров, а в результатах - категории, которые содержат эти товары.

Логика работы mFilter2:

  • Фильтр использует для поиска и вывода ресурсов один сниппет, указанный в &elements. В случае работы с товарами там обычно указывается msProducts.
  • К этому сниппету будет 2 обращения: предварительная выборка и возврат подходящих id товаров, а затем их вывод пользователю.
  • Различить эти два запроса можно по присылаемому параметру returnIds.

В получение id товаров вмешиваться не нужно, потому что фильтр должен построить из них фильтры. Нужно изменить только вывод этих товаров, заменив их на категории.

Пишем новый сниппет msProductsCategories:

php
<?php
// Он работает только, если это вывод товаров, а не запрос подходящих id
if (empty($returnIds)) {
  // Присоединяем таблицу категорий
  if (empty($innerJoin) || !$where = $modx->fromJSON($innerJoin)) {
    $innerJoin = array();
  }
  $innerJoin['Category'] = array(
    'class' => 'msCategory',
  );
  $scriptProperties['innerJoin'] = $modx->toJSON($innerJoin);
  // Группируем по категории
  $scriptProperties['groupby'] = 'Category.id';
  // Заменяем поля товаров полями категорий
  $scriptProperties['select'] = $modx->toJSON(array(
    'Category' => '*',
    // Можно переопределить еще и выборку полей товара, чтобы были с префиксом,
    // но я это закомментировал, потому что поля Data и так доступны, а товары не нужны
    // 'msProduct' => $modx->getSelectColumns('msProduct', 'msProduct', 'product.'),
    // 'Data' => $modx->getSelectColumns('msProductData', 'Data', 'data.'),
  ));
}

// Мы добавили свой опции, а дальше пусть работает стандартный сниппет
return $modx->runSnippet('msProducts', $scriptProperties);

Как видите, всё работает через стандартные параметры pdoTools, никаких хаков.

Остаётся только указать этот новый сниппет при вызове mFilter2:

modx
[[!mFilter2?
  &class=`msProduct`
  &element=`msProductsCategories`
  &parents=`0`
  &filters=`
    ms|price:number,
    msoption|tags,
    ms|vendor:vendors,
    ms|old_price:boolean,
  `
  &tpl=`@INLINE <p>
    <a href="{$uri}">
      <img src="{$thumb ?: '/assets/components/minishop2/img/web/ms2_small.png'}">
      {$pagetitle}
    </a>
  </p>`
  &tplFilter.outer.ms|price=`tpl.mFilter2.filter.slider`
  &tplFilter.row.ms|price=`tpl.mFilter2.filter.number`
]]

Получившееся решение не меняет исходников компонент, так что его можно безопасно обновлять.