implement permissions for Questgroups, Quests and Sidequests

This commit is contained in:
coderkun 2014-03-04 03:16:02 +01:00
commit 42a7e9303c
8 changed files with 355 additions and 19 deletions

View file

@ -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; $i<count($hierarchy['questgroups']); $i++) {
$hierarchy['questgroups'][$i]['access'] = $this->Questgroups->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<count($quests); $i++)
{
// Check permission
if($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']);
}
}

View file

@ -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']);

View file

@ -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; $i<count($hierarchy['questgroups']); $i++) {
$hierarchy['questgroups'][$i]['access'] = $this->Questgroups->hasCharacterSolvedQuestgroup($hierarchy['questgroups'][$i-1]['id'], $character['id']);
}
}

View file

@ -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];
}
}
?>

View file

@ -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);
}
}
?>

View file

@ -1,5 +1,5 @@
<h1><?=_('Seminaries')?></h2>
<h2><?=$seminary['title']?></h3>
<h1><?=_('Seminaries')?></h1>
<h2><?=$seminary['title']?></h2>
<?=$questgroupshierarchypath?>
<?=$questgroupspicture?>
@ -14,7 +14,14 @@
<h3><?=$hierarchy['title_plural']?></h3>
<ul>
<?php foreach($hierarchy['questgroups'] as &$group) : ?>
<li><?=$hierarchy['title_singular']?> <?=$group['pos']?>: <a href="<?=$linker->link(array('questgroups','questgroup',$seminary['url'],$group['url']))?>"><?=$group['title']?></a></li>
<li>
<?=$hierarchy['title_singular']?> <?=$group['pos']?>:
<?php if(!array_key_exists('access', $group) || $group['access']) : ?>
<a href="<?=$linker->link(array('questgroups','questgroup',$seminary['url'],$group['url']))?>"><?=$group['title']?></a>
<?php else : ?>
<?=_('locked')?>
<?php endif ?>
</li>
<?php endforeach?>
</ul>
<?php endif ?>
@ -25,6 +32,7 @@
<ul>
<?php foreach($quests as &$quest) : ?>
<li>
<?php if(!array_key_exists('access', $quest) || $quest['access']) : ?>
<a href="<?=$linker->link(array('quests','quest',$seminary['url'],$questgroup['url'],$quest['url']))?>"><?=$quest['title']?></a>
<br />
<?=_('containing optional Quests')?>:
@ -35,6 +43,9 @@
<?php endforeach ?>
</ul>
<?php endif ?>
<?php else : ?>
<?=_('Locked')?>
<?php endif ?>
</li>
<?php endforeach ?>
</ul>

View file

@ -48,14 +48,20 @@
</section>
<?php endif ?>
<?php if(!is_null($nextquests)) : ?>
<?php if(!is_null($nextquests) || !is_null($nextquestgroup)) : ?>
<section>
<h1><?=_('Next Quests')?></h1>
<h1><?=_('Go on') ?></h1>
<?php if(count($nextquests) > 0) : ?>
<ul>
<?php foreach($nextquests as &$nextquest) : ?>
<li><a href="<?=$linker->link(array($nextquest['questgroup_url'],$nextquest['url']),3)?>"><?=$nextquest['title']?></a></li>
<li><?=_('Quest')?>: <a href="<?=$linker->link(array($nextquest['questgroup_url'],$nextquest['url']),3)?>"><?=$nextquest['title']?></a></li>
<?php endforeach ?>
</ul>
<?php elseif(!is_null($nextquestgroup)) : ?>
<a href="<?=$linker->link(array('questgroups','questgroup',$seminary['url'],$nextquestgroup['url']))?>"><?=$nextquestgroup['hierarchy']['title_singular']?> <?=$nextquestgroup['pos']?>: <?=$nextquestgroup['title']?></a>
<?php else : ?>
Spiel vorbei
<?php endif ?>
</section>
<?php endif ?>

View file

@ -18,7 +18,13 @@
<h3><?=$hierarchy['title_plural']?></h3>
<ul>
<?php foreach($hierarchy['questgroups'] as &$group) : ?>
<li><?=$hierarchy['title_singular']?> <?=$group['pos']?>: <a href="<?=$linker->link(array('questgroups','questgroup',$seminary['url'],$group['url']))?>"><?=$group['title']?></a></li>
<li>
<?=$hierarchy['title_singular']?> <?=$group['pos']?>:
<?php if(!array_key_exists('access', $group) || $group['access']) : ?>
<a href="<?=$linker->link(array('questgroups','questgroup',$seminary['url'],$group['url']))?>"><?=$group['title']?></a></li>
<?php else : ?>
<?=_('locked')?>
<?php endif ?>
<?php endforeach?>
</ul>
<?php endforeach ?>