diff --git a/src/ServiceMap.php b/src/ServiceMap.php index c770aeb..39778af 100644 --- a/src/ServiceMap.php +++ b/src/ServiceMap.php @@ -9,13 +9,19 @@ use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Name; use PhpParser\Node\Scalar\String_; -use ReflectionException; use ReflectionFunction; use ReflectionNamedType; use RuntimeException; /** * @phpstan-type Yii2Definition object|string|Closure|array{class?: string, __class?: string} + * @phpstan-type YII2ContainerConfig array{ + * container?: array{ + * singletons?: array, + * definitions?: array, + * }, + * components?: array, + * } */ final class ServiceMap { @@ -46,7 +52,8 @@ final class ServiceMap { private array $components = []; /** - * @throws RuntimeException|ReflectionException + * @throws \RuntimeException + * @throws \ReflectionException */ public function __construct(string $configPath) { if (!file_exists($configPath)) { @@ -58,26 +65,18 @@ public function __construct(string $configPath) { defined('YII_ENV_PROD') || define('YII_ENV_PROD', false); defined('YII_ENV_TEST') || define('YII_ENV_TEST', true); - /** - * @var array{ - * container?: array{ - * singletons?: array, - * definitions?: array, - * }, - * components?: array, - * } $config - */ + /** @var YII2ContainerConfig $config */ $config = require $configPath; foreach ($config['container']['singletons'] ?? [] as $id => $definition) { - $this->services[$id] = $this->guessDefinition($id, $definition); + $this->services[$id] = $this->guessDefinition($id, $definition, $config); } foreach ($config['container']['definitions'] ?? [] as $id => $definition) { - $this->services[$id] = $this->guessDefinition($id, $definition); + $this->services[$id] = $this->guessDefinition($id, $definition, $config); } foreach ($config['components'] ?? [] as $id => $definition) { - $this->components[$id] = $this->guessDefinition($id, $definition); + $this->components[$id] = $this->guessDefinition($id, $definition, $config); } } @@ -99,13 +98,12 @@ public function getComponentClassById(string $id): ?string { /** * @param Yii2Definition $definition - * @throws RuntimeException|ReflectionException + * @param YII2ContainerConfig $config + * + * @throws \RuntimeException + * @throws \ReflectionException */ - private function guessDefinition(string $id, $definition): string { - if (is_string($definition) && (class_exists($definition) || interface_exists($definition))) { - return $definition; - } - + private function guessDefinition(string $id, $definition, $config): string { if ($definition instanceof Closure) { $returnType = (new ReflectionFunction($definition))->getReturnType(); if ($returnType instanceof ReflectionNamedType) { @@ -137,6 +135,20 @@ private function guessDefinition(string $id, $definition): string { } } + if (is_string($definition)) { + if (isset($config['container']['definitions'][$definition])) { + return $this->guessDefinition($definition, $config['container']['definitions'][$definition], $config); + } + + if (isset($config['container']['singletons'][$definition])) { + return $this->guessDefinition($definition, $config['container']['singletons'][$definition], $config); + } + + if (class_exists($definition) || interface_exists($definition)) { + return $definition; + } + } + if (class_exists($id)) { return $id; } diff --git a/tests/ServiceMapTest.php b/tests/ServiceMapTest.php index d5f60b9..1e51d3f 100644 --- a/tests/ServiceMapTest.php +++ b/tests/ServiceMapTest.php @@ -39,6 +39,7 @@ public function testItLoadsServicesAndComponents(): void { $this->assertSame(CacheInterface::class, $serviceMap->getComponentClassById('componentToContainer')); $this->assertSame(Request::class, $serviceMap->getComponentClassById('request')); $this->assertSame(Response::class, $serviceMap->getComponentClassById('response')); + $this->assertSame(\yii\caching\ArrayCache::class, $serviceMap->getComponentClassById('cache')); } public function testThrowExceptionWhenConfigurationFileDoesNotExist(): void { diff --git a/tests/assets/yii-config-valid.php b/tests/assets/yii-config-valid.php index 9f083e2..df161fe 100644 --- a/tests/assets/yii-config-valid.php +++ b/tests/assets/yii-config-valid.php @@ -13,6 +13,7 @@ 'request' => [ 'baseUrl' => '/', ], + 'cache' => 'cache.definition', ], 'container' => [ 'singletons' => [ @@ -34,6 +35,7 @@ public function __toString(): string { 'flag' => 'foo', ], Throwable::class => Exception::class, + 'cache.definition' => yii\caching\ArrayCache::class, ], ], ];