*/ private array $descriptors = []; /** * @var array */ private array $aliases = []; public function __construct() { foreach ($this->createDescriptors() as $descriptor) { $this->register($descriptor, $this->aliasMapFor($descriptor->getKey())); } } /** * @return array */ public function all(): array { return array_values($this->descriptors); } public function has(string $key): bool { return $this->findByNormalizedKey($key) instanceof ProviderDescriptor; } public function get(string $key): ?ProviderDescriptor { return $this->findByNormalizedKey($key); } public function require(string $key): ProviderDescriptor { $descriptor = $this->get($key); if ($descriptor instanceof ProviderDescriptor) { return $descriptor; } throw new OutOfBoundsException(sprintf('Provider descriptor not found for key "%s".', $key)); } /** * @return array */ public function keys(): array { return array_map(static fn (ProviderDescriptor $descriptor): string => $descriptor->getKey(), $this->all()); } public function findByNormalizedKey(string $key): ?ProviderDescriptor { $normalized = $this->normalizeAlias($key); if ($normalized === '') { return null; } if (isset($this->aliases[$normalized])) { $key = $this->aliases[$normalized]; return $this->descriptors[$key] ?? null; } foreach ($this->descriptors as $descriptor) { if ($this->normalizeAlias($descriptor->getKey()) === $normalized) { return $descriptor; } } return null; } /** * @return array */ private function createDescriptors(): array { return \TFGraphics\SmartImport\Providers\Foundation\RuntimeProviderCatalog::policy('reference_descriptors'); } public function register(ProviderDescriptor $descriptor, array $aliases): void { $this->descriptors[$descriptor->getKey()] = $descriptor; foreach ($aliases as $alias) { $normalizedAlias = $this->normalizeAlias($alias); if ($normalizedAlias === '') { continue; } $this->aliases[$normalizedAlias] = $descriptor->getKey(); } } /** * @return array */ private function aliasMapFor(string $key): array { return [$key]; } private function normalizeAlias(string $key): string { $normalized = preg_replace('/[^a-zA-Z0-9]+/', '', strtolower(trim($key))); return is_string($normalized) ? $normalized : ''; } }