[tvSuperSelect] Кейс. Удобное указание опций для фильтрации в mFilter2

Часто интернет магазину требуется большое кол-во разделов каталога (500) и такое же большое кол-во опций (200). Заказчик хочет, чтобы:
— опции можно было легко выбирать при редактировании категории товаров,
— на фронте, если у категории не выбрано ни одной опции, брать эти опции из родительской категории, у которой они указаны.
С tvSuperSelect теперь сделать это не так уж сложно, как может показаться.
Подготовка
Нам потребуется miniShop2, mSearch2, tvSuperSelect, Fenom.И даже не просите меня помочь сделать это без Fenom!
Шаг 1
Создаём ТВ поле mfilter_options с типом tvSuperSelect и указываем такие настройки:- Connector URL
/assets/custom/tvssconnector.php - Процессор
tvss/getms2options
Шаг 2
Создаём файл-коннектор.<?php
require_once dirname(dirname(dirname(__FILE__))) . '/config.core.php';
require_once MODX_CORE_PATH . 'config/' . MODX_CONFIG_KEY . '.inc.php';
require_once MODX_CONNECTORS_PATH . 'index.php';
$modx->request->handleRequest(array(
'processors_path' => MODX_CORE_PATH . 'custom/processors/',
'location' => '',
));Местонахождение: /assets/custom/tvssconnector.phpШаг 3
Создаём процессор, в котором будет происходить выборка опций miniShop2 и формирование массива для отображения в списке ComboBox.<?php
class customTvssComboGetMs2OptionsProcessor extends modObjectProcessor
{
public $classKey = 'msOption';
/** @var miniShop2 $ms2 */
protected $ms2;
/** @var tvSuperSelect $tvss */
protected $tvss;
/**
* @return bool
*/
public function initialize()
{
$this->ms2 = $this->modx->getService('minishop2', 'miniShop2', MODX_CORE_PATH . 'components/minishop2/model/minishop2/');
$this->tvss = $this->modx->getService('tvsuperselect', 'tvSuperSelect',
$this->modx->getOption('tvsuperselect_core_path', null, MODX_CORE_PATH . 'components/tvsuperselect/') . 'model/tvsuperselect/');
return parent::initialize();
}
/**
* @return string
*/
public function process()
{
$query = trim($this->getProperty('query'));
$limit = (int)$this->getProperty('limit', 0);
$resource_id = (int)$this->getProperty('resource_id', 0);
if (!$tv_id = (int)$this->getProperty('tv_id', 0)) {
//
}
$q = $this->modx->newQuery($this->classKey);
$q->select(array(
"{$this->classKey}.key as `key`",
"{$this->classKey}.caption as `caption`",
));
if (!empty($query)) {
$q->where(array(
"{$this->classKey}.key:LIKE" => "%{$query}%",
"OR:{$this->classKey}.caption:LIKE" => "%{$query}%"
));
}
$q->limit($limit);
$q->sortby($this->classKey . '.key', 'ASC');
$rows = array();
if ($q->prepare() && $q->stmt->execute()) {
if ($tmp = $q->stmt->fetchAll(PDO::FETCH_ASSOC)) {
foreach ($tmp as $v) {
$rows[] = array(
'display' => '(' . $v['key'] . ') <b>' . $v['caption'] . '</b>',
'value' => $v['key'],
);
}
}
}
foreach ($rows as &$row) {
if (empty($row['display'])) {
$row['display'] = $row['value'];
}
}
unset($row);
return $this->outputArray($rows);
}
}
return 'customTvssComboGetMs2OptionsProcessor';Местонахождение: /core/custom/processors/tvss/getms2options.class.phpШаг 4
Формирование списка опций пригодного для mFilter2 и вывод на фронте будет происходить при помощи Fenom.У вас должно получиться, что-то вроде этого:
{var $filters = []}
{* Мы можем указать свойства фильтра, которые отобразятся до опций, выбранных нами *}
{var $filters[] = 'ms|price:number'}
{var $filters[] = 'parent:categories'}
{* Магия *}
{var $mfilter_options = $_modx->resource['mfilter_options']}
{if !is_array($mfilter_options)}
{var $mfilter_options = ($mfilter_options | fromJSON)}
{/if}
{if $mfilter_options is empty}
{foreach $_modx->getParentIds($_modx->resource['id']) as $parent_id}
{if $parent_id == 0}
{continue}
{/if}
{var $mfilter_options = ($parent_id | resource : 'mfilter_options')}
{if !is_array($mfilter_options) AND $mfilter_options?}
{var $mfilter_options = ($mfilter_options | fromJSON)}
{/if}
{if $mfilter_options?}
{break}
{/if}
{unset $mfilter_options}
{/foreach}
{/if}
{if $mfilter_options?}
{foreach $mfilter_options as $v}
{var $filters[] = ('msoption|' ~ $v)}
{/foreach}
{/if}
{* Вывод mFilter2 *}
{'!mFilter2' | snippet : [
...
'filters' => ($filters | join : ','),
...
]}Итого
Как видите, всё довольно просто с новой версией tvSuperSelect. С этим функционалом теперь можно и не такое сделать!Комментарии: 13
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Очень хочется, чтобы поле работало в migx таблице.
у меня две тв-шки рядом: «video» (listbox-multiply) и «gallery» (tvsuperselect)
в migx сырые данные приходят в виде json, и этот кусок выглядит так:
что касается поля migx внутри migx (которое тоже json по идее), то оно экранируется и приходит вот так:
и думается мне, что tvsuperselect тоже надо экранировать и строкой отправлять, только где и когда это отловить пока не разобрался
modx.pro/components/16719
Шаг 3 заменил на это:
Шаг 4 заменил на это: