Files
michaelschiemer/src/Framework/Core/InterfaceImplementationVisitor.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

200 lines
6.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Core;
use App\Framework\Cache\Cache;
use App\Framework\Cache\CacheKey;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Discovery\FileVisitor;
use App\Framework\Discovery\ReflectionAwareVisitor;
use App\Framework\Filesystem\ValueObjects\FilePath;
use App\Framework\Reflection\WrappedReflectionClass;
/**
* Visitor zum Auffinden von Interface-Implementierungen
*/
final class InterfaceImplementationVisitor implements FileVisitor, ReflectionAwareVisitor
{
/** @var array<string, mixed> */
private array $interfaces = [];
/** @var array<string, array<int, string>> */
private array $implementations = [];
/** @var array<string, array<int, string>> */
private array $implementationsByClass = [];
/**
* @param array<int, string> $targetInterfaces Die zu suchenden Interfaces
*/
public function __construct(
private readonly array $targetInterfaces = []
) {
}
public function onScanStart(): void
{
$this->implementations = [];
$this->implementationsByClass = [];
}
public function onIncrementalScanStart(): void
{
// Bei inkrementellem Scan behalten wir vorhandene Implementierungen
// und aktualisieren sie mit neuen Daten
}
public function onIncrementalScanComplete(): void
{
// Sortiere nach inkrementellem Scan
$this->sortImplementations();
}
public function visitClass(ClassName $className, FilePath $filePath): void
{
// This method is kept for backward compatibility but should not be used
// when ReflectionProvider is available. The UnifiedDiscoveryService will
// prefer visitClassWithReflection() when possible.
}
public function visitClassWithReflection(ClassName $className, FilePath $filePath, WrappedReflectionClass $reflection): void
{
try {
// Skip abstract classes and interfaces - only process instantiable classes
if (! $reflection->isInstantiable()) {
return;
}
// Alte Einträge für diese Klasse entfernen (wichtig für inkrementelle Scans)
$classNameStr = $className->getFullyQualified();
$this->removeImplementationsForClass($classNameStr);
// Prüfe, ob die Klasse eines der Ziel-Interfaces implementiert
foreach ($this->targetInterfaces as $interface) {
if ($reflection->implementsInterface($interface)) {
if (! isset($this->implementations[$interface])) {
$this->implementations[$interface] = [];
}
// Prüfe auf Duplikate
if (! in_array($classNameStr, $this->implementations[$interface])) {
$this->implementations[$interface][] = $classNameStr;
// Umgekehrten Index für schnelleren Zugriff aufbauen
if (! isset($this->implementationsByClass[$classNameStr])) {
$this->implementationsByClass[$classNameStr] = [];
}
$this->implementationsByClass[$classNameStr][] = $interface;
}
}
}
} catch (\Throwable $e) {
// Silent failure - skip this class and continue with discovery
}
}
/**
* Entfernt alle Interface-Implementierungen für eine bestimmte Klasse
*/
private function removeImplementationsForClass(string $className): void
{
if (! isset($this->implementationsByClass[$className])) {
return;
}
foreach ($this->implementationsByClass[$className] as $interface) {
if (isset($this->implementations[$interface])) {
$key = array_search($className, $this->implementations[$interface]);
if ($key !== false) {
unset($this->implementations[$interface][$key]);
// Array-Indizes neu numerieren
$this->implementations[$interface] = array_values($this->implementations[$interface]);
}
}
}
unset($this->implementationsByClass[$className]);
}
public function onScanComplete(): void
{
// Sortiere Implementierungen für konsistente Reihenfolge
$this->sortImplementations();
}
/**
* Sortiert alle Implementierungen für konsistente Ergebnisse
*/
private function sortImplementations(): void
{
foreach ($this->implementations as &$classes) {
sort($classes);
}
}
public function loadFromCache(Cache $cache): void
{
$cacheItem = $cache->get($this->getCacheKey());
if ($cacheItem->isHit) {
if (is_array($cacheItem->value) && isset($cacheItem->value['implementations'], $cacheItem->value['byClass'])) {
$this->implementations = $cacheItem->value['implementations'];
$this->implementationsByClass = $cacheItem->value['byClass'];
}
}
}
public function getCacheKey(): CacheKey
{
return CacheKey::fromString('interface_implementations');
}
/**
* @return array<string, mixed>
*/
public function getCacheableData(): array
{
return [
'implementations' => $this->implementations,
'byClass' => $this->implementationsByClass,
];
}
/**
* Gibt alle Implementierungen eines Interfaces zurück
* @return array<int, string>
*/
public function getImplementations(string $interface): array
{
return $this->implementations[$interface] ?? [];
}
/**
* Prüft, ob eine Klasse ein bestimmtes Interface implementiert
*/
public function doesImplement(string $className, string $interface): bool
{
return isset($this->implementationsByClass[$className]) &&
in_array($interface, $this->implementationsByClass[$className]);
}
/**
* Gibt alle Interfaces zurück, die eine Klasse implementiert
* @return array<int, string>
*/
public function getClassInterfaces(string $className): array
{
return $this->implementationsByClass[$className] ?? [];
}
/**
* Gibt alle gefundenen Implementierungen zurück
* @return array<string, array<int, string>>
*/
public function getAllImplementations(): array
{
return $this->implementations;
}
}