From 1c1d12a1160ac7d4c79ae12b3d475c21ee756db3 Mon Sep 17 00:00:00 2001 From: coderkun Date: Wed, 19 Mar 2014 00:06:17 +0100 Subject: [PATCH] evolve QuesttypeAgents with fixed Actions and Character submission handling --- agents/intermediate/QuestsAgent.inc | 20 ++ app/QuesttypeAgent.inc | 34 +- app/QuesttypeController.inc | 48 ++- controllers/QuestsController.inc | 335 ++++++++++++++++-- locale/de_DE/LC_MESSAGES/The Legend of Z.mo | Bin 2719 -> 2705 bytes locale/de_DE/LC_MESSAGES/The Legend of Z.po | 37 +- models/CharactersModel.inc | 29 ++ models/QuestsModel.inc | 40 +++ questtypes/dummy/DummyQuesttypeController.inc | 64 +++- .../dummy/html/{index.tpl => quest.tpl} | 0 questtypes/dummy/html/submission.tpl | 0 questtypes/dummy/html/submissions.tpl | 0 .../MultiplechoiceQuesttypeController.inc | 108 +++--- .../html/{index.tpl => quest.tpl} | 0 questtypes/multiplechoice/html/submission.tpl | 0 .../multiplechoice/html/submissions.tpl | 0 .../TextinputQuesttypeController.inc | 109 +++--- .../textinput/html/{index.tpl => quest.tpl} | 0 questtypes/textinput/html/submission.tpl | 0 questtypes/textinput/html/submissions.tpl | 0 views/html/quests/submission.tpl | 14 + views/html/quests/submissions.tpl | 36 ++ 22 files changed, 729 insertions(+), 145 deletions(-) rename questtypes/dummy/html/{index.tpl => quest.tpl} (100%) create mode 100644 questtypes/dummy/html/submission.tpl create mode 100644 questtypes/dummy/html/submissions.tpl rename questtypes/multiplechoice/html/{index.tpl => quest.tpl} (100%) create mode 100644 questtypes/multiplechoice/html/submission.tpl create mode 100644 questtypes/multiplechoice/html/submissions.tpl rename questtypes/textinput/html/{index.tpl => quest.tpl} (100%) create mode 100644 questtypes/textinput/html/submission.tpl create mode 100644 questtypes/textinput/html/submissions.tpl create mode 100644 views/html/quests/submission.tpl create mode 100644 views/html/quests/submissions.tpl diff --git a/agents/intermediate/QuestsAgent.inc b/agents/intermediate/QuestsAgent.inc index c26a2f70..1a823fa6 100644 --- a/agents/intermediate/QuestsAgent.inc +++ b/agents/intermediate/QuestsAgent.inc @@ -32,6 +32,26 @@ $this->addSubAgent('Questgroupspicture', 'index', $request->getParam(3), $request->getParam(4), true); } + + /** + * Action: submissions. + */ + public function submissions(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + $this->addSubAgent('Questgroupspicture', 'index', $request->getParam(3), $request->getParam(4), true); + } + + + /** + * Action: submission. + */ + public function submission(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + $this->addSubAgent('Questgroupspicture', 'index', $request->getParam(3), $request->getParam(4), true); + } + } ?> diff --git a/app/QuesttypeAgent.inc b/app/QuesttypeAgent.inc index 9f104be1..9ae988da 100644 --- a/app/QuesttypeAgent.inc +++ b/app/QuesttypeAgent.inc @@ -189,6 +189,34 @@ + /** + * Save the answers of a Character for a Quest. + * + * @param int $questId ID of Quest to save answers for + * @param int $characterId ID of Character to save answers of + * @param array $answers Character answers for the Quest + */ + public function saveAnswersOfCharacter($questId, $characterId, $answers) + { + $this->controller->saveAnswersOfCharacter($questId, $characterId, $answers); + } + + + /** + * Check if answers of a Character for a Quest match the correct ones. + * + * @param int $questId ID of Quest to match answers for + * @param int $characterId ID of Character to match answers of + * @param array $answers Character answers for the Quest + */ + public function matchAnswersOfCharacter($questId, $characterId, $answers) + { + return $this->controller->matchAnswersOfCharacter($questId, $characterId, $answers); + } + + + + /** * Load the Controller of this Agent. * @@ -216,7 +244,11 @@ } // Determine Action - $action = \nre\configs\CoreConfig::$defaults['action']; + $action = $this->response->getParam(2); + if(is_null($action)) { + $action = $this->request->getParam(2, 'action'); + $this->response->addParam($action); + } // Load Controller diff --git a/app/QuesttypeController.inc b/app/QuesttypeController.inc index 743c5d59..2987659a 100644 --- a/app/QuesttypeController.inc +++ b/app/QuesttypeController.inc @@ -29,6 +29,52 @@ + /** + * Save the answers of a Character for a Quest. + * + * @param int $questId ID of Quest to save answers for + * @param int $characterId ID of Character to save answers of + * @param array $answers Character answers for the Quest + */ + public abstract function saveAnswersOfCharacter($questId, $characterId, $answers); + + + /** + * Check if answers of a Character for a Quest match the correct ones. + * + * @param int $questId ID of Quest to match answers for + * @param int $characterId ID of Character to match answers of + * @param array $answers Character answers for the Quest + * @return boolean True/false for a right/wrong answer or null for moderator evaluation + */ + public abstract function matchAnswersOfCharacter($questId, $characterId, $answers); + + + /** + * Action: quest. + * + * Show the task of a Quest. + * + * @param int $questId ID of Quest to show + * @param int $characterId ID of Character + */ + public abstract function quest($questId, $characterId); + + + + /** + * Action: submission. + * + * Show the submission of a Character for a Quest. + * + * @param int $questId ID of Quest to show submission for + * @param int $characterId ID of Character to show submission of + */ + public abstract function submission($questId, $characterId); + + + + /** * Load a QuesttypeController. * @@ -255,7 +301,7 @@ $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); // Set solved - $this->Quests->setQuestSolved($quest['id'], $character['id']); + $this->Quests->setQuestSolved($quest['id'], $character['id']); // Redirect diff --git a/controllers/QuestsController.inc b/controllers/QuestsController.inc index 211c8104..f3340578 100644 --- a/controllers/QuestsController.inc +++ b/controllers/QuestsController.inc @@ -31,7 +31,9 @@ * @var array */ public $permissions = array( - 'quest' => array('admin', 'moderator', 'user') + 'quest' => array('admin', 'moderator', 'user'), + 'submissions' => array('admin', 'moderator'), + 'submission' => array('admin', 'moderator') ); /** * User seminary permissions @@ -39,7 +41,9 @@ * @var array */ public $seminaryPermissions = array( - 'quest' => array('admin', 'moderator', 'user') + 'quest' => array('admin', 'moderator', 'user'), + 'submissions' => array('admin', 'moderator'), + 'submission' => array('admin', 'moderator') ); @@ -158,8 +162,8 @@ // Questtype $questtype = $this->Questtypes->getQuesttypeById($quest['questtype_id']); - // Task - $task = $this->runAndRenderTask($quest['id'], $questtype['classname']); + // Render task + $task = $this->renderTask($questtype['classname'], $seminary, $questgroup, $quest, $character); } // Next Quest/Questgroup @@ -203,42 +207,168 @@ } + /** + * List Character submissions for a Quest. + * + * @throws IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + */ + public function submissions($seminaryUrl, $questgroupUrl, $questUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + + // Get (related) Questtext (for Sidequests) + $relatedQuesttext = null; + if(!$quest['is_mainquest']) + { + $relatedQuesttext = $this->Questtexts->getQuesttextForSidequest($quest['id']); + if(!empty($relatedQuesttext)) { + $relatedQuesttext['quest'] = $this->Quests->getQuestById($relatedQuesttext['quest_id']); + } + } + + // Media + $questmedia = null; + if(!is_null($quest['questsmedia_id'])) { + $questmedia = $this->Media->getMediaById($quest['questsmedia_id']); + } + + // Get unsolved Character submissions + $unsolvedSubmissions = $this->Quests->getCharactersUnsolvedQuest($quest['id']); + foreach($unsolvedSubmissions as &$submission) { + $submission['character'] = $this->Characters->getCharacterById($submission['character_id']); + } + + // Get solved Character submissions + $solvedSubmissions = $this->Quests->getCharactersSolvedQuest($quest['id']); + foreach($solvedSubmissions as &$submission) { + $submission['character'] = $this->Characters->getCharacterById($submission['character_id']); + } + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + $this->set('relatedquesttext', $relatedQuesttext); + $this->set('media', $questmedia); + $this->set('unsolvedsubmissions', $unsolvedSubmissions); + $this->set('solvedsubmissions', $solvedSubmissions); + } /** - * Load, construct, run and render the Agent for the given - * classname of a Questtype and return ist output. + * Show and handle the submission of a Character for a Quest. * - * @param int $questId ID of Quest - * @param string $questtypeClassname Classname of Questtype to run and render - * @return string Rendered output of Questtype-Agent + * @throws IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + * @param string $characterUrl URL-Title of Character */ - private function runAndRenderTask($questId, $questtypeClassname) + public function submission($seminaryUrl, $questgroupUrl, $questUrl, $characterUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + + // Character + $character = $this->Characters->getCharacterByUrl($seminary['id'], $characterUrl); + + // Media + $questmedia = null; + if(!is_null($quest['questsmedia_id'])) { + $questmedia = $this->Media->getMediaById($quest['questsmedia_id']); + } + + // Questtype + $questtype = $this->Questtypes->getQuesttypeById($quest['questtype_id']); + + // Render Questtype output + $output = $this->renderTaskSubmission($questtype['classname'], $seminary, $questgroup, $quest, $character); + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + $this->set('character', $character); + $this->set('media', $questmedia); + $this->set('output', $output); + } + + + + + /** + * Render and handle the task of a Quest. + * + * @param string $questtypeClassname Name of the class for the Questtype of a Quest + * @param array $seminary Seminary data + * @param array $questgroup Questgroup data + * @param array $quest Quest data + * @param array $character Character data + * @return string Rendered output + */ + private function renderTask($questtypeClassname, $seminary, $questgroup, $quest, $character) { $task = null; - $questtypeAgent = null; try { - // Load Agent - \hhu\z\QuesttypeAgent::load($questtypeClassname); - // Construct Agent - $questtypeAgent = \hhu\z\QuesttypeAgent::factory($questtypeClassname, $this->request, $this->response); - - // Generate request + // Generate request and response $request = clone $this->request; - // Generate response - $response = clone $this->response; - $response->clearParams(1); - $response->addParams( - null, - \nre\configs\CoreConfig::$defaults['action'], - $questId - ); - // Run Agent - $questtypeAgent->run($request, $response); - - // Render output - $task = $questtypeAgent->render(); - + $response = $this->createQuesttypeResponse('quest', $quest['id'], $character['id']); + + // Load Questtype Agent + $questtypeAgent = $this->loadQuesttypeAgent($questtypeClassname, $request, $response); + + // Solve Quest + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('submit'))) + { + // Get user answers + $answers = $this->request->getPostParam('answers'); + + // Store answers in session + $_SESSION['answers'][$quest['id']] = $answers; + + // Save answers in database + $questtypeAgent->saveAnswersOfCharacter($quest['id'], $character['id'], $answers); + + // Match answers with correct ones + $status = $questtypeAgent->matchAnswersofCharacter($quest['id'], $character['id'], $answers); + if($status === true) + { + // Mark Quest as solved + $this->Quests->setQuestSolved($quest['id'], $character['id']); + + // Redirect + $this->redirect($this->linker->link('Epilog', 5, true, array('status'=>'solved'))); + } + elseif($status === false) + { + // Mark Quest as unsolved + $this->Quests->setQuestUnsolved($quest['id'], $character['id']); + + // Redirect + $this->redirect($this->linker->link('Prolog', 5, true, array('status'=>'unsolved'))); + } + } + + // Render Task + $task = $this->runQuesttypeAgent($questtypeAgent, $request, $response); } catch(\nre\exceptions\ViewNotFoundException $e) { $task = $e->getMessage(); @@ -270,6 +400,149 @@ return $task; } + + /** + * Render and handle a Character submission for a Quest. + * + * @param string $questtypeClassname Name of the class for the Questtype of a Quest + * @param array $seminary Seminary data + * @param array $questgroup Questgroup data + * @param array $quest Quest data + * @param array $character Character data + * @return string Rendered output + */ + private function renderTaskSubmission($questtypeClassname, $seminary, $questgroup, $quest, $character) + { + $task = null; + try { + // Generate request and response + $request = clone $this->request; + $response = $this->createQuesttypeResponse('submission', $quest['id'], $character['id']); + + // Load Questtype Agent + $questtypeAgent = $this->loadQuesttypeAgent($questtypeClassname, $request, $response); + + // Solve Quest + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('submit'))) + { + // Set status + if($this->request->getPostParam('submit') == _('solved')) + { + // Mark Quest as solved + $this->Quests->setQuestSolved($quest['id'], $character['id']); + } + else + { + // Mark Quest as unsolved + $this->Quests->setQuestUnsolved($quest['id'], $character['id']); + } + + // Redirect + $this->redirect($this->linker->link(array('submissions', $seminary['url'], $questgroup['url'], $quest['url']), 1)); + } + + // Render task submissions + $task = $this->runQuesttypeAgent($questtypeAgent, $request, $response); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeModelNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeModelNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeControllerNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeControllerNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeAgentNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeAgentNotFoundException $e) { + $task = $e->getMessage(); + } + + + // Return rendered output + return $task; + } + + + /** + * Create a response for the Questtype rendering. + * + * @param string $action Action to run + * @param mixed $param Additional parameters to add to the response + * @return Response Generated response + */ + private function createQuesttypeResponse($action, $param1) + { + // Clone current response + $response = clone $this->response; + // Clear parameters + $response->clearParams(1); + + // Add Action + $response->addParams( + null, + $action + ); + + // Add additional parameters + foreach(array_slice(func_get_args(), 1) as $param) { + $response->addParam($param); + } + + + // Return response + return $response; + } + + + /** + * Load and construct the QuesttypeAgent for a Questtype. + * + * @param string $questtypeClassname Name of the class for the Questtype of a Quest + * @param Request $request Request + * @param Response $response Response + * @return QuesttypeAgent + */ + private function loadQuesttypeAgent($questtypeClassname, $request, $response) + { + // Load Agent + \hhu\z\QuesttypeAgent::load($questtypeClassname); + + + // Construct and return Agent + return \hhu\z\QuesttypeAgent::factory($questtypeClassname, $request, $response); + } + + + /** + * Run and render the Agent for a QuesttypeAgent and return ist output. + * + * @param Agent $questtypeAgent QuesttypeAgent to run and render + * @param Request $request Request + * @param Response $response Response + * @return string Rendered output + */ + private function runQuesttypeAgent($questtypeAgent, $request, $response) + { + // Run Agent + $questtypeAgent->run($request, $response); + + + // Render and return output + return $questtypeAgent->render(); + } + } ?> diff --git a/locale/de_DE/LC_MESSAGES/The Legend of Z.mo b/locale/de_DE/LC_MESSAGES/The Legend of Z.mo index d2a2559161443dd7666423b67ee58c7d64c09e6e..0ad327264913d4f176c26dad8e53281cf46435cc 100644 GIT binary patch delta 634 zcmXxg&nrYx6u|NGyfO2}_!%!UHC~Dh3q#3|Bo<29U{-cUNHVi{9y>29YrQ{UQtT|0 zC`y#1EEHK-k)2YC4NKp{Rj)qxoOAEF=f0A=?H%gnV*p;tO<$uT1_H zlf(~LhEEvB7i`8?6Wb)~i7Qa+8DksjeVwTH4aFt=-7rc*FB->^B{F3;ekMd3$=ehw zFpUk^j!ig-RhYv%%wr|4VhwJh4zi83ls(h|_D%lG3I7`0kw{T^Mjjz=s0Th!8-1e= z;PCuvtVdGPin_l8b$`~_XB;;5G0ak*zyaJq9pofr!6W4cwb4Cl<44q&yqNeMb&xN# zF~Kw}C535pO`JuSco4PEq;UrI56z*T3sCP(h9plYe{`~aUU$zxS8r5`d;dZI;dT7GtZCx%*bfSe^965> Ra~v8878Ymo^U-ti;s-P2N>~5@ delta 648 zcmYMwF-RL>6u|L!UUKHz8WZ%aHc+qBLC_%y6)}S%DpV+xmJFp!Ng*~tF)c|DTn@3| zfK`6GP2Qz=1Mguc4q`WsV;erlB$n_NE@C^bpboNuw3K(K1MHgoVJ!ID z;4_Jv6fTh^+W7M5?ZNzp*k!1Qn~6ssTZp?pO?z(TDdY`mgYug|db->query( + 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, media.url AS avatar_url, media.description AS avatar_description '. + 'FROM v_characters AS characters '. + 'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '. + 'LEFT JOIN avatars ON avatars.id = characters.avatar_id '. + 'LEFT JOIN avatarpictures ON avatarpictures.media_id = avatars.avatarpicture_id '. + 'LEFT JOIN media ON media.id = avatarpictures.media_id '. + 'WHERE characters.id = ?', + 'i', + $characterId + ); + if(empty($data)) { + throw new \nre\exceptions\IdNotFoundException($characterUrl); + } + + + return $data[0]; + } + } ?> diff --git a/models/QuestsModel.inc b/models/QuestsModel.inc index 09ebc125..b93edfb1 100644 --- a/models/QuestsModel.inc +++ b/models/QuestsModel.inc @@ -299,6 +299,46 @@ 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 = 0'. + ')', + 'i', + $questId + ); + } + + + /** + * 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 = 0'. + ')', + 'i', + $questId + ); + } + } ?> diff --git a/questtypes/dummy/DummyQuesttypeController.inc b/questtypes/dummy/DummyQuesttypeController.inc index 0f3012fa..8c9a20dd 100644 --- a/questtypes/dummy/DummyQuesttypeController.inc +++ b/questtypes/dummy/DummyQuesttypeController.inc @@ -25,22 +25,58 @@ /** - * Action: index. + * Save the answers of a Character for a Quest. + * + * @param int $questId ID of Quest to save answers for + * @param int $characterId ID of Character to save answers of + * @param array $answers Character answers for the Quest */ - public function index() + public function saveAnswersOfCharacter($questId, $characterId, $answers) { - // Check for submission - if($this->request->getRequestMethod() == 'POST') - { - // Right answer (dummy) - if(!is_null($this->request->getPostParam('submit'))) { - $this->setQuestSolved(); - } - // Wrong answer (dummy) - else { - $this->setQuestUnsolved(); - } - } + // Do nothing + } + + + /** + * Check if answers of a Character for a Quest match the correct ones. + * + * @param int $questId ID of Quest to match answers for + * @param int $characterId ID of Character to match answers of + * @param array $answers Character answers for the Quest + * @return boolean True/false for a right/wrong answer or null for moderator evaluation + */ + public function matchAnswersOfCharacter($questId, $characterId, $answers) + { + // Set status + return true; + } + + + /** + * Action: quest. + * + * Show the task of a Quest. + * + * @param int $questId ID of Quest to show + * @param int $characterId ID of Character + */ + public function quest($questId, $characterId) + { + // Nothing to do + } + + + /** + * Action: submission. + * + * Show the submission of a Character for a Quest. + * + * @param int $questId ID of Quest to show submission for + * @param int $characterId ID of Character to show submission of + */ + public function submission($questId, $characterId) + { + // Nothing to do } } diff --git a/questtypes/dummy/html/index.tpl b/questtypes/dummy/html/quest.tpl similarity index 100% rename from questtypes/dummy/html/index.tpl rename to questtypes/dummy/html/quest.tpl diff --git a/questtypes/dummy/html/submission.tpl b/questtypes/dummy/html/submission.tpl new file mode 100644 index 00000000..e69de29b diff --git a/questtypes/dummy/html/submissions.tpl b/questtypes/dummy/html/submissions.tpl new file mode 100644 index 00000000..e69de29b diff --git a/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc b/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc index 44c99e3b..77717863 100644 --- a/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc +++ b/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc @@ -24,12 +24,61 @@ /** - * Action: index. + * Save the answers of a Character for a Quest. + * TODO saveAnswersOfCharacter() * - * Display a text with input fields and evaluate if user input - * matches with stored regular expressions. + * @param int $questId ID of Quest to save answers for + * @param int $characterId ID of Character to save answers of + * @param array $answers Character answers for the Quest */ - public function index($questId) + public function saveAnswersOfCharacter($questId, $characterId, $answers) + { + } + + + /** + * Check if answers of a Character for a Quest match the correct ones. + * + * @param int $questId ID of Quest to match answers for + * @param int $characterId ID of Character to match answers of + * @return boolean True/false for a right/wrong answer or null for moderator evaluation + */ + public function matchAnswersOfCharacter($questId, $characterId, $answers) + { + // Get right answers + $tickQuestions = $this->Multiplechoice->getTickQuestionsOfQuest($questId); + + // Match tick questions with user answers + $allSolved = true; + foreach($tickQuestions as &$tickQuestion) + { + $pos = intval($tickQuestion['pos'])-1; + if(!array_key_exists($pos, $answers) || $answers[$pos] != 'true') + { + $allSolved = false; + break; + } + else { + unset($answers[$pos]); + } + } + + + // Return status + return ($allSolved && count($answers) == 0); + } + + + /** + * Action: quest. + * + * Display questions with a checkbox to let the user choose the + * right ones. + * + * @param int $questId ID of Quest to show + * @param int $characterId ID of Character + */ + public function quest($questId, $characterId) { // Answers if(!array_key_exists('answers', $_SESSION)) { @@ -37,43 +86,6 @@ } $answers = array_key_exists($questId, $_SESSION['answers']) ? $_SESSION['answers'][$questId] : array(); - // Check for submission - if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('submit'))) - { - // Get answers - $answers = $this->request->getPostParam('answers'); - - // Store answers in session - $_SESSION['answers'][$questId] = $answers; - - // Get right answers - $tickQuestions = $this->Multiplechoice->getTickQuestionsOfQuest($questId); - - // Match tick questions with user answers - $allSolved = true; - foreach($tickQuestions as &$tickQuestion) - { - $pos = intval($tickQuestion['pos'])-1; - if(!array_key_exists($pos, $answers) && $answers[$pos] == 'true') - { - $allSolved = false; - break; - } - else { - unset($answers[$pos]); - } - } - - // Set status - if($allSolved && count($answers) == 0) { - $this->setQuestSolved(); - } - else { - $this->setQuestUnsolved(); - } - } - - // Get questions $questions = $this->Multiplechoice->getQuestionsOfQuest($questId); @@ -83,6 +95,20 @@ $this->set('answers', $answers); } + + /** + * Action: submission. + * @TODO submission() + * + * Show the submission of a Character for a Quest. + * + * @param int $questId ID of Quest to show submission for + * @param int $characterId ID of Character to show submission of + */ + public function submission($questId, $characterId) + { + } + } ?> diff --git a/questtypes/multiplechoice/html/index.tpl b/questtypes/multiplechoice/html/quest.tpl similarity index 100% rename from questtypes/multiplechoice/html/index.tpl rename to questtypes/multiplechoice/html/quest.tpl diff --git a/questtypes/multiplechoice/html/submission.tpl b/questtypes/multiplechoice/html/submission.tpl new file mode 100644 index 00000000..e69de29b diff --git a/questtypes/multiplechoice/html/submissions.tpl b/questtypes/multiplechoice/html/submissions.tpl new file mode 100644 index 00000000..e69de29b diff --git a/questtypes/textinput/TextinputQuesttypeController.inc b/questtypes/textinput/TextinputQuesttypeController.inc index 52acdb25..7963ffd7 100644 --- a/questtypes/textinput/TextinputQuesttypeController.inc +++ b/questtypes/textinput/TextinputQuesttypeController.inc @@ -24,12 +24,64 @@ /** - * Action: index. + * Save the answers of a Character for a Quest. + * TODO saveAnswersOfCharacter() + * + * @param int $questId ID of Quest to save answers for + * @param int $characterId ID of Character to save answers of + * @param array $answers Character answers for the Quest + */ + public function saveAnswersOfCharacter($questId, $characterId, $answers) + { + } + + + /** + * Check if answers of a Character for a Quest match the correct ones. + * + * @param int $questId ID of Quest to match answers for + * @param int $characterId ID of Character to match answers of + * @return boolean True/false for a right/wrong answer or null for moderator evaluation + */ + public function matchAnswersOfCharacter($questId, $characterId, $answers) + { + // Get right answers + $regexs = $this->Textinput->getTextinputRegexs($questId); + + // Match regexs with user answers + $allSolved = true; + foreach($regexs as $i => &$regex) + { + if(!array_key_exists($i, $answers)) + { + $allSolved = false; + break; + } + + $score = preg_match($regex['regex'], $answers[$i]); + if($score === 0 || $score === false) + { + $allSolved = false; + break; + } + } + + + // Set status + return $allSolved; + } + + + /** + * Action: quest. * * Display a text with input fields and evaluate if user input * matches with stored regular expressions. + * + * @param int $questId ID of Quest to show + * @param int $characterId ID of Character */ - public function index($questId) + public function quest($questId, $characterId) { // Answers if(!array_key_exists('answers', $_SESSION)) { @@ -37,45 +89,6 @@ } $answers = array_key_exists($questId, $_SESSION['answers']) ? $_SESSION['answers'][$questId] : array(); - // Check for submission - if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('submit'))) - { - // Get answers - $answers = $this->request->getPostParam('answers'); - - // Store answers in session - $_SESSION['answers'][$questId] = $answers; - - // Get right answers - $regexs = $this->Textinput->getTextinputRegexs($questId); - - // Match regexs with user answers - $allSolved = true; - foreach($regexs as $i => &$regex) - { - if(!array_key_exists($i, $answers)) - { - $allSolved = false; - break; - } - - $score = preg_match($regex['regex'], $answers[$i]); - if($score === 0 || $score === false) - { - $allSolved = false; - break; - } - } - - // Set status - if($allSolved) { - $this->setQuestSolved(); - } - else { - $this->setQuestUnsolved(); - } - } - // Get Task $task = $this->Textinput->getTextinputQuest($questId); @@ -89,6 +102,20 @@ $this->set('answers', $answers); } + + /** + * Action: submission. + * @TODO submission() + * + * Show the submission of a Character for a Quest. + * + * @param int $questId ID of Quest to show submission for + * @param int $characterId ID of Character to show submission of + */ + public function submission($questId, $characterId) + { + } + } ?> diff --git a/questtypes/textinput/html/index.tpl b/questtypes/textinput/html/quest.tpl similarity index 100% rename from questtypes/textinput/html/index.tpl rename to questtypes/textinput/html/quest.tpl diff --git a/questtypes/textinput/html/submission.tpl b/questtypes/textinput/html/submission.tpl new file mode 100644 index 00000000..e69de29b diff --git a/questtypes/textinput/html/submissions.tpl b/questtypes/textinput/html/submissions.tpl new file mode 100644 index 00000000..e69de29b diff --git a/views/html/quests/submission.tpl b/views/html/quests/submission.tpl new file mode 100644 index 00000000..0f28d7e5 --- /dev/null +++ b/views/html/quests/submission.tpl @@ -0,0 +1,14 @@ +

+

+ + + + + + + + +

+
+ +
diff --git a/views/html/quests/submissions.tpl b/views/html/quests/submissions.tpl new file mode 100644 index 00000000..7867e1d2 --- /dev/null +++ b/views/html/quests/submissions.tpl @@ -0,0 +1,36 @@ +

+

+ + + + + +

+ +

+

+ + + + + + +
+

+
    + +
  • + +
  • + +
+ +

+
    + +
  • + +
  • + +
+