headless_cms-1.0.3/modules/headless_cms_notify/src/NotifyMessage/HeadlessNotifyMessageDiscoveryService.php
modules/headless_cms_notify/src/NotifyMessage/HeadlessNotifyMessageDiscoveryService.php
<?php
declare(strict_types=1);
namespace Drupal\headless_cms_notify\NotifyMessage;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Finder\Exception\DirectoryNotFoundException;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
/**
* Discovers all message classes.
*/
class HeadlessNotifyMessageDiscoveryService {
public function __construct(
#[Autowire('@cache.headless_cms_notify')]
protected readonly CacheBackendInterface $cache,
protected readonly ModuleHandlerInterface $moduleHandler,
) {}
/**
* Get array of all message types.
*
* @return HeadlessNotifyMessageDiscoveryResult[]
* Array of message types.
*/
public function getMessageTypes(): array {
$cid = 'headless_cms_notify_message_discovery';
// Check if we have a cached result.
if ($item = $this->cache->get($cid)) {
return $item->data;
}
$types = [];
$moduleDirs = $this->moduleHandler->getModuleDirectories();
$finder = new Finder();
foreach ($moduleDirs as $moduleDir) {
try {
$finder
->files()
->in($moduleDir . '/src/NotifyMessage')
->name('*.php');
}
catch (DirectoryNotFoundException) {
}
}
foreach ($finder as $file) {
$fqcn = $this->getFullyQualifiedClassName($file);
if ($fqcn) {
$reflectionClass = new \ReflectionClass($fqcn);
if ($reflectionClass->implementsInterface(HeadlessNotifyMessageInterface::class) && !$reflectionClass->isAbstract()) {
$instance = $reflectionClass->newInstanceWithoutConstructor();
$types[] = new HeadlessNotifyMessageDiscoveryResult(
$fqcn,
$instance->getMessageTypeId(),
$instance->getMessageTypeLabel(),
);
}
}
}
// Cache the result.
$this->cache->set($cid, $types);
return $types;
}
/**
* Get the fully qualified class name from the file contents.
*/
public function getFullyQualifiedClassName(SplFileInfo $file): ?string {
$contents = $file->getContents();
// Get namespace.
if (preg_match('/namespace\s+([^;]+);/', $contents, $matches)) {
$namespace = $matches[1];
// Get class name.
if (preg_match('/class\s+(\w+)/', $contents, $classMatches)) {
$className = $classMatches[1];
$fqcn = $namespace . '\\' . $className;
return $fqcn;
}
}
return NULL;
}
}
