evolve QuesttypeAgents with fixed Actions and Character submission handling

This commit is contained in:
coderkun 2014-03-19 00:06:17 +01:00
commit 1c1d12a116
22 changed files with 724 additions and 140 deletions

View file

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

View file

@ -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

View file

@ -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.
*

View file

@ -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);
$response = $this->createQuesttypeResponse('quest', $quest['id'], $character['id']);
// Render output
$task = $questtypeAgent->render();
// 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();
}
}
?>

View file

@ -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"

View file

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

View file

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

View file

@ -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
}
}

View file

View file

View file

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

View file

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

View file

View file

@ -0,0 +1,14 @@
<h1><?=_('Seminaries')?></h1>
<h2><?=$seminary['title']?></h2>
<?=$questgroupshierarchypath?>
<?=$questgroupspicture?>
<?php if(!is_null($media)) : ?>
<img src="<?=$linker->link(array('media','index',$seminary['url'],$media['url']))?>" />
<?php endif ?>
<h3><?=sprintf(_('Submission of %s'),$character['name'])?></h1>
<section>
<?=$output?>
</section>

View file

@ -0,0 +1,36 @@
<h1><?=_('Seminaries')?></h1>
<h2><?=$seminary['title']?></h2>
<?=$questgroupshierarchypath?>
<?=$questgroupspicture?>
<?php if(is_null($relatedquesttext)) : ?>
<h3><?=$quest['title']?></h3>
<?php else : ?>
<h3><a href="<?=$linker->link(array('quest',$seminary['url'],$questgroup['url'],$relatedquesttext['quest']['url'],$relatedquesttext['type_url'],$relatedquesttext['pos']),1)?>"><?=$relatedquesttext['quest']['title']?></a></h3>
<h4><?=$quest['title']?></h4>
<?php endif ?>
<?php if(!is_null($media)) : ?>
<img src="<?=$linker->link(array('media','index',$seminary['url'],$media['url']))?>" />
<?php endif ?>
<section>
<h1><?=_('unsolved')?></h1>
<ul>
<?php foreach($unsolvedsubmissions as &$submission) : ?>
<li>
<a href="<?=$linker->link(array('submission',$seminary['url'],$questgroup['url'],$quest['url'],$submission['character']['url']),1)?>"><?=$submission['character']['name']?></a>
</li>
<?php endforeach?>
</ul>
<h1><?=_('solved')?></h1>
<ul>
<?php foreach($solvedsubmissions as &$submission) : ?>
<li>
<a href="<?=$linker->link(array('submission',$seminary['url'],$questgroup['url'],$quest['url'],$submission['character']['url']),1)?>"><?=$submission['character']['name']?></a>
</li>
<?php endforeach?>
</ul>
</section>