diff --git a/classes/local/backup/restore_lifecycle_workflow.php b/classes/local/backup/restore_lifecycle_workflow.php index 5a74df3d..bbd79857 100644 --- a/classes/local/backup/restore_lifecycle_workflow.php +++ b/classes/local/backup/restore_lifecycle_workflow.php @@ -66,24 +66,30 @@ public function __construct($xmldata) { * Executes the restore process. It loads the workflow with all steps and triggers from the xml data. * If all data is valid, it restores the workflow with all subplugins and settings. * Otherwise an array with error strings is returned. + * @param bool $force force import, even if there are errors. * @return string[] Errors, which occurred during the restore process. * @throws \coding_exception * @throws \moodle_exception */ - public function execute() { + public function execute(bool $force) { $this->reader->read(); $this->load_workflow(); // If the workflow could be loaded continue with the subplugins. if ($this->workflow) { $this->load_subplugins(); + + if (!$this->all_subplugins_installed()) { + return $this->errors; + } + // Validate the subplugin data. - if (empty($this->errors) && $this->all_subplugins_installed()) { - $this->check_subplugin_validity(); - if (empty($this->errors)) { - // If all loaded data is valid, the new workflow and the steps can be stored in the database. - $this->persist(); - } + $this->check_subplugin_validity(); + if (empty($this->errors) || $force) { + // If all loaded data is valid, the new workflow and the steps can be stored in the database. + // If we force the import, we empty the errors; + $this->errors = []; + $this->persist(); } } return $this->errors; diff --git a/classes/local/form/form_upload_workflow.php b/classes/local/form/form_upload_workflow.php index 5ccd6aec..ee30d441 100644 --- a/classes/local/form/form_upload_workflow.php +++ b/classes/local/form/form_upload_workflow.php @@ -43,6 +43,12 @@ public function definition() { $mform->addElement('filepicker', 'backupfile', get_string('file'), null, ['accepted_types' => 'xml']); + + $showforce = isset($this->_customdata['showforce']) && $this->_customdata['showforce']; + $mform->addElement($showforce ? 'checkbox' : 'hidden', 'force', get_string('force_import', 'tool_lifecycle')); + $mform->setDefault('force', 0); + $mform->setType('force', PARAM_BOOL); + $this->add_action_buttons('true', get_string('upload')); } diff --git a/lang/en/tool_lifecycle.php b/lang/en/tool_lifecycle.php index 533c4a4c..fb99fb1a 100644 --- a/lang/en/tool_lifecycle.php +++ b/lang/en/tool_lifecycle.php @@ -190,6 +190,8 @@ $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}": '; +$string['workflow_was_not_imported'] = 'The workflow was not imported!'; +$string['force_import'] = 'Try ignoring errors and import the workflow anyway. Use this at your own risk!'; // Events. $string['process_triggered_event'] = 'A process has been triggered'; diff --git a/renderer.php b/renderer.php index f9b7eb9b..6d3db9e7 100644 --- a/renderer.php +++ b/renderer.php @@ -53,15 +53,11 @@ public function header($title = null) { /** * Renders the workflow upload form including errors, which occured during upload. * @param \tool_lifecycle\local\form\form_upload_workflow $form - * @param array $errors * @throws coding_exception */ - public function render_workflow_upload_form($form, $errors = []) { + public function render_workflow_upload_form($form) { $this->header(get_string('adminsettings_edit_workflow_definition_heading', 'tool_lifecycle')); - foreach ($errors as $error) { - \core\notification::add($error, \core\notification::ERROR); - } - echo $form->render(); + $form->display(); $this->footer(); } diff --git a/trigger/categories/lang/de/lifecycletrigger_categories.php b/trigger/categories/lang/de/lifecycletrigger_categories.php index 926e9d88..fb3a9e89 100644 --- a/trigger/categories/lang/de/lifecycletrigger_categories.php +++ b/trigger/categories/lang/de/lifecycletrigger_categories.php @@ -28,4 +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}.'; +$string['categories_do_not_exist'] = 'Es gibt keine Kurskategorien mit den folgenden IDs: {$a}.'; diff --git a/trigger/categories/lang/en/lifecycletrigger_categories.php b/trigger/categories/lang/en/lifecycletrigger_categories.php index 7b1f9b3a..d065edb7 100644 --- a/trigger/categories/lang/en/lifecycletrigger_categories.php +++ b/trigger/categories/lang/en/lifecycletrigger_categories.php @@ -28,4 +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}.'; +$string['categories_do_not_exist'] = 'There are no categories with the following ids: {$a}.'; diff --git a/trigger/categories/lib.php b/trigger/categories/lib.php index 7ca38d58..95a64610 100644 --- a/trigger/categories/lib.php +++ b/trigger/categories/lib.php @@ -137,16 +137,19 @@ public function extend_add_instance_form_definition($mform) { * @return array List of errors with settings. If empty, the given settings are valid. */ public function ensure_validity(array $settings): array { - $errors = []; + $missingcategories = []; $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 (!isset($categoryobjects[$category]) || !$categoryobjects[$category]) { - $errors[] = get_string('category_does_not_exist', 'lifecycletrigger_categories', $category); + $missingcategories[] = $category; } } - return $errors; + if ($missingcategories) { + return [get_string('categories_do_not_exist', 'lifecycletrigger_categories', join(', ', $missingcategories))]; + } else { + return []; + } } } diff --git a/uploadworkflow.php b/uploadworkflow.php index 06161e1a..c71b473d 100644 --- a/uploadworkflow.php +++ b/uploadworkflow.php @@ -51,11 +51,18 @@ if ($data = $form->get_data()) { $xmldata = $form->get_file_content('backupfile'); $restore = new restore_lifecycle_workflow($xmldata); - $errors = $restore->execute(); + $force = $data->force ?? false; + $errors = $restore->execute($force); if (count($errors) != 0) { + \core\notification::add(get_string('workflow_was_not_imported', 'tool_lifecycle'), \core\notification::ERROR); + foreach ($errors as $error) { + \core\notification::add($error, \core\notification::ERROR); + } + $form = new form_upload_workflow(null, ['showforce' => true]); + /** @var \tool_lifecycle_renderer $renderer */ $renderer = $PAGE->get_renderer('tool_lifecycle'); - $renderer->render_workflow_upload_form($form, $errors); + $renderer->render_workflow_upload_form($form); die(); } else { // Redirect to workflow page.