[xLike] Идеальная система лайков с оптимистичным интерфейсом и правильной формулой
Пакет довольно прост и одновременно функционален. Выполняет систему рейтинга для любого объекта, по-умолчанию, для ресурсов. Чем-то напоминает систему лайков на YouTube, в частности, в пакете реализован оптимистичный интерфейс.

Также, особенностью компонента является правильный подсчет рейтинга на основе вычисления нижней границы доверительного интервала Вильсона для параметра Бернулли. По-простому: эта формула не даст встать новым записям с 1 лайком и 0 дизлайками выше более старых записей с сильным рейтингом.
Список преимуществ:

Выводит систему рейтинга на месте вызова.
mode — режим работы сниппета: db или local. В режиме local сниппет обходится без запроса к базе для того, чтобы узнать кол-во лайков/дизлайков и рейтинг, вместо этого вам необходимо передать эти цифры в сниппет в качестве параметров. По-умолчанию, db.
guest — разрешить гостям голосовать. По-умолчанию, Да.
parent — ID объекта. По-умолчанию, ID текущего ресурса.
class — класс объекта. По-умолчанию, modResource.
list — название списка (дополнительный параметр группировки). По-умолчанию, default.
Вывод рейтинга для текущего тикета без возможности голосовать гостям:
Вывод рейтинга для текущего ресурса в режиме local:
Данное событие срабатывает после голосования пользователем и всех проверок.
class — класс объекта,
list — название списка,
likes — кол-во лайков,
dislikes — кол-во дизлайков,
rating — текущий рейтинг, уже пересчитанный.
Код плагина:
Демо-сайт
Скачать в Modstore
Если есть желание отблагодарить:
ЯД — 4100159550314
PayPal — pavelgvozdb@yandex.ru

Также, особенностью компонента является правильный подсчет рейтинга на основе вычисления нижней границы доверительного интервала Вильсона для параметра Бернулли. По-простому: эта формула не даст встать новым записям с 1 лайком и 0 дизлайками выше более старых записей с сильным рейтингом.
Список преимуществ:
- Оптимистичный интерфейс,
- Наиболее правильная формула вычисления рейтинга,
- Работа с любыми объектами (modResource, modUser, кастомные объекты),
- Голосование гостями,
- Анимированное изменение полосы/числа рейтинга,
- Событие плагина — xLikeOnVote.

