From f900b2b6c9f6e8dd511376151b9a5a47e8be943b Mon Sep 17 00:00:00 2001 From: David Monllao Date: Wed, 17 Feb 2016 11:48:06 +0800 Subject: [PATCH] MDL-31989 component: Allow classes to be retrieved by namespace --- lib/classes/component.php | 36 +++++++++++++++++++++++++++++++++++- lib/tests/component_test.php | 18 ++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/classes/component.php b/lib/classes/component.php index bde0ae08d67..4fcad1509a7 100644 --- a/lib/classes/component.php +++ b/lib/classes/component.php @@ -397,7 +397,7 @@ $cache = '.var_export($cache, true).'; 'repository' => $CFG->dirroot.'/repository', 'rss' => $CFG->dirroot.'/rss', 'role' => $CFG->dirroot.'/'.$CFG->admin.'/roles', - 'search' => null, + 'search' => $CFG->dirroot.'/search', 'table' => null, 'tag' => $CFG->dirroot.'/tag', 'timezones' => null, @@ -439,6 +439,7 @@ $cache = '.var_export($cache, true).'; 'webservice' => $CFG->dirroot.'/webservice', 'repository' => $CFG->dirroot.'/repository', 'portfolio' => $CFG->dirroot.'/portfolio', + 'search' => $CFG->dirroot.'/search/engine', 'qbehaviour' => $CFG->dirroot.'/question/behaviour', 'qformat' => $CFG->dirroot.'/question/format', 'plagiarism' => $CFG->dirroot.'/plagiarism', @@ -897,6 +898,39 @@ $cache = '.var_export($cache, true).'; return $pluginfiles; } + /** + * Returns all classes in a component matching the provided namespace. + * + * It checks that the class exists. + * + * e.g. get_component_classes_in_namespace('mod_forum', 'event') + * + * @param string $component A valid moodle component (frankenstyle) + * @param string $namespace Namespace from the component name. + * @return array The full class name as key and the class path as value. + */ + public static function get_component_classes_in_namespace($component, $namespace = '') { + + // We will add them later. + $namespace = ltrim($namespace, '\\'); + + // We need add double backslashes as it is how classes are stored into self::$classmap. + $namespace = implode('\\\\', explode('\\', $namespace)); + + $regex = '/^' . $component . '\\\\' . $namespace . '/'; + $it = new RegexIterator(new ArrayIterator(self::$classmap), $regex, RegexIterator::GET_MATCH, RegexIterator::USE_KEY); + + // We want to be sure that they exist. + $classes = array(); + foreach ($it as $classname => $classpath) { + if (class_exists($classname)) { + $classes[$classname] = $classpath; + } + } + + return $classes; + } + /** * Returns the exact absolute path to plugin directory. * diff --git a/lib/tests/component_test.php b/lib/tests/component_test.php index d5f0b55bd24..f7b31c8ef63 100644 --- a/lib/tests/component_test.php +++ b/lib/tests/component_test.php @@ -451,4 +451,22 @@ class core_component_testcase extends advanced_testcase { $list = core_component::get_plugin_list_with_file('report', 'idontexist.php', true); $this->assertEquals(array(), array_keys($list)); } + + public function test_get_component_classes_int_namespace() { + + // Unexisting. + $this->assertCount(0, core_component::get_component_classes_in_namespace('core_unexistingcomponent', 'something')); + $this->assertCount(0, core_component::get_component_classes_in_namespace('auth_cas', 'something')); + + // Prefix with backslash if it doesn\'t come prefixed. + $this->assertCount(1, core_component::get_component_classes_in_namespace('auth_cas', 'task')); + $this->assertCount(1, core_component::get_component_classes_in_namespace('auth_cas', '\\task')); + + // Core as a component works. + $this->assertCount(7, core_component::get_component_classes_in_namespace('core', 'update')); + + // Multiple levels. + $this->assertCount(5, core_component::get_component_classes_in_namespace('core_user', '\\output\\myprofile\\')); + $this->assertCount(5, core_component::get_component_classes_in_namespace('core_user', '\\output\\myprofile')); + } } -- 2.43.0