From 42281e48f5521ec973ee2b07f361070b9e85bfc0 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Wed, 9 Jun 2021 23:53:22 +0100 Subject: [PATCH] MDL-70427 task: correct missing component when queuing adhoc task. If the task belongs to a component, and doesn't have it's own component property set then we can lazy-load it based on class namespace. --- lib/classes/task/task_base.php | 22 +++++++++++++++ lib/tests/adhoc_task_test.php | 40 ++++++++++++++++++++++++++++ lib/tests/fixtures/task_fixtures.php | 8 ++++++ 3 files changed, 70 insertions(+) diff --git a/lib/classes/task/task_base.php b/lib/classes/task/task_base.php index ecc89d15ea2..2b877556e2a 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() { + + } +}