From a39e53ad33c52199531993cae68921f7e7beb353 Mon Sep 17 00:00:00 2001 From: Justus Dieckmann Date: Tue, 20 Feb 2024 16:05:52 +0100 Subject: [PATCH] Check backup consistency before importing workflow --- .../backup/restore_lifecycle_workflow.php | 34 +++++++++++++++++++ lang/en/tool_lifecycle.php | 2 ++ step/lib.php | 10 ++++++ .../lang/de/lifecycletrigger_categories.php | 1 + .../lang/en/lifecycletrigger_categories.php | 1 + trigger/categories/lib.php | 18 ++++++++++ trigger/lib.php | 9 +++++ 7 files changed, 75 insertions(+) diff --git a/classes/local/backup/restore_lifecycle_workflow.php b/classes/local/backup/restore_lifecycle_workflow.php index 4fdf1640..36fb71a1 100644 --- a/classes/local/backup/restore_lifecycle_workflow.php +++ b/classes/local/backup/restore_lifecycle_workflow.php @@ -25,6 +25,7 @@ use tool_lifecycle\local\entity\step_subplugin; use tool_lifecycle\local\entity\trigger_subplugin; use tool_lifecycle\local\entity\workflow; +use tool_lifecycle\local\manager\lib_manager; use tool_lifecycle\local\manager\workflow_manager; use tool_lifecycle\local\manager\step_manager; use tool_lifecycle\local\manager\trigger_manager; @@ -76,6 +77,7 @@ public function execute() { // If the workflow could be loaded continue with the subplugins. if ($this->workflow) { $this->load_subplugins(); + $this->check_subplugin_validity(); // Validate the subplugin data. if (empty($this->errors) && $this->all_subplugins_installed()) { // If all loaded data is valid, the new workflow and the steps can be stored in the database. @@ -174,6 +176,38 @@ private function all_subplugins_installed() { return true; } + private function check_subplugin_validity() { + foreach ($this->steps as $step) { + $steplib = lib_manager::get_step_lib($step->subpluginname); + $filteredsettings = []; + foreach ($this->settings as $setting) { + if ($setting->pluginid === $step->id) { + $filteredsettings[$setting->name] = $setting->value; + } + } + $errors = array_map( + fn($x) => get_string('restore_error_in_step', 'tool_lifecycle', $step->instancename) . $x, + $steplib->ensure_validity($filteredsettings) + ); + $this->errors = array_merge($this->errors, $errors); + } + + foreach ($this->trigger as $trigger) { + $steplib = lib_manager::get_trigger_lib($trigger->subpluginname); + $filteredsettings = []; + foreach ($this->settings as $setting) { + if ($setting->pluginid === $trigger->id) { + $filteredsettings[$setting->name] = $setting->value; + } + } + $errors = array_map( + fn($x) => get_string('restore_error_in_trigger', 'tool_lifecycle', $trigger->instancename) . $x, + $steplib->ensure_validity($filteredsettings) + ); + $this->errors = array_merge($this->errors, $errors); + } + } + /** * Stores all loaded data in the database. * @throws \moodle_exception diff --git a/lang/en/tool_lifecycle.php b/lang/en/tool_lifecycle.php index c88413f3..533c4a4c 100644 --- a/lang/en/tool_lifecycle.php +++ b/lang/en/tool_lifecycle.php @@ -188,6 +188,8 @@ $string['restore_subplugins_invalid'] = 'Wrong format of the backup file. The structure of the subplugin elements is not as expected.'; $string['restore_step_does_not_exist'] = 'The step {$a} is not installed, but is included in the backup file. Please installed it first and try again.'; $string['restore_trigger_does_not_exist'] = 'The trigger {$a} is not installed, but is included in the backup file. Please installed it first and try again.'; +$string['restore_error_in_step'] = 'An error occurred when importing step "{$a}": '; +$string['restore_error_in_trigger'] = 'An error occurred when importing trigger "{$a}": '; // Events. $string['process_triggered_event'] = 'A process has been triggered'; diff --git a/step/lib.php b/step/lib.php index 86c8345c..20754d9b 100644 --- a/step/lib.php +++ b/step/lib.php @@ -142,6 +142,16 @@ public function extend_add_instance_form_definition_after_data($mform, $settings public function abort_course($process) { } + + /** + * Ensure validity of settings upon backup restoration. + * @param array $settings + * @return array List of errors with settings. If empty, the given settings are valid. + */ + public function ensure_validity(array $settings) : array { + return []; + } + } /** diff --git a/trigger/categories/lang/de/lifecycletrigger_categories.php b/trigger/categories/lang/de/lifecycletrigger_categories.php index fcec1378..926e9d88 100644 --- a/trigger/categories/lang/de/lifecycletrigger_categories.php +++ b/trigger/categories/lang/de/lifecycletrigger_categories.php @@ -28,3 +28,4 @@ $string['categories'] = 'Kategorien, für die der Workflow ausgelöst werden soll.'; $string['categories_noselection'] = 'Bitte wählen sie mindestens eine Kategorie aus.'; $string['exclude'] = 'Falls ausgewählt, werden gerade die Kurse der angegebenen Kategorien nicht ausgelöst.'; +$string['category_does_not_exist'] = 'Es gibt keine Kurskategorie mit der ID {$a}.'; diff --git a/trigger/categories/lang/en/lifecycletrigger_categories.php b/trigger/categories/lang/en/lifecycletrigger_categories.php index 423bd48e..7b1f9b3a 100644 --- a/trigger/categories/lang/en/lifecycletrigger_categories.php +++ b/trigger/categories/lang/en/lifecycletrigger_categories.php @@ -28,3 +28,4 @@ $string['categories'] = 'Categories, for which the workflow should be triggered'; $string['categories_noselection'] = 'Please choose at least one category.'; $string['exclude'] = 'If ticked, the named categories are excluded from triggering instead.'; +$string['category_does_not_exist'] = 'There is no course category with id {$a}.'; diff --git a/trigger/categories/lib.php b/trigger/categories/lib.php index 0ace8460..43b5f15e 100644 --- a/trigger/categories/lib.php +++ b/trigger/categories/lib.php @@ -131,4 +131,22 @@ public function extend_add_instance_form_definition($mform) { $mform->setType('exclude', PARAM_BOOL); } + /** + * Ensure validity of settings upon backup restoration. + * @param array $settings + * @return array List of errors with settings. If empty, the given settings are valid. + */ + public function ensure_validity(array $settings): array { + $errors = []; + $categories = explode(',', $settings['categories']); + // Use core_course_category for moodle 3.6 and higher. + $categoryobjects = \core_course_category::get_many($categories); + foreach ($categories as $category) { + if (!$categoryobjects[$category]) { + $errors[] = get_string('category_does_not_exist', 'lifecycletrigger_categories', $category); + } + } + return $errors; + } + } diff --git a/trigger/lib.php b/trigger/lib.php index 312c967c..c597c392 100644 --- a/trigger/lib.php +++ b/trigger/lib.php @@ -115,6 +115,15 @@ public function get_status_message() { return get_string("workflow_started", "tool_lifecycle"); } + /** + * Ensure validity of settings upon backup restoration. + * @param array $settings + * @return array List of errors with settings. If empty, the given settings are valid. + */ + public function ensure_validity(array $settings) : array { + return []; + } + } /**