namespace = mb_trim($namespace, '\\').'\\'; $this->directory = mb_rtrim($directory, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; } /** * Executes the extraction process and returns an array of actual Enum objects. */ public function extract(): array { $enumObjects = []; foreach ($this->getPhpFiles() as $file) { $className = $this->resolveClassName($file->getPathname()); $this->loadClassIfNeeded($className, $file->getPathname()); if (enum_exists($className)) { // $className::cases() returns an array of the actual Enum objects // e.g., [App\Enums\Status::Active, App\Enums\Status::Inactive] $enumObjects[$className] = $className::cases(); } } return $enumObjects; } /** * Yields only PHP files from the target directory. */ private function getPhpFiles(): Generator { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS) ); /** @var SplFileInfo $file */ foreach ($iterator as $file) { if ('php' === $file->getExtension()) { yield $file; } } } /** * Converts a physical file path to a fully qualified PSR-4 class name. */ private function resolveClassName(string $filePath): string { // Strip the base directory from the path $relativePath = str_replace($this->directory, '', $filePath); // Normalize slashes and remove the .php extension $normalizedPath = str_replace([DIRECTORY_SEPARATOR, '/', '.php'], ['\\', '\\', ''], $relativePath); return $this->namespace.mb_ltrim($normalizedPath, '\\'); } /** * Requires the file into memory if it hasn't been autoloaded yet. */ private function loadClassIfNeeded(string $className, string $filePath): void { if (! class_exists($className, false) && ! enum_exists($className, false) && ! interface_exists($className, false) ) { require_once $filePath; } } }