diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc index 1b86c448..6520b377 100644 --- a/configs/AppConfig.inc +++ b/configs/AppConfig.inc @@ -226,6 +226,10 @@ 'choice' => array( 'minlength' => 1, 'maxlength' => 128 + ), + 'answer' => array( + 'minlength' => 1, + 'maxlength' => 255 ) ); 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 fe054a8a..f80a3f79 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 e2054f68..db9566b3 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-08-17 20:38+0100\n" -"PO-Revision-Date: 2014-08-17 20:39+0100\n" +"POT-Creation-Date: 2014-08-29 15:17+0100\n" +"PO-Revision-Date: 2014-08-29 15:17+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: de_DE\n" @@ -106,7 +106,7 @@ msgid "Choice input invalid" msgstr "Die Auswahleingabe ist ungültig" #: questtypes/choiceinput/html/edittask.tpl:29 -#: questtypes/choiceinput/html/edittask.tpl:57 +#: questtypes/choiceinput/html/edittask.tpl:58 #, php-format msgid "Please select correct choice" msgstr "Bitte wähle die richtige Auswahleingabe aus" @@ -133,6 +133,7 @@ msgid "Preview" msgstr "Vorschau" #: questtypes/choiceinput/html/edittask.tpl:83 +#: questtypes/multiplechoice/html/edittask.tpl:79 #: questtypes/textinput/html/edittask.tpl:44 #: views/html/achievements/conditions.tpl:151 #: views/html/achievements/create.tpl:109 views/html/achievements/edit.tpl:112 @@ -153,6 +154,41 @@ msgstr "vertikal" msgid "horizontal" msgstr "horizontal" +#: questtypes/multiplechoice/html/edittask.tpl:12 +#: questtypes/multiplechoice/html/edittask.tpl:44 +#, php-format +msgid "Answer input is too short (min. %d chars)" +msgstr "Die Antwort ist zu kurz (min. %d Zeichen)" + +#: questtypes/multiplechoice/html/edittask.tpl:14 +#: questtypes/multiplechoice/html/edittask.tpl:46 +#, php-format +msgid "Answer input is too long (max. %d chars)" +msgstr "Die Antwort ist zu lang (max. %d Zeichen)" + +#: questtypes/multiplechoice/html/edittask.tpl:16 +#: questtypes/multiplechoice/html/edittask.tpl:48 +msgid "Answer input invalid" +msgstr "Die Anwort ist ungültig" + +#: questtypes/multiplechoice/html/edittask.tpl:30 +msgid "Questions" +msgstr "Fragen" + +#: questtypes/multiplechoice/html/edittask.tpl:34 +#: questtypes/multiplechoice/html/edittask.tpl:88 +msgid "Question" +msgstr "Frage" + +#: questtypes/multiplechoice/html/edittask.tpl:71 +#: questtypes/multiplechoice/html/edittask.tpl:90 +msgid "Remove question" +msgstr "Frage entfernen" + +#: questtypes/multiplechoice/html/edittask.tpl:75 +msgid "Add question" +msgstr "Frage hinzufügen" + #: questtypes/multiplechoice/html/quest.tpl:3 #, php-format msgid "Question %d of %d" diff --git a/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc b/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc index 485eab00..8bbca2d8 100644 --- a/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc +++ b/questtypes/multiplechoice/MultiplechoiceQuesttypeController.inc @@ -19,6 +19,12 @@ */ class MultiplechoiceQuesttypeController extends \hhu\z\controllers\QuesttypeController { + /** + * Required components + * + * @var array + */ + public $components = array('validation'); @@ -219,7 +225,7 @@ /** - * TODO Action: edittask. + * Action: edittask. * * Edit the task of a Quest. * @@ -229,6 +235,94 @@ */ public function edittask($seminary, $questgroup, $quest) { + // Get questions + $questions = $this->Multiplechoice->getQuestionsOfQuest($quest['id']); + foreach($questions as &$question) { + $question['answers'] = $this->Multiplechoice->getAnswersOfQuestion($question['id']); + } + + // Values + $validations = array(); + + // Save data + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('save'))) + { + // Get params and validate them + $questions = $this->request->getPostParam('questions'); + if(is_null($questions)) { + $questions = array(); + } + $questions = array_values($questions); + foreach($questions as $questionIndex => &$question) + { + // Validate answers + $question['answers'] = array_values($question['answers']); + foreach($question['answers'] as $answerIndex => &$answer) + { + $answerValidation = $this->Validation->validate($answer['answer'], \nre\configs\AppConfig::$validation['answer']); + if($answerValidation !== true) + { + if(!array_key_exists($questionIndex, $validations) || !is_array($validations[$questionIndex])) { + $validations[$questionIndex] = array(); + } + if(!array_key_exists('answers', $validations[$questionIndex])) { + $validations[$questionIndex]['answers'] = array(); + } + $validations[$questionIndex]['answers'][$answerIndex] = $answerValidation; + } + } + } + + // Save and redirect + if(empty($validations)) + { + // Save questions + foreach($questions as $questionIndex => &$question) + { + // Save question + $this->Multiplechoice->setQuestionForQuest( + $this->Auth->getUserId(), + $quest['id'], + $questionIndex + 1, + $question['question'] + ); + + // Save answers + foreach($question['answers'] as $answerIndex => &$answer) + { + $this->Multiplechoice->setAnswerForQuestion( + $this->Auth->getUserId(), + $quest['id'], + $questionIndex + 1, + $answerIndex + 1, + $answer['answer'], + array_key_exists('tick', $answer) + ); + } + + // Delete deleted answers + $this->Multiplechoice->deleteAnswersOfQuestion( + $quest['id'], + $questionIndex + 1, + count($question['answers']) + ); + } + + // Delete deleted questions + $this->Multiplechoice->deleteQuestionsOfQuest( + $quest['id'], + count($questions) + ); + + // Redirect + $this->redirect($this->linker->link(array('quest', $seminary['url'], $questgroup['url'], $quest['url']), 1)); + } + } + + + // Pass data to view + $this->set('questions', $questions); + $this->set('validations', $validations); } diff --git a/questtypes/multiplechoice/MultiplechoiceQuesttypeModel.inc b/questtypes/multiplechoice/MultiplechoiceQuesttypeModel.inc index be8c704b..5f91d360 100644 --- a/questtypes/multiplechoice/MultiplechoiceQuesttypeModel.inc +++ b/questtypes/multiplechoice/MultiplechoiceQuesttypeModel.inc @@ -153,6 +153,115 @@ return false; } + + + /** + * Set a question for a multiplechoice Quest. + * + * @param int $userId ID of user + * @param int $questId ID of Quest to set question for + * @param int $pos Position of question + * @param string $question Question text + */ + public function setQuestionForQuest($userId, $questId, $pos, $question) + { + $this->db->query( + 'INSERT INTO questtypes_multiplechoice '. + '(created_user_id, quest_id, pos, question) '. + 'VALUES '. + '(?, ?, ?, ?) '. + 'ON DUPLICATE KEY UPDATE '. + 'question = ?', + 'iiiss', + $userId, + $questId, + $pos, + $question, + $question + ); + } + + + /** + * Delete questions of a Quest. + * + * @param int $questId ID of Quest to delete question of + * @param int $offset Only delete questions after this position + */ + public function deleteQuestionsOfQuest($questId, $offset) + { + $this->db->query( + 'DELETE FROM questtypes_multiplechoice '. + 'WHERE quest_id = ? AND pos > ?', + 'ii', + $questId, + $offset + ); + } + + + /** + * Set an answer for a question. + * + * @param int $userId ID of user + * @param int $questId ID of Quest to set answer for + * @param int $questionPos Position of question + * @param int $answerPos Position of answer + * @param string $answer Answer text + * @param boolean $tick Whether answer is correct or not + */ + public function setAnswerForQuestion($userId, $questId, $questionPos, $answerPos, $answer, $tick) + { + // Get question + $question = $this->getQuestionOfQuest($questId, $questionPos); + if(is_null($question)) { + return; + } + + // Add answer + $this->db->query( + 'INSERT INTO questtypes_multiplechoice_answers '. + '(created_user_id, questtypes_multiplechoice_id, pos, answer, tick) '. + 'VALUES '. + '(?, ?, ?, ?, ?) '. + 'ON DUPLICATE KEY UPDATE '. + 'answer = ?, tick = ?', + 'iiisisi', + $userId, + $question['id'], + $answerPos, + $answer, + $tick, + $answer, + $tick + ); + } + + + /** + * Delete answers of a question. + * + * @param int $questId ID of Quest to delete answers for + * @param int $questionPos Position of question + * @param int $offset Only delete answers after this position + */ + public function deleteAnswersOfQuestion($questId, $questionPos, $offset) + { + // Get question + $question = $this->getQuestionOfQuest($questId, $questionPos); + if(is_null($question)) { + return; + } + + // Delete answer + $this->db->query( + 'DELETE FROM questtypes_multiplechoice_answers '. + 'WHERE questtypes_multiplechoice_id = ? AND pos > ?', + 'ii', + $question['id'], + $offset + ); + } } diff --git a/questtypes/multiplechoice/html/edittask.tpl b/questtypes/multiplechoice/html/edittask.tpl index c65158e7..8da183b5 100644 --- a/questtypes/multiplechoice/html/edittask.tpl +++ b/questtypes/multiplechoice/html/edittask.tpl @@ -1 +1,137 @@ -

TODO

+ + + +
+
+ +
    + &$question) : ?> +
  1. + : + + + +
      + + $value) : ?> +
    • + +
    • + + +
    + + +
      + &$answer) : ?> +
    • + checked="checked" /> + + +
    • + +
    • + +
    • +
    + +
  2. + +
  3. + +
  4. +
+
+ +
+ +