Необходима помощь в кастомизации mSearch2

Доброго вечера!

Столкнулся с необходимостью скорректировать поиск таким образом, чтобы он выдавал не только товары, но и категории. Например, по запросу «машины» отдавать не только товары, но и саму категорию «Машины».


Задача касается как mSearchForm, так и mSearch2.

Например, вызов:
$modx->runSnippet('mSearchForm', 
		array(
			'pageId' => 5,
			'element' => 'msProducts',
			'limit' => 50,
			'tpl' => 'tpl.mSearch2.ac'
		)
	);

Насколько я понимаю принцип работы поиска — результат (в т.ч. и id ресурса раздела «Машины») отдаётся, в данном случае, сниппету msProducts, который его не обрабатывает, т.к. это не товар.

Пока думаю, что решить задачу можно предварительно отдав массив ID'шников некоему prepareSnippet. Он определит наличие в массиве ID ресурса с классом msCategory и обработает самостоятельно; остальные отдаст msProducts. Либо вносить правки в assets/components/msearch2/action.php и msearch2.class.php, чего не хотелось бы.

Хочу спросить совета: может быть кто-то сталкивался с подобной задачей или знает, как правильнее её реализовать?

Заранее благодарен!
Алексей Шумаев
25 февраля 2016, 18:43
modx.pro
5
3 099
0
Поблагодарить автора Отправить деньги

Комментарии: 9

Наумов Алексей
26 февраля 2016, 10:17
0
1 вариант. Запустите 2 поиска: один с использованием msProducts, а второй с pdoResources
2 вариант. Используйте pdoResources, но у него есть параметры управления шаблоном в зависимости от неких условий, попробуйте настроить вывод для товаров одним способом, для категорий — другим
    Алексей Шумаев
    26 февраля 2016, 10:31
    0
    1 вариант: тоже о таком думал. Пока не знаю как сделать в случае с mSearchForm — необходимо отдать оба результата в 1 response.
    2 вариант: тоже без шаманства не прокатит, т.к. нужно подтягивать данные товара (картинка/цена). У меня в UI autocomplete они выводятся.
      Наумов Алексей
      26 февраля 2016, 10:39
      0
      А, не обратил внимание что mSearchForm, думал речь о mSearch
    Алексей Шумаев
    26 февраля 2016, 12:42
    0
    Не успеваю разобраться (.
    Готов оплатить данную работу.
    Рецепт выложим сюда — думаю пригодится сообществу.
    Алексей, не возьмёшься?
      Василий Наумкин
      27 февраля 2016, 22:12
      +1
      Пока думаю, что решить задачу можно предварительно отдав массив ID'шников некоему prepareSnippet. Он определит наличие в массиве ID ресурса с классом msCategory и обработает самостоятельно; остальные отдаст msProducts.
      Только так, да. Править в самом mSearch2 ничего не нужно, ибо он только ищет, а выводить должен другой сниппет.

      IDшники отдавать лучше не в msProducts, а в pdoResources, причём вызывать его с классом modResource и пытаться присоединять к нему поля товаров. Если есть присоединение — это товар, вот такой ему чанк, если нет — категория, другой чанк.

      Понятное дело, что можно и один общий чанк с разруливанием внутри через Fenom.
        Алексей Шумаев
        28 февраля 2016, 22:05
        0
        Василий, спасибо. Попробую.

        Вообще, я думаю, этот функционал нужен любому магазину.
        Т.к. искать нужно не только по товарам, но и по категориям. Конечно, если в выводе на фронт нужны данные товаров…
        Алексей Шумаев
        01 марта 2016, 02:03
        2
        +1
        Итак, временное решение — может кому пригодиться.

        1. Запуск (Fenom)
        {$_modx->runSnippet('mSearchForm', [
        	'pageId' => 5,
        	'element' => 'pdoResources',
        	'limit' => 15,
        	'tpl' => 'tpl.mSearch2.ac',
        	'class' => 'modResource'
        ])}

        2. Результат работы mSearchForm в tpl.mSearch2.ac отдаётся сниппету prepareSearchResult:
        <?php
        $out = '';
        
        $tpls = array (
        	'msCategory'  => 'tpl.mSearch2Category.ac',
        	'modDocument' => 'tpl.mSearch2Document.ac',
        	'msProduct'  => 'tpl.mSearch2Product.ac'
        	);
        
        if(isset($class_key) && isset($id)) {
        	
        	$pdo = $modx->getService('pdoTools');
        	$tpl = $tpls[$class_key];
        	
        	$placeholders['pagetitle'] = $pagetitle;
        	$placeholders['description'] = $description;
        	
        	if($class_key == 'msProduct') {
        		$product = $modx->getObject('msProduct', $id);
        		$placeholders['price'] = $product->get('price');
        		$thumb = $product->get('thumb');
        		if(empty($thumb)) {
        			$placeholders['thumb'] = '/assets/templates/img/no-photo.png';
        		}
        		else {
        			$placeholders['thumb'] = $product->get('thumb');
        		}
        	}
        	
        	$out = $pdo->getChunk($tpl, $placeholders);
        }
        return $out;

        3. Пример куска чанка для продукта (с использованием Fenom):
        <div class="img-wrapp">
        		<img src="{$thumb}" alt="{$pagetitle}">
        	</div>
        	<div class="search-body">
        		<span class="item-name">{$pagetitle}</span>
        		{if $decription?}
        			<span class="item-descript">{$description}</span>
        		{/if}
        	</div>
        	<div class="item-price">{$price}<small> руб.</small></div>
          Алексей Шумаев
          01 марта 2016, 09:59
          +1
          Можно было бы сразу join'ить данные товаров при запуске mSearchForm, но у меня есть разные типы цен, зависящие от группы покупателя. Цена для вывода на фронт определяется плагином на msOnGetProductPrice, поэтому в данном случаем мне представляется правильным сделать именно так.
            Алексей Шумаев
            01 марта 2016, 10:19
            0
            На странице выводов результата вызываем последовательно:

            {$_modx->runSnippet('!mSearch2', [
            	'where' => '{"class_key:!=":"msProduct"}'
            ])}
            ,

            затем

            {$_modx->runSnippet('!mFilter2@Products', [ #дополнительные параметры ])}
            .

            Получаем работающие фильтры по найденным товарам + отдельно оформленный результат поиска по остальным ресурсам.
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              9