Я думаю о лучшем способе разработки системы достижений для использования на моем сайте. Структура базы данных может быть найдена в Best way to tell 3 or more consecutive records missing, и эта тема действительно является расширением для получения идей от разработчиков.Лучший способ кода Система достижений
Проблема, с которой я сталкиваюсь с большим количеством разговоров о знаках/системах достижений на этом веб-сайте, - это все разговоры и отсутствие кода. Где примеры реализации кода?
Я предлагаю здесь дизайн, который я надеюсь, что люди могут внести свой вклад и, надеюсь, создать хороший дизайн для кодирования расширяемых систем достижений. Я не говорю, что это самое лучшее, далеко от него, но это возможный стартовый блок.
Пожалуйста, не стесняйтесь вносить свои идеи.
мой дизайн системы идея
Кажется, по общему мнению, чтобы создать «систему, основанную событие» - всякий раз, когда известное событие происходит, как пост создан, удален и т.д. он вызывает класс событий, как так ..
$event->trigger('POST_CREATED', array('id' => 8));
класс событий, то узнает, что значки «прослушивание» для этого события, то это requires
, что файл, и создает экземпляр этого класса, например, так:
require '/badges/' . $file;
$badge = new $class;
Затем он вызывает событие по умолчанию, передающее данные, полученные при вызове trigger
;
$badge->default_event($data);
знаки
Это то, где реальное волшебство происходит. каждый значок имеет свой собственный запрос/логику, чтобы определить, должен ли быть отмечен значок. Каждый значок указан в, например, этот формат:
class Badge_Name extends Badge
{
const _BADGE_500 = 'POST_500';
const _BADGE_300 = 'POST_300';
const _BADGE_100 = 'POST_100';
function get_user_post_count()
{
$escaped_user_id = mysql_real_escape_string($this->user_id);
$r = mysql_query("SELECT COUNT(*) FROM posts
WHERE userid='$escaped_user_id'");
if ($row = mysql_fetch_row($r))
{
return $row[0];
}
return 0;
}
function default_event($data)
{
$post_count = $this->get_user_post_count();
$this->try_award($post_count);
}
function try_award($post_count)
{
if ($post_count > 500)
{
$this->award(self::_BADGE_500);
}
else if ($post_count > 300)
{
$this->award(self::_BADGE_300);
}
else if ($post_count > 100)
{
$this->award(self::_BADGE_100);
}
}
}
award
функция исходит из расширенного класса Badge
, который в основном проверяет, чтобы увидеть, если пользователь уже присуждаются этот жетон, если нет, то будет обновлять таблицу значок дб. Класс значков также заботится о том, чтобы получить все значки для пользователя и вернуть его в массив и т. Д. (Так что значки могут отображаться, например, в профиле пользователя)
о том, когда система была впервые реализована на уже живой сайт?
Существует также запрос задания «cron», который может быть добавлен к каждому значку. Причина этого в том, что, когда система значков вначале реализована и инициализирована, значки, которые должны были быть заработаны, еще не были присуждены, поскольку это система, основанная на событиях. Таким образом, задание CRON запускается по требованию для каждого значка для награждения всего, что должно быть. Например, работа CRON для выше, будет выглядеть следующим образом:
class Badge_Name_Cron extends Badge_Name
{
function cron_job()
{
$r = mysql_query('SELECT COUNT(*) as post_count, user_id FROM posts');
while ($obj = mysql_fetch_object($r))
{
$this->user_id = $obj->user_id; //make sure we're operating on the right user
$this->try_award($obj->post_count);
}
}
}
Как выше класс хрон расширяет основной класс значок, он может повторно использовать логическую функцию try_award
причина, почему я создаю специализированные запрос для этого - хотя мы могли бы «имитировать» предыдущие события, т. е.пройти каждый пользовательский пост и вызвать класс события, например $event->trigger()
, это будет очень медленно, особенно для многих значков. Поэтому мы вместо этого создаем оптимизированный запрос.
какой пользователь получает награду? все о присуждении других пользователей на основе события
Badge
В классе award
функция действует на user_id
- они всегда будут даны награда. По умолчанию значок присваивается лицу, которое ВЫЗЫВАЛО событие, т.е. идентификатор пользователя сеанса (это верно для функции default_event
, хотя работа CRON, очевидно, проходит через всех пользователей и наделяет отдельными пользователями)
Так что давайте возьмем Например, пользователи веб-сайта, посвященные кодированию, отправляют свои записи в кодировку. Затем администратор оценивает записи и по завершении отправляет результаты на страницу запроса, чтобы все могли видеть. Когда это происходит, вызывается событие POSTED_RESULTS.
Если вы хотите награждать значки для пользователей за все опубликованные записи, скажем, если они были ранжированы в верхней пятерке, вы должны использовать работу cron (хотя, конечно, это будет обновление для всех пользователей, а не только для этой задачи были опубликованы результаты)
Если вы хотите настроить таргетинг на более конкретную область для обновления с помощью задания cron, давайте посмотрим, есть ли способ добавить параметры фильтрации в объект задания cron и получить cron_job чтобы использовать их. Например:
class Badge_Top5 extends Badge
{
const _BADGE_NAME = 'top5';
function try_award($position)
{
if ($position <= 5)
{
$this->award(self::_BADGE_NAME);
}
}
}
class Badge_Top5_Cron extends Badge_Top5
{
function cron_job($challenge_id = 0)
{
$where = '';
if ($challenge_id)
{
$escaped_challenge_id = mysql_real_escape_string($challenge_id);
$where = "WHERE challenge_id = '$escaped_challenge_id'";
}
$r = mysql_query("SELECT position, user_id
FROM challenge_entries
$where");
while ($obj = mysql_fetch_object($r))
{
$this->user_id = $obj->user_id; //award the correct user!
$this->try_award($obj->position);
}
}
Функция cron будет работать, даже если параметр не указан.
Связанный (может быть, дубликат): http://stackoverflow.com/questions/1744747/achievements-badges-system – Gordon
Это связано, но не дублируется. Прочтите второй абзац. «Проблема, с которой я сталкиваюсь с большим количеством разговоров о системах значков/достижений на этом веб-сайте, - это все - разговоры и отсутствие кода. Где примеры реализации кода?» –
хорошо, письменный рабочий код возможен только в определенной степени. Я бы сказал, что для людей достаточно просто дать вам теорию, только когда любая реализация будет слишком сложной. – Gordon