MDL-64284 core: improved performance of component class searching

Added static caching of classes to reduce load times and reduce calls to `get_component_classes`
by altering to accept a null component value to search classmap only once.
This commit is contained in:
Tom Dickman
2019-03-29 11:44:43 +11:00
parent 0920f35ed9
commit 0d6a45d2fe
4 changed files with 54 additions and 82 deletions
+29 -23
View File
@@ -923,32 +923,38 @@ $cache = '.var_export($cache, true).';
*
* 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 or empty if all $component namespace classes.
* @return array The full class name as key and the class path as value.
* @param string|null $component A valid moodle component (frankenstyle) or null if searching all components
* @param string $namespace Namespace from the component name or empty string if all $component classes.
* @return array The full class name as key and the class path as value, empty array if $component is `null`
* and $namespace is empty.
*/
public static function get_component_classes_in_namespace($component, $namespace = '') {
public static function get_component_classes_in_namespace($component = null, $namespace = '') {
$component = self::normalize_componentname($component);
if ($namespace) {
// We will add them later.
$namespace = trim($namespace, '\\');
// We need add double backslashes as it is how classes are stored into self::$classmap.
$namespace = implode('\\\\', explode('\\', $namespace));
$namespace = $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;
// Only look for components if a component name is set or a namespace is set.
if (isset($component) || !empty($namespace)) {
// If a component parameter value is set we only want to look in that component.
// Otherwise we want to check all components.
$component = (isset($component)) ? self::normalize_componentname($component) : '\w+';
if ($namespace) {
// We will add them later.
$namespace = trim($namespace, '\\');
// We need add double backslashes as it is how classes are stored into self::$classmap.
$namespace = implode('\\\\', explode('\\', $namespace));
$namespace = $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.
foreach ($it as $classname => $classpath) {
if (class_exists($classname)) {
$classes[$classname] = $classpath;
}
}
}