Подгрузка контента AJAX-PHP

Рейтинг: 0Ответов: 1Опубликовано: 14.03.2015

Есть сайт - новостной портал.

Новости могут отображаться двумя способами (пользователь выбирает в настройках): обычный постраничный вывод и подгрузка при прокрутке до конца страницы.

Если с первым проблем нет, то со вторым возникли некоторые сложности. В частности, с сортировкой новостей.

Если мы выводим новости просто по порядку их ID, то проблем нет. Передаём через ajax в php скрипт ID последней и выводим следующую порцию новостей, у которых ID меньше, чем передан.

Если же у каждой новости есть свой рейтинг и вывод должен осуществляться по количеству рейтинга, то возникают сложности с синхронизацией или... не знаю, как это назвать. Каждый пользователь может изменить рейтинг новости, кликнув по новости, идёт запись в БД и соответственно рейтинг новости увеличивается или уменьшается.

Пример возникающей проблемы. Есть новости с определённым рейтингом:

Новость 1 - рейтинг 10

Новость 2 - рейтинг 9

Новость 3 - рейтинг 8

Новость 4 - рейтинг 2

Новость 5 - рейтинг 1

Новость 6 - рейтинг 0

Новость 7 - рейтинг 0

Новость 8 - рейтинг 1

Допустим, при открытии страницы, пользователь видит 4 новости, то есть:

Новость 1 - рейтинг 10

Новость 2 - рейтинг 9

Новость 3 - рейтинг 8

Новость 4 - рейтинг 2

Соответственно переменная offset (смещение), которую будем передавать в ajax - равна 4.

Если пользователь просто прокрутит страницу до конца, не меняя рейтинг новостей и другие пользователи в этот момент не меняют рейтинг новостей, то проблемы не возникнет, произойдёт подгрузка новостей со смещения 4 и потом в переменную offset запишется новое значение для следующей подгрузки, если ещё остались новости.

НО, если же, пока пользователь видит только 4 новости, другие пользователи или он сам изменят рейтинг новости (например, у новости 4 рейтинг станет 0), то соответственно она будет подгружена второй раз, то есть будут подгружены новости 5,4,6,7, а не 5,6,7,8.

Код запроса:

SELECT p.*
FROM posts p
ORDER BY p.rating DESC
LIMIT $limit OFFSET $ofset

Как быть? Можно, конечно, после подгрузки, пробежаться по всем записям в DOM и удалить повторяющиеся, но этот вариант заведомо провальный, а всё остальное пока мне не даёт нужного результата.

Ответы

▲ 1

Общая идея решения, чтобы разделить посты и рейтинги по разным таблицам, то есть таблица рейтинга будет иметь вид:

| id | post_id | datetime         | value |
| 1  | 1       | 2015-03-20 10:00 | 5     |
| 2  | 1       | 2015-03-20 12:00 | -1    |
| 3  | 1       | 2015-03-20 15:00 | 3     |
| 4  | 1       | 2015-03-20 16:00 | -2    |

Тогда можно расчитать рейтинг на конкретный период времени, указав время:

SELECT sum(value) FROM rating WHERE datetime < '2015-03-20 15:00' GROUP BY post_id

Теперь объединяем все вместе:

SELECT
    p.*, (SELECT
        sum(value)
    FROM rating
    WHERE datetime < {$date}
    AND post_id = p.id) AS rating
ORDER BY rating DESC
LIMIT 5 OFFSET {$offset}

Параметры {$date} и {$offset} присылает пользователь date - это дата, для которой происходит расчет рейтинга.