Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -1,10 +1,12 @@
<?php
declare(strict_types=1);
namespace App\Framework\DI;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Reflection\ReflectionProvider;
use ReflectionMethod;
use ReflectionNamedType;
use App\Framework\Reflection\WrappedReflectionMethod;
/**
* Führt Methoden auf beliebigen Klassen mit automatischer Dependency Injection aus
@@ -13,15 +15,17 @@ final readonly class MethodInvoker
{
public function __construct(
private Container $container,
private ReflectionProvider $reflectionCache
) {}
private ReflectionProvider $reflectionProvider
) {
}
/**
* Führt eine Methode auf einer Klasse aus und löst alle Parameter automatisch auf
*/
public function invoke(string $className, string $methodName, array $overrides = []): mixed
public function invoke(ClassName $className, string $methodName, array $overrides = []): mixed
{
$instance = $this->container->get($className);
$instance = $this->container->get($className->getFullyQualified());
return $this->invokeOn($instance, $methodName, $overrides);
}
@@ -30,25 +34,28 @@ final readonly class MethodInvoker
*/
public function invokeOn(object $instance, string $methodName, array $overrides = []): mixed
{
$reflection = $this->reflectionCache->getClass($instance::class);
$className = ClassName::fromObject($instance);
$reflection = $this->reflectionProvider->getClass($className);
if (!$reflection->hasMethod($methodName)) {
if (! $reflection->hasMethod($methodName)) {
throw new \InvalidArgumentException(
"Method $methodName does not exist on class $instance::class"
"Method $methodName does not exist on class " . $instance::class
);
}
$method = $this->reflectionCache->getMethod($instance::class, $methodName);
// Framework WrappedReflectionMethod verwenden
$method = $this->reflectionProvider->getMethod($className, $methodName);
$nativeMethod = $this->reflectionProvider->getNativeMethod($className, $methodName);
if (!$method->isPublic()) {
if (! $nativeMethod->isPublic()) {
throw new \InvalidArgumentException(
"Method $methodName on class $instance::class is not public"
"Method $methodName on class " . $instance::class . " is not public"
);
}
$parameters = $this->resolveMethodParameters($method, $overrides);
$parameters = $this->resolveMethodParameters($className, $methodName, $overrides);
return $method->invokeArgs($instance, $parameters);
return $nativeMethod->invokeArgs($instance, $parameters);
}
/**
@@ -56,69 +63,77 @@ final readonly class MethodInvoker
*/
public function invokeStatic(string $className, string $methodName, array $overrides = []): mixed
{
$reflection = $this->reflectionCache->getClass($className);
$classNameObj = ClassName::create($className);
$reflection = $this->reflectionProvider->getClass($classNameObj);
if (!$reflection->hasMethod($methodName)) {
if (! $reflection->hasMethod($methodName)) {
throw new \InvalidArgumentException(
"Method '{$methodName}' does not exist on class '{$className}'"
);
}
$method = $this->reflectionCache->getMethod($className, $methodName);
// Framework WrappedReflectionMethod verwenden
$method = $this->reflectionProvider->getMethod($classNameObj, $methodName);
$nativeMethod = $this->reflectionProvider->getNativeMethod($classNameObj, $methodName);
if (!$method->isStatic()) {
if (! $nativeMethod->isStatic()) {
throw new \InvalidArgumentException(
"Method '{$methodName}' on class '{$className}' is not static"
);
}
$parameters = $this->resolveMethodParameters($method, $overrides);
$parameters = $this->resolveMethodParameters($classNameObj, $methodName, $overrides);
return $method->invokeArgs(null, $parameters);
return $nativeMethod->invokeArgs(null, $parameters);
}
/**
* Löst alle Parameter einer Methode auf
*/
private function resolveMethodParameters(ReflectionMethod $method, array $overrides): array
private function resolveMethodParameters(ClassName $className, string $methodName, array $overrides): array
{
$parameters = [];
foreach ($method->getParameters() as $param) {
// Framework ParameterCollection verwenden
$methodParameters = $this->reflectionProvider->getMethodParameters($className, $methodName);
foreach ($methodParameters as $param) {
$paramName = $param->getName();
// Override-Werte haben Priorität
if (array_key_exists($paramName, $overrides)) {
$parameters[] = $overrides[$paramName];
continue;
}
// Type-based injection
$type = $param->getType();
if ($type instanceof ReflectionNamedType && !$type->isBuiltin()) {
$typeName = $type->getName();
// Type-based injection mit Framework API
$typeName = $param->getTypeName();
if ($typeName !== null && ! $param->isBuiltin()) {
if ($this->container->has($typeName)) {
$parameters[] = $this->container->get($typeName);
continue;
}
}
// Default-Werte verwenden
if ($param->isDefaultValueAvailable()) {
if ($param->hasDefaultValue()) {
$parameters[] = $param->getDefaultValue();
continue;
}
// Nullable Parameter
if ($type && $type->allowsNull()) {
if ($param->allowsNull()) {
$parameters[] = null;
continue;
}
throw new \InvalidArgumentException(
"Cannot resolve parameter '{$paramName}' for method '{$method->getName()}' on class '{$method->getDeclaringClass()->getName()}'"
"Cannot resolve parameter '{$paramName}' for method '{$methodName}' on class '{$className->getFullyQualified()}'"
);
}