Başarılar sistemi kod için en iyi yol

0 Cevap php

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

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.

0 Cevap