modRelation - Похожие товары для minishop2 и pdoTools

В общем кратенькая заметка, но думаю некоторым поможет, нужно было реализовать правильную перелинковку сайта, а заказчик никак не хотел вручную делать связи, пришлось написать вот такой «Умный» сниппет, который при правильном заполнении каталога вполне неплохо себе справляется с подбором похожих ресурсов, если я ни для кого америку не открыл, то сорян, а если открыл, то могу собрать пакет с этим сниппетом и выложить в modstore бесплатно для более легкой установки :)

ОБНОВЛЕНО:
Компонент доступен для загрузки в modstore

Описание работы:
Сниппет разделяет по словам поле, которое вы укажите в field (по умолчанию pagetitle), выбирает рандомное слово из массива слов и выполянет поиск по базе ресурсов с похожими словами

Сниппет:
<?php
if (empty($field)) {
  $field = 'pagetitle';
}
if (empty($separator)) {
  $separator = ' ';
}
if (empty($element)) {
  $element = 'pdoResources';
}
if (empty($limitWord)) {
  $limitWord = 3;
} else {
  $limitWord = intval($limitWord);
}
$pagetitle = $modx->resource->get($field);
if (!$pagetitle) {
  return ;
}
$arr = explode($separator, $pagetitle);
$rand = array_rand($arr, 1);
while (iconv_strlen($arr[$rand]) < $limitWord):
  $rand = array_rand($arr, 1);
endwhile;

$rand_pt = $arr[$rand];

$where = array('where' => array(
    $field.':LIKE' => '%'.$rand_pt.'%',
    'id:!=' => $modx->resource->id
));

$scriptProperties = array_merge($where, $scriptProperties);
$pdoTools = $modx->getService('pdoTools');
return $pdoTools->runSnippet($element, $scriptProperties);
Внимание, код устаревший, используйте версию из modstore

Принимает на вход:
  • field — поле по которому будут искаться похожие ресурсы, можно использовать любые поля ресурса, если это не тв параметры по умолчанию pagetitle
  • separator — разделитель по которому будет делиться объекты для поиска по умолчанию пробел
  • limitWord — минимальная длина слова для поиска похожих ресурсов, по умолчанию 3
  • element — сниппет для вывода результатов, по умолчанию pdoResource
Далее просто передаете парметры нужные для сниппета elements, принцип работы по типу pdoPage

Примеры вызова:

Простой вызов для msProducts
[[!modRelation? 
  &element=`msProducts`
  &parents=`0`
  &sortby=`RAND()`
]]
Со всеми параметрами:
[[!modRelation? 
  &field=`pagetitle`
  &separator=` `
  &limitWord=`3`
  &element=`msProducts`
  &parents=`0`
  &tpl=`tpl_product_row`
  &sortby=`RAND()`
]]
Пример использования для статей и обычных ресурсов:
[[!modRelation? 
  &parents=`0`
  &sortby=`RAND()`
  &tpl=`@INLINE [[+pagetitle]]`
]]
Сниппет работает как с продуктами minishop2 так и с обычными ресурсами
Pavel Zarubin
07 ноября 2017, 06:51
14
1 537
+13

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

Yar
Yar
07 ноября 2017, 10:08
0
Сегодня же воткну на сайт, спасибо
Василий Столейков
07 ноября 2017, 10:12
1
0
Интересное решение!
Раньше пользовался для этих целей getRelated, твоё решение мне больше нравится простотой и интеграцией с pdoTools!
Можно и в пакет запаковать ))
Максим Кузнецов
07 ноября 2017, 12:29
3
+6
На fenom-е посимпатичнее будет:

{foreach $_modx->resource.pagetitle | split : ' ' as $pagetitle_word}
	{if $pagetitle_word | length > 3}
		{var $words[] = $pagetitle_word}
	{/if}
{/foreach}

{set $random_word_position = rand(1, $words| length)}
{set $random_word = $words[$random_word_position - 1]}

{$_modx->runSnippet('!msProducts', [
	'parent' => $_modx->resource.parent,
	'resources' => -$_modx->resource.id,
	'where' => '{
		"pagetitle:LIKE": "%' ~ $random_word ~ '%"
	}',
	...
])}
    Pavel Zarubin
    07 ноября 2017, 13:29
    +1
    Вкусовщина конечно, но не хотел бы я чтобы мне попался проект где вот таких вот сниппетов в шаблоне с десяток) Все таки надо разделять верстку и программирование, вы же не пишите все операции в одном файле, а резделяете на функции/классы, хоть их вызов и отнимает больше времени, но лайк однозначно поставлю!)
      Максим Кузнецов
      07 ноября 2017, 13:37
      0
      *пожал плечами* Для больших объемов или многократно повторяющихся вызовов — пожалуй.

      В данном случае «похожие товары», скорее всего, будут выводиться только на странице самого товара.
      Плюс, с fenom-ом кол-во запросов к бд сокращается минимум на 1..)

      К слову, по поводу разделения: логику разбивания и выборки случайного слова из заголовка можно вынести в модификатор.
