Скрипт звёздного рейтинга для сайта

Александр Мальцев
Александр Мальцев
21K
55
Скрипт звёздного рейтинга для сайта
Содержание:
  1. Обзор скрипта звёздного рейтинга
  2. Подключение скрипта звёздного рейтинга к сайту
  3. Настройка скрипта звёздного рейтинга
  4. Исходные коды звёздного рейтинга
  5. Комментарии

В этой статье рассмотрим скрипт рейтинга в виде звёзд, построенный на PHP и MySQL, и работающий без обновления страницы.

Обзор скрипта звёздного рейтинга

Скрипт рейтинга может применяться для оценки статей, услуг, товаров, видео, картинок и прочего материала на сайте в виде звёзд. С его помощью можно узнать среднюю оценку пользователей.

Этот скрипт можно привязать к любому материалу. Осуществляется это посредством указания ему некоторого идентификатора посредством атрибута data-id. На одну страницу можно добавить любое количество рейтингов.

Скрипт доступен в виде исходных кодов. Проект этого звёздного рейтинга расположен на GitHub.

Последняя версия данного скрипта - 1.0.4. Эта версия доступна по этой ссылке.

Проект реализован с использованием MySQL, PHP, JavaScript и CSS. При этом скрипт работает полностью через AJAX. Это означает, что его очень просто установить на сайт. Для этого достаточно к страницам просто подключить CSS и JavaScript файлы.

Скрипт звёздного рейтинга по умолчанию имеет защиту от накрутки по IP. Если она не нужна, то её можно отключить. Отметка рейтингов, пользователь которым выставил оценку сохраняется у него на устройстве в LocalStorage. Cookie в этом скрипте не используются.

Изображения звёздочек в этом скрипте выполнено с помощью SVG графики.

По умолчанию данный скрипт настроен на выставления оценки от 1 до 5. Но при необходимости вы можете установить любое другое количество звёзд.

Подключение скрипта звёздного рейтинга к сайту

Основные этапы:

  • создать таблицы в базе данных MySQL
  • поместить «process_star_rating.php» в некоторую папку проекта и указать в нём данные для подключения к базе данных;
  • подключить «star_rating.css» и «star_rating.js» к страницам сайта; указать в «star_rating.js» URL к «process_star_rating.php»;
  • вставить HTML-код рейтинга в необходимые места страниц сайта; задать им идентификатор с помощью атрибута data-id.

Создание таблиц в базе данных

Для работы звёздного рейтинга необходимо создать в базе данных MySQL две таблицы: star_rating и star_rating_ip.

Это действие, например можно выполнить с помощью инструмента phpmyadmin.

Для этого в phpmyadmin перейдите в вашу базу данных, нажмите на вкладку SQL и вставьте это содержимое:

