Skip to content
easyComm
easyComm
Создание модулей и разделов отзывов, комментариев, вопросов и ответов
  1. Компоненты
  2. easyComm
  3. Рейтинг в сниппетах pdoResources, msProducts

Рейтинг в сниппетах pdoResources, msProducts

Достаточно частый вопрос у пользователей компонента, как вывести рейтинг при использовании сниппетов mFilter2, msProducts, pdoResources и т.п.

У нас есть 2 варианта:

Вариант 1. Вызов сниппета ecThreadRating

Для того, чтобы вывести рейтинг товара мы можем вызвать сниппет ecThreadRating в чанке для каждого товара (напоминаю, по-умолчанию используется tpl.msProducts.row).

Здесь главное правильно сформировать параметр thread, на синтаксисе родного парсера MODX это будет

modx
[[ecThreadRating?
  &thread=`resource-[[+id]]`
]]
fenom
{'ecThreadRating' | snippet : [
  'thread' => 'resource-' ~ $id,
]}

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

Думаю, что если у вас на странице выводится 5-10-20 товаров, то особых проблем не будет, а вот если 50+, то лучше рассмотреть вариант, предложенный ниже.

Вариант 2. Объединение данных (используем JOIN)

В этом варианте мы используем оператор JOIN, чтобы одним запросом выбирать нужные данные.

У нас есть два способа того, как присоединять таблицы:

  • поле resource объекта ecThread, которое указывает на товар (или страницу);
  • поле name объекта ecThread так же содержит в себе id товара (например resource-42).

Если у вас одному товару соответствует одна цепочка (например отзывы), то можно сделать JOIN с использованием первого варианта:

modx
&loadModels=`easycomm`
&leftJoin=`{
  "ecThread": {
    "class": "ecThread",
    "on": "msProduct.id = ecThread.resource"
  }
}`
&select=`{
  "msProduct": "*",
  "ecThread": "ecThread.rating_simple AS rating"
}`

Обращаю внимание, в select мы указали, что выбираем только поле rating_simple как rating, нужно больше - или пишите *, или указывайте нужные поля.

Код выше сработает некорректно, если у вас одному товару соответствует несколько (две и более) цепочек, к примеру у вас есть Отзывы и Вопрос-Ответ. Цепочек две, но мы явно не указываем, какую использовать в нашем JOIN, в результате получим неверные данные.

Решение - делать выборку с использованием поля ecThread.name. В примере ниже мы вообще из одной цепочки узнаем рейтинг (Rating), а из другой цепочки мы узнаем кол-во вопросов по этому товару (QA). В этом примере имена цепочек формируются как resource-rating-XX и resource-qa-XX.

modx
&loadModels=`easycomm`
&leftJoin=`{
  "ecThreadRating": {
    "class": "ecThread",
    "alias": "ecThreadRating",
    "on": " CONCAT('resource-rating-', modResource.id) = ecThreadRating.name"
  },
  "ecThreadQA": {
    "class": "ecThread",
    "alias": "ecThreadQA",
    "on": " CONCAT('resource-qa-', modResource.id) = ecThreadReviews.name"
  }
}`
&select=`{
  "modResource": "*",
  "ecThreadRating": "ecThreadRating.rating_simple AS rating",
  "ecThreadQA": "ecThreadQA.count AS qa_count"
}`

Как видно, мы используем оператор CONCAT, чтобы сформировать с использованием id товара имя цепочки и выборку ограничиваем им.

Используя данные примеры вы сможете сформировать тот запрос, который нужен на вашем сайте.