diff --git a/app/models/QuesttypeModel.inc b/app/models/QuesttypeModel.inc index 5829dcf3..57f51c30 100644 --- a/app/models/QuesttypeModel.inc +++ b/app/models/QuesttypeModel.inc @@ -34,6 +34,14 @@ public abstract function copyQuest($userId, $sourceQuestId, $targetQuestId, $seminaryMediaIds); + /** + * Delete a Quest. + * + * @param int $questId ID of Quest to delete + */ + public abstract function deleteQuest($questId); + + /** * Load a Model. * diff --git a/db/create.sql b/db/create.sql index b93ba39f..5c402dcf 100644 --- a/db/create.sql +++ b/db/create.sql @@ -218,7 +218,7 @@ CREATE TABLE `avatarpictures` ( PRIMARY KEY (`seminarymedia_id`), KEY `created_user_id` (`created_user_id`), CONSTRAINT `avatarpictures_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), - CONSTRAINT `avatarpictures_ibfk_3` FOREIGN KEY (`seminarymedia_id`) REFERENCES `seminarymedia` (`id`) + CONSTRAINT `avatarpictures_ibfk_3` FOREIGN KEY (`seminarymedia_id`) REFERENCES `seminarymedia` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -847,8 +847,8 @@ CREATE TABLE `questgroups_questgroupshierarchy` ( KEY `parent_questgoup_id` (`parent_questgroup_id`), KEY `questgroupshierarchy_id` (`questgroupshierarchy_id`), CONSTRAINT `questgroups_questgroupshierarchy_ibfk_1` FOREIGN KEY (`questgroup_id`) REFERENCES `questgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `questgroups_questgroupshierarchy_ibfk_2` FOREIGN KEY (`questgroupshierarchy_id`) REFERENCES `questgroupshierarchy` (`id`), - CONSTRAINT `questgroups_questgroupshierarchy_ibfk_3` FOREIGN KEY (`parent_questgroup_id`) REFERENCES `questgroups` (`id`) + CONSTRAINT `questgroups_questgroupshierarchy_ibfk_2` FOREIGN KEY (`questgroupshierarchy_id`) REFERENCES `questgroupshierarchy` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questgroups_questgroupshierarchy_ibfk_3` FOREIGN KEY (`parent_questgroup_id`) REFERENCES `questgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -865,8 +865,8 @@ CREATE TABLE `questgroups_questtexts` ( `entry_text` text COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`questgroup_id`,`questtext_id`), KEY `questtext_id` (`questtext_id`), - CONSTRAINT `questgroups_questtexts_ibfk_1` FOREIGN KEY (`questgroup_id`) REFERENCES `questgroups` (`id`), - CONSTRAINT `questgroups_questtexts_ibfk_2` FOREIGN KEY (`questtext_id`) REFERENCES `questtexts` (`id`) + CONSTRAINT `questgroups_questtexts_ibfk_1` FOREIGN KEY (`questgroup_id`) REFERENCES `questgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questgroups_questtexts_ibfk_2` FOREIGN KEY (`questtext_id`) REFERENCES `questtexts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/models/AchievementsModel.inc b/models/AchievementsModel.inc index aafae4b7..5b2a05bc 100644 --- a/models/AchievementsModel.inc +++ b/models/AchievementsModel.inc @@ -1402,6 +1402,18 @@ $this->db->setAutocommit(true); } + + /** + * Delete all Achievements of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete Achievements of + */ + public function deleteAchievementsOfSeminary($seminaryId) + { + // Delete Achievements + $this->db->query('DELETE FROM achievements WHERE seminary_id = ?', 'i', $seminaryId); + } + } ?> diff --git a/models/AvatarsModel.inc b/models/AvatarsModel.inc index 9abd09b3..493eb88e 100644 --- a/models/AvatarsModel.inc +++ b/models/AvatarsModel.inc @@ -218,6 +218,25 @@ } } + + /** + * Delete Avatars. + * + * @param array $charactertypeIds List of Charactertype-IDs to delete Avatars of + * @param array $xplevelIds List of XP-level-IDs to delete Avatars of + */ + public function deleteAvatars($charactertypeIds, $xplevelIds) + { + $this->db->query( + sprintf( + 'DELETE FROM avatars '. + 'WHERE charactertype_id IN (%s) OR xplevel_id IN (%s)', + implode(',', $charactertypeIds), + implode(',', $xplevelIds) + ) + ); + } + } ?> diff --git a/models/CharactergroupsModel.inc b/models/CharactergroupsModel.inc index bcca2802..1b36324a 100644 --- a/models/CharactergroupsModel.inc +++ b/models/CharactergroupsModel.inc @@ -20,6 +20,12 @@ */ class CharactergroupsModel extends \hhu\z\Model { + /** + * Required models + * + * @var array + */ + public $models = array('charactergroupsquests'); @@ -225,6 +231,31 @@ } + /** + * Delete all Character groups-groups of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete Character groups-groups of + */ + public function deleteGroupsgroupsOfSeminary($seminaryId) + { + // Get Groupsgroups + $charactergroupsgroups = $this->getGroupsroupsForSeminary($seminaryId); + + // Delete each Groupsgroup + foreach($charactergroupsgroups as $groupsgroup) + { + // Delete Groups + $this->deleteGroupsOfGroupsgroup($groupsgroup['id']); + + // Delete Groupsquests + $this->Charactergroupsquests->deleteQuestsOfGroupsgroup($groupsgroup['id']); + + // Delete Groupsgroup + $this->db->query('DELETE FROM charactergroupsgroups WHERE seminary_id = ?', 'i', $seminaryId); + } + } + + /** * Get Character groups for a Character groups-group. * @@ -475,6 +506,17 @@ } + /** + * Delete all Character groups of a groups-group. + * + * @param int $groupsgroupId ID of Character groups-group to delete groups of + */ + public function deleteGroupsOfGroupsgroup($groupsgroupId) + { + $this->db->query('DELETE FROM charactergroups WHERE charactergroupsgroup_id = ?', 'i', $groupsgroupId); + } + + /** * Get the rank of a XP-value of a Character. * diff --git a/models/CharactergroupsquestsModel.inc b/models/CharactergroupsquestsModel.inc index 32b9cafa..61de9715 100644 --- a/models/CharactergroupsquestsModel.inc +++ b/models/CharactergroupsquestsModel.inc @@ -437,6 +437,17 @@ } + /** + * Delete all Character groups Quests of a Character groups-group. + * + * @param int $groupsgroupId ID of Character groups-group to delete Quests of + */ + public function deleteQuestsOfGroupsgroup($groupsgroupId) + { + $this->db->query('DELETE FROM charactergroupsquests WHERE charactergroupsgroup_id = ?', 'i', $groupsgroupId); + } + + } ?> diff --git a/models/CharactertypesModel.inc b/models/CharactertypesModel.inc index eb812864..039db838 100644 --- a/models/CharactertypesModel.inc +++ b/models/CharactertypesModel.inc @@ -247,6 +247,17 @@ $this->db->query('DELETE FROM charactertypes WHERE id = ?', 'i', $charactertypeId); } + + /** + * Delete all Charactertypes of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete Charactertypes of + */ + public function deleteCharactertypesOfSeminary($seminaryId) + { + $this->db->query('DELETE FROM charactertypes WHERE seminary_id = ?', 'i', $seminaryId); + } + } ?> diff --git a/models/MapModel.inc b/models/MapModel.inc index ff7393b5..2bd4e28e 100644 --- a/models/MapModel.inc +++ b/models/MapModel.inc @@ -115,7 +115,7 @@ public function deleteMapOfSeminary($seminaryId) { // Get map - $map = $this->getMap($seminaryId); + $map = $this->getMapOfSeminary($seminaryId); if(is_null($map)) { return; } diff --git a/models/MediaModel.inc b/models/MediaModel.inc index bb63c399..5ac31aea 100644 --- a/models/MediaModel.inc +++ b/models/MediaModel.inc @@ -200,6 +200,35 @@ } + /** + * Delete all media of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete media of + */ + public function deleteSeminaryMediaOfSeminary($seminaryId) + { + // Get all media from a Seminary + $seminaryMedia = $this->db->query( + 'SELECT id '. + 'FROM seminarymedia '. + 'WHERE seminary_id = ?', + 'i', + $seminaryId + ); + + // Delete each medium + foreach($seminaryMedia as &$medium) + { + // Delete file + $filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$medium['id']; + @unlink($filename); + } + + // Delete database entries + $this->db->query('DELETE FROM seminarymedia WHERE seminary_id = ?', 'i', $seminaryId); + } + + /** * Create a new moodpic. * diff --git a/models/QuestgroupsModel.inc b/models/QuestgroupsModel.inc index f79e2031..9e659450 100644 --- a/models/QuestgroupsModel.inc +++ b/models/QuestgroupsModel.inc @@ -749,6 +749,28 @@ } + /** + * Delete all Questgroups of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete Questgroups of + */ + public function deleteQuestgroupsOfSeminary($seminaryId) + { + // Get Questgroups + $questgroups = $this->getQuestgroupsForSeminary($seminaryId); + + // Delete each Questgroup + foreach($questgroups as &$questgroup) + { + // Delete Questgroup texts + $this->Questgrouptexts->deleteQuestgrouptexts($questgroup['id']); + + // Delete Questgroup + $this->db->query('DELETE FROM questgroups WHERE id = ?', 'i', $questgroup['id']); + } + } + + /** diff --git a/models/QuestgroupshierarchyModel.inc b/models/QuestgroupshierarchyModel.inc index 16a8d326..5b18cf9c 100644 --- a/models/QuestgroupshierarchyModel.inc +++ b/models/QuestgroupshierarchyModel.inc @@ -339,6 +339,17 @@ } + /** + * Delete complete Questgroupshierarchy of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete Questgroupshierarchy of + */ + public function deleteQuestgroupshierarchyOfSeminary($seminaryId) + { + $this->db->query('DELETE FROM questgroupshierarchy WHERE seminary_id = ?', 'i', $seminaryId); + } + + /** diff --git a/models/QuestgrouptextsModel.inc b/models/QuestgrouptextsModel.inc index 0ebb76b1..bfdb970a 100644 --- a/models/QuestgrouptextsModel.inc +++ b/models/QuestgrouptextsModel.inc @@ -146,6 +146,17 @@ ); } + + /** + * Delete all Questgroup texts of a Questgroup. + * + * @param int $questgroupId ID of Questgroup to delete texts of + */ + public function deleteQuestgrouptexts($questgroupId) + { + $this->db->query('DELETE FROM questgrouptexts WHERE questgroup_id = ?', 'i', $questgroupId); + } + } ?> diff --git a/models/QuestsModel.inc b/models/QuestsModel.inc index 7a55a9fd..11eae68e 100644 --- a/models/QuestsModel.inc +++ b/models/QuestsModel.inc @@ -813,6 +813,42 @@ $this->db->setAutocommit(true); } + + /** + * Delete all Quests of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete all Quests of + */ + public function deleteQuestsOfSeminary($seminaryId) + { + // Get Quests + $quests = $this->getQuestsForSeminary($seminaryId); + + // Delete each Quest + foreach($quests as &$quest) + { + // Delete content + $questtype = $this->Questtypes->getQuesttypeById($quest['questtype_id']); + if(!is_null($questtype['classname'])) + { + // Load Questtype Model + \hhu\z\models\QuesttypeModel::load($questtype['classname']); + + // Construct Questtype Model + $questtypeModel = \hhu\z\models\QuesttypeModel::factory($questtype['classname']); + + // Delete content + $questtypeModel->deleteQuest($quest['id']); + } + + // Delete Quests texts + $this->Questtexts->deleteQuesttexts($quest['id']); + + // Delete quest + $this->db->query('DELETE FROM quests WHERE id = ?', 'i', $quest['id']); + } + } + } ?> diff --git a/models/QuesttextsModel.inc b/models/QuesttextsModel.inc index 950d9b7b..e818f421 100644 --- a/models/QuesttextsModel.inc +++ b/models/QuesttextsModel.inc @@ -384,6 +384,17 @@ ); } + + /** + * Delete all Quest texts of a Quest. + * + * @param int $questId ID of Quest to delete all texts of + */ + public function deleteQuesttexts($questId) + { + $this->db->query('DELETE FROM questtexts WHERE quest_id = ?', 'i', $questId); + } + } ?> diff --git a/models/QuesttopicsModel.inc b/models/QuesttopicsModel.inc index ac906fb3..94de7913 100644 --- a/models/QuesttopicsModel.inc +++ b/models/QuesttopicsModel.inc @@ -470,6 +470,17 @@ $this->db->query('DELETE FROM questsubtopics WHERE id = ?', 'i', $questtopicId); } + + /** + * Delete all Questtopics of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete Questtopics of + */ + public function deleteQuesttopicsOfSeminary($seminaryId) + { + $this->db->query('DELETE FROM questtopics WHERE seminary_id = ?', 'i', $seminaryId); + } + } ?> diff --git a/models/SeminariesModel.inc b/models/SeminariesModel.inc index 53462668..20984de6 100644 --- a/models/SeminariesModel.inc +++ b/models/SeminariesModel.inc @@ -24,7 +24,7 @@ * * @var array */ - public $models = array('questgroupshierarchy', 'questgroups', 'quests', 'questtopics', 'media', 'charactertypes', 'xplevels', 'avatars', 'achievements', 'charactergroups', 'charactergroupsquests', 'seminarycharacterfields', 'map'); + public $models = array('questgroupshierarchy', 'questgroups', 'quests', 'questtopics', 'media', 'characters', 'charactertypes', 'xplevels', 'avatars', 'achievements', 'charactergroups', 'charactergroupsquests', 'seminarycharacterfields', 'map', 'uploads'); @@ -470,13 +470,64 @@ /** * Delete a seminary. - * TODO Delete media * * @param int $seminaryId ID of the seminary to delete */ public function deleteSeminary($seminaryId) { - $this->db->query('DELETE FROM seminaries WHERE id = ?', 'i', $seminaryId); + $this->db->setAutocommit(false); + try { + // Map + $this->Map->deleteMapOfSeminary($seminaryId); + + // Charactergroups content + $this->Charactergroups->deleteGroupsgroupsOfSeminary($seminaryId); + + // Achievements + $this->Achievements->deleteAchievementsOfSeminary($seminaryId); + + // Character content + // Delete Characters + $characters = $this->Characters->getCharactersForSeminary($seminaryId); + foreach($characters as &$character) { + $this->Characters->deleteCharacter($character['id']); + } + // Delete Avatars + $charactertypes = $this->Charactertypes->getCharacterTypesForSeminary($seminaryId); + $charactertypeIds = array_map(function($type) { return $type['id']; }, $charactertypes); + $xplevels = $this->Xplevels->getXPLevelsForSeminary($seminaryId); + $xplevelIds = array_map(function($level) { return $level['id']; }, $xplevels); + $this->Avatars->deleteAvatars($charactertypeIds, $xplevelIds); + // Delete XP-levels + $this->Xplevels->deleteXPLevelsOfSeminary($seminaryId); + // Delete Charactertypes + $this->Charactertypes->deleteCharactertypesOfSeminary($seminaryId); + + // Delete Quests content + // Delete Quest topics + $this->Questtopics->deleteQuesttopicsOfSeminary($seminaryId); + // Delete Quests + $this->Quests->deleteQuestsOfSeminary($seminaryId); + // Delete Questgroups + $this->Questgroups->deleteQuestgroupsOfSeminary($seminaryId); + // Delete Questgroupshierarchy + $this->Questgroupshierarchy->deleteQuestgroupshierarchyOfSeminary($seminaryId); + + // Media + $this->Media->deleteSeminaryMediaOfSeminary($seminaryId); + + // Uploads + $this->Uploads->deleteSeminaryUploadsOfSeminary($seminaryId); + + // Delete Seminary + $this->db->query('DELETE FROM seminaries WHERE id = ?', 'i', $seminaryId); + } + catch(\Exception $e) { + $this->db->rollback(); + $this->db->setAutocommit(true); + throw $e; + } + $this->db->setAutocommit(true); } } diff --git a/models/UploadsModel.inc b/models/UploadsModel.inc index 7a555659..2b7f2a2d 100644 --- a/models/UploadsModel.inc +++ b/models/UploadsModel.inc @@ -170,6 +170,35 @@ $this->db->setAutocommit(true); } + + /** + * Delete all Seminary uploads of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete all Uploads of + */ + public function deleteSeminaryUploadsOfSeminary($seminaryId) + { + // Get all uploads from a Seminary + $seminaryUploads = $this->db->query( + 'SELECT id, url '. + 'FROM seminaryuploads '. + 'WHERE seminary_id = ?', + 'i', + $seminaryId + ); + + // Delete each upload + foreach($seminaryUploads as &$upload) + { + // Delete file + $filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminaryuploads'].DS.$upload['url']; + @unlink($filename); + } + + // Delete database entries + $this->db->query('DELETE FROM seminaryuploads WHERE seminary_id = ?', 'i', $seminaryId); + } + } ?> diff --git a/models/XplevelsModel.inc b/models/XplevelsModel.inc index 8f249dfe..8d657dd7 100644 --- a/models/XplevelsModel.inc +++ b/models/XplevelsModel.inc @@ -231,6 +231,17 @@ $this->db->setAutocommit(true); } + + /** + * Delete all XP-levels of a Seminary. + * + * @param int $seminaryId ID of Seminary to delete XP-levels of + */ + public function deleteXPLevelsOfSeminary($seminaryId) + { + $this->db->query('DELETE FROM xplevels WHERE seminary_id = ?', 'i', $seminaryId); + } + } ?> diff --git a/questtypes/bossfight/BossfightQuesttypeModel.inc b/questtypes/bossfight/BossfightQuesttypeModel.inc index 36efafa7..76ff44fb 100644 --- a/questtypes/bossfight/BossfightQuesttypeModel.inc +++ b/questtypes/bossfight/BossfightQuesttypeModel.inc @@ -68,6 +68,17 @@ } + /** + * Delete a Quest. + * + * @param int $questId ID of Quest to delete + */ + public function deleteQuest($questId) + { + $this->db->query('DELETE FROM questtypes_bossfight WHERE quest_id = ?', 'i', $questId); + } + + /** * Get a Boss-Fight. * diff --git a/questtypes/choiceinput/ChoiceinputQuesttypeModel.inc b/questtypes/choiceinput/ChoiceinputQuesttypeModel.inc index 20ad7988..cc34a1d0 100644 --- a/questtypes/choiceinput/ChoiceinputQuesttypeModel.inc +++ b/questtypes/choiceinput/ChoiceinputQuesttypeModel.inc @@ -97,6 +97,17 @@ } + /** + * Delete a Quest. + * + * @param int $questId ID of Quest to delete + */ + public function deleteQuest($questId) + { + $this->db->query('DELETE FROM questtypes_choiceinput WHERE quest_id = ?', 'i', $questId); + } + + /** * Get choiceinput-text for a Quest. * diff --git a/questtypes/crossword/CrosswordQuesttypeModel.inc b/questtypes/crossword/CrosswordQuesttypeModel.inc index e223a553..8a55e6ae 100644 --- a/questtypes/crossword/CrosswordQuesttypeModel.inc +++ b/questtypes/crossword/CrosswordQuesttypeModel.inc @@ -47,6 +47,17 @@ } + /** + * Delete a Quest. + * + * @param int $questId ID of Quest to delete + */ + public function deleteQuest($questId) + { + $this->db->query('DELETE FROM questtypes_crossword_words WHERE quest_id = ?', 'i', $questId); + } + + /** * Get all words for a crossword-Quest. * diff --git a/questtypes/dragndrop/DragndropQuesttypeModel.inc b/questtypes/dragndrop/DragndropQuesttypeModel.inc index 055dcc8d..d076711e 100644 --- a/questtypes/dragndrop/DragndropQuesttypeModel.inc +++ b/questtypes/dragndrop/DragndropQuesttypeModel.inc @@ -127,6 +127,16 @@ } + /** + * Delete a Quest. + * + * @param int $questId ID of Quest to delete + */ + public function deleteQuest($questId) + { + $this->db->query('DELETE FROM questtypes_dragndrop WHERE quest_id = ?', 'i', $questId); + } + /** * Create a new Drag&Drop field for a Quest. diff --git a/questtypes/multiplechoice/MultiplechoiceQuesttypeModel.inc b/questtypes/multiplechoice/MultiplechoiceQuesttypeModel.inc index 003e9161..dc5b4943 100644 --- a/questtypes/multiplechoice/MultiplechoiceQuesttypeModel.inc +++ b/questtypes/multiplechoice/MultiplechoiceQuesttypeModel.inc @@ -67,6 +67,17 @@ } + /** + * Delete a Quest. + * + * @param int $questId ID of Quest to delete + */ + public function deleteQuest($questId) + { + $this->db->query('DELETE FROM questtypes_multiplechoice WHERE quest_id = ?', 'i', $questId); + } + + /** * Get the count of multiple choice questions for a Quest. * diff --git a/questtypes/submit/SubmitQuesttypeModel.inc b/questtypes/submit/SubmitQuesttypeModel.inc index 100a7000..b3b8f7bb 100644 --- a/questtypes/submit/SubmitQuesttypeModel.inc +++ b/questtypes/submit/SubmitQuesttypeModel.inc @@ -42,6 +42,17 @@ } + /** + * Delete a Quest. + * + * @param int $questId ID of Quest to delete + */ + public function deleteQuest($questId) + { + $this->db->query('DELETE FROM questtypes_submit_characters WHERE quest_id = ?', 'i', $questId); + } + + /** * Save Character’s submitted upload. * diff --git a/questtypes/textinput/TextinputQuesttypeModel.inc b/questtypes/textinput/TextinputQuesttypeModel.inc index 59c41d1d..9d3fb8d8 100644 --- a/questtypes/textinput/TextinputQuesttypeModel.inc +++ b/questtypes/textinput/TextinputQuesttypeModel.inc @@ -59,6 +59,17 @@ } + /** + * Delete a Quest. + * + * @param int $questId ID of Quest to delete + */ + public function deleteQuest($questId) + { + $this->db->query('DELETE FROM questtypes_textinput WHERE quest_id = ?', 'i', $questId); + } + + /** * Get textinput-text for a Quest. *