Je suis en train de penser à la meilleure façon de concevoir un système de succès pour l'utiliser sur mon site. La structure de base de données peut être trouvé à MySQL: la Meilleure façon de dire 3 ou plus consécutifs enregistrements manquants et ce fil est vraiment une extension pour obtenir les idées des développeurs.
Le problème que j'ai avec beaucoup de parler de badges/réalisation de systèmes sur ce site est juste que -- c'est parler et sans code. Où est le code réel, la mise en œuvre des exemples?
Je vous propose ici une conception que j'espère que les gens pourraient contribuer et nous espérons créer un bon design pour le codage extensible réalisation des systèmes. Je ne dis pas que c'est le meilleur, loin de là, mais c'est un départ possible de bloquer.
N'hésitez pas à apporter vos idées.
mon système d'idée de la conception
Il semble que le consensus général est de créer un "événement en fonction système" -- chaque fois qu'un événement connu se produit comme un poste est créé, supprimé, etc il appelle la classe d'événements comme si..
$event->trigger('POST_CREATED', array('id' => 8));
La classe event puis découvre ce que les badges sont "à l'écoute" pour cet événement, il requires
le fichier, et crée une instance de cette classe, comme ceci:
require '/badges/' . $file;
$badge = new $class;
Il appelle ensuite l'événement par défaut de transmettre les données reçues lors de l' trigger
a été appelé;
$badge->default_event($data);
les badges
C'est alors là que la vraie magie se produit. chaque badge a sa propre requête/logique pour déterminer si un badge devrait être accordée. Chaque badge est définie dans ce format:
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
de la fonction provient d'une classe étendue Badge
qui, fondamentalement, vérifie si l'utilisateur a déjà décerné le badge, si non, va mettre à jour l'insigne de la table db. L'insigne de classe prend également soin de récupérer tous les badges pour l'utilisateur et de le retourner dans un tableau, etc (donc les badges peuvent être affichés sur le profil de l'utilisateur)
qu'en est-il du système est très d'abord mis en œuvre sur un site en ligne?
Il y a aussi un "cron" emploi requête qui peut être ajouté à chaque badge. La raison pour cela est parce que quand le système de badge est très d'abord mis en œuvre et initilaised, les badges qui aurait déjà été gagnés n'ont pas encore être accordé parce que c'est un événement à partir du système. Si une tâche est exécutée à la demande pour chaque badge à prix tout ce qui doit être. Par exemple, la tâche CRON pour le ci-dessus ressemblerait à:
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);
}
}
}
Comme ci-dessus cron classe étend la principale insigne de classe, il peut ré-utiliser la fonction logique, try_award
La raison pour laquelle j'ai créer un spécialisé requête pour c'est bien que l'on puisse "simuler" les événements précédents, c'est à dire passer par chaque utilisateur de poste et de déclencher l'événement de classe comme $event->trigger()
il serait très lente, en particulier pour de nombreux badges. Nous avons donc au lieu de créer une optimisation de requête.
ce que l'utilisateur obtient le prix? tout à propos de l'attribution des autres utilisateurs sur la base de l'événement
L' Badge
classe award
fonction agit sur user_id
-- ils seront toujours donné le prix. Par défaut, le badge est attribué à la personne qui a CAUSÉ l'événement de se produire c'est à dire l'utilisateur de la session id (ce qui est vrai pour l' default_event
de la fonction, bien que la tâche CRON évidemment une boucle par tous les utilisateurs et les prix de séparer les utilisateurs)
Donc, nous allons prendre un exemple, sur un codage de site web du défi utilisateurs de soumettre leurs codage d'entrée. L'administrateur alors les juges les entrées et lorsqu'ils ont terminé, les résultats sont affichés pour le défi page pour que tous puissent les voir. Lorsque cela se produit, un POSTED_RESULTS événement est appelé.
Si vous voulez attribuer des badges pour les utilisateurs de toutes les écritures validées, permet de dire que, s'ils ont été classés dans le top 5, vous devez utiliser le cron job (bien que bare à l'esprit cette volonté de mise à jour pour tous les utilisateurs, pas seulement pour ce défi, les résultats ont été affichés pour)
Si vous souhaitez cibler une zone plus précise de mise à jour avec le cron job, nous allons voir si il existe un moyen d'ajouter des fonctions de filtrage des paramètres dans le cron objet de travail, et d'obtenir le cron_job la fonction à utiliser. Par exemple:
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);
}
}
La fonction cron fonctionne même si le paramètre n'est pas fourni.