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 d2a25591..0ad32726 100644 Binary files a/locale/de_DE/LC_MESSAGES/The Legend of Z.mo and b/locale/de_DE/LC_MESSAGES/The Legend of Z.mo differ diff --git a/locale/de_DE/LC_MESSAGES/The Legend of Z.po b/locale/de_DE/LC_MESSAGES/The Legend of Z.po index 80b79587..95a49652 100644 --- a/locale/de_DE/LC_MESSAGES/The Legend of Z.po +++ b/locale/de_DE/LC_MESSAGES/The Legend of Z.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: The Legend of Z\n" -"POT-Creation-Date: 2014-03-04 11:59+0100\n" -"PO-Revision-Date: 2014-03-04 12:00+0100\n" +"POT-Creation-Date: 2014-03-18 23:06+0100\n" +"PO-Revision-Date: 2014-03-18 23:09+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: de_DE\n" @@ -27,7 +27,8 @@ msgstr "Fehler" #: ../../../views/html/menu/index.tpl:3 #: ../../../views/html/questgroups/questgroup.tpl:1 #: ../../../views/html/quests/quest.tpl:1 -#: ../../../views/html/quests/sidequest.tpl:1 +#: ../../../views/html/quests/submission.tpl:1 +#: ../../../views/html/quests/submissions.tpl:1 #: ../../../views/html/seminaries/create.tpl:1 #: ../../../views/html/seminaries/delete.tpl:1 #: ../../../views/html/seminaries/edit.tpl:1 @@ -39,7 +40,7 @@ msgstr "Kurse" #: ../../../views/html/charactergroups/group.tpl:3 #: ../../../views/html/charactergroups/groupsgroup.tpl:3 #: ../../../views/html/charactergroups/index.tpl:3 -#: ../../../views/html/characters/character.tpl:16 +#: ../../../views/html/characters/character.tpl:19 #: ../../../views/html/seminaries/seminary.tpl:9 msgid "Character Groups" msgstr "Charaktergruppen" @@ -116,36 +117,37 @@ msgstr "Logout" msgid "locked" msgstr "gesperrt" -#: ../../../views/html/questgroups/questgroup.tpl:38 +#: ../../../views/html/questgroups/questgroup.tpl:39 msgid "containing optional Quests" msgstr "Enthaltene optionale Quests" -#: ../../../views/html/quests/quest.tpl:15 -#: ../../../views/html/quests/sidequest.tpl:17 +#: ../../../views/html/quests/quest.tpl:21 +#: ../../../views/html/quests/submissions.tpl:28 msgid "solved" msgstr "gelöst" -#: ../../../views/html/quests/quest.tpl:17 -#: ../../../views/html/quests/sidequest.tpl:19 +#: ../../../views/html/quests/quest.tpl:23 +#: ../../../views/html/quests/submissions.tpl:19 msgid "unsolved" msgstr "ungelöst" -#: ../../../views/html/quests/quest.tpl:53 +#: ../../../views/html/quests/quest.tpl:56 msgid "Go on" msgstr "Hier geht es weiter" -#: ../../../views/html/quests/quest.tpl:57 +#: ../../../views/html/quests/quest.tpl:61 +#: ../../../views/html/quests/quest.tpl:63 msgid "Quest" msgstr "Quest" -#: ../../../views/html/quests/quest.tpl:70 -#: ../../../views/html/quests/sidequest.tpl:51 +#: ../../../views/html/quests/quest.tpl:77 msgid "Task" msgstr "Aufgabe" -#: ../../../views/html/quests/sidequest.tpl:9 -msgid "This Quest is optional" -msgstr "Diese Quest ist optional" +#: ../../../views/html/quests/submission.tpl:11 +#, php-format +msgid "Submission of %s" +msgstr "Lösungen von %s" #: ../../../views/html/seminaries/create.tpl:2 msgid "New seminary" @@ -253,6 +255,9 @@ msgstr "registriert am %s" msgid "Roles" msgstr "Rollen" +#~ msgid "This Quest is optional" +#~ msgstr "Diese Quest ist optional" + #~ msgid "created by %s on %s at %s" #~ msgstr "erstellt von %s am %s um %s Uhr" diff --git a/models/CharactersModel.inc b/models/CharactersModel.inc index 59125e32..109bee80 100644 --- a/models/CharactersModel.inc +++ b/models/CharactersModel.inc @@ -150,6 +150,35 @@ return $data[0]; } + + /** + * Get a Character by its Id. + * + * @throws IdNotFoundException + * @param string $characterId ID of the Character + * @return array Character data + */ + public function getCharacterById($characterId) + { + $data = $this->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 @@ +

+

+ + + + + +

+ +

+

+ + + + + + +
+

+ + +

+ +