diff --git a/composer.json b/composer.json index 67ac6781..1d4dce92 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "php": "~8.1.0 || ~8.2.0", "brick/varexporter": "^0.3.8", "laminas/laminas-stdlib": "^3.2.1", - "psr/container": "^1.1" + "psr/container": "^1.1 || ^2.0" }, "extra": { "laminas": { @@ -58,7 +58,7 @@ "vimeo/psalm": "^5.10" }, "provide": { - "psr/container-implementation": "^1.0" + "psr/container-implementation": "^1.0 || ^2.0" }, "conflict": { "laminas/laminas-code": "<3.3.1", diff --git a/composer.lock b/composer.lock index 59830e24..72d74319 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6639b46f0ff002d522b4eb0e7c619b0c", + "content-hash": "7820edc27a7811bcfb6bb97de1a22960", "packages": [ { "name": "brick/varexporter", @@ -172,22 +172,27 @@ }, { "name": "psr/container", - "version": "1.1.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -214,9 +219,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2021-11-05T16:47:00+00:00" } ], "packages-dev": [ @@ -5165,22 +5170,21 @@ }, { "name": "symfony/service-contracts", - "version": "v2.5.2", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + "reference": "a8c9cedf55f314f3a186041d19537303766df09a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a", + "reference": "a8c9cedf55f314f3a186041d19537303766df09a", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.1", + "psr/container": "^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -5191,7 +5195,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -5201,7 +5205,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5228,7 +5235,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/service-contracts/tree/v3.2.1" }, "funding": [ { @@ -5244,7 +5251,7 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:29+00:00" + "time": "2023-03-01T10:32:47+00:00" }, { "name": "symfony/string", diff --git a/psalm-baseline.xml b/psalm-baseline.xml index e8be8867..44b18f1b 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -99,10 +99,6 @@ - - $name - $name - diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 39d80fee..b576c5a7 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -184,7 +184,7 @@ public function setService(string $name, mixed $service): void /** * {@inheritDoc} */ - public function get($id): mixed + public function get(string $id): mixed { if (! $this->has($id)) { if (! $this->autoAddInvokableClass || ! class_exists($id)) { diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 29b3beb6..710356f7 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -204,35 +204,35 @@ public function __construct( } /** {@inheritDoc} */ - public function get($name) + public function get(string $id): mixed { // We start by checking if we have cached the requested service; // this is the fastest method. - if (isset($this->services[$name])) { - return $this->services[$name]; + if (isset($this->services[$id])) { + return $this->services[$id]; } // Determine if the service should be shared. - $sharedService = $this->shared[$name] ?? $this->sharedByDefault; + $sharedService = $this->shared[$id] ?? $this->sharedByDefault; // We achieve better performance if we can let all alias // considerations out. if (! $this->aliases) { /** @psalm-suppress MixedAssignment Yes indeed, service managers can return mixed. */ - $service = $this->doCreate($name); + $service = $this->doCreate($id); // Cache the service for later, if it is supposed to be shared. if ($sharedService) { - $this->services[$name] = $service; + $this->services[$id] = $service; } return $service; } // We now deal with requests which may be aliases. - $resolvedName = $this->aliases[$name] ?? $name; + $resolvedName = $this->aliases[$id] ?? $id; // Update shared service information as we checked if the alias was shared before. - if ($resolvedName !== $name) { + if ($resolvedName !== $id) { $sharedService = $this->shared[$resolvedName] ?? $sharedService; } @@ -241,7 +241,7 @@ public function get($name) // If the alias is configured as a shared service, we are done. if ($sharedAlias) { - $this->services[$name] = $this->services[$resolvedName]; + $this->services[$id] = $this->services[$resolvedName]; return $this->services[$resolvedName]; } @@ -253,7 +253,7 @@ public function get($name) // Cache the object for later, if it is supposed to be shared. if ($sharedService) { $this->services[$resolvedName] = $service; - $this->services[$name] = $service; + $this->services[$id] = $service; } return $service; @@ -274,10 +274,10 @@ public function build(string $name, ?array $options = null): mixed * @param string|class-string $name * @return bool */ - public function has($name) + public function has(string $id): bool { // Check static services and factories first to speedup the most common requests. - return $this->staticServiceOrFactoryCanCreate($name) || $this->abstractFactoryCanCreate($name); + return $this->staticServiceOrFactoryCanCreate($id) || $this->abstractFactoryCanCreate($id); } /** diff --git a/test/Tool/FactoryCreatorTest.php b/test/Tool/FactoryCreatorTest.php index 36293022..a260e86a 100644 --- a/test/Tool/FactoryCreatorTest.php +++ b/test/Tool/FactoryCreatorTest.php @@ -15,7 +15,11 @@ use Psr\Container\ContainerInterface; use stdClass; +use function array_pop; +use function count; use function file_get_contents; +use function func_get_args; +use function is_array; use function preg_match; use const PHP_EOL; @@ -55,9 +59,9 @@ public function testCreateFactoryCreatesForSimpleDependencies(): void $this->container ->expects(self::atLeastOnce()) ->method('has') - ->willReturnMap([ + ->willReturnCallback($this->createReturnMapCallbackWithDefault([ [InvokableObject::class, true], - ]); + ], false)); self::assertSame($factory, $this->factoryCreator->createFactory($className)); } @@ -70,10 +74,10 @@ public function testCreateFactoryCreatesForComplexDependencies(): void $this->container ->expects(self::atLeastOnce()) ->method('has') - ->willReturnMap([ + ->willReturnCallback($this->createReturnMapCallbackWithDefault([ [SimpleDependencyObject::class, true], [SecondComplexDependencyObject::class, true], - ]); + ], false)); self::assertSame($factory, $this->factoryCreator->createFactory($className)); } @@ -89,10 +93,10 @@ public function testNamespaceGeneration(): void $this->container ->expects(self::atLeastOnce()) ->method('has') - ->willReturnMap([ + ->willReturnCallback($this->createReturnMapCallbackWithDefault([ [SimpleDependencyObject::class, true], [SecondComplexDependencyObject::class, true], - ]); + ], false)); foreach ($testClassNames as $testFqcn => $expectedNamespace) { $generatedFactory = $this->factoryCreator->createFactory($testFqcn); @@ -108,4 +112,27 @@ public function testNamespaceGeneration(): void self::assertSame($expectedNamespace, $namespaceMatch[1]); } } + + private function createReturnMapCallbackWithDefault(array $values, mixed $default): callable + { + return function () use ($values, $default): mixed { + $args = func_get_args(); + $parameterCount = count($args); + + foreach ($values as $map) { + if (! is_array($map) || $parameterCount !== count($map) - 1) { + continue; + } + + /** @var mixed $return */ + $return = array_pop($map); + + if ($args === $map) { + return $return; + } + } + + return $default; + }; + } }