diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index f5680374add02..53570621ab756 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -313,23 +313,11 @@ protected function query(string $name, bool $autoload = true, array $chain = []) return $this->appName; } - $isServerClass = str_starts_with($name, 'OCP\\') || str_starts_with($name, 'OC\\'); - if ($isServerClass && !$this->has($name)) { - return $this->server->query($name, $autoload, $chain); - } - - try { - return $this->queryNoFallback($name, $chain); - } catch (QueryException $firstException) { - try { - return $this->server->query($name, $autoload, $chain); - } catch (QueryException $secondException) { - if ($firstException->getCode() === 1) { - throw $secondException; - } - throw $firstException; - } + $result = $this->queryNoFallback($name, $chain); + if ($result !== null) { + return $result; } + return $this->server->query($name, $autoload, $chain); } /** @@ -353,8 +341,6 @@ public function queryNoFallback($name, array $chain) { /* AppFramework services are scoped to the application */ return parent::query($name, chain: $chain); } - - throw new QueryException('Could not resolve ' . $name . '!' - . ' Class can not be instantiated', 1); + return null; } } diff --git a/lib/private/AppFramework/Utility/SimpleContainer.php b/lib/private/AppFramework/Utility/SimpleContainer.php index 9d137117ef8f7..e2a8c53347c43 100644 --- a/lib/private/AppFramework/Utility/SimpleContainer.php +++ b/lib/private/AppFramework/Utility/SimpleContainer.php @@ -32,6 +32,9 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer { protected Container $container; + /** @var array */ + private array $aliases = []; + public function __construct() { $this->container = new Container(); } @@ -43,13 +46,13 @@ public function __construct() { */ #[\Override] public function get(string $id): mixed { - return $this->query($this->sanitizeName($id)); + return $this->query($this->resolveAlias($this->sanitizeName($id))); } #[\Override] public function has(string $id): bool { // If a service is no registered but is an existing class, we can probably load it - return isset($this->container[$id]) || class_exists($id); + return isset($this->aliases[$id]) || isset($this->container[$id]) || class_exists($id); } /** @@ -93,7 +96,7 @@ private function buildClassConstructorParameters(\ReflectionMethod $constructor, try { $builtIn = $parameterType !== null && ($parameterType instanceof ReflectionNamedType) && $parameterType->isBuiltin(); - return $this->query($resolveName, !$builtIn, $chain); + return $this->query($this->resolveAlias($resolveName), !$builtIn, $chain); } catch (ContainerExceptionInterface $e) { // Service not found, use the default value when available if ($parameter->isDefaultValueAvailable()) { @@ -103,7 +106,7 @@ private function buildClassConstructorParameters(\ReflectionMethod $constructor, if ($parameterType !== null && ($parameterType instanceof ReflectionNamedType) && !$parameterType->isBuiltin()) { $resolveName = $parameter->getName(); try { - return $this->query($resolveName, chain: $chain); + return $this->query($this->resolveAlias($resolveName), chain: $chain); } catch (ContainerExceptionInterface $e2) { // Pass null if typed and nullable if ($parameter->allowsNull() && ($parameterType instanceof ReflectionNamedType)) { @@ -148,7 +151,7 @@ public function resolve(string $name, array $chain = []): mixed { } /** - * @param string $name Already sanitized name + * @param string $name Already sanitized name and alias resolved * @param list $chain */ protected function query(string $name, bool $autoload = true, array $chain = []): mixed { @@ -195,6 +198,9 @@ public function registerService(string $name, Closure $closure, bool $shared = t if (isset($this->container[$name])) { unset($this->container[$name]); } + if (isset($this->aliases[$name])) { + unset($this->aliases[$name]); + } if ($shared) { $this->container[$name] = $wrapped; } else { @@ -210,11 +216,14 @@ public function registerService(string $name, Closure $closure, bool $shared = t * @param string $target the target that should be resolved instead */ public function registerAlias(string $alias, string $target): void { - $this->registerService( - $alias, - static fn (ContainerInterface $container): mixed => $container->get($target), - false, - ); + $this->aliases[$alias] = $target; + } + + protected function resolveAlias(string $name) : string { + if (isset($this->aliases[$name])) { + return $this->resolveAlias($this->aliases[$name]); + } + return $name; } protected function registerDeprecatedAlias(string $alias, string $target): void { diff --git a/lib/private/ServerContainer.php b/lib/private/ServerContainer.php index 4c345e132b4cc..cfee05694a14a 100644 --- a/lib/private/ServerContainer.php +++ b/lib/private/ServerContainer.php @@ -124,22 +124,15 @@ public function has($id, bool $noRecursion = false): bool { #[\Override] protected function query(string $name, bool $autoload = true, array $chain = []): mixed { if (str_starts_with($name, 'OCA\\')) { - // Skip server container query for app namespace classes - if (isset($this->container[$name])) { - return $this->container[$name]; - } - // Continue with general autoloading - // In case the service starts with OCA\ we try to find the service in - // the apps container first. + // In case the service starts with OCA\ we try to find the service in the apps container. if (($appContainer = $this->getAppContainerForService($name)) !== null) { - try { - return $appContainer->queryNoFallback($name, $chain); - } catch (QueryException $e) { - // Didn't find the service or the respective app container - // In this case the service won't be part of the core container, - // so we can throw directly - throw $e; + return $appContainer->queryNoFallback($name, $chain); + $result = $appContainer->queryNoFallback($name, $chain); + if ($result !== null) { + return $result; } + throw new QueryException('Could not resolve ' . $name . '!' + . ' Class can not be instantiated', 1); } }