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

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