Рейтинг в сниппетах pdoResources, msProducts
Достаточно частый вопрос у пользователей компонента, как вывести рейтинг при использовании сниппетов mFilter2, msProducts, pdoResources и т.п.
У нас есть 2 варианта:
Вариант 1. Вызов сниппета ecThreadRating
Для того, чтобы вывести рейтинг товара мы можем вызвать сниппет ecThreadRating в чанке для каждого товара (напоминаю, по-умолчанию используется tpl.msProducts.row).
Здесь главное правильно сформировать параметр thread, на синтаксисе родного парсера MODX это будет
[[ecThreadRating?
&thread=`resource-[[+id]]`
]]
{'ecThreadRating' | snippet : [
'thread' => 'resource-' ~ $id,
]}
Этот вариант прост, но при выводе большого количества товаров на одной странице мы получим большое количество запросов в базу данных. Можно столкнуться с падением скорости работы сайта.
Думаю, что если у вас на странице выводится 5-10-20 товаров, то особых проблем не будет, а вот если 50+, то лучше рассмотреть вариант, предложенный ниже.
Вариант 2. Объединение данных (используем JOIN)
В этом варианте мы используем оператор JOIN, чтобы одним запросом выбирать нужные данные.
У нас есть два способа того, как присоединять таблицы:
- поле resource объекта ecThread, которое указывает на товар (или страницу);
- поле name объекта ecThread так же содержит в себе id товара (например resource-42).
Если у вас одному товару соответствует одна цепочка (например отзывы), то можно сделать JOIN с использованием первого варианта:
&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.
&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 товара имя цепочки и выборку ограничиваем им.
Используя данные примеры вы сможете сформировать тот запрос, который нужен на вашем сайте.