diff --git a/app/controllers/SeminaryController.inc b/app/controllers/SeminaryController.inc index 7574d455..8b722e33 100644 --- a/app/controllers/SeminaryController.inc +++ b/app/controllers/SeminaryController.inc @@ -93,7 +93,8 @@ $this->checkPermission($request, $response); // Check achievements - $this->checkAchievements($request, $response); + $this->checkAchievements($request, $response, 'date'); + $this->checkAchievements($request, $response, 'achievement'); // Set Seminary and Character data $this->set('loggedSeminary', self::$seminary); @@ -148,7 +149,7 @@ /** * Check for newly achieved Achievements. */ - private function checkAchievements(\nre\core\Request $request, \nre\core\Response $response) + protected function checkAchievements(\nre\core\Request $request, \nre\core\Response $response, $checkConditions=null) { // Do not check MediaController if($this->request->getParam(0, 'toplevel') != \nre\configs\AppConfig::$defaults['toplevel']) { @@ -160,6 +161,11 @@ return; } + // Set conditions to check + if(!is_null($checkConditions) && !is_array($checkConditions)) { + $checkConditions = array($checkConditions); + } + // Get unachieved Achievments $achievements = $this->Achievements->getUnachhievedAchievementsForCharacter(self::$seminary['id'], self::$character['id']); if(in_array('user', self::$character['characterroles'])) { @@ -169,6 +175,11 @@ // Check conditions foreach($achievements as &$achievement) { + // Check condition to test + if(!is_null($checkConditions) && !in_array($achievement['condition'], $checkConditions)) { + continue; + } + // Check deadline if(!is_null($achievement['deadline']) && $achievement['deadline'] < date('Y-m-d H:i:s')) { continue; diff --git a/controllers/QuestgroupsController.inc b/controllers/QuestgroupsController.inc index 3d24a678..8eb03d38 100644 --- a/controllers/QuestgroupsController.inc +++ b/controllers/QuestgroupsController.inc @@ -73,10 +73,14 @@ // Check permission if(count(array_intersect(array('admin','moderator'), SeminaryController::$character['characterroles'])) == 0) { - $previousQuestgroup = $this->Questgroups->getPreviousQuestgroup($questgroup['id']); - if(!is_null($previousQuestgroup)) { - if(!$this->Questgroups->hasCharacterSolvedQuestgroup($previousQuestgroup['id'], $character['id'])) { - throw new \nre\exceptions\AccessDeniedException(); + // Only check permissions if Character has not entered Quest before + if(!$this->Questgroups->hasCharacterEnteredQuestgroup($questgroup['id'], $character['id'])) + { + $previousQuestgroup = $this->Questgroups->getPreviousQuestgroup($questgroup['id']); + if(!is_null($previousQuestgroup)) { + if(!$this->Questgroups->hasCharacterSolvedQuestgroup($previousQuestgroup['id'], $character['id'])) { + throw new \nre\exceptions\AccessDeniedException(); + } } } } diff --git a/controllers/QuestsController.inc b/controllers/QuestsController.inc index 2d7fda45..c506219b 100644 --- a/controllers/QuestsController.inc +++ b/controllers/QuestsController.inc @@ -53,6 +53,21 @@ + /** + * Prefilter that is executed before running the Controller. + * + * @param Request $request Current request + * @param Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + $this->checkAchievements($request, $response, array('character', 'quest')); + $this->checkAchievements($request, $response, 'achievement'); + } + + /** * Action: index. * diff --git a/models/QuestgroupsModel.inc b/models/QuestgroupsModel.inc index b95389c0..111fd967 100644 --- a/models/QuestgroupsModel.inc +++ b/models/QuestgroupsModel.inc @@ -318,8 +318,7 @@ /** - * Determine if the given Character has solved the Quests form - * this Questgroup. + * Determine if the given Character has solved a Questgroup. * * @param int $questgroupId ID of Questgroup to check * @param int $characterId ID of Character to check @@ -330,39 +329,20 @@ // Get data of Questgroup $questgroup = $this->getQuestgroupById($questgroupId); - // Chack all Quests - $currentQuest = $this->Quests->getFirstQuestOfQuestgroup($questgroup['id']); - if(!is_null($currentQuest)) + // Check last Quest(s) + $solvedLastQuest = false; + $lastQuests = $this->Quests->getLastQuestsOfQuestgroup($questgroup['id']); + foreach($lastQuests as &$lastQuest) { - if(!$this->Quests->hasCharacterSolvedQuest($currentQuest['id'], $characterId)) { - return false; - } - - // Get next Quests - $nextQuests = !is_null($currentQuest) ? $this->Quests->getNextQuests($currentQuest['id']) : null; - while(!is_null($currentQuest) && !empty($nextQuests)) + if($this->Quests->hasCharacterSolvedQuest($lastQuest['id'], $characterId)) { - // Get choosed Quest - $currentQuest = null; - foreach($nextQuests as &$nextQuest) { - if($this->Quests->hasCharacterEnteredQuest($nextQuest['id'], $characterId)) { - $currentQuest = $nextQuest; - } - } - - // Check Quest - if(is_null($currentQuest)) { - return false; - } - - // Check status - if(!$this->Quests->hasCharacterSolvedQuest($currentQuest['id'], $characterId)) { - return false; - } - - $nextQuests = !is_null($currentQuest) ? $this->Quests->getNextQuests($currentQuest['id']) : null; + $solvedLastQuest = true; + break; } } + if(!$solvedLastQuest) { + return false; + } // Check all child Questgroups $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); diff --git a/models/QuestsModel.inc b/models/QuestsModel.inc index f7141efc..d87deff9 100644 --- a/models/QuestsModel.inc +++ b/models/QuestsModel.inc @@ -137,6 +137,29 @@ } + /** + * Get all Quests a Qusetgroup that do not have a following + * Quest. + * + * @param int $questId ID of Questgroup + * @return array List of last Quests + */ + public function getLastQuestsOfQuestgroup($questgroupId) + { + return $this->db->query( + 'SELECT id, questtype_id, title, url, xps, task '. + 'FROM quests '. + 'WHERE questgroup_id = ? AND NOT EXISTS ('. + 'SELECT quest_id '. + 'FROM quests_previousquests '. + 'WHERE quests_previousquests.previous_quest_id = quests.id'. + ')', + 'i', + $questgroupId + ); + } + + /** * Get Quests that follow-up a Quest. *