From 95837803a1d32c3b8f61ccf50bae357b6221f52d Mon Sep 17 00:00:00 2001
From: coderkun
Date: Wed, 23 Apr 2014 15:08:53 +0200
Subject: [PATCH] improve Questtype ?submit? and store additional data for
Character answers
---
app/QuesttypeController.inc | 12 +++
configs/AppConfig.inc | 4 +-
controllers/QuestsController.inc | 5 +-
models/QuestsModel.inc | 27 +++++++
.../BossfightQuesttypeController.inc | 14 ++++
.../ChoiceinputQuesttypeController.inc | 14 ++++
.../CrosswordQuesttypeController.inc | 14 ++++
.../DragndropQuesttypeController.inc | 14 ++++
.../MultiplechoiceQuesttypeController.inc | 14 ++++
.../submit/SubmitQuesttypeController.inc | 79 ++++++++++++++++---
questtypes/submit/SubmitQuesttypeModel.inc | 62 ++++++++++++---
questtypes/submit/html/quest.tpl | 33 +++++++-
questtypes/submit/html/submission.tpl | 34 ++++++--
.../TextinputQuesttypeController.inc | 14 ++++
14 files changed, 302 insertions(+), 38 deletions(-)
diff --git a/app/QuesttypeController.inc b/app/QuesttypeController.inc
index 25544ab2..9b13512e 100644
--- a/app/QuesttypeController.inc
+++ b/app/QuesttypeController.inc
@@ -41,6 +41,18 @@
public abstract function saveAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers);
+ /**
+ * Save additional data for the answers of a Character for a Quest.
+ *
+ * @param array $seminary Current Seminary data
+ * @param array $questgroup Current Questgroup data
+ * @param array $quest Current Quest data
+ * @param array $character Current Character data
+ * @param array $data Additional (POST-) data
+ */
+ public abstract function saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $data);
+
+
/**
* Check if answers of a Character for a Quest match the correct ones.
*
diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc
index 38fef10e..28f4c00f 100644
--- a/configs/AppConfig.inc
+++ b/configs/AppConfig.inc
@@ -117,12 +117,12 @@
),
'prename' => array(
'minlength' => 2,
- 'maxlength' => 128,
+ 'maxlength' => 32,
'regex' => '/^\S*$/'
),
'surname' => array(
'minlength' => 2,
- 'maxlength' => 128,
+ 'maxlength' => 32,
'regex' => '/^\S*$/'
),
'password' => array(
diff --git a/controllers/QuestsController.inc b/controllers/QuestsController.inc
index 6da2906d..04fd1d31 100644
--- a/controllers/QuestsController.inc
+++ b/controllers/QuestsController.inc
@@ -625,7 +625,7 @@
$this->Quests->setQuestSubmitted($quest['id'], $character['id']);
// Redirect
- $this->redirect($this->linker->link('Prolog', 5, true));
+ //$this->redirect($this->linker->link('Prolog', 5, true));
}
}
catch(\hhu\z\exceptions\SubmissionNotValidException $e) {
@@ -703,6 +703,9 @@
$this->Quests->setQuestUnsolved($quest['id'], $character['id']);
}
+ // Save additional data for Character answers
+ $questtypeAgent->controller->saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $this->request->getPostParam('characterdata'));
+
// Redirect
$this->redirect($this->linker->link(array('submissions', $seminary['url'], $questgroup['url'], $quest['url']), 1));
}
diff --git a/models/QuestsModel.inc b/models/QuestsModel.inc
index ffffb536..d4175545 100644
--- a/models/QuestsModel.inc
+++ b/models/QuestsModel.inc
@@ -406,6 +406,33 @@
}
+ /**
+ * Get the last status of a Quest for a Character.
+ *
+ * @param int $questId ID of Quest
+ * @param int $characterId ID of Character to get status for
+ * @return int Last status
+ */
+ public function getLastQuestStatus($questId, $characterId)
+ {
+ $data = $this->db->query(
+ 'SELECT id, created, status '.
+ 'FROM quests_characters '.
+ 'WHERE quest_id = ? AND character_id = ? '.
+ 'ORDER BY created DESC '.
+ 'LIMIT 1',
+ 'ii',
+ $questId, $characterId
+ );
+ if(!empty($data)) {
+ return $data[0];
+ }
+
+
+ return null;
+ }
+
+
/**
* Create a new Quest.
*
diff --git a/questtypes/bossfight/BossfightQuesttypeController.inc b/questtypes/bossfight/BossfightQuesttypeController.inc
index 366aabc8..4f8001e7 100644
--- a/questtypes/bossfight/BossfightQuesttypeController.inc
+++ b/questtypes/bossfight/BossfightQuesttypeController.inc
@@ -53,6 +53,20 @@
}
+ /**
+ * Save additional data for the answers of a Character for a Quest.
+ *
+ * @param array $seminary Current Seminary data
+ * @param array $questgroup Current Questgroup data
+ * @param array $quest Current Quest data
+ * @param array $character Current Character data
+ * @param array $data Additional (POST-) data
+ */
+ public function saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $data)
+ {
+ }
+
+
/**
* Check if answers of a Character for a Quest match the correct ones.
*
diff --git a/questtypes/choiceinput/ChoiceinputQuesttypeController.inc b/questtypes/choiceinput/ChoiceinputQuesttypeController.inc
index 1b7eff27..be75b852 100644
--- a/questtypes/choiceinput/ChoiceinputQuesttypeController.inc
+++ b/questtypes/choiceinput/ChoiceinputQuesttypeController.inc
@@ -48,6 +48,20 @@
}
+ /**
+ * Save additional data for the answers of a Character for a Quest.
+ *
+ * @param array $seminary Current Seminary data
+ * @param array $questgroup Current Questgroup data
+ * @param array $quest Current Quest data
+ * @param array $character Current Character data
+ * @param array $data Additional (POST-) data
+ */
+ public function saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $data)
+ {
+ }
+
+
/**
* Check if answers of a Character for a Quest match the correct ones.
*
diff --git a/questtypes/crossword/CrosswordQuesttypeController.inc b/questtypes/crossword/CrosswordQuesttypeController.inc
index ba3e5a0c..318271f9 100644
--- a/questtypes/crossword/CrosswordQuesttypeController.inc
+++ b/questtypes/crossword/CrosswordQuesttypeController.inc
@@ -81,6 +81,20 @@
}
+ /**
+ * Save additional data for the answers of a Character for a Quest.
+ *
+ * @param array $seminary Current Seminary data
+ * @param array $questgroup Current Questgroup data
+ * @param array $quest Current Quest data
+ * @param array $character Current Character data
+ * @param array $data Additional (POST-) data
+ */
+ public function saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $data)
+ {
+ }
+
+
/**
* Check if answers of a Character for a Quest match the correct ones.
*
diff --git a/questtypes/dragndrop/DragndropQuesttypeController.inc b/questtypes/dragndrop/DragndropQuesttypeController.inc
index 5fbf6328..9797f8fd 100644
--- a/questtypes/dragndrop/DragndropQuesttypeController.inc
+++ b/questtypes/dragndrop/DragndropQuesttypeController.inc
@@ -65,6 +65,20 @@
}
+ /**
+ * Save additional data for the answers of a Character for a Quest.
+ *
+ * @param array $seminary Current Seminary data
+ * @param array $questgroup Current Questgroup data
+ * @param array $quest Current Quest data
+ * @param array $character Current Character data
+ * @param array $data Additional (POST-) data
+ */
+ public function saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $data)
+ {
+ }
+
+
/**
* Check if answers of a Character for a Quest match the correct ones.
*
diff --git a/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc b/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc
index bca8c33a..b025f758 100644
--- a/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc
+++ b/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc
@@ -55,6 +55,20 @@
}
+ /**
+ * Save additional data for the answers of a Character for a Quest.
+ *
+ * @param array $seminary Current Seminary data
+ * @param array $questgroup Current Questgroup data
+ * @param array $quest Current Quest data
+ * @param array $character Current Character data
+ * @param array $data Additional (POST-) data
+ */
+ public function saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $data)
+ {
+ }
+
+
/**
* Check if answers of a Character for a Quest match the correct ones.
*
diff --git a/questtypes/submit/SubmitQuesttypeController.inc b/questtypes/submit/SubmitQuesttypeController.inc
index 18e55d1b..e064c542 100644
--- a/questtypes/submit/SubmitQuesttypeController.inc
+++ b/questtypes/submit/SubmitQuesttypeController.inc
@@ -24,7 +24,7 @@
*
* @var array
*/
- public $models = array('quests');
+ public $models = array('quests', 'uploads', 'users');
@@ -41,11 +41,8 @@
*/
public function saveAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers)
{
- // Get already submitted answer
- $characterSubmission = $this->Submit->getCharacterSubmission($quest['id'], $character['id']);
-
// Save answer
- if(is_null($characterSubmission) && array_key_exists('answers', $_FILES))
+ if(array_key_exists('answers', $_FILES))
{
$answer = $_FILES['answers'];
@@ -78,8 +75,17 @@
);
}
+ // Create filename
+ $filename = sprintf(
+ '%s,%s,%s.%s',
+ $character['url'],
+ mb_substr($quest['url'], 0, 32),
+ date('Ymd-His'),
+ mb_substr(mb_substr($answer['name'], strrpos($answer['name'], '.')+1), 0, 4)
+ );
+
// Save file
- if(!$this->Submit->setCharacterSubmission($seminary['id'], $quest['id'], $this->Auth->getUserId(), $character['id'], $answer)) {
+ if(!$this->Submit->setCharacterSubmission($seminary['id'], $quest['id'], $this->Auth->getUserId(), $character['id'], $answer, $filename)) {
throw new \hhu\z\exceptions\SubmissionNotValidException(
new \hhu\z\exceptions\FileUploadException(error_get_last()['message'])
);
@@ -88,6 +94,21 @@
}
+ /**
+ * Save additional data for the answers of a Character for a Quest.
+ *
+ * @param array $seminary Current Seminary data
+ * @param array $questgroup Current Questgroup data
+ * @param array $quest Current Quest data
+ * @param array $character Current Character data
+ * @param array $data Additional (POST-) data
+ */
+ public function saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $data)
+ {
+ $this->Submit->addCommentForCharacterAnswer($this->Auth->getUserId(), $data['submission_id'], $data['comment']);
+ }
+
+
/**
* Check if answers of a Character for a Quest match the correct ones.
*
@@ -119,19 +140,38 @@
*/
public function quest($seminary, $questgroup, $quest, $character, $exception)
{
- // Answer (Submission)
- $characterSubmission = $this->Submit->getCharacterSubmission($quest['id'], $character['id']);
+ // Answers (Submissions)
+ $characterSubmissions = $this->Submit->getCharacterSubmissions($quest['id'], $character['id']);
+ foreach($characterSubmissions as &$submission)
+ {
+ $submission['upload'] = $this->Uploads->getSeminaryuploadById($submission['upload_id']);
+ $submission['comments'] = $this->Submit->getCharacterSubmissionComments($submission['id']);
+ foreach($submission['comments'] as &$comment)
+ {
+ try {
+ $comment['user'] = $this->Users->getUserById($comment['created_user_id']);
+ $comment['user']['character'] = $this->Characters->getCharacterForUserAndSeminary($comment['user']['id'], $seminary['id']);
+ }
+ catch(\nre\exceptions\IdNotFoundException $e) {
+ }
+ }
+ }
// Has Character already solved Quest?
$solved = $this->Quests->hasCharacterSolvedQuest($quest['id'], $character['id']);
+ // Last Quest status for Character
+ $lastStatus = $this->Quests->getLastQuestStatus($quest['id'], $character['id']);
+
// Get allowed mimetypes
$mimetypes = $this->Submit->getAllowedMimetypes($seminary['id']);
// Pass data to view
- $this->set('submission', $characterSubmission);
+ $this->set('seminary', $seminary);
+ $this->set('submissions', $characterSubmissions);
$this->set('solved', $solved);
+ $this->set('lastStatus', $lastStatus);
$this->set('mimetypes', $mimetypes);
$this->set('exception', $exception);
}
@@ -149,15 +189,30 @@
*/
public function submission($seminary, $questgroup, $quest, $character)
{
- // Get Character submission
- $submission = $this->Submit->getCharacterSubmission($quest['id'], $character['id']);
+ // Get Character submissions
+ $submissions = $this->Submit->getCharacterSubmissions($quest['id'], $character['id']);
+ foreach($submissions as &$submission)
+ {
+ $submission['upload'] = $this->Uploads->getSeminaryuploadById($submission['upload_id']);
+ $submission['comments'] = $this->Submit->getCharacterSubmissionComments($submission['id']);
+ foreach($submission['comments'] as &$comment)
+ {
+ try {
+ $comment['user'] = $this->Users->getUserById($comment['created_user_id']);
+ $comment['user']['character'] = $this->Characters->getCharacterForUserAndSeminary($comment['user']['id'], $seminary['id']);
+ }
+ catch(\nre\exceptions\IdNotFoundException $e) {
+ }
+ }
+ }
// Status
$solved = $this->Quests->hasCharacterSolvedQuest($quest['id'], $character['id']);
// Pass data to view
- $this->set('submission', $submission);
+ $this->set('seminary', $seminary);
+ $this->set('submissions', $submissions);
$this->set('solved', $solved);
}
diff --git a/questtypes/submit/SubmitQuesttypeModel.inc b/questtypes/submit/SubmitQuesttypeModel.inc
index 2d0a17e3..5d821655 100644
--- a/questtypes/submit/SubmitQuesttypeModel.inc
+++ b/questtypes/submit/SubmitQuesttypeModel.inc
@@ -32,14 +32,15 @@
/**
* Save Character’s submitted upload.
*
+ * @param int $seminaryId ID of Seminary
* @param int $questId ID of Quest
* @param int $characterId ID of Character
* @param array $file Submitted upload
*/
- public function setCharacterSubmission($seminaryId, $questId, $userId, $characterId, $file)
+ public function setCharacterSubmission($seminaryId, $questId, $userId, $characterId, $file, $filename)
{
// Save file on harddrive
- $uploadId = $this->Uploads->uploadFile($userId, $file['name'], $file['tmp_name'], $file['type'], $seminaryId);
+ $uploadId = $this->Uploads->uploadSeminaryFile($userId, $seminaryId, $file['name'], $filename, $file['tmp_name'], $file['type']);
if($uploadId === false) {
return false;
}
@@ -60,27 +61,44 @@
/**
- * Get upload submitted by Character.
+ * Add a comment for the answer of a Character.
+ *
+ * @param int $userId ID of user that comments
+ * @param int $submissionId ID of Character answer to comment
+ * @param string $comment Comment text
+ */
+ public function addCommentForCharacterAnswer($userId, $submissionId, $comment)
+ {
+ $this->db->query(
+ 'INSERT INTO questtypes_submit_characters_comments '.
+ '(created_user_id, questtypes_submit_character_id, comment) '.
+ 'VALUES '.
+ '(?, ?, ?)',
+ 'iis',
+ $userId,
+ $submissionId,
+ $comment
+ );
+ }
+
+
+ /**
+ * Get all uploads submitted by Character.
*
* @param int $questId ID of Quest
* @param int $characterId ID of Character
* @return array Text submitted by Character or NULL
*/
- public function getCharacterSubmission($questId, $characterId)
+ public function getCharacterSubmissions($questId, $characterId)
{
- $data = $this->db->query(
- 'SELECT upload_id '.
+ return $this->db->query(
+ 'SELECT id, created, upload_id '.
'FROM questtypes_submit_characters '.
- 'WHERE quest_id = ? AND character_id = ?',
+ 'WHERE quest_id = ? AND character_id = ? '.
+ 'ORDER BY created ASC',
'ii',
$questId, $characterId
);
- if(!empty($data)) {
- return $this->Uploads->getUploadById($data[0]['upload_id']);
- }
-
-
- return null;
}
@@ -101,6 +119,24 @@
);
}
+
+ /**
+ * Get all comments for a Character submission.
+ *
+ * @param int $characterSubmissionId ID of Character submission
+ * @return array Comments for this submission
+ */
+ public function getCharacterSubmissionComments($characterSubmissionId)
+ {
+ return $this->db->query(
+ 'SELECT id, created, created_user_id, comment '.
+ 'FROM questtypes_submit_characters_comments '.
+ 'WHERE questtypes_submit_character_id = ?',
+ 'i',
+ $characterSubmissionId
+ );
+ }
+
}
?>
diff --git a/questtypes/submit/html/quest.tpl b/questtypes/submit/html/quest.tpl
index 7132de5e..4581c40d 100644
--- a/questtypes/submit/html/quest.tpl
+++ b/questtypes/submit/html/quest.tpl
@@ -11,17 +11,42 @@
-
+ $submissions[count($submissions)-1]['created'])) : ?>
-
-=$submission['name']?> (=sprintf(_('submitted at %s on %s h'), $dateFormatter->format(new \DateTime($submission['created'])), $timeFormatter->format(new \DateTime($submission['created'])))?>)
+
+
+ 0) : ?>
+=_('Past submissions')?>
+
+
+ -
+ =$submission['upload']['name']?>
+ =sprintf(_('submitted at %s on %s h'), $dateFormatter->format(new \DateTime($submission['created'])), $timeFormatter->format(new \DateTime($submission['created'])))?>
+
+ =_('This submission is waiting for approval')?>
+
+ 0) : ?>
+
+
+ -
+
+ =sprintf(_('Comment from %s on %s at %s'), $comment['user']['character']['name'], $dateFormatter->format(new \DateTime($comment['created'])), $timeFormatter->format(new \DateTime($comment['created'])))?>:
+
+ =\hhu\z\Utils::t($comment['comment'])?>
+
+
+
+
+
+
+
diff --git a/questtypes/submit/html/submission.tpl b/questtypes/submit/html/submission.tpl
index b3d89275..f3c748ef 100644
--- a/questtypes/submit/html/submission.tpl
+++ b/questtypes/submit/html/submission.tpl
@@ -1,10 +1,32 @@
+ 0) : ?>
+
+
+ -
+ =$submission['upload']['name']?>
+ =sprintf(_('submitted at %s on %s h'), $dateFormatter->format(new \DateTime($submission['created'])), $timeFormatter->format(new \DateTime($submission['created'])))?>
+ 0) : ?>
+
+
+ -
+
+ =sprintf(_('Comment from %s on %s at %s'), $comment['user']['character']['name'], $dateFormatter->format(new \DateTime($comment['created'])), $timeFormatter->format(new \DateTime($comment['created'])))?>:
+
+ =\hhu\z\Utils::t($comment['comment'])?>
+
+
+
+
+
+
+
+
+