* @copyright 2014 Heinrich-Heine-Universität Düsseldorf * @license http://www.gnu.org/licenses/gpl.html * @link https://bitbucket.org/coderkun/the-legend-of-z */ namespace hhu\z\models; /** * Model to interact with Quests-table. * * @author Oliver Hanraths */ class QuestsModel extends \hhu\z\Model { /** * Quest-status: Entered * * @var int; */ const QUEST_STATUS_ENTERED = 1; /** * Quest-status: Solved * * @var int; */ const QUEST_STATUS_SOLVED = 0; /** * Quest-status: Unsolved * * @var int; */ const QUEST_STATUS_UNSOLVED = -1; /** * Construct a new QuestsModel. */ public function __construct() { parent::__construct(); } /** * Get a Quest and its data by its URL. * * @throws IdNotFoundException * @param int $seminaryId ID of the corresponding Seminary * @param int $questgroupId ID of the corresponding Questgroup * @param string $questURL URL-title of a Quest * @return array Quest data */ public function getQuestByUrl($seminaryId, $questgroupId, $questUrl) { $data = $this->db->query( 'SELECT quests.id, quests.questgroup_id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.task, quests.right_text, quests.wrong_text, quests.questsmedia_id '. 'FROM quests '. 'LEFT JOIN questgroups ON questgroups.id = quests.questgroup_id '. 'WHERE questgroups.seminary_id = ? AND questgroups.id = ? AND quests.url = ?', 'iis', $seminaryId, $questgroupId, $questUrl ); if(empty($data)) { throw new \nre\exceptions\IdNotFoundException($questUrl); } return $data[0]; } /** * Get a Quest and its data by its ID. * * @throws IdNotFoundException * @param string $questId ID of a Quest * @return array Quest data */ public function getQuestById($questId) { $data = $this->db->query( 'SELECT quests.id, quests.questgroup_id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.task, quests.right_text, quests.wrong_text, quests.questsmedia_id '. 'FROM quests '. 'LEFT JOIN questgroups ON questgroups.id = quests.questgroup_id '. 'WHERE quests.id = ?', 'i', $questId ); if(empty($data)) { throw new \nre\exceptions\IdNotFoundException($questId); } return $data[0]; } /** * Get the first Quest of a Qusetgroup. * * @param int $questId ID of Questgroup * @return array Data of first Quest */ public function getFirstQuestOfQuestgroup($questgroupId) { $data = $this->db->query( 'SELECT id, questtype_id, title, url, xps, task '. 'FROM quests '. 'LEFT JOIN quests_previousquests ON quests_previousquests.quest_id = quests.id '. 'WHERE questgroup_id = ? AND quests_previousquests.previous_quest_id IS NULL', 'i', $questgroupId ); if(!empty($data)) { return $data[0]; } return null; } /** * Get Quests that follow-up a Quest. * * @param int $questId ID of Quest to get next Quests of * @return array Quests data */ public function getNextQuests($questId) { return $this->db->query( 'SELECT quests.id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.task, questgroups.title AS questgroup_title, questgroups.url AS questgroup_url '. 'FROM quests_previousquests '. 'INNER JOIN quests ON quests.id = quests_previousquests.quest_id '. 'INNER JOIN questgroups ON questgroups.id = quests.questgroup_id '. 'WHERE quests_previousquests.previous_quest_id = ?', 'i', $questId ); } /** * 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 '. 'INNER JOIN quests ON quests.id = quests_previousquests.previous_quest_id '. 'INNER JOIN questgroups ON questgroups.id = quests.questgroup_id '. 'WHERE quests_previousquests.quest_id = ?', 'i', $questId ); } /** * Mark a Quest as entered for a Character. * * @param int $questId ID of Quest to mark as entered * @param int $characterId ID of Character that entered the Quest */ public function setQuestEntered($questId, $characterId) { $this->setQuestStatus($questId, $characterId, static::QUEST_STATUS_ENTERED, false); } /** * Mark a Quest as solved for a Character. * * @param int $questId ID of Quest to mark as solved * @param int $characterId ID of Character that solved the Quest */ public function setQuestSolved($questId, $characterId) { $this->setQuestStatus($questId, $characterId, static::QUEST_STATUS_SOLVED); } /** * Mark a Quest as unsolved for a Character. * * @param int $questId ID of Quest to mark as unsolved * @param int $characterId ID of Character that unsolved the Quest */ public function setQuestUnsolved($questId, $characterId) { $this->setQuestStatus($questId, $characterId, static::QUEST_STATUS_UNSOLVED); } /** * Determine if the given Character has entered a Quest. * * @param int $questId ID of Quest to check * @param int $characterId ID of Character to check * @result boolean Whether Character has entered the Quest or not */ public function hasCharacterEnteredQuest($questId, $characterId) { $count = $this->db->query( 'SELECT count(id) AS c '. 'FROM quests_characters '. 'WHERE quest_id = ? AND character_id = ? AND status IN (?,?,?)', 'iiiii', $questId, $characterId, static::QUEST_STATUS_ENTERED, static::QUEST_STATUS_SOLVED, static::QUEST_STATUS_UNSOLVED ); return (!empty($count) && intval($count[0]['c']) > 0); } /** * Determine if the given Character has tried to solve a Quest. * * @param int $questId ID of Quest to check * @param int $characterId ID of Character to check * @result boolean Whether Character has tried to solved the Quest or not */ public function hasCharacterTriedQuest($questId, $characterId) { $count = $this->db->query( 'SELECT count(id) AS c '. 'FROM quests_characters '. 'WHERE quest_id = ? AND character_id = ? AND status IN (?,?)', 'iiii', $questId, $characterId, static::QUEST_STATUS_SOLVED, static::QUEST_STATUS_UNSOLVED ); return (!empty($count) && intval($count[0]['c']) > 0); } /** * 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 = ?', 'iii', $questId, $characterId, static::QUEST_STATUS_SOLVED ); return (!empty($count) && intval($count[0]['c']) > 0); } /** * Get Characters that solved a Quest. * * @param int $questId ID of Quest to get Characters for * @return array Characters data */ public function getCharactersSolvedQuest($questId) { return $data = $this->db->query( 'SELECT character_id, created, text '. 'FROM questtypes_submit_characters '. 'WHERE quest_id = ? AND EXISTS ('. 'SELECT character_id FROM quests_characters WHERE quest_id = questtypes_submit_characters.quest_id AND status = ?'. ')', 'ii', $questId, static::QUEST_STATUS_SOLVED ); } /** * Get Characters that did not solved a Quest. * * @param int $questId ID of Quest to get Characters for * @return array Characters data */ public function getCharactersUnsolvedQuest($questId) { return $data = $this->db->query( 'SELECT character_id, created, text '. 'FROM questtypes_submit_characters '. 'WHERE quest_id = ? AND NOT EXISTS ('. 'SELECT character_id FROM quests_characters WHERE quest_id = questtypes_submit_characters.quest_id AND status = ?'. ')', 'ii', $questId, static::QUEST_STATUS_SOLVED ); } /** * Mark a Quest for a Character. * * @param int $questId ID of Quest to mark * @param int $characterId ID of Character to mark the Quest for * @param int $status Quest status to mark * @param boolean $repeated Insert although status is already set for this Quest and Character */ private function setQuestStatus($questId, $characterId, $status, $repeated=true) { // Check if status is already set if(!$repeated) { $count = $this->db->query( 'SELECT count(*) AS c '. 'FROM quests_characters '. 'WHERE quest_id = ? AND character_id = ? AND status = ?', 'iii', $questId, $characterId, $status ); if(!empty($count) && intval($count[0]['c']) > 0) { return; } } // Set status $this->db->query( 'INSERT INTO quests_characters '. '(quest_id, character_id, status) '. 'VALUES '. '(?, ?, ?) ', 'iii', $questId, $characterId, $status ); } } ?>