function HookCollectorPass::collectModuleHookImplementations

Collects procedural and Attribute hook implementations.

Parameters

$dir: The directory in which the module resides.

$module: The name of the module.

$module_preg: A regular expression matching every module, longer module names are matched first.

Return value

void

File

core/lib/Drupal/Core/Hook/HookCollectorPass.php, line 159

Class

HookCollectorPass
Collects and registers hook implementations.

Namespace

Drupal\Core\Hook

Code

protected function collectModuleHookImplementations($dir, $module, $module_preg) : void {
    $hook_file_cache = FileCacheFactory::get('hook_implementations');
    $procedural_hook_file_cache = FileCacheFactory::get('procedural_hook_implementations:' . $module_preg);
    $iterator = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::FOLLOW_SYMLINKS);
    $iterator = new \RecursiveCallbackFilterIterator($iterator, static::filterIterator(...));
    $iterator = new \RecursiveIteratorIterator($iterator);
    
    /** @var \RecursiveDirectoryIterator | \RecursiveIteratorIterator $iterator*/
    foreach ($iterator as $fileinfo) {
        assert($fileinfo instanceof \SplFileInfo);
        $extension = $fileinfo->getExtension();
        $filename = $fileinfo->getPathname();
        if ($extension === 'module' && !$iterator->getDepth()) {
            // There is an expectation for all modules to be loaded. However,
            // .module files are not supposed to be in subdirectories.
            include_once $filename;
        }
        if ($extension === 'php') {
            $cached = $hook_file_cache->get($filename);
            if ($cached) {
                $class = $cached['class'];
                $attributes = $cached['attributes'];
            }
            else {
                $namespace = preg_replace('#^src/#', "Drupal/{$module}/", $iterator->getSubPath());
                $class = $namespace . '/' . $fileinfo->getBasename('.php');
                $class = str_replace('/', '\\', $class);
                if (class_exists($class)) {
                    $attributes = static::getHookAttributesInClass($class);
                    $hook_file_cache->set($filename, [
                        'class' => $class,
                        'attributes' => $attributes,
                    ]);
                }
                else {
                    $attributes = [];
                }
            }
            foreach ($attributes as $attribute) {
                $this->addFromAttribute($attribute, $class, $module);
            }
        }
        else {
            $implementations = $procedural_hook_file_cache->get($filename);
            if ($implementations === NULL) {
                $finder = MockFileFinder::create($filename);
                $parser = new StaticReflectionParser('', $finder);
                $implementations = [];
                foreach ($parser->getMethodAttributes() as $function => $attributes) {
                    if (!StaticReflectionParser::hasAttribute($attributes, LegacyHook::class) && preg_match($module_preg, $function, $matches)) {
                        $implementations[] = [
                            'function' => $function,
                            'module' => $matches['module'],
                            'hook' => $matches['hook'],
                        ];
                    }
                }
                $procedural_hook_file_cache->set($filename, $implementations);
            }
            foreach ($implementations as $implementation) {
                $this->addProceduralImplementation($fileinfo, $implementation['hook'], $implementation['module'], $implementation['function']);
            }
        }
        if ($extension === 'inc') {
            $parts = explode('.', $fileinfo->getFilename());
            if (count($parts) === 3 && $parts[0] === $module) {
                $this->groupIncludes[$parts[1]][] = $filename;
            }
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.