chore: complete update

This commit is contained in:
2025-07-17 16:24:20 +02:00
parent 899227b0a4
commit 64a7051137
1300 changed files with 85570 additions and 2756 deletions

View File

@@ -0,0 +1,174 @@
<?php
declare(strict_types=1);
namespace App\Framework\Reflection;
use ReflectionClass;
use ReflectionMethod;
use ReflectionParameter;
use ReflectionProperty;
use ReflectionException;
final class CachedReflectionProvider implements ReflectionProvider
{
private array $classCache = [];
private array $methodCache = [];
private array $parameterCache = [];
private array $propertyCache = [];
private array $attributeCache = [];
private array $parameterInfoCache = [];
private array $instantiableCache = [];
private array $interfaceCache = [];
private array $wrappedClassCache = [];
private array $wrappedMethodCache = [];
public function getWrappedClass(string $className): WrappedReflectionClass
{
return $this->wrappedClassCache[$className] ??= new WrappedReflectionClass(
$this->getClass($className)
);
}
public function getWrappedMethod(string $className, string $methodName): WrappedReflectionMethod
{
$key = "{$className}::{$methodName}";
return $this->wrappedMethodCache[$key] ??= new WrappedReflectionMethod(
$this->getMethod($className, $methodName)
);
}
public function getClass(string $className): ReflectionClass
{
return $this->classCache[$className] ??= new ReflectionClass($className);
}
public function getMethod(string $className, string $methodName): ReflectionMethod
{
$key = "{$className}::{$methodName}";
return $this->methodCache[$key] ??= $this->getClass($className)->getMethod($methodName);
}
public function getMethodParameters(string $className, string $methodName): array
{
$key = "{$className}::{$methodName}::params";
return $this->parameterCache[$key] ??= $this->getMethod($className, $methodName)->getParameters();
}
public function getProperties(string $className): array
{
$key = "{$className}::properties";
return $this->propertyCache[$key] ??= $this->getClass($className)->getProperties();
}
public function getAttributes(string $className, ?string $attributeClass = null): array
{
$key = "{$className}::attributes::" . ($attributeClass ?? 'all');
return $this->attributeCache[$key] ??= $attributeClass
? $this->getClass($className)->getAttributes($attributeClass)
: $this->getClass($className)->getAttributes();
}
public function getMethodAttributes(string $className, string $methodName, ?string $attributeClass = null): array
{
$key = "{$className}::{$methodName}::attributes::" . ($attributeClass ?? 'all');
return $this->attributeCache[$key] ??= $attributeClass
? $this->getMethod($className, $methodName)->getAttributes($attributeClass)
: $this->getMethod($className, $methodName)->getAttributes();
}
public function hasAttribute(string $className, string $attributeClass): bool
{
return !empty($this->getAttributes($className, $attributeClass));
}
public function getParameterInfo(string $className, string $methodName): array
{
$key = "{$className}::{$methodName}::paramInfo";
return $this->parameterInfoCache[$key] ??= $this->buildParameterInfo($className, $methodName);
}
public function isInstantiable(string $className): bool
{
return $this->instantiableCache[$className] ??= $this->getClass($className)->isInstantiable();
}
public function implementsInterface(string $className, string $interfaceName): bool
{
$key = "{$className}::implements::{$interfaceName}";
return $this->interfaceCache[$key] ??= $this->getClass($className)->implementsInterface($interfaceName);
}
private function buildParameterInfo(string $className, string $methodName): array
{
$parameters = $this->getMethodParameters($className, $methodName);
$paramInfo = [];
foreach ($parameters as $param) {
$type = $param->getType();
$paramInfo[] = [
'name' => $param->getName(),
'type' => $type ? $type->getName() : null,
'isBuiltin' => $type ? $type->isBuiltin() : true,
'allowsNull' => $param->allowsNull(),
'isOptional' => $param->isOptional(),
'hasDefaultValue' => $param->isDefaultValueAvailable(),
'default' => $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null,
'position' => $param->getPosition(),
];
}
return $paramInfo;
}
public function forget(string $className): void
{
unset($this->classCache[$className]);
unset($this->instantiableCache[$className]);
unset($this->wrappedClassCache[$className]);
// Alle zugehörigen Caches leeren
$this->clearRelatedCaches($className);
}
public function flush(): void
{
$this->classCache = [];
$this->methodCache = [];
$this->parameterCache = [];
$this->propertyCache = [];
$this->attributeCache = [];
$this->parameterInfoCache = [];
$this->instantiableCache = [];
$this->interfaceCache = [];
$this->wrappedClassCache = [];
$this->wrappedMethodCache = [];
}
private function clearRelatedCaches(string $className): void
{
$prefix = $className . '::';
$caches = [
&$this->methodCache,
&$this->parameterCache,
&$this->propertyCache,
&$this->attributeCache,
&$this->parameterInfoCache,
&$this->interfaceCache,
&$this->wrappedMethodCache
];
foreach ($caches as &$cache) {
$cache = array_filter(
$cache,
fn($key) => !str_starts_with($key, $prefix),
ARRAY_FILTER_USE_KEY
);
}
}
}

View File

