Currently, I'm working on gamification platform and I have the following rules for achieving a new level:
- Level 0: When user registers
- Level 1: When user confirms account
- Level 2: When user completes a quiz
- Level 3: When user completes a mission and publish more than 5 comments in the blog
- Level 4: When user completes more than two missions and completes a campaign (campaign means donating money for something)
- Level 5: Raised at least $50 in campaigns and complete at least two campaigns
Now, I have the following database where I'll keep a track of each user action (e.g. complete_quiz
, complete_mission
, etc.):
Achievements
id
(int
)event
(varchar
)amount
(int
) # used when event has specific value, e.g. money forcomplete_campaign
eventuser_id
(int
)date_created
(int
)
When the user make any action (e.g. complete_mission
), I'll insert the action in the table above and will call the following method to check if user has new level unlocked:
public function checkIfAchievmentUnlocksNewLevel($userObj)
{
$currentLevel = $userObj->level;
$nextLevel = ++$currentLevel
$isLevelUnlocked = false;
switch($nextLevel)
{
case 0:
case 1:
// Each registered user will have these levels by default.
break;
case 2:
$completedQuiz = $this->db->select("SELECT " . $this->fieldsList . " FROM " . $this->table . " WHERE event = :event AND user_id = :user_id ", array(':event' => 'complete_quiz', ':user_id' => $userObj->id));
$isLevelUnlocked = count($completedQuiz) ? true : false;
break;
case 3:
$completedMissions = $this->db->select("SELECT " . $this->fieldsList . " FROM " . $this->table . " WHERE event = :event AND user_id = :user_id", array(':event' => 'complete_mission', ':user_id' => $userObj->id));
$wildwireComments = $this->db->select("SELECT " . $this->fieldsList ." FROM " . $this->table . " WHERE event = :event AND user_id = :user_id", array(':event' => 'wildwire_comment', ':user_id' => $userObj->id));
$isLevelUnlocked = (count($completedMissions) && count($wildwireComments) >= 5) ? true : false;
break;
case 4:
$completedMissions = $this->db->select("SELECT " . $this->fieldsList . " FROM " . $this->table . " WHERE event = :event AND user_id = :user_id", array(':event' => 'complete_mission', ':user_id' => $userObj->id));
$completedCampaigns = $this->db->select("SELECT " . $this->fieldsList ." FROM " . $this->table . " WHERE event = :event AND user_id = :user_id", array(':event' => 'complete_campaign', ':user_id' => $userObj->id));
$isLevelUnlocked = (count($completedMissions) >= 2 && count($completedCampaigns)) ? true : false;
break;
case 5:
$campaignRaisedMoney = $this->db->select("SELECT SUM(amount) FROM " . $this->table . " WHERE event = :event AND user_id = :user_id", array(':event' => 'complete_campaign', ':user_id' => $userObj->id));
$completedCampaigns = $this->db->select("SELECT " . $this->fieldsList ." FROM " . $this->table . " WHERE event = :event AND user_id = :user_id", array(':event' => 'complete_campaign', ':user_id' => $userObj->id));
$isLevelUnlocked = (count($compaignRaisedMoney) >= 50.00 && count($completedCampaigns) >= 2) ? true : false;
break;
}
if($isLevelUnlocked)
{
$userHelper->setLevel($nextLevel);
}
}
This code is working now, but I want to refactor it and am looking for any suggestions on how to improve it.