From 8abf29b2b0b1df89fa4543f0402dade73a8fdab0 Mon Sep 17 00:00:00 2001 From: coderkun Date: Fri, 4 Apr 2014 13:32:31 +0200 Subject: [PATCH] implement uploading a file as answer for Questtype ?Submit? --- app/exceptions/MaxFilesizeException.inc | 51 ++++++++++++++++++ app/exceptions/WrongFiletypeException.inc | 51 ++++++++++++++++++ .../submit/SubmitQuesttypeController.inc | 54 ++++++++++++++----- questtypes/submit/SubmitQuesttypeModel.inc | 52 ++++++++++++++---- questtypes/submit/html/quest.tpl | 31 +++++++---- questtypes/submit/html/submission.tpl | 2 +- 6 files changed, 207 insertions(+), 34 deletions(-) create mode 100644 app/exceptions/MaxFilesizeException.inc create mode 100644 app/exceptions/WrongFiletypeException.inc diff --git a/app/exceptions/MaxFilesizeException.inc b/app/exceptions/MaxFilesizeException.inc new file mode 100644 index 00000000..f16f335e --- /dev/null +++ b/app/exceptions/MaxFilesizeException.inc @@ -0,0 +1,51 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: File exceeds size maximum. + * + * @author Oliver Hanraths + */ + class MaxFilesizeException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 202; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'File exceeds size maximum'; + + + + + /** + * Construct a new exception. + */ + function __construct($message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code + ); + } + + } + +?> diff --git a/app/exceptions/WrongFiletypeException.inc b/app/exceptions/WrongFiletypeException.inc new file mode 100644 index 00000000..a3bfbe41 --- /dev/null +++ b/app/exceptions/WrongFiletypeException.inc @@ -0,0 +1,51 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: File has wrong filetype. + * + * @author Oliver Hanraths + */ + class WrongFiletypeException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 201; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'File has wrong type'; + + + + + /** + * Construct a new exception. + */ + function __construct($message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code + ); + } + + } + +?> diff --git a/questtypes/submit/SubmitQuesttypeController.inc b/questtypes/submit/SubmitQuesttypeController.inc index 32193bb0..42f98aeb 100644 --- a/questtypes/submit/SubmitQuesttypeController.inc +++ b/questtypes/submit/SubmitQuesttypeController.inc @@ -32,6 +32,7 @@ /** * Save the answers of a Character for a Quest. * + * @throws SubmissionNotValidException * @param array $seminary Current Seminary data * @param array $questgroup Current Questgroup data * @param array $quest Current Quest data @@ -44,8 +45,34 @@ $characterSubmission = $this->Submit->getCharacterSubmission($quest['id'], $character['id']); // Save answer - if(is_null($characterSubmission) && array_key_exists(0, $answers)) { - $this->Submit->setCharacterSubmission($quest['id'], $character['id'], $answers[0]); + if(is_null($characterSubmission) && array_key_exists('answers', $_FILES)) + { + $answer = $_FILES['answers']; + + // Check mimetype + $mimetypes = $this->Submit->getAllowedMimetypes($seminary['id']); + $answerMimetype = null; + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $answer['type']) { + $answerMimetype = $mimetype; + break; + } + } + + // Check file + if(is_null($answerMimetype)) { + throw new \hhu\z\exceptions\SubmissionNotValidException( + new \hhu\z\exceptions\WrongFiletypeException() + ); + } + if($answer['size'] > $answerMimetype['size']) { + throw new \hhu\z\exceptions\SubmissionNotValidException( + new \hhu\z\exceptions\MaxFilesizeException() + ); + } + + // Save file + $this->Submit->setCharacterSubmission($seminary['id'], $quest['id'], $this->Auth->getUserId(), $character['id'], $answer); } } @@ -73,30 +100,29 @@ * Display a big textbox to let the user enter a text that has * to be evaluated by a moderator. * - * @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 $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param Exception $exception Character submission exception */ - public function quest($seminary, $questgroup, $quest, $character) + public function quest($seminary, $questgroup, $quest, $character, $exception) { // Answer (Submission) $characterSubmission = $this->Submit->getCharacterSubmission($quest['id'], $character['id']); - // Wordcount - $wordcount = 0; - if(!is_null($characterSubmission)) { - $wordcount = count(preg_split('/\s+/', $characterSubmission['text'])); - } - // Has Character already solved Quest? $solved = $this->Quests->hasCharacterSolvedQuest($quest['id'], $character['id']); + // Get allowed mimetypes + $mimetypes = $this->Submit->getAllowedMimetypes($seminary['id']); + // Pass data to view $this->set('submission', $characterSubmission); - $this->set('wordcount', $wordcount); $this->set('solved', $solved); + $this->set('mimetypes', $mimetypes); + $this->set('exception', $exception); } diff --git a/questtypes/submit/SubmitQuesttypeModel.inc b/questtypes/submit/SubmitQuesttypeModel.inc index 4f361533..2d0a17e3 100644 --- a/questtypes/submit/SubmitQuesttypeModel.inc +++ b/questtypes/submit/SubmitQuesttypeModel.inc @@ -19,32 +19,48 @@ */ class SubmitQuesttypeModel extends \hhu\z\QuesttypeModel { + /** + * Required models + * + * @var array + */ + public $models = array('uploads'); /** - * Save Character’s submitted text. + * Save Character’s submitted upload. * * @param int $questId ID of Quest * @param int $characterId ID of Character - * @param string $text Submitted text + * @param array $file Submitted upload */ - public function setCharacterSubmission($questId, $characterId, $text) + public function setCharacterSubmission($seminaryId, $questId, $userId, $characterId, $file) { + // Save file on harddrive + $uploadId = $this->Uploads->uploadFile($userId, $file['name'], $file['tmp_name'], $file['type'], $seminaryId); + if($uploadId === false) { + return false; + } + + // Create database record $this->db->query( 'INSERT INTO questtypes_submit_characters '. - '(quest_id, character_id, text) '. + '(quest_id, character_id, upload_id) '. 'VALUES '. '(?, ?, ?) ', - 'iis', - $questId, $characterId, $text + 'iii', + $questId, $characterId, $uploadId ); + + + return true; } /** - * Get text submitted by Character. + * Get upload submitted by Character. * * @param int $questId ID of Quest * @param int $characterId ID of Character @@ -53,20 +69,38 @@ public function getCharacterSubmission($questId, $characterId) { $data = $this->db->query( - 'SELECT created, text '. + 'SELECT upload_id '. 'FROM questtypes_submit_characters '. 'WHERE quest_id = ? AND character_id = ?', 'ii', $questId, $characterId ); if(!empty($data)) { - return $data[0]; + return $this->Uploads->getUploadById($data[0]['upload_id']); } return null; } + + /** + * Get allowed mimetypes for uploading a file. + * + * @param int $seminaryId ID of Seminary + * @return array Allowed mimetypes + */ + public function getAllowedMimetypes($seminaryId) + { + return $this->db->query( + 'SELECT id, mimetype, size '. + 'FROM questtypes_submit_mimetypes '. + 'WHERE seminary_id = ?', + 'i', + $seminaryId + ); + } + } ?> diff --git a/questtypes/submit/html/quest.tpl b/questtypes/submit/html/quest.tpl index b170ef97..34e30f7c 100644 --- a/questtypes/submit/html/quest.tpl +++ b/questtypes/submit/html/quest.tpl @@ -1,14 +1,25 @@ -
-
- - - 1) : ?> -
+ +

+ getNestedException() instanceof \hhu\z\exceptions\WrongFiletypeException) : ?> + + getNestedException() instanceof \hhu\z\exceptions\WrongFiletypeException) : ?> + -
+ getNestedException()->getMessage()?> - (format(new \DateTime($submission['created'])), $timeFormatter->format(new \DateTime($submission['created'])))?>) - +

+ + + +
+ Erlaubte Dateiformate: +
    + +
  • ( format(round($mimetype['size']/(1024*1024),2))?> MiB)
  • + +
-
+ + (format(new \DateTime($submission['created'])), $timeFormatter->format(new \DateTime($submission['created'])))?>) + diff --git a/questtypes/submit/html/submission.tpl b/questtypes/submit/html/submission.tpl index 77403dc9..b3d89275 100644 --- a/questtypes/submit/html/submission.tpl +++ b/questtypes/submit/html/submission.tpl @@ -1,5 +1,5 @@
- + (format(new \DateTime($submission['created'])), $timeFormatter->format(new \DateTime($submission['created'])))?>)