ILoveYAnny
@ILoveYAnny

Как организовать возможность какого-либо действия пользователя 5 раз в 3 суток?

Добрый день, передо мной стоит следующая задача. Есть таблица в которой распечатаны пользователя, за каждого пользователя можно проголосовать ( голосовать могут только зарегистрированные пользователи). Голосовать можно 5 раз за 3-е суток. Таблица очень важная , она ранжируется по голосам, у кого больше тот наверху поэтому на стороне браузера хранить информацию нельзя, т.к. если стереть куки то можно голосовать бесконечно и весь проект загнётся. Обрабатывать нужно только на сервере, идея возникла следующая, хранить в бд в строке конкретного пользователя :

1) Дату первого голосования
2) Дата попытки проголосовать
3) Счётик голосов

Логика был такая
Когда счётчик набирает 5 голосов, до следующего периода голосовать нельзя, следующий период определялся так :
Если модуль разности "Дата первого голосования" - "Дата попытка проголосовать" делиться на 3 без остатка, то значит прошло 3 дня и можно счётчик обнулять.

Например
(Пример А) Первый голосов был 5 числа, а попытка последняя была 6, ток 5-6 =1(модуль), а 1 на 3 не делится без остатка.
(Пример Б) А если первая была 5 а последняя 8 числа, то 5-8=3(модуль), 3 делится и очевидно что 3 дня с 5 числа прошло.

Дак вот у меня проблема возникла, программа будет бесконечно счётчик обновлять в день начала нового периода, как заставить её обновить только один раз в Примере Б.

Я понимаю что решения на первый взгляд это Сron, однако пользователей тысяча , они будут постоянно голосовать в течении месяца. То есть программа должна отслеживать каждого и корректно считать, как это сделать Кроном я не представляю. Была мысль ставить средствами PHP задачи Cron'у, но почитав в инете понял что этого сделать не льзя. В общем друзья, помогите пожалуйста совсем в тупике упёрся в одну точку, а решить проблему нужно..
  • Вопрос задан
  • 477 просмотров
Решения вопроса 1
Не нужно никакого Cron`а и хранения попыток проголосовать.
Создаете табличку, где будут логгироваться голоса:
CREATE TABLE IF NOT EXISTS `votes_log` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

При попытке проголосовать делаете запрос в базу:
SELECT COUNT(*) FROM `votes_log` WHERE date > DATE_SUB(NOW(), INTERVAL 3 DAY) AND user_id=?

Этот запрос возвращает сколько раз проголосовал пользователь за последние 3 суток.
Если меньше 5-ти - принимаем голос (и записываем в эту таблицу).
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
ммм.... откуда тут взялся cron.... просто храните даты голосований, заведите отдельную табличку куда сваливайте кто, за кого и когда проголосовал. Далее простая проверка.
Ответ написан
Комментировать
saboteur_kiev
@saboteur_kiev
software engineer
Я не очень понимаю, почему вы делите разность даты на три?

Почему бы просто не отнять от текущей даты (пользователь пытается проголосовать) дату первого голосования, и если она меньше 3 дней, то едем дальше - проверяем лимит голосов, если он меньше 5, тогда голосуем. Если больше - все.

Если же дата больше 3 дней, то счетчик обнуляется, производим голосованием и в базу записываем дату этого голосования, от которого будет отсчитываться 3 дня.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы