class HookCollectorBase
Provides shared hook collection functionality.
@internal
Hierarchy
- class \Drupal\Core\Hook\HookCollectorBase
Expanded class hierarchy of HookCollectorBase
1 file declares its use of HookCollectorBase
- HookCollectorPassTest.php in core/
tests/ Drupal/ Tests/ Core/ Hook/ HookCollectorPassTest.php
File
-
core/
lib/ Drupal/ Core/ Hook/ HookCollectorBase.php, line 15
Namespace
Drupal\Core\HookView source
abstract class HookCollectorBase {
/**
* Gets the files that can contain hook implementations.
*
* @param string $dir
* The extension directory.
* @param list<string> $procedural_files
* The root-level procedural hook implementation files.
*
* @return \Generator<\SplFileInfo>
* The procedural hook files and PHP files in src/Hook.
*/
protected function getHookFileIterator(string $dir, array $procedural_files) : \Generator {
foreach ($procedural_files as $filename) {
$filename = "{$dir}/{$filename}";
if (is_file($filename)) {
yield new \SplFileInfo($filename);
}
}
$hook_directory = "{$dir}/src/Hook";
if (!is_dir($hook_directory)) {
return;
}
$flags = \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::FOLLOW_SYMLINKS;
$iterator = new \RecursiveDirectoryIterator($hook_directory, $flags);
$iterator = new \RecursiveCallbackFilterIterator($iterator, static fn(\SplFileInfo $fileinfo): bool => $fileinfo->isDir() || $fileinfo->getExtension() === 'php');
foreach (new \RecursiveIteratorIterator($iterator) as $fileinfo) {
yield $fileinfo;
}
}
/**
* Registers hook implementation services.
*
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
* The container builder.
* @param array<string, array<string, string>> $implementations_by_hook
* Implementations keyed by hook name and identifier.
*/
protected static function registerHookServices(ContainerBuilder $container, array $implementations_by_hook) : void {
$classes_map = [];
foreach ($implementations_by_hook as $hook_implementations) {
foreach (array_keys($hook_implementations) as $identifier) {
$parts = explode('::', $identifier, 2);
if (isset($parts[1])) {
$classes_map[$parts[0]] = TRUE;
}
}
}
foreach (array_keys($classes_map) as $class) {
if (!$container->hasDefinition($class)) {
$container->register($class, $class)
->setAutowired(TRUE);
}
}
}
/**
* Gets attribute instances from a class reflection.
*
* @param \ReflectionClass $reflection_class
* The class reflection.
*
* @return array<string, list<\Drupal\Core\Hook\Attribute\HookAttributeInterface>>
* Attribute instances keyed by method name.
*/
protected static function getAttributeInstances(\ReflectionClass $reflection_class) : array {
$attributes = [];
$reflections = $reflection_class->getMethods(\ReflectionMethod::IS_PUBLIC);
$reflections[] = $reflection_class;
foreach ($reflections as $reflection) {
if ($reflection_attributes = $reflection->getAttributes(HookAttributeInterface::class, \ReflectionAttribute::IS_INSTANCEOF)) {
$method = $reflection instanceof \ReflectionMethod ? $reflection->getName() : '__invoke';
$attributes[$method] = array_map(static fn(\ReflectionAttribute $reflection_attribute) => $reflection_attribute->newInstance(), $reflection_attributes);
}
}
return $attributes;
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.