diff --git a/lib/classes/task/task_base.php b/lib/classes/task/task_base.php index bffd73682d7..6ccd782fccb 100644 --- a/lib/classes/task/task_base.php +++ b/lib/classes/task/task_base.php @@ -136,6 +136,28 @@ abstract class task_base { * @return string */ public function get_component() { + if (empty($this->component)) { + // The component should be the root of the class namespace. + $classname = get_class($this); + $parts = explode('\\', $classname); + + if (count($parts) === 1) { + $component = substr($classname, 0, strpos($classname, '_task')); + } else { + [$component] = $parts; + } + + // Load component information from plugin manager. + if ($component !== 'core' && strpos($component, 'core_') !== 0) { + $plugininfo = \core_plugin_manager::instance()->get_plugin_info($component); + if ($plugininfo && $plugininfo->component) { + $this->set_component($plugininfo->component); + } else { + debugging("Component not set and the class namespace does not match a valid component ({$component})."); + } + } + } + return $this->component; } diff --git a/lib/tests/adhoc_task_test.php b/lib/tests/adhoc_task_test.php index b0fdbb52f67..cc9b135e943 100644 --- a/lib/tests/adhoc_task_test.php +++ b/lib/tests/adhoc_task_test.php @@ -110,6 +110,46 @@ class core_adhoc_task_testcase extends advanced_testcase { \core\task\manager::adhoc_task_complete($task); } + /** + * Test queueing an adhoc task belonging to a component, where we set the task component accordingly + */ + public function test_queue_adhoc_task_for_component(): void { + $this->resetAfterTest(); + + $task = new \mod_forum\task\refresh_forum_post_counts(); + $task->set_component('mod_test'); + + \core\task\manager::queue_adhoc_task($task); + $this->assertDebuggingNotCalled(); + } + + /** + * Test queueing an adhoc task belonging to a component, where we do not set the task component + */ + public function test_queue_task_for_component_without_set_component(): void { + $this->resetAfterTest(); + + $task = new \mod_forum\task\refresh_forum_post_counts(); + + \core\task\manager::queue_adhoc_task($task); + $this->assertDebuggingNotCalled(); + + // Assert the missing component was set. + $this->assertEquals('mod_forum', $task->get_component()); + } + + /** + * Test queueing an adhoc task belonging to an invalid component, where we do not set the task component + */ + public function test_queue_task_for_invalid_component_without_set_component(): void { + $this->resetAfterTest(); + + $task = new \mod_fake\task\adhoc_component_task(); + + \core\task\manager::queue_adhoc_task($task); + $this->assertDebuggingCalled('Component not set and the class namespace does not match a valid component (mod_fake).'); + } + /** * Test empty set of adhoc tasks */ diff --git a/lib/tests/fixtures/task_fixtures.php b/lib/tests/fixtures/task_fixtures.php index ead50031c3a..9ece85de681 100644 --- a/lib/tests/fixtures/task_fixtures.php +++ b/lib/tests/fixtures/task_fixtures.php @@ -62,3 +62,11 @@ class scheduled_test3_task extends \core\task\scheduled_task { public function execute() { } } + +namespace mod_fake\task; + +class adhoc_component_task extends \core\task\adhoc_task { + public function execute() { + + } +}