Pavel Zarubin
07 ноября 2017, 14:38
+1
Обновление: Раз сниппет оказался много кому нужен, собрал транспортный пакет и допилил его вид до более универсального
    Pavel Zarubin
    07 ноября 2017, 14:55
    +1
    Как только опубликуют в modstore допилю похожесть по полям цвета и размера, эти поля хранят не строку, а массив
carlo
07 ноября 2017, 23:06
+2
Can I use this plugin like GetRelated for Modx? Does it work with Articles?

I am so sorry, I don't speak Russian.

Google Translate:

Могу ли я использовать этот плагин, как GetRelated для Modx? Это работает со статьями?

Мне очень жаль, я не говорю по-русски.
    Pavel Zarubin
    08 ноября 2017, 08:19
    1
    +4
    Sure, simple example for use:
    [[!modRelation? 
      &parents=`0`
      &element=`pdoResources`
      &tpl=`@INLINE [[+pagetitle]] 
    `
    ]]
      carlo
      08 ноября 2017, 17:19
      +1
      Thank you! I will try that!
      carlo
      11 июня 2018, 22:25
      0
      Hi Pavel, I am trying to implement your code

      [[!modRelation? 
        &parents=`3,157,158,159`
        &limit=`3`
        &element=`pdoResources`
        &includeTVs=`featureimage`
        &tpl=`modrelationchunck`
        &wrapIfEmpty=`modrelationchunck`
      ]]
      Do you think is it possible to display a default chunck or result if result is empty?
        carlo
        12 июня 2018, 16:43
        0
        It is ok, I managed to do it with
        [[!modRelation:default=``?
        .

        I just have 2 questions:

        — What can I use for &field?
        — is it necessary to call the plugin uncached?
Олег
14 ноября 2017, 10:40
0
А как быть с опциями товаров?
Мне надо чтобы похожие шины выводил по ширине, высоте и радиусу.
    Pavel Zarubin
    14 ноября 2017, 11:03
    +1
    Пока что нет такого функционала, нет времени и желания (да и желающих на него тоже нет), возможно вы хотите проспонсировать разработку, тогда добро пожаловать в личные сообщения :)
Yar
Yar
15 ноября 2017, 14:36
0
c Tickets не работает чтоли? При вызове снипета — выводится пустая страница
    Pavel Zarubin
    15 ноября 2017, 14:38
    0
    Покажи вызов сниппета
      Yar
      Yar
      15 ноября 2017, 14:40
      0
      [[!modRelation? 
        &parents=`0`
        &sortby=`RAND()`
        &includeTVs=`image`
        &tpl=`tpl-side-bar-articles`
        &element=`getTickets`
      ]]
        Pavel Zarubin
        15 ноября 2017, 14:51
        0
        Только что проверил скопировав твой вызов все нормально отрабатывает, если можешь прислать доступы в личку, пришли гляну
      Yar
      Yar
      15 ноября 2017, 14:42
      0
      с
      &element=`pdoResources`
      тоже самое — пустая страница. Вызов на странице тикета
v2254303
15 декабря 2017, 21:19
0
А как сделать чтобы не выводились записи рандомно при каждом обновлении страницы

<div class="modrelation">
      <div class="modrelation_title">Похожие темы</div>  
{$_modx->runSnippet('!modRelation',[
			'field' => 'pagetitle',
			'parents' => '0',
			'element' => 'msProducts',
			'tpl' => '@FILE chunks/products/item-catalog.tpl',
])}
</div>
    Pavel Zarubin
    15 декабря 2017, 22:02
    0
    Сделай сниппет некешируемый, убрав восклицательный знак в вызове, тогда результаты будут сгенерированы только один раз
Андрей
22 марта 2018, 09:23
0
Подскажите, вывожу сниппет, наглухо вешает страницу. В результате 504 ошибка. Что может быть?
{'!modRelation' | snippet : [
                    'element' => 'msProducts',
                    'parents' => 2,
                    'sortby' => 'RAND()',
                    'limit' => 3,
                ]}
    Александр
    10 апреля 2018, 13:12
    0
    Такая же проблема. Удалось решить?
Alex Zhuravlev
26 марта 2018, 00:53
0
А как в field указать свое кастомное поле из minishop?

У меня в товаре есть кастомное поле где я прописываю параметры товара и нужно выводить похожие по этому полю, указываю его в field но ничего не выводит.
Владимир
14 июня 2018, 17:26
0
Почему-то дополнение modRelation не найдено в магазине приложений.