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
modx.pro
17
6 063
+13
Поблагодарить автора Отправить деньги

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

brioni
07 ноября 2017, 10:08
0
Сегодня же воткну на сайт, спасибо
    Василий Столейков
    07 ноября 2017, 10:12
    1
    0
    Интересное решение!
    Раньше пользовался для этих целей getRelated, твоё решение мне больше нравится простотой и интеграцией с pdoTools!
    Можно и в пакет запаковать ))
      Максим Кузнецов
      07 ноября 2017, 12:29
      5
      +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 допилю похожесть по полям цвета и размера, эти поля хранят не строку, а массив
            Pavel
            04 декабря 2018, 15:25
            0
            Приветствую. Еще не реализовано?
          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
                Пока что нет такого функционала, нет времени и желания (да и желающих на него тоже нет), возможно вы хотите проспонсировать разработку, тогда добро пожаловать в личные сообщения :)
                brioni
                15 ноября 2017, 14:36
                0
                c Tickets не работает чтоли? При вызове снипета — выводится пустая страница
                  Pavel Zarubin
                  15 ноября 2017, 14:38
                  0
                  Покажи вызов сниппета
                    brioni
                    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
                      Только что проверил скопировав твой вызов все нормально отрабатывает, если можешь прислать доступы в личку, пришли гляну
                      brioni
                      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
                      1
                      0
                      Подскажите, вывожу сниппет, наглухо вешает страницу. В результате 504 ошибка. Что может быть?
                      {'!modRelation' | snippet : [
                                          'element' => 'msProducts',
                                          'parents' => 2,
                                          'sortby' => 'RAND()',
                                          'limit' => 3,
                                      ]}
                      Alex Zhuravlev
                      26 марта 2018, 00:53
                      0
                      А как в field указать свое кастомное поле из minishop?

                      У меня в товаре есть кастомное поле где я прописываю параметры товара и нужно выводить похожие по этому полю, указываю его в field но ничего не выводит.
                        Владимир
                        14 июня 2018, 17:26
                        0
                        Почему-то дополнение modRelation не найдено в магазине приложений.
                          Vlad Brise
                          06 декабря 2018, 22:10
                          +3
                          Вчера установил, остался доволен, Павел молодец
                            Эрадж Шамс
                            24 декабря 2018, 11:54
                            0
                            Здравствуйте, не обнаружил дополнение в репозитории (( вы случайно не удалили его от туда?
                              Андрей
                              24 декабря 2018, 13:35
                              0
                              Прошу прощения, из установщика пакетов действительно не видит.
                                Pavel Zarubin
                                24 декабря 2018, 15:57
                                0
                                Максимальная версия стояла 2.6, исправил
                                  Андрей Перевезенцев
                                  12 апреля 2019, 12:33
                                  1
                                  0
                                  Добрый день. Возник вопрос с выводом.

                                  Вывожу так:
                                  [[!modRelation? 
                                                  &element=`msProducts`
                                                  &field=`pagetitle`
                                                  &separator=` `
                                                  &limit=`10`
                                                  &parents=`0`
                                                  &tpl=`TestminipProductTpl`
                                                ]]
                                  Выводит через раз, то сразу, то после нескольких обновлений страницы
                                    Сергей
                                    22 апреля 2019, 23:49
                                    0
                                    Та же самая проблема! опробывал на 3х боевых интернет-магазинах. Везде выводит через раз, непонятно с чем связано… Сделал вызов с кешированием, помогло ровно на день. Обновлял до посинения все работало, потом опять перестало работать
                                      Pavel Zarubin
                                      23 апреля 2019, 00:37
                                      0
                                      Вы бы хоть принцип работы читали бы… Если ничего не вывело значит не нашло для конкретного сочитания похожие ресурсы, делайте логику обработки пустых выводов, например так:
                                      {set $relations = '!modRelation' | snippet: [...]}
                                      {if $relations}
                                          {$relations}
                                      {else}
                                         ...Ваш вывод, например рандомные статьи....
                                      {/if}
                                        Сергей
                                        23 апреля 2019, 11:14
                                        0
                                        Выводит через раз, зашел в товар, похожих товаров нет. Через 5 секунд обновил они появились
                                          Станислав
                                          10 января 2020, 21:45
                                          0
                                          поробовал вывод больше 30 товаров лимита, хостинг заругался, нагрузка слишком высокая
                                  Сергей Карпович
                                  26 января 2021, 17:32
                                  1
                                  0
                                  Кто ни будь делал вывод похожих товаров по значению опции в минишопе?
                                    Евгений
                                    05 марта 2021, 05:05
                                    0
                                    а почему по значению TV нельзя сделать вывод?
                                      Сергей
                                      17 сентября 2021, 16:30
                                      0
                                      Еще давно писал, что выводит некорректно. Если выводить через феном, то все работает отлично!
                                      Это вывод случайных товаров для minishop2
                                      Если подходящих результатов нет, то выведет случайные товары через pdo

                                      {set $relations = '!modRelation' | snippet: [
                                                'parents' => 2,
                                                'element' => 'msProducts',
                                                'field' => 'pagetitle',
                                                'limitWord' => 5,
                                                'limit' => 8,
                                                'sortby' => 'RAND()',
                                                'tpl' => 'tpl.catalog-rand',
                                                'substr' => '-3'
                                      ]}
                                      {if $relations}
                                      {$relations}
                                      {else}
                                        {'!pdoPage' | snippet : [
                                              'parents' => $_modx->resource.parent,
                                              'element' => 'msProducts',
                                              'sortby' => 'RAND()',
                                              'tpl' => 'tpl.catalog-rand',
                                              'sortby' => 'RAND()',
                                              'optionFilters' => ['square:>' =>'4']
                                      	]}
                                      {/if}
                                        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                                        39