CREATE TABLE `star_rating` (
  `id` int(10) UNSIGNED NOT NULL,
  `rating_id` varchar(20) NOT NULL,
  `rating_avg` float NOT NULL,
  `total_votes` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `star_rating_ip` (
  `id` int(10) UNSIGNED NOT NULL,
  `rating_id` int(10) UNSIGNED NOT NULL,
  `rating_value` tinyint(2) UNSIGNED NOT NULL,
  `rating_ip` varchar(16) NOT NULL DEFAULT '0.0.0.0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `star_rating`
  ADD PRIMARY KEY (`id`);
ALTER TABLE `star_rating_ip`
  ADD PRIMARY KEY (`id`),
  ADD KEY `rating_id` (`rating_id`);

ALTER TABLE `star_rating`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `star_rating_ip`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;

Нажмите на кнопку «Вперёд».

Создание таблиц для звёздного рейтинга с использованием инструмента phpmyadmin

Таблица star_rating является основной. Она состоит из следующих полей:

  • id – первичный ключ, его значение будет генерироваться автоматически (AUTO_INCREMENT);
  • rating_id – текстовый идентификатор рейтинга, его значение будет определять в HTML с помощью атрибута data-id;
  • rating_avg – среднее значение рейтинга;
  • total_votes – количество пользователей, поставивших оценку.

Таблица star_rating_ip является дополнительной. Она предназначена для хранения IP адресов пользователей. Данная таблица используется для определения того поставил ли оценку пользователь с данным IP за этот материал или нет. Она применяется для защиты рейтинга от накрутки.

Эта таблица состоит из следующих полей:

  • id – первичный ключ, его значение будет генерироваться автоматически (AUTO_INCREMENT);
  • rating_id – будет определять с каким id таблицы star_rating будет связана эта запись;
  • rating_value – значение рейтинга, установленного пользователем;
  • rating_ip – IP пользователя.

Настройка и загрузка на сайт PHP скрипта

Для того чтобы PHP файл мог осуществлять запросы к созданным таблицам, в него необходимо внести ваши настройки для подключения к базе данных:

const
  DB_HOST = 'localhost', // хост
  DB_NAME = 'mydb', // имя базы данных
  DB_CHARSET = 'utf8', // кодировка
  DB_USER = 'root', // имя пользователя MySQL
  DB_PASSWORD = '', // пароль пользователя MySQL
  MAX_RATING = 5,
  IS_CHECK_IP = true;

После сохранения настроек, переместите PHP файл «process_star_rating.php» в любую папку вашего проекта.

Включать «process_star_rating.php» в страницы этого сайта не нужно, т.к. этот звёздный рейтинг работает исключительно через AJAX.

Подключение CSS и JavaScript. Настройка URL к PHP файлу

Третий этап – это подключить к своим страницам файлы «star_rating.css» и «star_rating.js».

...
<link rel="stylesheet" href="star_rating.css">
...
<script src="star_rating.js"></script>

При желании вместо этого вы можете включить их содержимое в свои файлы.

Файл «star_rating.css» содержит стили (оформление рейтинга), а «star_rating.js» – логику для обновления данных рейтинга на странице как после загрузки страницы, так и после выполнения оценки. Файл «star_rating.js» написан на JavaScript с применением библиотеки jQuery.

Перед подключением «star_rating.js» его необходимо отредактировать, а именно указать в нём URL к файлу «process_star_rating.php», которое хранится в переменной processURL.

Значение переменной processURL по умолчанию:

processURL = '/process_star_rating.php',  

Вставка HTML-кода рейтинга в необходимые места страниц

Заключительный этап – это вставить HTML-код рейтинга в определённые места страницы и задать ему с помощью атрибута data-id уникальный идентификатор.

<!-- star rating data-id="page-1" -->
<div class="star-rating__container">
  <div class="star-rating__wrapper">
    <div class="star-rating__avg"></div>
      <div class="star-rating" data-id="page-1">
        <div class="star-rating__bg">
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
        </div>
        <div class="star-rating__live">
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="1">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="2">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="3">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="4">
            <path fill="currentColor"

            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="5">
            <path fill="currentColor"
            d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z">
            </path>
          </svg>
        </div>
      </div>
    <div class="star-rating__votes"></div>
  </div>
</div>

Настройка скрипта звёздного рейтинга

Рассмотрим решения некоторых вопросов для адаптации этого рейтинга под свой проект.

1.Как отключить ограничения по IP?

Для отключения проверки пользователя по IP необходимо в файле «process_star_rating.php» установить константе IS_CHECK_IP значение false:

IS_CHECK_IP = false;

После этого возможность у пользователя оценить уже оценённый материал будет ограничено только данными находящимися в Local Storage.

2. Как изменить количество звёзд?

Как изменить количество звёзд в рейтинге, построенном с использованием PHP, MySQL, CSS, JavaScript и SVG

Для того чтобы изменить количество звёзд, например на 10, необходимо выполнить следующие действия.

Изменить HTML код, а именно добавить в каждый из элементов .star-rating__bg и .star-rating__live дополнительно по 5 элементов svg. Звёздам (элементам svg), находящихся в .star-rating__live установить соответствующее значение data-rating.

<div class="star-rating__container">
  <div class="star-rating__wrapper">
    <div class="star-rating__avg"></div>
    <div class="star-rating" data-id="page-8">
      <div class="star-rating__bg">
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
        <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
      </div>
      <div class="star-rating__live">
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="1"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="2"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="3"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="4"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="5"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="6"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="7"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="8"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="9"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="10"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
      </div>
    </div>
    <div class="star-rating__votes"></div>
  </div>
</div>

В «star_rating.js» изменить значение переменной maxStars на 10:

maxStars = 10, 

В «process_star_rating.php» изменить значение константы MAX_RATING на 10:

MAX_RATING = 10,

3. Как установить другой цвет звёздам?

Как изменить цвет звездам в рейтинге

Цвет звёздам задаётся в CSS:

.star-rating__bg {
  color: #e0e0e0; /* фоновый цвет звёздочек */
  display: flex;
}

.star-rating_active:hover .star-rating__live {
  overflow: auto;
  width: 100% !important;
  color: #e0e0e0; /* фоновый цвет звёздочек */
}

.star-rating__live {
  display: flex;
  color: #ffb74d; /* цвет звёздочек для указания текущего рейтинга */
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 0;
}

.star-rating__item_active {
  color: #fb8c00; /* цвет звездочек при наведении на них */
  cursor: pointer;
  transition: color 0.1s ease-in-out;
}

Поэтому чтобы изменить цвет звёзд необходимо заменить данные значения на другие.

4. Как изменить размеры звёзд?

Установка размера звёздам выполняется с помощью CSS:

.star-rating__item {
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
}

Чтобы уменьшить или увеличить размер звёзд вам нужно просто вместо 32px указать другое необходимое значение.

Например, 50px:

.star-rating__item {
  width: 50px;
  height: 50px;
  flex: 0 0 50px;
}

Исходные коды звёздного рейтинга

Скрипт звёздного рейтинга состоит из 3 файлов: «star_rating.css», «star_rating.js» и «process_star_rating.php»:

Содержимое файла «star_rating.css»:

.star-rating__container {
  display: inline-block;
}

.star-rating__wrapper {
  position: relative;
  display: flex;
}

.star-rating {
  display: inline-block;
  position: relative;
  user-select: none;
}

.star-rating__bg {
  color: #e0e0e0;
  display: flex;
}

.star-rating__live {
  display: flex;
  color: #ffb74d;
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 0;
}

.star-rating_active:hover .star-rating__live {
  overflow: auto;
  width: 100% !important;
  color: #e0e0e0;
}

.star-rating__item_active {
  color: #fb8c00;
  cursor: pointer;
  transition: color 0.1s ease-in-out;
}

.star-rating__item {
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
}

.star-rating__avg {
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  text-align: center;
  width: 2em;
}

.star-rating__votes {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-left: 0.5em;
  font-size: 0.875em;
}

Содержимое файла «star_rating.js»:

$(function () {

  var
    processURL = '/process_star_rating.php',
    maxStars = 5,
    output = [],
    ratingStarClass = '.star-rating_active .star-rating__item';
  if (localStorage.getItem('star_rating')) {
    output = JSON.parse(localStorage.getItem('star_rating'));
  }
  $('.star-rating').each(function () {
    var
      _this = this,
      ratingId = $(_this).attr('data-id');
    $.post(processURL, { 'action': 'get_rating', 'id': ratingId })
      .done(function (data) {
        if (data['result'] === 'success') {
          var
            ratingAvg = parseFloat(data['data']['rating_avg']),
            totalVotes = data['data']['total_votes'];
          $(_this).find('.star-rating__live').css('width', ratingAvg.toFixed(1) / maxStars * 100 + '%');
          $(_this).closest('.star-rating__wrapper').find('.star-rating__avg').text(ratingAvg.toFixed(1));
          $(_this).closest('.star-rating__wrapper').find('.star-rating__votes').text('оценок: ' + totalVotes);
          if (data['data']['is_vote'] !== undefined) {
            if (data['data']['is_vote'] === false) {
              if (output.indexOf(ratingId) < 0) {
                $(_this).addClass('star-rating_active');
              }
            }
          } else {
            if (output.indexOf(ratingId) < 0) {
              $(_this).addClass('star-rating_active');
            }
          }
        }
      });
  });

  var starRatingItems = $('.star-rating__live .star-rating__item');
  starRatingItems.on('mouseover', function () {
    var
      rating = $(this).attr('data-rating'),
      items = $(this).closest('.star-rating__live').find('.star-rating__item');
    if (!$(this).closest('.star-rating').hasClass('star-rating_active')) {
      return;
    }
    items.each(function (index, element) {
      if (index < rating) {
        if (!$(element).hasClass('star-rating__item_active')) {
          $(element).addClass('star-rating__item_active');
        } else {
          if ($(element).hasClass('star-rating__item_active')) {
            $(element).removeClass('star-rating__item_active');
          }
        }
      }
    })
  });

  starRatingItems.on('mouseout', function () {
    if (!$(this).closest('.star-rating').hasClass('star-rating_active')) {
      return;
    }
    $(this).closest('.star-rating__live').find('.star-rating__item').removeClass('star-rating__item_active');
  });

  $(document).on('click', ratingStarClass, function (e) {
    e.preventDefault();
    var
      _this = this,
      ratingId = $(_this).closest('.star-rating').attr('data-id'),
      rating = $(_this).attr('data-rating');
    $.post(processURL, { 'action': 'set_rating', 'id': ratingId, 'rating': rating })
      .done(function (data) {
        if (!$.isEmptyObject(data)) {
          if (data['result'] === 'success') {
            var
              ratingAvg = parseFloat(data['data']['rating_avg']),
              totalVotes = data['data']['total_votes'],
              output = [];
            $(_this).closest('.star-rating').removeClass('star-rating_active')
              .find('.star-rating__item_active').removeClass('star-rating__item_active')
              .end().find('.star-rating__live').css('width', ratingAvg.toFixed(1) / maxStars * 100 + '%');
            $(_this).closest('.star-rating__wrapper')
              .find('.star-rating__avg').text(ratingAvg.toFixed(1))
              .end().find('.star-rating__votes').text('оценок: ' + totalVotes);
            if (localStorage.getItem('star_rating')) {
              output = JSON.parse(localStorage.getItem('star_rating'));
            }
            if (output.indexOf(ratingId) < 0) {
              output.push(ratingId);
            }
            localStorage.setItem('star_rating', JSON.stringify(output));
          }
        }
      });
  });
});    

Содержимое файла «process_star_rating.php»:

<?php

const
DB_HOST = 'localhost',
DB_NAME = 'mydb',
DB_CHARSET = 'utf8',
DB_USER = 'root',
DB_PASSWORD = '',
MAX_RATING = 5,
IS_CHECK_IP = false;

function log_write($message)
{
  $log = date('d.m.Y H:i:s') . PHP_EOL . $message . PHP_EOL . '-------------------------' . PHP_EOL;
  file_put_contents('error.log', $log, FILE_APPEND);
}

function getIp()
{
  $keys = [
    'HTTP_CLIENT_IP',
    'HTTP_X_FORWARDED_FOR',
    'REMOTE_ADDR'
  ];
  foreach ($keys as $key) {
    if (!empty($_SERVER[$key])) {
      $ip = trim(end(explode(',', $_SERVER[$key])));
      if (filter_var($ip, FILTER_VALIDATE_IP)) {
        return $ip;
      }
    }
  }
}

if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
  exit(json_encode($output));
}

if ($_SERVER['REQUEST_METHOD'] != 'POST') {
  exit(json_encode($output));
}

$output['result'] = 'error';

$count = 0;
$totalVotes = 1;
if (empty($_POST['id'])) {
  log_write('Не передан id!');
  exit(json_encode($output));
}
$ratingId = filter_var($_POST['id'], FILTER_SANITIZE_STRING);
if (strlen($ratingId) == 0) {
  log_write('Параметр id имеет в качестве значения пустую строку!');
  exit(json_encode($output));
}

try {
  $conn = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET, DB_USER, DB_PASSWORD);
  $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
  log_write('Подключение не удалось: ' . $e->getMessage());
  exit(json_encode($output));
}

