diff --git a/.scrutinizer.yml b/.scrutinizer.yml index cf46d83..c5d5b38 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -24,7 +24,7 @@ tools: php_code_coverage: false php_code_sniffer: config: - standard: PSR2 + standard: PSR12 filter: paths: ['src'] php_loc: diff --git a/.travis.yml b/.travis.yml index 93a02ab..b1b93c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: php php: - - 7.0 - - 7.1 - 7.2 - 7.3 - 7.4 diff --git a/README.md b/README.md index 3c38f7b..48aa393 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,11 @@ [![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/container.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/container) [![Total Downloads](https://img.shields.io/packagist/dt/league/container.svg?style=flat-square)](https://packagist.org/packages/league/container) -This package is compliant with [PSR-1], [PSR-2], [PSR-4] and [PSR-11]. If you notice compliance oversights, please send a patch via pull request. +This package is compliant with [PSR-1], [PSR-2], [PSR-12], [PSR-4] and [PSR-11]. If you notice compliance oversights, please send a patch via pull request. [PSR-1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md [PSR-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md +[PSR-12]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-12-extended-coding-style-guide.md [PSR-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md [PSR-11]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md @@ -27,10 +28,9 @@ $ composer require league/container The following versions of PHP are supported by this version. -* PHP 7.0 -* PHP 7.1 * PHP 7.2 * PHP 7.3 +* PHP 7.4 ## Documentation @@ -40,6 +40,7 @@ Contribute to this documentation in the [docs/](https://github.com/thephpleague/ ## Testing +Testing includes PHPUnit and PHPStan (Level 7). ``` bash $ composer test ``` diff --git a/composer.json b/composer.json index 5b4125f..64f7881 100644 --- a/composer.json +++ b/composer.json @@ -21,12 +21,13 @@ } ], "require": { - "php": "^7.0", + "php": "^7.2", "psr/container": "^1.0" }, "require-dev": { "phpunit/phpunit" : "^6.0", - "squizlabs/php_codesniffer": "^3.3" + "squizlabs/php_codesniffer": "^3.3", + "phpstan/phpstan": "^0.11.8" }, "provide": { "psr/container-implementation": "^1.0" @@ -53,7 +54,8 @@ }, "scripts": { "test": [ - "phpunit" + "phpunit", + "phpstan analyse --level 7 src" ] } } diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index 888ade9..0000000 --- a/phpcs.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - PSR2 ruleset ignoring only grouped use statements. - - - - */vendor/* - *.js - *.css - diff --git a/src/Argument/RawArgumentInterface.php b/src/Argument/ArgumentInterface.php similarity index 72% rename from src/Argument/RawArgumentInterface.php rename to src/Argument/ArgumentInterface.php index 14157de..e6db634 100644 --- a/src/Argument/RawArgumentInterface.php +++ b/src/Argument/ArgumentInterface.php @@ -1,8 +1,10 @@ -getContainer(); + } catch (ContainerException $e) { + $container = ($this instanceof ReflectionContainer) ? $this : null; + } + foreach ($arguments as &$arg) { - if ($arg instanceof RawArgumentInterface) { + if ($arg instanceof ArgumentInterface) { $arg = $arg->getValue(); continue; } - if ($arg instanceof ClassNameInterface) { - $arg = $arg->getValue(); - } - if (! is_string($arg)) { continue; } - $container = null; - - try { - $container = $this->getLeagueContainer(); - } catch (ContainerException $e) { - if ($this instanceof ReflectionContainer) { - $container = $this; - } - } - - - if ($container !== null && $container->has($arg)) { + if ($container instanceof ContainerInterface && $container->has($arg)) { $arg = $container->get($arg); - if ($arg instanceof RawArgumentInterface) { + if ($arg instanceof ArgumentInterface) { $arg = $arg->getValue(); } - - continue; } } @@ -58,7 +49,7 @@ public function resolveArguments(array $arguments) : array /** * {@inheritdoc} */ - public function reflectArguments(ReflectionFunctionAbstract $method, array $args = []) : array + public function reflectArguments(ReflectionFunctionAbstract $method, array $args = []): array { $arguments = array_map(function (ReflectionParameter $param) use ($method, $args) { $name = $param->getName(); @@ -87,12 +78,9 @@ public function reflectArguments(ReflectionFunctionAbstract $method, array $args } /** - * @return ContainerInterface - */ - abstract public function getContainer() : ContainerInterface; - - /** - * @return Container + * Get the container. + * + * @return DefinitionContainerInterface */ - abstract public function getLeagueContainer() : Container; + abstract public function getContainer(): DefinitionContainerInterface; } diff --git a/src/Argument/ClassName.php b/src/Argument/ClassName.php deleted file mode 100644 index d468fd4..0000000 --- a/src/Argument/ClassName.php +++ /dev/null @@ -1,29 +0,0 @@ -value = $value; - } - - /** - * {@inheritdoc} - */ - public function getValue() : string - { - return $this->value; - } -} diff --git a/src/Argument/ClassNameInterface.php b/src/Argument/ClassNameInterface.php deleted file mode 100644 index e27d118..0000000 --- a/src/Argument/ClassNameInterface.php +++ /dev/null @@ -1,13 +0,0 @@ -value = $value; - } - - /** - * {@inheritdoc} - */ - public function getValue() - { - return $this->value; - } -} diff --git a/src/Container.php b/src/Container.php index cca5fb0..684a862 100644 --- a/src/Container.php +++ b/src/Container.php @@ -1,18 +1,16 @@ -definitions = $definitions ?? new DefinitionAggregate; - $this->providers = $providers ?? new ServiceProviderAggregate; - $this->inflectors = $inflectors ?? new InflectorAggregate; + $this->definitions = $definitions ?? new DefinitionAggregate(); + $this->providers = $providers ?? new ServiceProviderAggregate(); + $this->inflectors = $inflectors ?? new InflectorAggregate(); if ($this->definitions instanceof ContainerAwareInterface) { $this->definitions->setLeagueContainer($this); @@ -69,15 +67,9 @@ public function __construct( } /** - * Add an item to the container. - * - * @param string $id - * @param mixed $concrete - * @param boolean $shared - * - * @return DefinitionInterface + * {@inheritdoc} */ - public function add(string $id, $concrete = null, bool $shared = null) : DefinitionInterface + public function add(string $id, $concrete = null, bool $shared = null): DefinitionInterface { $concrete = $concrete ?? $id; $shared = $shared ?? $this->defaultToShared; @@ -86,14 +78,9 @@ public function add(string $id, $concrete = null, bool $shared = null) : Definit } /** - * Proxy to add with shared as true. - * - * @param string $id - * @param mixed $concrete - * - * @return DefinitionInterface + * {@inheritdoc} */ - public function share(string $id, $concrete = null) : DefinitionInterface + public function share(string $id, $concrete = null): DefinitionInterface { return $this->add($id, $concrete, true); } @@ -105,7 +92,7 @@ public function share(string $id, $concrete = null) : DefinitionInterface * * @return self */ - public function defaultToShared(bool $shared = true) : ContainerInterface + public function defaultToShared(bool $shared = true): ContainerInterface { $this->defaultToShared = $shared; @@ -113,13 +100,9 @@ public function defaultToShared(bool $shared = true) : ContainerInterface } /** - * Get a definition to extend. - * - * @param string $id [description] - * - * @return DefinitionInterface + * {@inheritdoc} */ - public function extend(string $id) : DefinitionInterface + public function extend(string $id): DefinitionInterface { if ($this->providers->provides($id)) { $this->providers->register($id); @@ -135,16 +118,11 @@ public function extend(string $id) : DefinitionInterface } /** - * Add a service provider. - * - * @param ServiceProviderInterface|string $provider - * - * @return self + * {@inheritdoc} */ - public function addServiceProvider($provider) : self + public function addServiceProvider($provider): DefinitionContainerInterface { $this->providers->add($provider); - return $this; } @@ -191,7 +169,7 @@ public function get($id, bool $new = false) /** * {@inheritdoc} */ - public function has($id) : bool + public function has($id): bool { if ($this->definitions->has($id)) { return true; @@ -215,14 +193,9 @@ public function has($id) : bool } /** - * Allows for manipulation of specific types on resolution. - * - * @param string $type - * @param callable|null $callback - * - * @return InflectorInterface + * {@inheritdoc} */ - public function inflector(string $type, callable $callback = null) : InflectorInterface + public function inflector(string $type, callable $callback = null): InflectorInterface { return $this->inflectors->add($type, $callback); } @@ -235,7 +208,7 @@ public function inflector(string $type, callable $callback = null) : InflectorIn * * @return self */ - public function delegate(ContainerInterface $container) : self + public function delegate(ContainerInterface $container): self { $this->delegates[] = $container; diff --git a/src/ContainerAwareInterface.php b/src/ContainerAwareInterface.php index 870bfa3..c61f03f 100644 --- a/src/ContainerAwareInterface.php +++ b/src/ContainerAwareInterface.php @@ -1,40 +1,24 @@ -container = $container; - return $this; } /** * Get the container. * - * @return ContainerInterface + * @return DefinitionContainerInterface */ - public function getContainer() : ContainerInterface + public function getContainer(): DefinitionContainerInterface { - if ($this->container instanceof ContainerInterface) { + if ($this->container instanceof DefinitionContainerInterface) { return $this->container; } throw new ContainerException('No container implementation has been set.'); } - - /** - * Set a container. - * - * @param Container $container - * - * @return self - */ - public function setLeagueContainer(Container $container) : ContainerAwareInterface - { - $this->container = $container; - $this->leagueContainer = $container; - - return $this; - } - - /** - * Get the container. - * - * @return Container - */ - public function getLeagueContainer() : Container - { - if ($this->leagueContainer instanceof Container) { - return $this->leagueContainer; - } - - throw new ContainerException('No container implementation has been set.'); - } } diff --git a/src/Definition/Definition.php b/src/Definition/Definition.php index 19a329e..401ccb5 100644 --- a/src/Definition/Definition.php +++ b/src/Definition/Definition.php @@ -1,9 +1,11 @@ -tags[$tag] = true; - + $this->tags[] = $tag; return $this; } /** * {@inheritdoc} */ - public function hasTag(string $tag) : bool + public function hasTag(string $tag): bool { return isset($this->tags[$tag]); } @@ -84,17 +85,16 @@ public function hasTag(string $tag) : bool /** * {@inheritdoc} */ - public function setAlias(string $id) : DefinitionInterface + public function setAlias(string $id): DefinitionInterface { $this->alias = $id; - return $this; } /** * {@inheritdoc} */ - public function getAlias() : string + public function getAlias(): string { return $this->alias; } @@ -102,17 +102,16 @@ public function getAlias() : string /** * {@inheritdoc} */ - public function setShared(bool $shared = true) : DefinitionInterface + public function setShared(bool $shared = true): DefinitionInterface { $this->shared = $shared; - return $this; } /** * {@inheritdoc} */ - public function isShared() : bool + public function isShared(): bool { return $this->shared; } @@ -128,28 +127,26 @@ public function getConcrete() /** * {@inheritdoc} */ - public function setConcrete($concrete) : DefinitionInterface + public function setConcrete($concrete): DefinitionInterface { $this->concrete = $concrete; $this->resolved = null; - return $this; } /** * {@inheritdoc} */ - public function addArgument($arg) : DefinitionInterface + public function addArgument($arg): DefinitionInterface { $this->arguments[] = $arg; - return $this; } /** * {@inheritdoc} */ - public function addArguments(array $args) : DefinitionInterface + public function addArguments(array $args): DefinitionInterface { foreach ($args as $arg) { $this->addArgument($arg); @@ -161,7 +158,7 @@ public function addArguments(array $args) : DefinitionInterface /** * {@inheritdoc} */ - public function addMethodCall(string $method, array $args = []) : DefinitionInterface + public function addMethodCall(string $method, array $args = []): DefinitionInterface { $this->methods[] = [ 'method' => $method, @@ -174,7 +171,7 @@ public function addMethodCall(string $method, array $args = []) : DefinitionInte /** * {@inheritdoc} */ - public function addMethodCalls(array $methods = []) : DefinitionInterface + public function addMethodCalls(array $methods = []): DefinitionInterface { foreach ($methods as $method => $args) { $this->addMethodCall($method, $args); @@ -190,7 +187,7 @@ public function resolve(bool $new = false) { $concrete = $this->concrete; - if ($this->isShared() && $this->resolved !== null && $new === false) { + if ($new === false && $this->resolved !== null && $this->isShared()) { return $this->resolved; } @@ -198,9 +195,8 @@ public function resolve(bool $new = false) $concrete = $this->resolveCallable($concrete); } - if ($concrete instanceof RawArgumentInterface) { + if ($concrete instanceof ArgumentInterface) { $this->resolved = $concrete->getValue(); - return $concrete->getValue(); } @@ -231,7 +227,6 @@ public function resolve(bool $new = false) protected function resolveCallable(callable $concrete) { $resolved = $this->resolveArguments($this->arguments); - return call_user_func_array($concrete, $resolved); } @@ -248,7 +243,6 @@ protected function resolveClass(string $concrete) { $resolved = $this->resolveArguments($this->arguments); $reflection = new ReflectionClass($concrete); - return $reflection->newInstanceArgs($resolved); } @@ -263,7 +257,6 @@ protected function invokeMethods($instance) { foreach ($this->methods as $method) { $args = $this->resolveArguments($method['arguments']); - /** @var callable $callable */ $callable = [$instance, $method['method']]; call_user_func_array($callable, $args); diff --git a/src/Definition/DefinitionAggregate.php b/src/Definition/DefinitionAggregate.php index 3c4fb8d..a7f8acb 100644 --- a/src/Definition/DefinitionAggregate.php +++ b/src/Definition/DefinitionAggregate.php @@ -22,7 +22,7 @@ class DefinitionAggregate implements DefinitionAggregateInterface */ public function __construct(array $definitions = []) { - $this->definitions = array_filter($definitions, function ($definition) { + $this->definitions = array_filter($definitions, static function ($definition) { return ($definition instanceof DefinitionInterface); }); } @@ -32,14 +32,11 @@ public function __construct(array $definitions = []) */ public function add(string $id, $definition, bool $shared = false) : DefinitionInterface { - if (!$definition instanceof DefinitionInterface) { + if (false === ($definition instanceof DefinitionInterface)) { $definition = new Definition($id, $definition); } - $this->definitions[] = $definition - ->setAlias($id) - ->setShared($shared) - ; + $this->definitions[] = $definition->setAlias($id)->setShared($shared); return $definition; } @@ -115,10 +112,6 @@ public function resolveTagged(string $tag, bool $new = false) : array */ public function getIterator() : Generator { - $count = count($this->definitions); - - for ($i = 0; $i < $count; $i++) { - yield $this->definitions[$i]; - } + yield from $this->definitions; } } diff --git a/src/Definition/DefinitionAggregateInterface.php b/src/Definition/DefinitionAggregateInterface.php index 3e9876d..783dab7 100644 --- a/src/Definition/DefinitionAggregateInterface.php +++ b/src/Definition/DefinitionAggregateInterface.php @@ -1,4 +1,6 @@ -cacheResolutions = $cacheResolutions; + } + /** * {@inheritdoc} * @@ -48,7 +58,7 @@ public function get($id, array $args = []) $construct = $reflector->getConstructor(); $resolution = $construct === null - ? new $id + ? new $id() : $resolution = $reflector->newInstanceArgs($this->reflectArguments($construct, $args)) ; @@ -62,7 +72,7 @@ public function get($id, array $args = []) /** * {@inheritdoc} */ - public function has($id) : bool + public function has($id): bool { return class_exists($id); } @@ -99,7 +109,6 @@ public function call(callable $callable, array $args = []) if (is_object($callable)) { $reflection = new ReflectionMethod($callable, '__invoke'); - return $reflection->invokeArgs($callable, $this->reflectArguments($reflection, $args)); } @@ -107,19 +116,4 @@ public function call(callable $callable, array $args = []) return $reflection->invokeArgs($this->reflectArguments($reflection, $args)); } - - /** - * Whether the container should default to caching resolutions and returning - * the cache on following calls. - * - * @param boolean $option - * - * @return self - */ - public function cacheResolutions(bool $option = true) : ContainerInterface - { - $this->cacheResolutions = $option; - - return $this; - } } diff --git a/tests/Argument/ArgumentResolverTest.php b/tests/Argument/ArgumentResolverTest.php index 5a9a179..b327ac0 100644 --- a/tests/Argument/ArgumentResolverTest.php +++ b/tests/Argument/ArgumentResolverTest.php @@ -1,8 +1,8 @@ getMockBuilder(Container::class)->getMock(); - $container->expects($this->at(0))->method('has')->with($this->equalTo('alias1'))->willReturn(true); + $container + ->expects($this->at(0)) + ->method('has') + ->with($this->equalTo('alias1')) + ->willReturn(true) + ; + $container->expects($this->at(1))->method('get')->with($this->equalTo('alias1'))->willReturn($resolver); $container->expects($this->at(2))->method('has')->with($this->equalTo('alias2'))->willReturn(false); + /** @var Container $container */ $resolver->setLeagueContainer($container); $args = $resolver->resolveArguments(['alias1', 'alias2']); @@ -49,11 +56,12 @@ public function testResolverResolvesResolvesRawArguments() $container = $this->getMockBuilder(Container::class)->getMock(); $container->expects($this->at(0))->method('has')->with($this->equalTo('alias1'))->willReturn(true); - $container->expects($this->at(1))->method('get')->with($this->equalTo('alias1'))->willReturn(new RawArgument('value1')); + $container->expects($this->at(1))->method('get')->with($this->equalTo('alias1'))->willReturn(new Argument('value1')); + /** @var Container $container */ $resolver->setLeagueContainer($container); - $args = $resolver->resolveArguments(['alias1', new RawArgument('value2')]); + $args = $resolver->resolveArguments(['alias1', new Argument('value2')]); $this->assertSame('value1', $args[0]); $this->assertSame('value2', $args[1]); @@ -94,6 +102,7 @@ public function testResolverResolvesArgumentsViaReflection() use ContainerAwareTrait; }; + /** @var Container $container */ $resolver->setLeagueContainer($container); $args = $resolver->reflectArguments($method, ['param3' => 'value3']); @@ -124,6 +133,7 @@ public function testResolverThrowsExceptionWhenReflectionDoesNotResolve() use ContainerAwareTrait; }; + /** @var ReflectionFunctionAbstract $method */ $resolver->reflectArguments($method); } } diff --git a/tests/Argument/ClassNameTest.php b/tests/Argument/ClassNameTest.php index 29900aa..20d378b 100644 --- a/tests/Argument/ClassNameTest.php +++ b/tests/Argument/ClassNameTest.php @@ -1,6 +1,6 @@ assertSame($expected, $argument->getValue()); } } diff --git a/tests/Definition/DefinitionTest.php b/tests/Definition/DefinitionTest.php index 2cf7fd7..dbe97b6 100644 --- a/tests/Definition/DefinitionTest.php +++ b/tests/Definition/DefinitionTest.php @@ -2,7 +2,7 @@ namespace League\Container\Test\Definition; -use League\Container\Argument\{ClassName, RawArgument}; +use League\Container\Argument\{ClassName, Argument}; use League\Container\Definition\Definition; use League\Container\Test\Asset\{Foo, FooCallable, Bar}; use PHPUnit\Framework\TestCase; @@ -32,7 +32,7 @@ public function testDefinitionResolvesClosureWithDefinedArgs() public function testDefinitionResolvesClosureReturningRawArgument() { $definition = new Definition('callable', function () { - return new RawArgument('hello world'); + return new Argument('hello world'); }); $actual = $definition->resolve(); diff --git a/tests/Inflector/InflectorAggregateTest.php b/tests/Inflector/InflectorAggregateTest.php index 1b829fc..7e6b94f 100644 --- a/tests/Inflector/InflectorAggregateTest.php +++ b/tests/Inflector/InflectorAggregateTest.php @@ -2,8 +2,8 @@ namespace League\Container\Test\Inflector; -use League\Container\ContaineAwareInterface; -use League\Container\Inflector\{InflectorAggregate, Inflector}; +use League\Container\ContainerAwareInterface; +use League\Container\Inflector\InflectorAggregate; use PHPUnit\Framework\TestCase; use League\Container\Container; @@ -43,11 +43,11 @@ public function testAggregateAddsAndIteratesMultipleInflectors() public function testAggregateIteratesAndInflectsOnObject() { $aggregate = new InflectorAggregate; - $containerAware = $this->getMockBuilder(ContaineAwareInterface::class)->setMethods(['setLeagueContainer'])->getMock(); + $containerAware = $this->getMockBuilder(ContainerAwareInterface::class)->getMock(); $container = $this->getMockBuilder(Container::class)->getMock(); $containerAware->expects($this->once())->method('setLeagueContainer')->with($this->equalTo($container)); - $aggregate->add(ContaineAwareInterface::class)->invokeMethod('setLeagueContainer', [$container]); + $aggregate->add(ContainerAwareInterface::class)->invokeMethod('setLeagueContainer', [$container]); $aggregate->add('Ignored\Type'); $aggregate->setLeagueContainer($container);