Сниппет xLike
Выводит систему рейтинга на месте вызова.
Параметры
tpl — чанк шаблона вывода. По-умолчанию, tpl.xLike.mode — режим работы сниппета: db или local. В режиме local сниппет обходится без запроса к базе для того, чтобы узнать кол-во лайков/дизлайков и рейтинг, вместо этого вам необходимо передать эти цифры в сниппет в качестве параметров. По-умолчанию, db.
guest — разрешить гостям голосовать. По-умолчанию, Да.
parent — ID объекта. По-умолчанию, ID текущего ресурса.
class — класс объекта. По-умолчанию, modResource.
list — название списка (дополнительный параметр группировки). По-умолчанию, default.
Примеры
Вывод рейтинга для текущего ресурса с возможностью голосовать гостям:{'!xLike' | snippet}Вывод рейтинга для текущего тикета без возможности голосовать гостям:
{'!xLike' | snippet : [
'guest' => false,
'class' => 'Ticket',
]}Вывод рейтинга для текущего ресурса в режиме local:
{'!xLike' | snippet : [
'mode' => 'local',
'likes' => $_modx->resource['likes'],
'dislikes' => $_modx->resource['dislikes'],
'rating' => $_modx->resource['rating'],
]}Подразумевается, что в ТВ полях likes, dislikes, rating хранится соответствующая информация.Событие xLikeOnVote
Данное событие срабатывает после голосования пользователем и всех проверок.
Параметры плагина
parent — ID объекта, к которому привязан рейтинг,class — класс объекта,
list — название списка,
likes — кол-во лайков,
dislikes — кол-во дизлайков,
rating — текущий рейтинг, уже пересчитанный.
Практическое применение
Задача: при голосовании в рейтинге (с параметрами сниппета class=modResource, list=default), записывать текущий рейтинг в ТВ поле rating.Код плагина:
switch ($modx->event->name) {
case "xLikeOnVote":
if ($class == 'modResource' && $list == 'default') {
if ($resource = $modx->getObject($class, array('id' => $parent))) {
$resource->setTVValue('rating', $rating);
}
}
break;
}Таким образом, мы сможем сортировать ресурсы (или любые другие объекты) по правильно подсчитанному рейтингу.Демо-сайт
Скачать в Modstore
Если есть желание отблагодарить:
ЯД — 4100159550314
PayPal — pavelgvozdb@yandex.ru
Комментарии: 113
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Подразумевается, что в ТВ полях likes, dislikes, rating хранится соответствующая информация.
В TV записаны значения и они нормально выводятся пользователю.
Если он «голосует» то в БД попадает соответствующая запись. (НО другому пользователю опять выведется то же значение TV что и было)
Я переношу систему рейтингов и думала, что к значению в TV будут прибавляться значения из БД, но видимо это не так.
Чтобы обновлять TV создала плагин
но он все предыдущие значения TV обнуляет.
Так как он должен работать?
Делать как-то так?
Вероятно у вас что-то закешено. Может база, не знаю. У меня работает корректно на демо-сайте.
в tv like стояло 520 стало 2
в tv dislike стояло 70 стало 0
то есть просто записались(посчитались) данные из БД, минуя значения в tv
в снипете заменить
на ?
PS Значения не накрученные, попрошу, просто переношу данные из LikeDislike )
Без разницы. Ради удобства повествования.
PS При использовании tv надо в настройках системы cache_resource выставить на Нет
Вопросы от меня:
1. пример выборки для pdoResources (с LEFT JOIN имею ввиду) можно?
2. Как реализована защита от повторного голосования гостями и авторизованными пользователями?
2) IP или номер сессии. Для авторизованных юзеров не вижу смысла объяснять…
Например — отсортировать по популярности.
Записываете рейтинг в ТВ при голосовании на событии xLikeOnVote и сортируете. Ничего сложного.
Можно даже рейтинг посчитать, но это зашквар какой-то:
В шаблоне вызываю чанк
Не работают и на xLike.tpl
Меняла и Пример здесь
Все равно не накпливаются лайки. как исправить?
2) Потом мне не ясно, что вы хотите накапливать и куда?
3) Я показал конкретные примеры на демо сайте, как надо вызывать и что из этого получается. Если почитать внимательно, то поймете, что к чему и как с этим работать.
Fenom pdotools_fenom_parser активировала
Создал плагин: xLikeOnVote с кодом который вы приводите в описании
Вывод делаю так:
В чанке afisha-popular вызываю Подскажите, как вывести на первое место ресурс с большим рейтингом?
работает, но на гостей никак не влияет и гости так же могут ставить лайки. или вызов параметров снипета в данном случае не сработают?
habrahabr.ru/company/darudar/blog/143188/
Что бы обновлялось не при перезагрузке страницы, а ajax
Но обновляется только после перезагрузки страницы
что-то не работает корректно
Как правильно прописать чтобы после нажатия на likes появлялось кол-во лайков и рейтинг?
Есть товары. miniShop2
В карточке товара вызываю:
[[!xLike?
&parent=[[*id]]
&mode=`db`
&likes=`$_modx->resource['likes']`
&dislikes=`$_modx->resource['dislikes']`
&rating=`$_modx->resource['rating']`
&tpl=`tpl.xLike`
&class=`msProduct`
&list=`default`
]]
Создал дополнительные TV поля:
likes
dislikes
rating
Далее ставлю лайк товару. Но при редактировании товара поля likes, dislikes, rating по-прежнему пусты. Что я сделал не так? Или чего-то не сделал? Заранее спасибо.
В текущем тикете так:
Данные лайков заносятся в TV likes с помощью плагина.
Как сниппет вызвать в списке?
Никак.
По-поводу IP, мне бы хотелось отключать эту проверку где-нибудь в настройках. Сейчас ситуация такая. Есть фотография, которой пытаются поставить оценку, к примеру, три пользователя (каждый со своего устройства), подключенные к одной точке wi-fi. И если кто-то из них первый поставил оценку, то максимум, что могут сделать другие, это отменить оценку, поставленную первым проголосовавшим пользователем, а не оставить свою.
На демо сайт добавил возможность «потыкать». Второй пример.
Укажите сниппету xLike
Т.е. чтобы было как нормальное голосование без учета дизлайка? Куда копать вообще?
Сейчас к примеру 4 голоса и 51%, при скольки голосах будет 100%?
Проще говоря, если вам надо отсортировать записи на основании только лайков, то сортируйте по лайкам, а не по рейтингу. А если вам надо вывести процентный рейтинг текущей записи, учитывая все записи, то пишите эту логику самостоятельно.
www.strawpoll.me/107782
Т.е. например, проголосовало 10 человек — это 100%
1 работа — 5 человек — 50%
2 работа — 3 человека — 30%
3 работа — 2 человека — 20%
Всего — 10 человек — 100 %
Вашим компонентом такого не сделаешь?
Проблема в том, что если один юзер проголосовал, на странице подставится класс link_active и она закешируется. Зайдет другой пользователь и ему отдастся страница уже с классом link_active (если он нажмет кнопку с этим классом, по идее ему отдастся окно access denied, но не уверен) Есть возможность настраивать исключения для кеширования, но что тут исключать не понятно. Если кто сталкивался с подобным, поделитесь опытом.
Upd хотя вроде всё работает…
Периодически откуда-то всплывает класс link_active там где его не должно быть, но после обновления страницы уходит
Ни у кого не было проблем после обновления версии до 1.0.3-beta? У меня после обновления перестали работать лайки, нажимаешь на лайк и ничего не происходит. В журнале ошибок ничего нет. Вызываю сниппет так: [[!xLike]]
tpl_count_like
Теперь без вызова сниппета скрипты не будут подключаться.
Скажите, вы могли бы доработать дополнение, чтобы оно сохраняло в тв-поле список проголосовавших (зарегистрированные пользователи)? Я готов профинансировать.
Заранее благодарен.
Мысль интересная, спасибо
Условно: 76% пользователей считают, что сайт хороший
{'!xLike' | snippet: [
'parent' => $id,
'class' => 'modResource',
'mode' => 'db',
'list' => 'default',
'likes' => $_modx->resource['likes'],
'dislikes' => $_modx->resource['dislikes'],
'rating' => $_modx->resource['rating'],
]}
tpl.xLike:
{*@formatter:off*}
<{$can? 'a': 'span'}
class=«xlike__link {$value > 0? 'xlike__link_active': ''} [ {$can? 'js-xlike-button': ''} ]»
{$can? 'data-xlike-value=«1» href=«javascript:undefined;»': ''}
>
<svg version=«1.1» id=«Слой_1» xmlns=«www.w3.org/2000/svg» xmlns:xlink=«www.w3.org/1999/xlink» x=«0px» y=«0px»
width=«31px» height=«27px» viewBox=«0 0 31 27» enable-background=«new 0 0 31 27» xml:space=«preserve»>
/>
{$likes | number_format: 0: '': ' '}
</{$can? 'a': 'span'}>
Добавление в TV поле (Плагин: add-rating):
<?php
switch ($modx->event->name) {
case «xLikeOnVote»:
if ($class == 'modResource' && $list == 'default') {
if ($resource = $modx->getObject($class, array('id' => $parent))) {
$resource->setTVValue('rating', $rating);
$resource->save();
}
}
break;
}
вывожу так:
[[!xLike?
&parent=`[[*id]]`
&class=`modResource`
&list=`default`
&likes=`$_modx->resource['likes']`
&dislikes=`$_modx->resource['dislikes']`
&rating=`$_modx->resource['rating']`
]]