switch ($_POST['action']) {
  case 'get_rating':
    $output['data'] = [
      'rating_avg' => 0,
      'total_votes' => 0
    ];
    try {
      $sql = 'SELECT id, rating_avg, total_votes FROM star_rating WHERE rating_id = :rating_id LIMIT 1';
      $result = $conn->prepare($sql);
      $data = ['rating_id' => $ratingId];
      $result->execute($data);
      $row = $result->fetch(PDO::FETCH_ASSOC);
      if ($row) {
        $output['data'] = [
          'rating_avg' => $row['rating_avg'],
          'total_votes' => $row['total_votes']
        ];
        if (IS_CHECK_IP == true) {
          $sql = 'SELECT count(*) FROM star_rating_ip WHERE rating_id = :rating_id AND rating_ip = :rating_ip';
          $result = $conn->prepare($sql);
          $data = ['rating_id' => $row[id], 'rating_ip' => getIp()];
          $result->execute($data);
          $countRows = $result->fetchColumn();
          if ($countRows == 0) {
            $output['data']['is_vote'] = false;
          } else {
            $output['data']['is_vote'] = true;
          }
        }
      }
    } catch (PDOException $e) {
      log_write('Ошибка выборки данных: ' . $e->getMessage());
      break;
    }
    $output['result'] = 'success';
    break;

  case 'set_rating':
    if (empty($_POST['rating'])) {
      log_write('Не получено значение рейтинга!');
      break;
    }
    $id = 0;
    $rating = (int)$_POST['rating'];
    if ($rating < 1 || $rating > MAX_RATING) {
      log_write('Полученное значение рейтинга ' . $rating . ' лежит вне допустимого диапазона!');
      break;
    }
    $ratingAvg = $rating;
    try {
      $sql = 'SELECT id, rating_avg, total_votes FROM star_rating WHERE rating_id = :rating_id LIMIT 1';
      $result = $conn->prepare($sql);
      $data = ['rating_id' => $ratingId];
      $result->execute($data);
      $row = $result->fetch(PDO::FETCH_ASSOC);
      if ($row) {
        $count = 1;
        $id = $row['id'];
        $ratingAvg = $row['rating_avg'];
        $totalVotes = $row['total_votes'];
      }
    } catch (PDOException $e) {
      log_write('Ошибка выборки данных: ' . $e->getMessage());
      break;
    }

    if ($count == 0) {
      try {
        $result = $conn->prepare('INSERT INTO star_rating (rating_id, rating_avg, total_votes) VALUES (:rating_id, :rating_avg, :total_votes)');
        $result->execute(['rating_id' => $ratingId, 'rating_avg' => $ratingAvg, 'total_votes' => $totalVotes]);
        if (IS_CHECK_IP == true) {
          try {
            $sql = 'SELECT id FROM star_rating WHERE rating_id = :rating_id LIMIT 1';
            $result = $conn->prepare($sql);
            $data = ['rating_id' => $ratingId];
            $result->execute($data);
            $row = $result->fetch(PDO::FETCH_ASSOC);
            if ($row) {
              try {
                $result = $conn->prepare('INSERT INTO star_rating_ip (rating_id, rating_value, rating_ip) VALUES (:rating_id, :rating_value, :rating_ip)');
                $result->execute(['rating_id' => $row['id'], 'rating_value' => $rating, 'rating_ip' => getIp()]);
              } catch (PDOException $e) {
                log_write('Ошибка добавления новой записи в таблицу star_rating_ip: ' . $e->getMessage());
                break;
              }
            }
          } catch (PDOException $e) {
            log_write('Ошибка выборки данных: ' . $e->getMessage());
            break;
          }
        }
      } catch (PDOException $e) {
        log_write('Ошибка добавления новой записи в базу: ' . $e->getMessage());
        break;
      }
    } else {
      $ratingAvg = ($ratingAvg * $totalVotes + $rating) / ($totalVotes + 1);
      $totalVotes = $totalVotes + 1;
      if (IS_CHECK_IP == true) {
        $ip = getIp();
        $sql = 'SELECT count(*) FROM star_rating_ip WHERE rating_id = :rating_id AND rating_ip = :rating_ip';
        $result = $conn->prepare($sql);
        $data = ['rating_id' => $id, 'rating_ip' => $ip];
        $result->execute($data);
        $countRows = $result->fetchColumn();
        if ($countRows > 0) {
          break;
        }
        try {
          $result = $conn->prepare('INSERT INTO star_rating_ip (rating_id, rating_value, rating_ip) VALUES (:rating_id, :rating_value, :rating_ip)');
          $result->execute(['rating_id' => $id, 'rating_value' => $rating, 'rating_ip' => $ip]);
        } catch (PDOException $e) {
          log_write('Ошибка добавления новой записи в таблицу star_rating_ip: ' . $e->getMessage());
          break;
        }
      }
      $sql = 'UPDATE star_rating SET rating_avg=:rating_avg, total_votes=:total_votes WHERE rating_id=:rating_id';
      $data = [
        'rating_id' => $ratingId,
        'rating_avg' => $ratingAvg,
        'total_votes' => $totalVotes
      ];
      try {
        $conn->prepare($sql)->execute($data);
      } catch (PDOException $e) {
        log_write('Ошибка добавления записи с rating_id = ' . $ratingId . ': ' . $e->getMessage());
        break;
      }
    }

    $output['result'] = 'success';

    $output['data'] = [
      'rating_avg' => $ratingAvg,
      'total_votes' => $totalVotes
    ];
    break;
}

