diff --git a/course/classes/task/course_delete_modules.php b/course/classes/task/course_delete_modules.php index ad796ee349f..0b789542fdc 100644 --- a/course/classes/task/course_delete_modules.php +++ b/course/classes/task/course_delete_modules.php @@ -61,13 +61,30 @@ class course_delete_modules extends \core\task\adhoc_task { } $cms = $this->get_custom_data()->cms; - foreach ($cms as $cm) { + $exceptions = []; + $cmsfailed = []; + foreach ($cms as $key => $cm) { try { course_delete_module($cm->id); } catch (\Exception $e) { - throw new \coding_exception("The course module {$cm->id} could not be deleted. " - . "{$e->getMessage()}: {$e->getFile()}({$e->getLine()}) {$e->getTraceAsString()}"); + // Keep the information instead of throw an exception and continue with next cms. + $exceptions[] = ("The course module {$cm->id} could not be deleted. " + . "{$e->getMessage()}: {$e->getFile()}({$e->getLine()}) {$e->getTraceAsString()}"); + // Save the cms that has failed to set the data only with this values. + $cmsfailed[$key] = $cm; + continue; } } + + // Throw the existing exceptions if there is any. + if (!empty($exceptions)) { + // Save the failed CMS. + $customdata = $this->get_custom_data(); + $customdata->cms = $cmsfailed; + $this->set_custom_data($customdata); + + throw new \coding_exception("The following course modules could not be deleted:\n " . + implode('\n', $exceptions)); + } } } diff --git a/course/tests/course_delete_modules_test.php b/course/tests/course_delete_modules_test.php index 72098f0b16a..28e241f6cf8 100644 --- a/course/tests/course_delete_modules_test.php +++ b/course/tests/course_delete_modules_test.php @@ -56,7 +56,7 @@ class course_delete_modules_test extends \advanced_testcase { $data = [ 'cms' => [$assigncm], 'userid' => $user->id, - 'realuserid' => $user->id + 'realuserid' => $user->id, ]; $removaltask->set_custom_data($data); $removaltask->execute(); @@ -64,13 +64,14 @@ class course_delete_modules_test extends \advanced_testcase { // The module has deleted from the course. $coursedmodules = get_course_mods($course->id); $this->assertCount(0, $coursedmodules); - } /** - * Test to have a message in the exception. + * Test with failed and successful cms + * + * @covers ::course_delete_modules */ - public function test_delete_module_exception() { + public function test_delete_module_exception(): void { global $DB; $this->resetAfterTest(); @@ -86,12 +87,19 @@ class course_delete_modules_test extends \advanced_testcase { $module->name = 'TestModuleToDelete'; $DB->update_record('modules', $module); + // Generate successful test data. + $quiz1 = $generator->create_module('quiz', ['course' => $course]); + $quizcm1 = get_coursemodule_from_id('quiz', $quiz1->cmid); + + $quiz2 = $generator->create_module('quiz', ['course' => $course]); + $quizcm2 = get_coursemodule_from_id('quiz', $quiz2->cmid); + // Execute the task. $removaltask = new \core_course\task\course_delete_modules(); $data = [ - 'cms' => [$assigncm], + 'cms' => [$quizcm1, $assigncm, $quizcm2], 'userid' => $user->id, - 'realuserid' => $user->id + 'realuserid' => $user->id, ]; $removaltask->set_custom_data($data); try { @@ -113,5 +121,9 @@ class course_delete_modules_test extends \advanced_testcase { // Assert the error message has correct line number. $this->assertMatchesRegularExpression($regex, $errormsg); } + + // The success modules have been deleted from the course, and only the failed module is in the course. + $coursedmodules = get_course_mods($course->id); + $this->assertCount(1, $coursedmodules); } }