@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace App\Framework\Reflection;
use ReflectionClass;
use ReflectionMethod;
use ReflectionParameter;
use ReflectionProperty;
interface ReflectionProvider
{
// Wrapped Objekte für erweiterte API
public function getWrappedClass(string $className): WrappedReflectionClass;
public function getWrappedMethod(string $className, string $methodName): WrappedReflectionMethod;
// Original Reflection Objekte
public function getClass(string $className): ReflectionClass;
public function getMethod(string $className, string $methodName): ReflectionMethod;
public function getMethodParameters(string $className, string $methodName): array;
public function getProperties(string $className): array;
public function getAttributes(string $className, ?string $attributeClass = null): array;
public function getMethodAttributes(string $className, string $methodName, ?string $attributeClass = null): array;
public function hasAttribute(string $className, string $attributeClass): bool;
public function getParameterInfo(string $className, string $methodName): array;
public function isInstantiable(string $className): bool;
public function implementsInterface(string $className, string $interfaceName): bool;
public function forget(string $className): void;
public function flush(): void;
}

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace App\Framework\Reflection;
use ReflectionClass;
use ReflectionAttribute;
final readonly class WrappedReflectionClass
{
public function __construct(
public ReflectionClass $reflection
) {}
public function getName(): string
{
return $this->reflection->getName();
}
public function getShortName(): string
{
return $this->reflection->getShortName();
}
public function isInstantiable(): bool
{
return $this->reflection->isInstantiable();
}
public function implementsInterface(string $interface): bool
{
return $this->reflection->implementsInterface($interface);
}
// Erweiterte Convenience-Methoden
public function getAttributeInstances(?string $attributeClass = null): array
{
$attributes = $this->reflection->getAttributes($attributeClass);
return array_map(fn(ReflectionAttribute $attr) => $attr->newInstance(), $attributes);
}
public function hasAttribute(string $attributeClass): bool
{
return !empty($this->reflection->getAttributes($attributeClass));
}
public function getFirstAttribute(string $attributeClass): ?object
{
$instances = $this->getAttributeInstances($attributeClass);
return $instances[0] ?? null;
}
public function getMethodsWithAttribute(string $attributeClass): array
{
$methods = [];
foreach ($this->reflection->getMethods() as $method) {
if (!empty($method->getAttributes($attributeClass))) {
$methods[] = new WrappedReflectionMethod($method);
}
}
return $methods;
}
public function getWrappedMethod(string $name): WrappedReflectionMethod
{
return new WrappedReflectionMethod($this->reflection->getMethod($name));
}
public function getWrappedMethods(?int $filter = null): array
{
return array_map(
fn($method) => new WrappedReflectionMethod($method),
$this->reflection->getMethods($filter)
);
}
}

View File

@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace App\Framework\Reflection;
use ReflectionMethod;
use ReflectionAttribute;
final readonly class WrappedReflectionMethod
{
public function __construct(
public ReflectionMethod $reflection
) {}
public function getName(): string
{
return $this->reflection->getName();
}
public function getWrappedParameters(): array
{
return array_map(
fn($param) => new WrappedReflectionParameter($param),
$this->reflection->getParameters()
);
}
// Erweiterte Parameter-Info als Array (für DI)
public function getParameterInfo(): array
{
$params = [];
foreach ($this->reflection->getParameters() as $param) {
$type = $param->getType();
$params[] = [
'name' => $param->getName(),
'type' => $type ? $type->getName() : null,
'isBuiltin' => $type ? $type->isBuiltin() : true,
'allowsNull' => $param->allowsNull(),
'isOptional' => $param->isOptional(),
'hasDefaultValue' => $param->isDefaultValueAvailable(),
'default' => $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null,
'position' => $param->getPosition(),
];
}
return $params;
}
public function getAttributeInstances(?string $attributeClass = null): array
{
$attributes = $this->reflection->getAttributes($attributeClass);
return array_map(fn(ReflectionAttribute $attr) => $attr->newInstance(), $attributes);
}
public function hasAttribute(string $attributeClass): bool
{
return !empty($this->reflection->getAttributes($attributeClass));
}
public function getFirstAttribute(string $attributeClass): ?object
{
$instances = $this->getAttributeInstances($attributeClass);
return $instances[0] ?? null;
}
}

View File

@@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
namespace App\Framework\Reflection;
use ReflectionParameter;
final readonly class WrappedReflectionParameter
{
public function __construct(
public ReflectionParameter $reflection
) {}
public function getName(): string
{
return $this->reflection->getName();
}
public function getTypeName(): ?string
{
$type = $this->reflection->getType();
return $type ? $type->getName() : null;
}
public function isBuiltin(): bool
{
$type = $this->reflection->getType();
return $type ? $type->isBuiltin() : true;
}
public function isOptional(): bool
{
return $this->reflection->isOptional();
}
public function hasDefaultValue(): bool
{
return $this->reflection->isDefaultValueAvailable();
}
public function getDefaultValue(): mixed
{
return $this->reflection->isDefaultValueAvailable()
? $this->reflection->getDefaultValue()
: null;
}
public function allowsNull(): bool
{
return $this->reflection->allowsNull();
}
public function getPosition(): int
{
return $this->reflection->getPosition();
}
// Convenience-Methode für DI
public function toArray(): array
{
return [
'name' => $this->getName(),
'type' => $this->getTypeName(),
'isBuiltin' => $this->isBuiltin(),
'allowsNull' => $this->allowsNull(),
'isOptional' => $this->isOptional(),
'hasDefaultValue' => $this->hasDefaultValue(),
'default' => $this->getDefaultValue(),
'position' => $this->getPosition(),
];
}
}