From 178361ef945f8a5a74cfadf34a6e57b3bd9f4833 Mon Sep 17 00:00:00 2001 From: oliver Date: Sat, 27 Feb 2016 19:05:54 +0100 Subject: [PATCH] add Stationtype ?singlechoice? --- db/create.sql | 67 ++++- db/import.sql | 2 +- .../MultiplechoiceStationtypeController.inc | 18 -- .../SinglechoiceStationtypeAgent.inc | 24 ++ .../SinglechoiceStationtypeController.inc | 203 +++++++++++++ .../SinglechoiceStationtypeModel.inc | 282 ++++++++++++++++++ stationtypes/singlechoice/html/edittask.tpl | 60 ++++ stationtypes/singlechoice/html/quest.tpl | 13 + .../charactergroupsqueststations/create.tpl | 2 + 9 files changed, 649 insertions(+), 22 deletions(-) create mode 100644 stationtypes/singlechoice/SinglechoiceStationtypeAgent.inc create mode 100644 stationtypes/singlechoice/SinglechoiceStationtypeController.inc create mode 100644 stationtypes/singlechoice/SinglechoiceStationtypeModel.inc create mode 100644 stationtypes/singlechoice/html/edittask.tpl create mode 100644 stationtypes/singlechoice/html/quest.tpl diff --git a/db/create.sql b/db/create.sql index 2863f7c6..a4a5544a 100644 --- a/db/create.sql +++ b/db/create.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.16 Distrib 10.1.10-MariaDB, for Linux (x86_64) +-- MySQL dump 10.16 Distrib 10.1.11-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: z -- ------------------------------------------------------ --- Server version 10.1.10-MariaDB-log +-- Server version 10.1.11-MariaDB-log /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2083,6 +2083,67 @@ CREATE TABLE `stationtypes_multiplechoice_charactergroups` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `stationtypes_singlechoice` +-- + +DROP TABLE IF EXISTS `stationtypes_singlechoice`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `stationtypes_singlechoice` ( + `station_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `answer_id` int(11) DEFAULT NULL, + PRIMARY KEY (`station_id`), + KEY `created_user_id` (`created_user_id`), + KEY `answer_id` (`answer_id`), + CONSTRAINT `stationtypes_singlechoice_ibfk_1` FOREIGN KEY (`station_id`) REFERENCES `charactergroupsqueststations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `stationtypes_singlechoice_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `stationtypes_singlechoice_ibfk_3` FOREIGN KEY (`answer_id`) REFERENCES `stationtypes_singlechoice_answers` (`id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `stationtypes_singlechoice_answers` +-- + +DROP TABLE IF EXISTS `stationtypes_singlechoice_answers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `stationtypes_singlechoice_answers` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `stationtypes_singlechoice_station_id` int(11) NOT NULL, + `pos` int(11) NOT NULL, + `answer` text COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `station_id_2` (`stationtypes_singlechoice_station_id`,`pos`), + KEY `station_id` (`stationtypes_singlechoice_station_id`), + CONSTRAINT `stationtypes_singlechoice_answers_ibfk_1` FOREIGN KEY (`stationtypes_singlechoice_station_id`) REFERENCES `stationtypes_singlechoice` (`station_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `stationtypes_singlechoice_charactergroups` +-- + +DROP TABLE IF EXISTS `stationtypes_singlechoice_charactergroups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `stationtypes_singlechoice_charactergroups` ( + `stationtypes_singlechoice_station_id` int(11) NOT NULL, + `charactergroup_id` int(11) NOT NULL, + `answer_id` int(11) DEFAULT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`stationtypes_singlechoice_station_id`,`charactergroup_id`), + KEY `answer_id` (`answer_id`), + KEY `charactergroup_id` (`charactergroup_id`), + CONSTRAINT `stationtypes_singlechoice_charactergroups_ibfk_1` FOREIGN KEY (`stationtypes_singlechoice_station_id`) REFERENCES `stationtypes_singlechoice` (`station_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `stationtypes_singlechoice_charactergroups_ibfk_2` FOREIGN KEY (`charactergroup_id`) REFERENCES `charactergroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `stationtypes_singlechoice_charactergroups_ibfk_3` FOREIGN KEY (`answer_id`) REFERENCES `stationtypes_singlechoice_answers` (`id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `userroles` -- @@ -2485,4 +2546,4 @@ DELIMITER ; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2016-01-15 13:19:51 +-- Dump completed on 2016-02-27 18:47:43 diff --git a/db/import.sql b/db/import.sql index 24c2c902..29bb18eb 100644 --- a/db/import.sql +++ b/db/import.sql @@ -700,7 +700,7 @@ UNLOCK TABLES; LOCK TABLES `stationtypes` WRITE; /*!40000 ALTER TABLE `stationtypes` DISABLE KEYS */; -INSERT INTO `stationtypes` (`id`, `created`, `title`, `url`, `classname`) VALUES (1,'2015-12-25 15:50:52','Empty','Empty',NULL),(2,'2015-12-25 15:50:52','Keyword','Keyword','keyword'),(3,'2015-12-25 15:51:16','Multiple Choice','Multiple-Choice','multiplechoice'); +INSERT INTO `stationtypes` (`id`, `created`, `title`, `url`, `classname`) VALUES (1,'2015-12-25 15:50:52','Empty','Empty',NULL),(2,'2015-12-25 15:50:52','Keyword','Keyword','keyword'),(3,'2015-12-25 15:51:16','Multiple Choice','Multiple-Choice','multiplechoice'),(4,'2016-02-27 17:22:11','Single Choice','Single-Choice','singlechoice'); /*!40000 ALTER TABLE `stationtypes` ENABLE KEYS */; UNLOCK TABLES; diff --git a/stationtypes/multiplechoice/MultiplechoiceStationtypeController.inc b/stationtypes/multiplechoice/MultiplechoiceStationtypeController.inc index 85a7ea48..bacabf7a 100644 --- a/stationtypes/multiplechoice/MultiplechoiceStationtypeController.inc +++ b/stationtypes/multiplechoice/MultiplechoiceStationtypeController.inc @@ -191,24 +191,6 @@ $this->set('answers', $answers); } - - - - /** - * Check if an Character answer matches a Regex. - * - * @param string $regex Regex to match against - * @param string $answer Character answer to match - * @return boolean Whether answer matches Regex or not - */ - private function isMatching($regex, $answer) - { - $score = preg_match($regex, trim($answer)); - - - return ($score !== false && $score > 0); - } - } ?> diff --git a/stationtypes/singlechoice/SinglechoiceStationtypeAgent.inc b/stationtypes/singlechoice/SinglechoiceStationtypeAgent.inc new file mode 100644 index 00000000..ab125ab4 --- /dev/null +++ b/stationtypes/singlechoice/SinglechoiceStationtypeAgent.inc @@ -0,0 +1,24 @@ + + * @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\stationtypes; + + + /** + * StationtypeAgent for a single choice task. + * + * @author Oliver Hanraths + */ + class SinglechoiceStationtypeAgent extends \hhu\z\agents\StationtypeAgent + { + } + +?> diff --git a/stationtypes/singlechoice/SinglechoiceStationtypeController.inc b/stationtypes/singlechoice/SinglechoiceStationtypeController.inc new file mode 100644 index 00000000..400a4405 --- /dev/null +++ b/stationtypes/singlechoice/SinglechoiceStationtypeController.inc @@ -0,0 +1,203 @@ + + * @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\stationtypes; + + + /** + * Controller of the StationtypeAgent for a single choice task. + * + * @author Oliver Hanraths + */ + class SinglechoiceStationtypeController extends \hhu\z\controllers\StationtypeController + { + /** + * Required models + */ + public $models = array('charactergroupsqueststations'); + + + + + /** + * Save the answer of a Character group for a Station. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $station Current Station data + * @param array $charactergroup Current Character group data + * @param array $answer Character group answer for the Station + */ + public function saveAnswer($seminary, $groupsgroup, $quest, $station, $charactergroup, $answer) + { + $this->Singlechoice->setCharactergroupSubmission( + $station['id'], + $charactergroup['id'], + intval($answer) + ); + } + + + /** + * Check if answer of a Character group for a Station matches the correct one. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $station Current Station data + * @param array $charactergroup Current Character group data + * @param array $answer Character group answer for the Station + * @return boolean True/false for a right/wrong answer + */ + public function matchAnswer($seminary, $groupsgroup, $quest, $station, $charactergroup, $answer) + { + // Get question + $question = $this->Singlechoice->getQuestion($station['id']); + + + // ID of answer maches correct one’s + return $question['answer_id'] == intval($answer); + } + + + /** + * Action: quest. + * + * Show the task of a Station. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $station Current Station data + * @param array $charactergroup Current Character group data + */ + public function quest($seminary, $groupsgroup, $quest, $station, $charactergroup) + { + // Get question + $question = $this->Singlechoice->getQuestion($station['id']); + + // Get answers + $answers = $this->Singlechoice->getAnswers($station['id']); + + // Get submission + if(!is_null($charactergroup)) { + $question['submission'] = $this->Singlechoice->getCharactergroupSubmission( + $station['id'], + $charactergroup['id'] + ); + } + + // Get status + $tried = false; + if(!is_null($charactergroup)) { + $tried = $this->Charactergroupsqueststations->hasCharactergroupTriedStation( + $station['id'], + $charactergroup['id'] + ); + } + + + // Pass data to view + $this->set('question', $question); + $this->set('answers', $answers); + $this->set('tried', $tried); + } + + + /** + * Action: edittask. + * + * Edit the task of a Station. + * + * @param array $seminary Current Seminary data + * @param array $groupsgroup Current Groups group data + * @param array $quest Current Quest data + * @param array $station Current Station data + */ + public function edittask($seminary, $groupsgroup, $quest, $station) + { + // Get question + $question = $this->Singlechoice->getQuestion($station['id']); + + // Get answers + $answers = $this->Singlechoice->getAnswers($station['id']); + + // Save data + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('save'))) + { + // Get params + $corectAnswerIndex = $this->request->getPostParam('answer'); + $corectAnswerIndex = intval($corectAnswerIndex); + $answers = $this->request->getPostParam('answers'); + if(is_null($answers)) { + $answers = array(); + } + + // Save question + $this->Singlechoice->setQuestion( + $this->Auth->getUserId(), + $station['id'] + ); + + // Save answers + $correctAnswerId = null; + $index = 0; + foreach($answers as $answerIndex => &$answer) + { + $answerId = $this->Singlechoice->setAnswer( + $this->Auth->getUserId(), + $station['id'], + ++$index, + $answer['answer'] + ); + if($answerIndex == $corectAnswerIndex || is_null($correctAnswerId)) { + $correctAnswerId = $answerId; + } + } + + // Delete deleted answers + $this->Singlechoice->deleteAnswers( + $station['id'], + count($answers) + ); + + // Set correct answer + $this->Singlechoice->setCorrectAnswer( + $station['id'], + $correctAnswerId + ); + + // Redirect + $this->redirect( + $this->linker->link( + array( + 'station', + $seminary['url'], + $groupsgroup['url'], + $quest['url'], + $station['url'] + ), + 1 + ) + ); + } + + + // Pass data to view + $this->set('task', $station['task']); + $this->set('question', $question); + $this->set('answers', $answers); + } + + } + +?> diff --git a/stationtypes/singlechoice/SinglechoiceStationtypeModel.inc b/stationtypes/singlechoice/SinglechoiceStationtypeModel.inc new file mode 100644 index 00000000..151676aa --- /dev/null +++ b/stationtypes/singlechoice/SinglechoiceStationtypeModel.inc @@ -0,0 +1,282 @@ + + * @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\stationtypes; + + + /** + * Model of the StationtypeAgent for a single choice task. + * + * @author Oliver Hanraths + */ + class SinglechoiceStationtypeModel extends \hhu\z\models\StationtypeModel + { + + + + + /** + * Copy a Station. + * + * @param int $userId ID of creating user + * @param int $sourceStationId ID of Station to copy from + * @param int $targetStationId ID of Station to copy to + * @param int $seminaryMediaIds Mapping of SeminaryMedia-IDs from source Seminary to targetSeminary + */ + public function copyStation($userId, $sourceStationId, $targetStationId, $seminaryMediaIds) + { + // Copy question + $question = $this->getQuestion($sourceStationId); + $this->db->query( + 'INSERT INTO stationtypes_singlechoice '. + '(station_id, created_user_id) '. + 'VALUES '. + '(?, ?)', + 'ii', + $targetStationId, $userId + ); + + // Copy answers + $answerIds = array(); + $answers = $this->getAnswers($sourceStationId); + foreach($answers as &$answer) { + $this->db->query( + 'INSERT INTO stationtypes_singlechoice_answers '. + '(stationtypes_singlechoice_station_id, pos, answer) '. + 'SELECT ?, pos, answer '. + 'FROM stationtypes_singlechoice_answers '. + 'WHERE id = ?', + 'ii', + $targetStationId, + $answer['id'] + ); + $answerIds[$answer['id']] = $this->db->getInsertId(); + } + + // Set correct answer + if(!is_null($question['answer_id'])) { + $this->setCorrectAnswer( + $targetStationId, + $answerIds[$question['answer_id']] + ); + } + } + + + /** + * Set the question for a Station. + * + * @param int $userId ID of creating user + * @param int $stationId ID of Station to set + */ + public function setQuestion($userId, $stationId) + { + $this->db->query( + 'INSERT INTO stationtypes_singlechoice '. + '(station_id, created_user_id) '. + 'VALUES '. + '(?, ?) '. + 'ON DUPLICATE KEY UPDATE '. + 'created_user_id = ?', + 'iii', + $stationId, + $userId, + $userId + ); + } + + + /** + * Get the question for a Station. + * + * @param int $stationId ID of Station to get question for + * @return array Question data + */ + public function getQuestion($stationId) + { + $data = $this->db->query( + 'SELECT station_id, created, answer_id '. + 'FROM stationtypes_singlechoice '. + 'WHERE station_id = ?', + 'i', + $stationId + ); + if(!empty($data)) { + return $data[0]; + } + + + return null; + } + + + /** + * Get all answers for a question. + * + * @param int $stationId ID of Station + * @return array List of answers + */ + public function getAnswers($stationId) + { + return $this->db->query( + 'SELECT id, pos, answer '. + 'FROM stationtypes_singlechoice_answers '. + 'WHERE stationtypes_singlechoice_station_id = ? '. + 'ORDER BY pos', + 'i', + $stationId + ); + } + + + /** + * Set an answer for a Station. + * + * @param int $userId ID of creating user + * @param int $stationId ID of Station to set answer for + * @param int $pos Position of answer + * @param string $answer Answer text + */ + public function setAnswer($userId, $stationId, $pos, $answer) + { + // Check if answer already exists + $data = $this->db->query( + 'SELECT id '. + 'FROM stationtypes_singlechoice_answers '. + 'WHERE stationtypes_singlechoice_station_id = ? AND pos = ?', + 'ii', + $stationId, + $pos + ); + + // Set new answer + if(!empty($data)) + { + // Update answer + $answerId = $data[0]['id']; + $this->db->query( + 'UPDATE stationtypes_singlechoice_answers '. + 'SET answer = ? '. + 'WHERE id = ?', + 'si', + $answer, + $answerId + ); + + return $answerId; + } + else + { + // Insert new answer + $this->db->query( + 'INSERT INTO stationtypes_singlechoice_answers '. + '(stationtypes_singlechoice_station_id, pos, answer) '. + 'VALUES '. + '(?, ?, ?)', + 'iis', + $stationId, + $pos, + $answer + ); + + // Get ID of inserted anser + return $this->db->getInsertId(); + } + } + + + /** + * Set the correct answer for a Station/question. + * + * @param int $stationId ID of Station to set + * @param int $answerId ID of correct answer + */ + public function setCorrectAnswer($stationId, $answerId) + { + $this->db->query( + 'UPDATE stationtypes_singlechoice '. + 'SET answer_id = ? '. + 'WHERE station_id = ?', + 'ii', + $answerId, + $stationId + ); + } + + + /** + * Delete all answers of a Station above a given index. + * + * @param int $stationId ID of Station to delete answers for + * @param int $offset Offset to delete answers above + */ + public function deleteAnswers($stationId, $offset) + { + // Delete answers + $this->db->query( + 'DELETE FROM stationtypes_singlechoice_answers '. + 'WHERE stationtypes_singlechoice_station_id = ? AND pos > ?', + 'ii', + $stationId, + $offset + ); + } + + + /** + * Save Character group’s submitted answer for a station/question. + * + * @param int $stationId ID of Station/question + * @param int $charactergroupId ID of Character group + * @param int $answerId ID of submitted answer + */ + public function setCharactergroupSubmission($stationId, $charactergroupId, $answerId) + { + $this->db->query( + 'INSERT INTO stationtypes_singlechoice_charactergroups '. + '(stationtypes_singlechoice_station_id, charactergroup_id, answer_id) '. + 'VALUES '. + '(?, ?, ?) '. + 'ON DUPLICATE KEY UPDATE '. + 'answer_id = ?', + 'iiii', + $stationId, $charactergroupId, $answerId, $answerId + ); + } + + + /** + * Get Character group’s submission for a Station/question. + * + * @param int $stationId ID of Station/question + * @param int $charactergroupId ID of Character group + * @return int ID of submitted answer + */ + public function getCharactergroupSubmission($stationId, $charactergroupId) + { + $data = $this->db->query( + 'SELECT answer_id '. + 'FROM stationtypes_singlechoice_charactergroups '. + 'WHERE stationtypes_singlechoice_station_id = ? AND charactergroup_id = ?', + 'ii', + $stationId, $charactergroupId + ); + if(!empty($data)) { + return intval($data[0]['answer_id']); + } + + + return null; + } + + } + +?> diff --git a/stationtypes/singlechoice/html/edittask.tpl b/stationtypes/singlechoice/html/edittask.tpl new file mode 100644 index 00000000..ba3457ff --- /dev/null +++ b/stationtypes/singlechoice/html/edittask.tpl @@ -0,0 +1,60 @@ +
+
+ + t($task)?> +
+
+ +
    + &$answer) : ?> +
  1. + :
    + + + +
    +
  2. + +
  3. + +
  4. +
+
+ +
+ + diff --git a/stationtypes/singlechoice/html/quest.tpl b/stationtypes/singlechoice/html/quest.tpl new file mode 100644 index 00000000..fb259c69 --- /dev/null +++ b/stationtypes/singlechoice/html/quest.tpl @@ -0,0 +1,13 @@ +
+
    + &$answer) : ?> +
  1. + checked="checked" disabled="disabled"/> + +
  2. + +
+ + + +
diff --git a/views/html/charactergroupsqueststations/create.tpl b/views/html/charactergroupsqueststations/create.tpl index f28b066c..e39423c4 100644 --- a/views/html/charactergroupsqueststations/create.tpl +++ b/views/html/charactergroupsqueststations/create.tpl @@ -89,6 +89,8 @@