easyComm 1.10.0. Голосование за сообщения (отзывы)

Всем привет!
Выпущено обновление easyComm, про которое у меня не раз спрашивали: возможность голосовать (Нравится/Не нравится) за любое сообщение.



Вот вам еще тройка примеров с таких известных сайтов, как Яндекс.Маркет, Ютуб, Wildberries в качестве демонстрации:


Кстати, в магазине ModStore можно найти компонент с таким функционалом, это xLike. Он позволяет осуществлять голосование за любой объект и в целом его можно прикрутить и к easyComm. Может быть будут небольшие трудности где-то, но все реализуемо. В принципе, тех, кто у меня спрашивал, когда будут лайки и дизлайки, я и направлял в сторону xLike.

Но выдалась немного времени и я решил расширить возможности и easyComm из коробки.

Основные возможности
  • Можно оставить один голос (За или Против) за одно сообщение для пользователя. Проверка пользователя идет по id для авторизованных, по session (или IP) для не авторизованных.
  • Подсчет общего рейтинга голосов у каждого сообщения, его отображение в виде шкалы (полосы внизу на скриншоте).
  • Отображение «своих» голосов после обновления страницы. Естественно, если у неавторизованного пользователя все еще та же сессия (или IP).
  • Возможность сортировки сообщений по рейтингу голосов, к примеру мы можем показать «самые полезные» отзывы сначала.
Как включить голосование за комментарии/отзывы?

1. Сначала обновляем компонент :) Без этого никуда!
Обратите внимание, в этой версии компонента изменились css, js файлы:
/assets/components/easycomm/css/web/ec.default.css
/assets/components/easycomm/js/web/ec.default.js
Так же поменялось содержимое чанка tpl.ecMessages.Row.

Поэтому если вы меняли стандартный чанк, вам нужно будет следить за этим.
Если у вас кастомные css/js, вам нужно будет добавить новый код себе.

2. У сниппета ecMessages появилось 3 новых параметра:
  • votingEnable — включить голосование;
  • votingAllowGuest — разрешить голосовать гостям;
  • votingConsiderIP — проверять IP для гостей.
{'!ecMessages' | snippet : [
...
'votingEnable' => 1,
'votingAllowGuest' => 1,
...
]}

Таким образом, сначала включаем голосование (votingEnable), затем думаем, нужно ли разрешить голосовать неавторизованным пользователям (votingAllowGuest, проверка идет в этом случае по php сессии), альтернативно можно включить проверку по IP адресу (votingConsiderIP), но здесь надо понимать, что в одной квартире IP будет общий к примеру для разных девайсов.

Каждый вызов ecMessages может быть с любым набором этих параметров, т.е. в одном вызове у вас может быть включена возможность голосовать, а в другом нет.

Как хранится в базе данных?
1. Все голоса хранятся в отдельной табличке (объект ecVote, таблица modx_ec_votes). Структуру таблицы можно посмотреть в базе данных, там ничего сложного.

2. Кроме этого, у объекта ecMessages добавились 4 новых поля:
— votes — общее кол-во голосов (лайки + дизлайки);
— likes — кол-во «нравится»;
— dislikes — кол-во «не нравится»;
— votes_rating — общий рейтинг голосов, число от 0 до 1. Этот рейтинг считается по тому же алгоритму, что и общий рейтинг цепочек, т.е., цитирую:
Рейтинг = Нижняя граница доверительного интервала Вильсона (Wilson) для параметра Бернулли
Таким образом, по полю votes_rating очень легко отсортировать отзывы, чтобы впереди шли «полезные»:
{'!ecMessages' | snippet : [
...
'sortby' => 'votes_rating'
...
]}