header('Content-Type: application/json');
exit(json_encode($output));

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

  1. Сергій
    28 января 2021, 07:40
    Добрый день. Подскажите как сделать так чтобы допустим из нескольких рейтингов пользователь мог выбрать только 1 рейтинг из списка, а остальные заблокировались.
    1. Цыганок Анастасия Сергеевна
      30 сентября 2020, 11:58
      Александр, добрый день. Большое спасибо за статью. Очень полезная и написана доступно. Но я столкнулась с такой проблемой. Все настроила и под админом все работает, а вот под обычным пользователем все звездочки желтые и данные по рейтингу не показываются. Я так понимаю что под пользователем не запускается process_star_rating.php. Подскажите, пожалуйста как это исправить?
      1. Александр Мальцев
        30 сентября 2020, 14:00
        Здравствуйте! Спасибо! Для этого необходимо поместить файл «process_star_rating.php» в такое место сайта, чтобы он был доступен для обычного пользователя с фронтенда. Также попробуйте проверить в режиме инкогнито.
        1. Цыганок Анастасия Сергеевна
          01 октября 2020, 15:37
          После нажатия Ctrl+F5 везде перестало работать :(
          1. Александр Мальцев
            01 октября 2020, 15:51
            Так это защита от накрутки. После того как пользователь проголосовал, в его браузер сохраняется соответствующая информация (по умолчанию в LocalStorage). Второй раз проголосовать за этот материал он уже не может. Кроме этой защиты также ещё можно включить защиту по IP (по умолчанию она отключена).
            1. Цыганок Анастасия Сергеевна
              01 октября 2020, 16:48
              Это хорошо что есть защита. Но почему не показывается рейтинг, а просто изображены звездочки желтого цвета?
              1. Александр Мальцев
                03 октября 2020, 01:06
                Тогда нужно разбираться из-за чего это происходит. Посмотрите, что возвращает сервер, если он возвращает всё правильно, то тогда нужно искать проблему на клиенте. Например, на странице у вас могут быть подключены стили, которые переопределяют то, что задано в «star_rating.css» или что-то другое.
                1. Цыганок Анастасия Сергеевна
                  03 октября 2020, 14:24
                  А на мобильном тоже из-за этого может не работать?
                  1. Александр Мальцев
                    03 октября 2020, 14:36
                    Конечно. Откройте инструменты разработчика в браузере и посмотрите что у вас приходит с сервера, есть ли элементы с рейтингом на странице, какие стили к ним применены и т.д.
                    1. Цыганок Анастасия Сергеевна
                      04 октября 2020, 06:55
                      Можете посмотреть, пожалуйста? vseonline.info/
                      Сама разобраться не могу :(
                      1. Александр Мальцев
                        04 октября 2020, 13:21
                        Вам необходимо в файле «star_rating.js» указать протокол http (т.к. используете его), а не https.
                        ...
                        processURL = 'http://vseonline.info/process_star_rating.php',
                        ...
                        
                        1. Цыганок Анастасия Сергеевна
                          06 октября 2020, 19:18
                          Спасибо большое за помощь. Всё получилось настроить. Правда я наоборот включила на сервере https.
                          1. Александр Мальцев
                            08 октября 2020, 13:18
                            Рад, что получилось.
          2. Цыганок Анастасия Сергеевна
            01 октября 2020, 07:08
            Я разместила все три файла в корневом каталоге сайта, остальные же файлы от туда отрабатывают. В режиме инкогнито работает. А в обычном режиме нет.
        2. Сергей
          26 августа 2020, 23:46
          Александр, приветствую! Столкнулся с такой проблемой: дублируется один и тот же рейтинг. Например, я ставлю пять звезд статье, однако этот же рейтинг дублируется на все остальные материалы, где есть возможность поставить оценку. Где может быть ошибка?
          1. Александр Мальцев
            27 августа 2020, 04:11
            Привет! Нужно установить для разных материалов разное значение атрибуту data-id.
            1. Сергей
              27 августа 2020, 13:33
              Спасибо за помощь!
          2. alexandr_k
            26 апреля 2020, 22:50
            Доброго дня, подскажите, пожалуйста, как правильно подключить этот скрипт на Joomla 3?
            Файл process_star_rating.php на вкладке network имеет статус 403 forbidden.
            Спасибо
            1. alexandr_k
              27 апреля 2020, 00:16
              по 403 ошибке вопрос решился.
              Но рейтинг не включается, вкладка network на файле process_star_rating.php показывает

              {«result»:«error»,«data»:{«rating_avg»:0,«total_votes»:0}}
              1. alexandr_k
                27 апреля 2020, 00:30
                Нашел свой косяк, все работает. Скрипт очень полезный, большое спасибо.

                Но, все-таки, если можете, подскажите, пожалуйста, что нужно дописать, чтобы использовать подключение к базе данных средствами Джумлы, без указания имени и пароля?

                1. Александр Мальцев
                  27 апреля 2020, 15:02
                  Отлично! Вам нужно подключить Joomla API к этому внешнему файлу. После этого доработать код используя её функции.
            2. Mish
              02 марта 2020, 22:37
              Скажите пожалуйста как сделать «Вывод ресурсов с самым большим рейтингом», как тут: itchief.ru/lessons/modx-revo/modx-star-rating-for-articles-site
              1. Александр Мальцев
                07 марта 2020, 15:38
                Вы хотите это выполнить для MODX? Если да, то вам нужно из этого решения сначала сделать компонент для MODX. Ну или по крайней мере сгенерировать для него модель.
                1. Mish
                  07 марта 2020, 15:56
                  Да на MODX. Ничего не понял = (
              2. Резников Сергей
                23 февраля 2020, 10:22
                здравствуйте!
                не могу настроить работу звездного рейтинга.
                вот код который на сайте.
                              <!-- --star-rating__container-- -->
                				<div class="star-rating__container">
                				  <div class="star-rating__wrapper"itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
                				    <div class="star-rating__avg" itemprop="ratingValue"></div>
                				      <div class="star-rating" data-id="page-'.$ids.'1">
                				        <div class="star-rating__bg">
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				        </div>
                				        <div class="star-rating__live">
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="1"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="2"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="3"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="4"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				          <svg class="star-rating__item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" data-rating="5"><path fill="currentColor"d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg>
                				        </div>
                				      </div>
                				    <div class="star-rating__votes"></div>
                				  </div>
                				</div>
                              <!-- --star-rating__container-- -->
                              <!-- footer -->
                <link href="../js/rating/with_aggregaterating/jquery-3.4.1.min.js" media="screen">
                <link href="../js/rating/with_aggregaterating/star_rating.js" media="screen">
                    
                стили включены в style.css в header
                
                
                <!-- process_star_rating.php  -->
                const
                DB_HOST = 'localhost',
                DB_NAME = 'vistab_vistablog',
                DB_CHARSET = 'utf8',
                DB_USER = 'vistab',
                DB_PASSWORD = 'y76pK2ecKCbPNcI',
                MAX_RATING = 5,
                IS_CHECK_IP = true;
                
                <!-- star_rating.js  -->
                $(function () {
                
                    var
                        processURL = $global_href.'js/rating/with_aggregaterating/process_star_rating.php',
                
                
                отображается 5 желтых звезд и все. как статика
                1. Александр Мальцев
                  24 февраля 2020, 14:23
                  Проверьте, есть ли какие ошибки в консоли браузере и на вкладке Network для «process_star_rating.php». Так же стоит проверить есть ли ошибки в файле error.log, а также ошибки error_log в Apache или другом веб-сервере, который вы используете. Может просто дело в версии PHP, обычно не тестирую скрипт на версии меньше 7.0.
                  1. Резников Сергей
                    25 февраля 2020, 21:20
                    Добрый вечер! Посмотрел, лог ошибок пустой, PHP Version 7.3.14. Не пойму что не так
                    1. Александр Мальцев
                      26 февраля 2020, 14:04
                      А что в базе? Записи создаются?
                      1. Резников Сергей
                        26 февраля 2020, 14:10
                        Обе базы пустые
                        1. Александр Мальцев
                          26 февраля 2020, 14:21
                          Проверьте по какому URL у вас достпен файл «process_star_rating.php» и задайте его в JavaScript файле:
                          processURL = '/process_star_rating.php', 
                          
                          1. Резников Сергей
                            26 февраля 2020, 14:29
                            Если ввести в адресной строке адрес файла выводится {«result»:«error»}
                            1. Александр Мальцев
                              26 февраля 2020, 14:50
                              Посмотрите, что возвращает «process_star_rating.php» в браузере на вкладке Network.
                              1. Резников Сергей
                                26 февраля 2020, 14:57
                                --------- Headers ---------
                                general
                                Request URL: http:------------------убрал-----------------/process_star_rating.php
                                Request Method: GET
                                Status Code: 200 OK
                                Remote Address: 91.219.194.7:80
                                Referrer Policy: no-referrer-when-downgrade
                                
                                Response Headers
                                Connection: Upgrade, Keep-Alive
                                Content-Encoding: gzip
                                Content-Length: 38
                                Content-Type: text/html; charset=UTF-8
                                Date: Wed, 26 Feb 2020 11:51:35 GMT
                                Keep-Alive: timeout=15, max=100
                                Server: Apache
                                Upgrade: h2,h2c
                                Vary: Accept-Encoding,User-Agent
                                X-Powered-By: PHP/7.3.14
                                
                                Request Headers
                                Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
                                Accept-Encoding: gzip, deflate
                                Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
                                Cache-Control: max-age=0
                                Connection: keep-alive
                                Cookie: __utma=150660145.1318745452.1582714393.1582714393.1582714393.1; __utmc=150660145; __utmz=150660145.1582714393.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none); fid=679de0fe-a998-4308-865f-a478f7f36de7; s=1; _ym_uid=1582714463341127256; _ym_d=1582714463; _ym_isad=2; tmr_lvid=dec317aeca9ca98a10094d75170989d7; tmr_lvidTS=1582714463080; dbl=aa8d3d87aa79428ea59c844cc783b956; fco2r3=aa8d3d87aa79428ea59c844cc783b956; last_visit=1582703677250::1582714477250; tmr_detect=0%7C1582714487788; tmr_reqNum=5
                                Host: ---------------- убрал
                                Upgrade-Insecure-Requests: 1
                                User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
                                
                                --------- Preview ---------
                                {result: "error"}
                                result: "error"
                                
                                --------- Response ---------
                                {result: "error"}
                                
                                1. Александр Мальцев
                                  26 февраля 2020, 15:03
                                  Он должен возвращать JSON. Сохраните файл «process_star_rating.php» в кодировке UTF-8 без BOM.
                2. Andrey
                  06 февраля 2020, 23:58
                  Здравствуйте, подскажите пожалуйста, как можно заменить SVG на иконки к примеру от font awesome?
                  1. Александр Мальцев
                    08 февраля 2020, 16:00
                    Здравствуйте!
                    Просто замените svg-графику на иконки Font Awesome:
                    <div class="star-rating__container">
                      <div class="star-rating__wrapper">
                        <div class="star-rating__avg"></div>
                        <div class="star-rating" data-id="page-1">
                          <div class="star-rating__bg">
                            <i class="star-rating__item fas fa-star"></i>
                            <i class="star-rating__item fas fa-star"></i>
                            <i class="star-rating__item fas fa-star"></i>
                            <i class="star-rating__item fas fa-star"></i>
                            <i class="star-rating__item fas fa-star"></i>
                          </div>
                          <div class="star-rating__live">
                            <i class="star-rating__item fas fa-star" data-rating="1"></i>
                            <i class="star-rating__item fas fa-star" data-rating="2"></i>
                            <i class="star-rating__item fas fa-star" data-rating="3"></i>
                            <i class="star-rating__item fas fa-star" data-rating="4"></i>
                            <i class="star-rating__item fas fa-star" data-rating="5"></i>
                          </div>
                        </div>
                        <div class="star-rating__votes">
                          <div class="star-rating__votes_count"></div>
                          <div class="star-rating__votes_message d-none">Оцени!</div>
                        </div>
                      </div>
                    </div>
                    
                    После этого необходимо будет поправить стили, т.к. ширина изменится и размер звездочек уже нужно устанавливать с помощью font-size:
                    .star-rating__item {
                      width: 32px;
                      height: 32px;
                      font-size: 32px;
                      flex: 0 0 32px;
                    }
                    ...
                    
                    Тут стили уже настраиваете так, как вам нужно.
                  2. Павел
                    16 января 2020, 11:51
                    itemReviewed Необходимо указать значение для поля itemReviewed.
                    Где и что необходимо вписать?
                    1. Александр Мальцев
                      16 января 2020, 13:59
                      А вы к какому объекту добавляете звёздочки?
                      1. Павел
                        16 января 2020, 14:07
                        Вот страница с которой воюю. bienvenidospb.com/tour-1-dia-por-san-petersburgo-en-espanol.html
                        К Product
                        1. Александр Мальцев
                          16 января 2020, 14:27
                          У вас на страницу структурированные данные добавляются с помощью формата JSON-LD. В этом случае так делать нельзя, вам нужно семантическую разметку звёздочек тоже включить в JSON-LD.
                          1. Павел
                            16 января 2020, 15:09
                            Изменил как у вас в примере. Проблема ушла. Спасибо за помощь!
                            Но возник другой вопрос как сделать, чтобы значения ratingValue и reviewCount вставлялись автоматически? Сейчас они прописаны руками в нужные поля.
                            если их удалить — возникают ошибки с разметкой.
                            1. Александр Мальцев
                              16 января 2020, 15:32
                              Они вставляются на страницу с помощью JavaScript. А как нужно?
                              1. Павел
                                16 января 2020, 15:53
                                Если их не вставить вручную то почему при разметки они не видны
                                bienvenidospb.com/tour-2-dias-por-san-petersburgo-en-espanol.html
                                Выдает 2 ошибки
                                1. Александр Мальцев
                                  17 января 2020, 12:50
                                  Инструмент тестирования Google не выполняет JavaScript как Googlebot.
                                  Поэтому ваш ajax-контент не отображается в инструменте.

                                  В этом случае для проверки семантической разметки вам необходимо просто скопировать отрисованный код страницы в инструмент и проверить его.

                                  На данный момент проверить, что Googlebot берёт этот код — это подождать и посмотреть, появиться ли он в отчёте структурированных данных Google или в поиске (в сниппетах).
                    2. Игорь
                      19 ноября 2019, 11:33
                      Отличная статья! Подскажите, а эти звезды индексируются Google? Знаете иногда под статьями при выдачи по запросу отображаются звезды рейтинга.
                      1. Александр Мальцев
                        19 ноября 2019, 15:25
                        Спасибо! Добавил в проект разметку schema.org/AggregateRating. С помощью неё Google будет индексировать звёзды и показывать их в выдачи.
                        Райтинг с микроразметкой AggregateRating находится на GitHub и в архиве проекта в каталоге with_aggregaterating. Рейтинг без микроразметки schema.org находится в корне проекта.
                        1. radiooo
                          20 декабря 2019, 15:16
                          Гугл не видит звезды, можно проверить на странице проверки структурированных данных
                          https://search.google.com/structured-data/testing-tool/u/0/
                          1. Александр Мальцев
                            21 декабря 2019, 03:40
                            Их нужно добавить к какой-нибудь сущности, например, к товару. Этот пример добавлен на Github.
                            Ссылка на проверку.
                            1. alexandr_k
                              27 апреля 2020, 12:06
                              Доброго дня.
                              В вашем примере после отрисовки кода itemprop=«ratingValue» сохраняется. А вот в скрипте по этой ссылке github.com/itchief/StarRating/archive/v.1.0.4.zip itemprop=«ratingValue» исчезает. При этом, itemprop=«reviewCount» остается.

                              1. alexandr_k
                                27 апреля 2020, 13:12
                                у меня глюк какой-то был, теперь не исчезает…
                              2. Павел
                                16 января 2020, 09:12
                                Подскажите, пожалуйста, как их добавить?
                            2. Игорь
                              19 ноября 2019, 16:47
                              Вам спасибо за Ваш труд!
                          2. Александр
                            11 ноября 2019, 15:45
                            Александр, здравствуйте! Отличное руководство, спасибо. Скажите а как в pdoTools и в mFilter2, сортировать по данному рейтингу? Как можно вывести оценку пользователя?

                            И если возможно, есть ли какие преимущества данного способа в плане скорости работы, перед готовыми компонентами рейтинга, такими как LexRating и подобными, если теоретически?

                            1. Александр Мальцев
                              12 ноября 2019, 03:08
                              Привет!
                              Это решение не связано с какой-то CMS. Его можно добавить на любой сайт, даже если он является статическим. Единственное требование — это наличие на хостинге поддержки PHP и MySQL.
                              Чтобы этот звёздный рейтинг связать с какими-то объектами CMS, необходимо всё это конечно прописывать самостоятельно. Например, в MODX нужно будет просто создать компонент (модель для этих таблиц). После этого его можно будет использовать с pdoTools и mFilter2.
                              Про оценку пользователя… Оценку пользователя можно сохранить в Local Storage, а затем её просто выводить. Если нужно сделать это решение именно для авторизированных пользоватей MODX, то это дело конечно нужно дописывать.

                              Про быстродействие… Решение не связанное с CMS, если оно корректно написанное, в любом случае будет работать быстрее. Т.к. не будут выполняться различные проверки и другие механизмы CMS.
                              Если заметили, то это решение выполняется только после загрузки страницы через AJAX. Оно вообще не увеличивается время парсинга страницы. Это первое отличие, если конечно его как-то сравнивать с LexRating. Второе — это то, что звёздочки выполнены с помощью SVG графики. Это означает что звёздочки будут выглядеть отлично на любом устройстве. Кроме этого, это решение позволяет очень просто изменить цвет и размер звёздочек.
                              1. Александр
                                12 ноября 2019, 15:13
                                Спасибо, предельно понятно.
                            Войдите, пожалуйста, в аккаунт, чтобы оставить комментарий.