Skip to content

Commit

Permalink
Fixes #14. Handle aliased component configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
erickskrauch committed Jan 31, 2025
1 parent f561249 commit 25d1989
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 20 deletions.
52 changes: 32 additions & 20 deletions src/ServiceMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, Yii2Definition>,
* definitions?: array<string, Yii2Definition>,
* },
* components?: array<string, Yii2Definition>,
* }
*/
final class ServiceMap {

Expand Down Expand Up @@ -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)) {
Expand All @@ -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<string, Yii2Definition>,
* definitions?: array<string, Yii2Definition>,
* },
* components?: array<string, Yii2Definition>,
* } $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);
}
}

Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions tests/ServiceMapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions tests/assets/yii-config-valid.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
'request' => [
'baseUrl' => '/',
],
'cache' => 'cache.definition',
],
'container' => [
'singletons' => [
Expand All @@ -34,6 +35,7 @@ public function __toString(): string {
'flag' => 'foo',
],
Throwable::class => Exception::class,
'cache.definition' => yii\caching\ArrayCache::class,
],
],
];

0 comments on commit 25d1989

Please sign in to comment.