Начнем с того, что пойдем в админку и включим модуль Profile, если он ещё не включен. Для чего это нужно - читаем дальше.
Administer -> User management -> Profile. Тут создаем новое single-line textfield поле, в котором будем указывать сколько очков начислять пользователю за каждое 1000 посещение его ноды. Категорию для этого поля обзываем "Какие-нибудь preferences". Заголовок поля будет, например "Points per 1000 Article views" и его "form name" что-нибудь типа "profile_points". "Visibility" ставим "Public field, content shown on profile page but not used on member list pages." (это потом можно будет убрать). Чтобы админ мог редактировать это поле ему нужно будет зайти в профайл пользователя, там найти кнопку "Какие-нибудь preferences", ввести нужное значение и сохранить. Мы же сохраняем, едем дальше.
Дальше скачаем и установим модуль UserPoints, чтобы сохранять очки пользователя в базу и функционал для того, чтобы не изобретать велосипед.
Идем в настройки этого модуля (Administer -> Site configuration -> Userpoints) и устанавливаем все поинты в 0, нам ведь надо начислять очки только за просмотр, а не написание, комментирование и т.д.
Суть происходящего такова: модуль UserPoints имеет функцию "userpoints_nodeapi()". Это огромное для нас подспорье. Смотрим в код - обрабатываемые этой функцией операции следующие - insert, delete, update. Теперь идем в файлик modules/node/node.module, ищем функцию node_load(), листаем вниз и видим, ага - node_invoke_nodeapi($node, 'load'). А значит это примерно следующее - когда вызывается функция node_load(), а вызывается она часто, то node_invoke_nodeapi() ищет по всем установленным модулям функцию "имя_модуля_nodeapi()" и вызывает её с параметром 'load'. У нас эта функция есть, а обработки параметра 'load' - нету. Что нам остается? Правильно - добавить обработчик операции 'load' в функцию userpoints_nodeapi(). Что и сделаем.
<?php case 'load':
// берем статистику для нашей просматриваемой ноды
$stats_array = statistics_get($node->nid);
// проверяем - есть ли у автора ноды какие-нибудь начисленные очки, а именно когда они были начислены
$result = db_query("SELECT last_update FROM {userpoints} WHERE uid = %d", $node->uid);
if ($last_update_array = db_fetch_array($result))
// если были - сохраняем этот timestamp
$last_update = $last_update_array['last_update'];
else
// если нет - приравниваем его к дате начисления счетчика посещений
$last_update = $stats_array['timestamp'];
if (
// смотрим, есть ли посещения вообще, а то мало ли
$stats_array['totalcount'] &&
// это 1000-е посещение?
$stats_array['totalcount'] % 1000 == 0 &&
// ***
($stats_array['timestamp'] - $last_update > 60*60*24 ||
// это условие говорит о том, что у пользователя до этого не было очков и нам-таки придется ему начислить
$last_update == $stats_array['timestamp']))
{
// загружаем автора ноды
$user = user_load(array('uid' => $node->uid));
// из модуля Profile берем информацию о том сколько начислять нашему автору
profile_load_profile($user);
// если админ не указал сколько начислять - подставляем дефолтовое значение, которое определяем в начале файла userpoints.module
$points = ($user->profile_points) ? $user->profile_points : USERPOINTS_DEFAULT_1000;
// собственно начисляем
_userpoints_update_points($points, $node->uid, "op=$op type=".$node->type);
}
break;
?>
***: Теперь самое непонятное для меня место в этом коде. Проверяем разницу между моментом последнего начисления очков пользователю и моментом зачисления 1000 посещения. Если больше суток (взял из головы), то пропускаем это условие, если нет, то это говорит о следующем.
1) Какой-то чел зашел на страницу и сделал автору 1000 подключений, автору начислили очки.
2) Если чел будет жать F5 - будет вызываться наш обработчик, в котором без этого условия каждый раз начислялись бы очки автору ноды, а зачем это надо?
3) Если зайдет автор статьи, то понятное дело, его посещение не будет зачтено и будет так же 1000 посещений и опять же без этого условия будут начисляться очки.
До конца не понимаю почему так, с утра разберусь.
Несколько моментов. Модуль Profile и модуль UserPoins имеют такие хуки, как _user(). Это говорит нам о том, что когда юзер зайдет на страницу своего профайла он может увидеть сколько у него очков на текущий момент и сколько очков ему будет начисляться за каждое 1000 посещение, что иногда может составлять коммерческую или иную тайну. Выход прост - ищем функции "profile_user()" и "userpoints_user()", комментируем куски кода которые нам эту информацию подсовывают, все.
Комментарии
Хорошая идея для привлечения юзеров. Обязательно сделаю нечто похожее у себя. Спасибо
Полный бред
Вернее, пардон, реализация красивая но зачем это?
Я могу зарегистрироваться с другим акаунтом и зайти сам на свою статью 100 000 000 раз.
Или даже проще, написать скрипт который будет через прокси сервера, меняя IP заходить периодически по данной ссылке на вашем сайте, а скрипт положить например к себе на хостинг.
ИМХО, идея не востребованная — рейтинг, не нужен как класс, вобще.
Если интересно, я могу вам много аргументов привести, отнюдь не в пользу рейтинга автора.
Хотя сделано, повторюсь, изящно и лаконично.
----------------------------------------------------------
Локализация некоторых модулей
Ну тут видишь, от проэкта зависит. Не поспоришь конечно, что накрутить то можно. Знающий человек обойдет все. Мне идея эта пригодилась, попробую сегодня запустить на своем проекте.
Замечания:
1) На ресурсе, который использует данную схему юзеры не могут регистрироваться сами, их регает админ.
2) 100 000 000 раз - из которых засчитается сколько?! Смотрим внимательнее пост, должны пройти сутки с момента последнего посещения страницы.
3) Прокси сервера - это уже лучше, но в данном случае "овчинка выделки не стоит", ибо на этом ресурсе получать очки за 1000 просмотров не единственный и не приоритетный способ.
4) Рейтинг, как класс, нужен именно для моего проекта. Применять его на своих - решать каждому в отдельности.
Уже сделал, я не стал править модуль node, а изменил шаблон коммента. Помимо постинга комментов и статей сделал так же и с просмотром, создал таблицу, в которой хранятся проверенные значения количества просмотров (чтобы не начислять дважды) и проверяю по кратности разницу между текущим количеством и сохраненным. Если же разница есть (сумма просмотров опять набрана), то юзаю функцию из модуля userpoints для начисления дополнительных поинтов:
userpoints_userpointsapi('points', $number_of_points, $uid, $event);
А вывожу в теме коммента, используя опять же его api:
$current_points = userpoints_get_current_points($uid);
Я старался сделать функционал, который будет максимально использовать средства, предложенные самим друпалом.
Была идея с отдельной таблицей, но как оказалось - "зачем?" - если можно включить Access log и не париться. Если по проекту нужно будет считать количество посещений с момента первого захода на страницу - тогда да, будем делать по-другому, о чем и напишем непременно.
есть более сурьозное решение для похожей задачи?