- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
81 lines
2.9 KiB
PHP
81 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Core;
|
|
|
|
use App\Framework\Core\ValueObjects\ClassName;
|
|
use RecursiveDirectoryIterator;
|
|
use RecursiveIteratorIterator;
|
|
use ReflectionClass;
|
|
use Throwable;
|
|
|
|
class InterfaceImplementationLocator
|
|
{
|
|
/**
|
|
* Findet alle Klassen, die ein bestimmtes Interface implementieren
|
|
*
|
|
* @param string $directory Das Basisverzeichnis, in dem gesucht werden soll
|
|
* @param string $interfaceName Der vollständige Name des Interfaces (mit Namespace)
|
|
* @param bool $instantiate Gibt an, ob die gefundenen Klassen instanziiert werden sollen
|
|
* @return array<int, object|string> Array von Instanzen oder Klassennamen
|
|
*/
|
|
public function locate(string $directory, string $interfaceName, bool $instantiate = true): array
|
|
{
|
|
$implementations = [];
|
|
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
|
|
|
|
foreach ($rii as $file) {
|
|
if (! $file->isFile() || $file->getExtension() !== 'php') {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$className = $this->getClassNameFromFile($file->getPathname());
|
|
|
|
if (! $className || ! ClassName::create($className)->exists()) {
|
|
continue;
|
|
}
|
|
|
|
$refClass = new ReflectionClass($className);
|
|
|
|
// Überprüfen, ob die Klasse das gewünschte Interface implementiert
|
|
if ($refClass->implementsInterface($interfaceName) &&
|
|
! $refClass->isAbstract() &&
|
|
! $refClass->isInterface()) {
|
|
|
|
if ($instantiate) {
|
|
// Prüfen, ob der Konstruktor Parameter hat
|
|
$constructor = $refClass->getConstructor();
|
|
if ($constructor === null || $constructor->getNumberOfRequiredParameters() === 0) {
|
|
$implementations[] = $refClass->newInstance();
|
|
} else {
|
|
// Bei Konstruktoren mit Pflichtparametern nur den Klassennamen zurückgeben
|
|
$implementations[] = $className;
|
|
}
|
|
} else {
|
|
$implementations[] = $className;
|
|
}
|
|
}
|
|
} catch (Throwable $e) {
|
|
#error_log("InterfaceImplementationLocator Warnung: Fehler in Datei {$file->getPathname()}: " . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
return $implementations;
|
|
}
|
|
|
|
private function getClassNameFromFile(string $file): ?string
|
|
{
|
|
$contents = file_get_contents($file);
|
|
if (
|
|
preg_match('#namespace\s+([^;]+);#', $contents, $nsMatch)
|
|
&& preg_match('/class\s+(\w+)/', $contents, $classMatch)
|
|
) {
|
|
return trim($nsMatch[1]) . '\\' . trim($classMatch[1]);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|