Ben sitemde kullanmak için bir başarıları sistemi tasarımı için en iyi yolu düşünüyorum. Veritabanı yapısı MySQL: Best way to tell 3 or more consecutive records missing bulunabilir ve bu konu gerçekten geliştiricilerin fikirlerini almak için bir uzantısıdır.
Ben bu sitede rozetleri / başarı sistemleri hakkında konuşmak bir sürü var sorun sadece - tüm konuşma ve hiçbir kod bulunuyor. Nerede gerçek kod Gerçekleştiren örnekleri var?
Ben burada insanlar katkı ve umarım genişletilebilir başarı kodlama sistemleri için iyi bir tasarım oluşturmak umuyoruz bir tasarım öneriyoruz. Ben bu kadar ondan, iyi olduğunu söylemiyorum, ama olası bir başlangıç blok bulunuyor.
Fikirlerinizi katkıda çekinmeyin.
my system design idea
Bu genel bir fikir birliği, bir "olay tabanlı sistem" yaratmak gibi görünüyor - bu gibi pek olay sınıfı çağıran bilinen bir olay, bir yazı gibi oluşunca oluşturulan, silinmiş, vb ..
$event->trigger('POST_CREATED', array('id' => 8));
Olay sınıfı daha sonra da requires
bu dosya, ve böylece gibi, bu sınıfın bir örneğini oluşturur, bu olay için rozetleri "dinleme" ne olduğunu bulur:
require '/badges/' . $file;
$badge = new $class;
Daha sonra verileri geçirmeden varsayılan olay trigger
çağrıldığında aldı çağırır;
$badge->default_event($data);
the badges
Bu daha sonra gerçek sihirli olur nerede. Her rozet rozet layık gerektiğini belirlemek için kendi sorgu / mantığı vardır. Her rozet örneğin ortaya konmaktadır Bu 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
işlevi temelde kullanıcı zaten rozet, değilse, rozet db tablosunu güncelleştirmek olacağı verilebilecek olup olmadığını görmek için denetler uzun bir sınıf Badge
geliyor. Rozeti sınıfı da (yani rozetler örneğin kullanıcı profili görüntülenir olabilir) bir kullanıcı için tüm rozetleri almak ve bir dizi, vb iade önemser
what about when the system is very first implemented on an already live site?
Her rozet eklenebilir bir "cron" iş sorgusu da vardır. Rozet sistemi ilk uygulanan ve initilaised olduğunda bu olay tabanlı bir sistem olduğu için, zaten kazanılmış olmalıdır rozetleri henüz layık olamaz çünkü bunun nedeni budur. Yani CRON iş olması gerekir ödül şey her rozet için talep üzerine çalışır. Örneğin yukarıda için CRON iş gibi görünecektir:
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);
}
}
}
Yukarıdaki cron sınıf ana rozeti sınıfını genişleten gibi, bu mantık işlevini yeniden kullanabilirsiniz try_award
Daha önceki olayları "taklit" olabilir, ancak ben bunun için özel bir sorgu oluşturmak nedeni de budur, yani her kullanıcının mesaja geçmesi ve $event->trigger()
özellikle birçok rozetleri için, çok yavaş olacak gibi olay sınıfı tetikleyebilir. Bu yüzden yerine optimize sorgusu oluşturun.
Olaya dayanan what user gets the award? all about awarding other, kullanıcıların strong>
Onlar her zaman ödül verilecek - Badge
class award
fonksiyonu user_id
davranır. Varsayılan rozeti (CRON iş Açıkçası tüm kullanıcılar ve ödüller ayrı kullanıcıların aracılığıyla döngüler rağmen bu, default_event
fonksiyonu için geçerlidir) oturumu kullanıcı kimliği yani gerçekleşmesi olayı SEBEP kişiye verilir
Bir kodlama zorluk web sitesi, kullanıcıların kendi kodlama giriş göndermek üzerine Yani, bir örnek verelim. Admin sonra tüm görmek için meydan sayfasına girişleri ve tamamlandığında, mesajlarını sonuçları yargılar. Bu durumda, bir POSTED_RESULTS olay olarak adlandırılır.
Çıplak aklında bu tüm kullanıcılar için güncelleme rağmen deftere tüm girişler için kullanıcılar için ödül rozetleri istiyorsanız onlar ilk 5 içinde sıralanır olsaydı, diyelim, o meydan için değil sadece, (cron işi kullanmalısınız sonuç) için yazılmıştır
Eğer cron ile güncelleştirmek için daha spesifik bir bölgeyi hedeflemek istiyorsanız, cron iş nesnesine filtre parametreleri eklemek için bir yol olup olmadığını görelim, ve cron_job fonksiyon onları kullanmak olsun. Örneğin:
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);
}
}
Parametre sağlanmazsa bile cron fonksiyonu hala çalışacaktır.