From d49bc7261a9d0bb06188e10e565c27f4360cac16 Mon Sep 17 00:00:00 2001 From: coderkun Date: Tue, 4 Mar 2014 03:16:02 +0100 Subject: [PATCH] implement permissions for Questgroups, Quests and Sidequests --- controllers/QuestgroupsController.inc | 33 +++++- controllers/QuestsController.inc | 82 ++++++++++++- controllers/SeminariesController.inc | 12 +- models/QuestgroupsModel.inc | 164 ++++++++++++++++++++++++++ models/QuestsModel.inc | 46 +++++++- views/html/questgroups/questgroup.tpl | 17 ++- views/html/quests/quest.tpl | 12 +- views/html/seminaries/seminary.tpl | 8 +- 8 files changed, 355 insertions(+), 19 deletions(-) diff --git a/controllers/QuestgroupsController.inc b/controllers/QuestgroupsController.inc index a0639592..1e7c2a29 100644 --- a/controllers/QuestgroupsController.inc +++ b/controllers/QuestgroupsController.inc @@ -65,10 +65,28 @@ // Get Questgrouphierarchy $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyById($questgroup['questgroupshierarchy_id']); + // Get Character + $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + + // Check permission + $previousQuestgroup = $this->Questgroups->getPreviousQuestgroup($questgroup['id']); + if(!is_null($previousQuestgroup)) { + if(!$this->Questgroups->hasCharacterSolvedQuestgroup($previousQuestgroup['id'], $character['id'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + // Get child Questgroupshierarchy $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($questgroupshierarchy['id']); - foreach($childQuestgroupshierarchy as &$hierarchy) { + foreach($childQuestgroupshierarchy as &$hierarchy) + { + // Get Questgroups $hierarchy['questgroups'] = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id'], $questgroup['id']); + + // Check permission of Questgroups + for($i=1; $iQuestgroups->hasCharacterSolvedQuestgroup($hierarchy['questgroups'][$i-1]['id'], $character['id']); + } } // Get texts @@ -79,10 +97,15 @@ if(count($childQuestgroupshierarchy) == 0) { $quests = $this->Quests->getQuestsForQuestgroup($questgroup['id']); - - // Attach sidequests - foreach($quests as &$quest) { - $quest['sidequests'] = $this->Quests->getSidequestsForQuest($quest['id']); + for($i=0; $i 0) { + $quests[$i]['access'] = $this->Quests->hasCharacterSolvedQuest($quests[$i-1]['id'], $character['id']); + } + + // Attach sidequests + $quests[$i]['sidequests'] = $this->Quests->getSidequestsForQuest($quests[$i]['id']); } } diff --git a/controllers/QuestsController.inc b/controllers/QuestsController.inc index fd64d771..e6e7ce54 100644 --- a/controllers/QuestsController.inc +++ b/controllers/QuestsController.inc @@ -24,7 +24,7 @@ * * @var array */ - public $models = array('seminaries', 'questgroups', 'quests', 'questtexts', 'media', 'questtypes'); + public $models = array('seminaries', 'questgroups', 'quests', 'questtexts', 'media', 'questtypes', 'questgroupshierarchy'); /** * User permissions * @@ -68,6 +68,35 @@ // Get Quest $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + // Get Character + $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + + // Check permissions + $previousQuests = $this->Quests->getPreviousQuests($quest['id']); + if(count($previousQuests) == 0) + { + // Previous Questgroup + $previousQuestgroup = $this->Questgroups->getPreviousQuestgroup($questgroup['id']); + if(!$this->Questgroups->hasCharacterSolvedQuestgroup($previousQuestgroup['id'], $character['id'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + else + { + // Previous Quests + $solved = false; + foreach($previousQuests as &$previousQuest) + { + if($this->Quests->hasCharacterSolvedQuest($previousQuest['id'], $character['id'])) { + $solved = true; + break; + } + } + if(!$solved) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + // Get Questtext $questtext = null; if(is_null($questtexttypeUrl)) { @@ -111,7 +140,7 @@ // Task $task = null; - if($questtext['type'] == 'Prolog') + if($questtexttypeUrl == 'Prolog') { // Questtype $questtype = $this->Questtypes->getQuesttypeById($quest['questtype_id']); @@ -120,10 +149,20 @@ $task = $this->runAndRenderTask($questtype['classname']); } - // Next Quest + // Next Quest/Questgroup $nextQuests = null; - if($questtexttypeUrl == 'Epilog') { + $nextQuestgroup = null; + if($questtexttypeUrl == 'Epilog') + { + // Next Quest $nextQuests = $this->Quests->getNextQuests($quest['id']); + + // Next Questgroup + if(empty($nextQuests)) + { + $nextQuestgroup = $this->Questgroups->getNextQuestgroup($questgroup['id']); + $nextQuestgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyById($nextQuestgroup['questgroupshierarchy_id']); + } } @@ -135,6 +174,7 @@ $this->set('queststatus', $questStatus); $this->set('queststatustext', $questStatusText); $this->set('nextquests', $nextQuests); + $this->set('nextquestgroup', $nextQuestgroup); $this->set('task', $task); $this->set('media', $questmedia); } @@ -167,6 +207,38 @@ // Get Sidequest $sidequest = $this->Quests->getSidequestByUrl($seminary['id'], $questgroup['id'], $quest['id'], $sidequestUrl); + // Get Character + $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + + // Check permission + $previousQuests = $this->Quests->getPreviousQuests($quest['id']); + if(count($previousQuests) == 0) + { + // Previous Questgroup + $previousQuestgroup = $this->Questgroups->getPreviousQuestgroup($questgroup['id']); + if(!$this->Questgroups->hasCharacterSolvedQuestgroup($previousQuestgroup['id'], $character['id'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + else + { + // Previous Quests + if(count($previousQuests) > 0) + { + $solved = false; + foreach($previousQuests as &$previousQuest) + { + if($this->Quests->hasCharacterSolvedQuest($previousQuest['id'], $character['id'])) { + $solved = true; + break; + } + } + if(!$solved) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + } + // Get Questtext $questtext = $this->Questtexts->getQuesttextForSidequest($sidequest['id']); @@ -215,7 +287,7 @@ // Task $task = null; - if(!is_null($sidequesttext) && $sidequesttext['type'] == 'Prolog') + if($sidequesttexttypeUrl == 'Prolog') { // Questtype $questtype = $this->Questtypes->getQuesttypeById($sidequest['questtype_id']); diff --git a/controllers/SeminariesController.inc b/controllers/SeminariesController.inc index 94303d88..bf89b9f2 100644 --- a/controllers/SeminariesController.inc +++ b/controllers/SeminariesController.inc @@ -90,10 +90,20 @@ // Created user $seminary['creator'] = $this->Users->getUserById($seminary['created_user_id']); + // Get Character + $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + // Questgrouphierarchy and Questgroups $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyForSeminary($seminary['id']); - foreach($questgroupshierarchy as &$hierarchy) { + foreach($questgroupshierarchy as &$hierarchy) + { + // Get Questgroups $hierarchy['questgroups'] = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id']); + + // Check permission of Questgroups + for($i=1; $iQuestgroups->hasCharacterSolvedQuestgroup($hierarchy['questgroups'][$i-1]['id'], $character['id']); + } } diff --git a/models/QuestgroupsModel.inc b/models/QuestgroupsModel.inc index ac820bf1..471fef71 100644 --- a/models/QuestgroupsModel.inc +++ b/models/QuestgroupsModel.inc @@ -19,6 +19,12 @@ */ class QuestgroupsModel extends \hhu\z\Model { + /** + * Required models + * + * @var array + */ + public $models = array('questgroupshierarchy', 'quests'); @@ -138,6 +144,164 @@ ); } + + /** + * Get the next Questgroup. + * + * Determine the next Questgroup. If there is no next Questgroup + * on the same level as the given Quest then the followed-up + * Questgroup from a higher hierarchy level is returned. + * + * @param int $questgroupId ID of Questgroup to get next Questgroup of + * @return array Questgroup data + */ + public function getNextQuestgroup($questgroupId) + { + $currentQuestgroup = $this->getQuestgroupById($questgroupId); + $nextQuestgroup = $this->_getNextQuestgroup($currentQuestgroup['parent_questgroup_id'], $currentQuestgroup['pos']); + while(is_null($nextQuestgroup) && !is_null($currentQuestgroup['parent_questgroup_id'])) + { + $currentQuestgroup = $this->getQuestgroupById($currentQuestgroup['parent_questgroup_id']); + $nextQuestgroup = $this->_getNextQuestgroup($currentQuestgroup['parent_questgroup_id'], $currentQuestgroup['pos']); + } + + + return $nextQuestgroup; + } + + + /** + * Get the previous Questgroup. + * + * Determine the previous Questgroup. If there is no previous + * Questgroup on the same level as the given Quest then the + * followed-up Questgroup from a higher hierarchy level is + * returned. + * + * @param int $questgroupId ID of Questgroup to get previous Questgroup of + * @return array Questgroup data + */ + public function getPreviousQuestgroup($questgroupId) + { + $currentQuestgroup = $this->getQuestgroupById($questgroupId); + $previousQuestgroup = $this->_getPreviousQuestgroup($currentQuestgroup['parent_questgroup_id'], $currentQuestgroup['pos']); + while(is_null($previousQuestgroup) && !is_null($currentQuestgroup['parent_questgroup_id'])) + { + $currentQuestgroup = $this->getQuestgroupById($currentQuestgroup['parent_questgroup_id']); + $previousQuestgroup = $this->_getPreviousQuestgroup($currentQuestgroup['parent_questgroup_id'], $currentQuestgroup['pos']); + } + + + return $previousQuestgroup; + } + + + /** + * Determine if the given Character has solved the Quests form + * this Questgroup. + * + * @param int $questgroupId ID of Questgroup to check + * @param int $characterId ID of Character to check + * @result boolean Whether Character has solved the Questgroup or not + */ + public function hasCharacterSolvedQuestgroup($questgroupId, $characterId) + { + $currentQuestgroup = $this->getQuestgroupById($questgroupId); + $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($currentQuestgroup['questgroupshierarchy_id']); + $lastChildQuestgroupshierarchy = array_pop($childQuestgroupshierarchy); + while(!is_null($lastChildQuestgroupshierarchy)) + { + $questgroups = $this->getQuestgroupsForHierarchy($lastChildQuestgroupshierarchy['id'], $currentQuestgroup['id']); + $currentQuestgroup = array_pop($questgroups); + $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($currentQuestgroup['questgroupshierarchy_id']); + $lastChildQuestgroupshierarchy = array_pop($childQuestgroupshierarchy); + } + + $quests = $this->Quests->getQuestsForQuestgroup($currentQuestgroup['id']); + $lastQuest = array_pop($quests); + + + return $this->Quests->hasCharacterSolvedQuest($lastQuest['id'], $characterId); + } + + + + + /** + * Get the next (direct) Questgroup. + * + * @param int $parentQuestgroupId ID of parent Questgroup to get next Questgroup of + * @param int $questgroupPos Position of Questgroup to get next Questgroup of + * @return array Data of next Questgroup or NULL + */ + private function _getNextQuestgroup($parentQuestgroupId, $questgroupPos) + { + if(!is_null($parentQuestgroupId)) + { + $data = $this->db->query( + 'SELECT * '. + 'FROM questgroups '. + 'WHERE parent_questgroup_id = ? AND pos = ? + 1', + 'ii', + $parentQuestgroupId, $questgroupPos + ); + } + else + { + $data = $this->db->query( + 'SELECT * '. + 'FROM questgroups '. + 'WHERE parent_questgroup_id IS NULL AND pos = ? + 1', + 'i', + $questgroupPos + ); + } + if(empty($data)) { + return null; + } + + + return $data[0]; + } + + + /** + * Get the previous (direct) Questgroup. + * + * @param int $parentQuestgroupId ID of parent Questgroup to get previous Questgroup of + * @param int $questgroupPos Position of Questgroup to get previous Questgroup of + * @return array Data of previous Questgroup or NULL + */ + private function _getPreviousQuestgroup($parentQuestgroupId, $questgroupPos) + { + if(!is_null($parentQuestgroupId)) + { + $data = $this->db->query( + 'SELECT * '. + 'FROM questgroups '. + 'WHERE parent_questgroup_id = ? AND pos = ? - 1', + 'ii', + $parentQuestgroupId, $questgroupPos + ); + } + else + { + $data = $this->db->query( + 'SELECT * '. + 'FROM questgroups '. + 'WHERE parent_questgroup_id IS NULL AND pos = ? - 1', + 'i', + $questgroupPos + ); + } + if(empty($data)) { + return null; + } + + + return $data[0]; + } + } ?> diff --git a/models/QuestsModel.inc b/models/QuestsModel.inc index 4ac41986..e531ac26 100644 --- a/models/QuestsModel.inc +++ b/models/QuestsModel.inc @@ -109,7 +109,7 @@ $seminaryId ); if(empty($data)) { - throw new \nre\exceptions\IdNotFoundException(); + throw new \nre\exceptions\IdNotFoundException($sidequestUrl); } @@ -175,6 +175,27 @@ } + /** + * Get Quests that the given Quests follows-up to. + * + * @param int $questId ID of Quest to get previous Quests of + * @return array Quests data + */ + public function getPreviousQuests($questId) + { + return $this->db->query( + 'SELECT quests.id, quests.title, quests.url, questgroups.title AS questgroup_title, questgroups.url AS questgroup_url '. + 'FROM quests_previousquests '. + 'LEFT JOIN quests ON quests.id = quests_previousquests.previous_quest_id '. + 'LEFT JOIN questgroups ON questgroups.id = quests.questgroup_id '. + 'LEFT JOIN questgroupshierarchy ON questgroupshierarchy.id = questgroups.questgroupshierarchy_id '. + 'WHERE quests_previousquests.quest_id = ?', + 'i', + $questId + ); + } + + /** * Mark a Quest as solved for a Character. * @@ -216,6 +237,29 @@ ); } + + /** + * Determine if the given Character has solved the given Quest. + * + * @param int $questId ID of Quest to check + * @param int $characterId ID of Character to check + * @result boolean Whether Character has solved the Quest or not + */ + public function hasCharacterSolvedQuest($questId, $characterId) + { + $count = $this->db->query( + 'SELECT count(id) AS c '. + 'FROM quests_characters '. + 'WHERE quest_id = ? AND character_id = ? AND status = 0', + 'ii', + $questId, + $characterId + ); + + + return (!empty($count) && intval($count[0]['c']) > 0); + } + } ?> diff --git a/views/html/questgroups/questgroup.tpl b/views/html/questgroups/questgroup.tpl index 5699bfa7..848bf187 100644 --- a/views/html/questgroups/questgroup.tpl +++ b/views/html/questgroups/questgroup.tpl @@ -1,5 +1,5 @@ -

-

+

+

@@ -14,7 +14,14 @@

    -
  • :
  • +
  • + : + + + + + +
@@ -25,6 +32,7 @@
  • +
    : @@ -35,6 +43,9 @@
+ + + diff --git a/views/html/quests/quest.tpl b/views/html/quests/quest.tpl index 2c919a3d..6aca7048 100644 --- a/views/html/quests/quest.tpl +++ b/views/html/quests/quest.tpl @@ -48,14 +48,20 @@ - +
-

+

+ 0) : ?>
    -
  • +
  • :
+ + : + + Spiel vorbei +
diff --git a/views/html/seminaries/seminary.tpl b/views/html/seminaries/seminary.tpl index 3ff9b9c0..e84f15f4 100644 --- a/views/html/seminaries/seminary.tpl +++ b/views/html/seminaries/seminary.tpl @@ -18,7 +18,13 @@

    -
  • :
  • +
  • + : + +
  • + + +