Ежедневное вознаграждение пользователей за визит

Уважаемые коллеги,

Может кому-то будет полезно описание решения задачи ежедневного вознаграждения пользователей за заход на ЛС-сайт (для версии 1.0.1).

Раньше это уже обсуждали, но, похоже, в 2009ом году была функция User->AutoUpdateUser, а сейчас её уже нет, и, не имея старых сырцов, я не смог найти прямую ей замену (самая ранняя версия файла в GitHub от 2010-го года, там её уже нет).

Я сделал следующее (в моём случае это вынесено в плагин, но там ещё много чего, поэтому отдельно пока не выкладываю), в User.class.php добавил приватную (перестраховался? :)) функцию вознаграждения:
// Вознаградить пользователя, если дата последней активности раньше текущей
private function RewardSiteVisit($oUser, $sDateLast) {
    $todaydate = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
    $datelast = strtotime($sDateLast);

    if($todaydate > $datelast) {
        // в плагине лучше использовать Config::Get('plugin.plugin_name.value_name')) вместо константы
        $oUser->setRating($oUser->getRating() + 1;
	$this->User_Update($oUser);
    }
}


Во-первых, эта функция вызывается в методе User->UpdateSession (обновление данных существующей сессии), для этого в начало метода я добавил следующий вызов:
protected function UpdateSession() {
	$this->RewardSiteVisit($this->oUserCurrent, $this->oSession->getDateLast());
        …


Во-вторых, функция вознаграждения вызывается в методе User->CreateSession (создание сессии при авторизации). Здесь дата предыдущего захода не присутствует в прямом виде, пришлось выуживать:
protected function CreateSession(ModuleUser_EntityUser $oUser,$sKey) {
	$oldSession = $oUser->getSession();
	if($oldSession)
		$this->RewardSiteVisit($oUser, $oUser->getSession()->getDateLast());
        …


Насколько я смог проверить (редактируя SESSION/session_date_last в БД напрямую), работает корректно в следующих ситуациях:
  • Пользователь ходит по сайту, рейтинг не обновляется
  • Пользователь залогинен, но зашёл в первый раз за сегодня, рейтинг обновляется
  • Пользователь не залогинен, но уже заходил сегодня, рейтинг не обновляется
  • Пользователь не залогинен, но зашёл в первый раз сегодня, рейтинг обновляется
  • Пользователь зашёл в первый раз вообще (нет записи о старой сессии), рейтинг не обновляется

PS Буду благодарен за любые отзывы и комментарии о том, верно ли я подошёл к решению задачи.

13 комментариев

avatar
if($todaydate > $datelast) а в данном случае это разве не всегда будет true? Вы же сравниваете секунды, а не дни, допустим?
  • Ell
  • 0
avatar
В session_date_last как раз записывается с часами и т.п. ($oSession->setDateLast(date(«Y-m-d H:i:s»))), так что всё ок.
avatar
А, пардон, я почему-то для себя решил, что это должно работать при заходе раз в сутки, чтобы пользователи не могли «накачивать» себе рейтинг, а то так получается, что при каждом перезаходе идет +к рейтингу, можно скриптами себе догнать его до заоблачных значений…
avatar
Да, оно раз в сутки и работает.

Смотри, если $todaydate = 24 сент 2012 00:00:00, а $datelast = 24 сент 2012 16:30:00, то условие $todaydate > $datelast не сработает. Сам $datelast дальше в этих функциях устанавливается в текущее время при любом телодвижении на сайте.
avatar
Все понял, туплю под вечер =)
avatar
Ну так $todaydate — это полночь сегодняшнего дня. Условие верно, если $datelast — вчерашний день.
avatar
Пользователь не залогинен, но зашёл в первый раз сегодня, рейтинг обновляется
что то не понял, как зафиксируется первый заход за сегодня, если пользователь не залогинен
avatar
при регистрации он залогиневатся хотяб 1 раз
avatar
Да, начисление производится по факту логина (в функции CreateSession). Анонимных пользователей не вознаграждаем :)
avatar
NPC подскажи, а для ласт версии все так же и работает?
avatar
Если под «ласт» ты имеешь в виду 1.0.3, то да, работает. Я уже не помню, делал ли я это для предыдущей, но 1.0.3 незначительно от неё отличалась.
avatar
Я просто вставил этот код между
}
?>

в файле, что находиться здесь \classes\modules\user\User.class.php, а оно, падло, матюкается на ошибку
avatar
Без текста ошибки никто не сможет помочь. К тому же, кроме добавления RewardSiteVisit, ещё надо собственно вызывать эту логику из User->CreateSession и User->UpdateSession (иначе она просто мёртвым грузом будет лежать).
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.