Немного про быстродействие и дополнительные запросы
Если голосование включено (votingEnable=1), то в сниппете ecMessages усложняется запрос в базу данных в зависимости от условия:
— Пользователь авторизован. Делаем JOIN таблицы modx_ec_votes с целью найти «свой» голос, т.е. нам нужно получить информацию, голосовал ли пользователь за каждое сообщение, чтобы потом показать ему этот голос.
— Пользователь не авторизован. Здесь все зависит от параметра votingAllowGuest, если отключен, то дополнительного JOIN нет, если включен, то так же делается JOIN, но фильтрация голосов идет уже не по id пользователя, а по его session или IP, что по идее может быть медленнее.

Естественно, чтобы это все работало, вызов ecMessages должен быть не кешированный (оно и раньше так было).

Про «накрутку»
Лучший способ избежать ее — разрешить голосование только авторизованным пользователям.
Для контроля же сейчас вы можете в админке сайта просмотреть список всех голосов на отдельной вкладке, там есть дата и время голоса, а так же значение IP и сессии пользователя, по которым будет видно накрутку.
Да, администратор может удалить «левые» голоса (отредактировать нельзя).

P.S.
Это первый выпуск компонента с данным функционалом. У меня нет рабочего проекта, где бы я его протестировал, делалось все исключительно на демо-сайте после нескольких просьб.
Если у вас есть замечания, улучшения — напишите, я постараюсь поправить.
Наумов Алексей
15 ноября 2019, 09:37
modx.pro
2 258
+27

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

Александр Мельник
16 ноября 2019, 22:05
+2
Вот у менеджеров добавится работы))
Мало того что писать бесконечно фейковые отзывы, так теперь еще и лайкать их, переключая ip.
    Тимур
    18 ноября 2019, 09:55
    +1
    Отличное обновление, как раз не хватало подобного в прошлом проекте. Спасибо
      Konstantin
      18 ноября 2019, 18:33
      0
      Жду когда уже звездочки и лайки через background-url будут заменены нормальными fontawesome…
        Наумов Алексей
        19 ноября 2019, 09:33
        0
        Тащить целую библиотеку за собой ради 2-х иконок?..
        Если на сайте установлен font-awesome, вы всегда можете изменить css файл и верстку, чтобы его использовать.
          Konstantin
          19 ноября 2019, 09:47
          0
          Fontawesome почти у всех уже есть. А если лень библиотеку тащить, так хотя-бы svg надо использовать…
        Роман
        19 ноября 2019, 13:57
        0
        было бы круто сделать галочку как в тикетах уведомлять о новых комметах чтоб пользователь сам выбирал нужны ему уведомления или нет
          Наумов Алексей
          19 ноября 2019, 14:19
          0
          Какие уведомления, о чем?
          Типовой сценарий использования компонента — отзывы о товарах.
          С трудом могу представить ситуацию, когда я захочу получать уведомления о том, что на каком-то сайте появился новый отзыв о пылесосе или книге.
          Или я не понял, про что речь.
            Роман
            19 ноября 2019, 17:16
            0
            да все верно!
          Vladislav Shuklin
          07 января 2020, 23:52
          0
          Начали тестировать лайки, но почему-то возникают проблемы с голосованием через мобильный телефон. С десктопа все ОК. Также не могу понять, как реальзовать пагинацию / аякс подгрузку комментариев, если их будет слишком много
            Наумов Алексей
            09 января 2020, 10:42
            +1
            Добрый день!
            А что на мобильном не так работает? Можете описать? какой телефон/браузер?
            Пагинация через pdoPage.
              Vladislav Shuklin
              09 января 2020, 10:53
              0
              Спасибо за рекомендацию по пагинации. Буду пробовать, но было бы классно, если в документацию добавить пример. С мобильными в принципе решил вопрос путем чистки кэша папки Core + добавления некешируемого сниппета. Но промучился пару дней. Скорее всего плагин кешировал настройки votingConsiderIP после чего блокирвал доступ к голосованию так как я выходил в сеть с одного IP. Правда, я пытался выходить через VPN и другой браузер — была та же проблема.
                Наумов Алексей
                09 января 2020, 11:16
                0
                Сниппеты конечно нужно некешированными вызывать.
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            12