From 7b99602feb7e24be16e3d1be042737258df2e620 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Mon, 2 May 2022 18:21:54 -0400 Subject: [PATCH 01/21] Update Container.php Signed-off-by: Nathanael Esayeas --- src/Container.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Container.php b/src/Container.php index 3927c39..888f09f 100644 --- a/src/Container.php +++ b/src/Container.php @@ -57,16 +57,36 @@ public function __clone() throw BadMethodCallException::dontClone(self::class); } + public function __get(string $name) + { + return $this->get($name); + } + + public function __isset(string $name): bool + { + return $this->has($name); + } + public function __serialize(): array { throw BadMethodCallException::dontSerialize(self::class); } + public function __set(string $name, $value): void + { + $this->set($name, $value); + } + public function __unserialize(array $data): void { throw BadMethodCallException::dontUnserialize(self::class); } + public function __unset(string $name): void + { + $this->remove($name); + } + public function add(string $id, ExtensionInterface $extension): void { if (array_key_exists($extension::class, $this->services[self::EXTENSIONS][self::class])) { From 501674317d51c6b0845d12ea8f0eafdfbbf87837 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Mon, 2 May 2022 18:24:40 -0400 Subject: [PATCH 02/21] Add tests Signed-off-by: Nathanael Esayeas --- tests/Unit/ContainerTest.php | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/Unit/ContainerTest.php b/tests/Unit/ContainerTest.php index 962949d..3b9eab5 100644 --- a/tests/Unit/ContainerTest.php +++ b/tests/Unit/ContainerTest.php @@ -294,6 +294,14 @@ static function (Container $container): void { ]; } + /** @return iterable */ + public function dataProviderPropertyAccessorMagicMethods(): iterable + { + foreach (['__get', '__isset', '__set', '__unset'] as $method) { + yield $method => [$method]; + } + } + /** @return iterable */ public function dataProviderServiceClasses(): iterable { @@ -527,6 +535,38 @@ public function testContainerImplementsArrayAccessInterface(): void self::assertArrayNotHasKey(__METHOD__, $this->container); } + /** + * @covers \Ghostwriter\Container\Container::__construct + * @covers \Ghostwriter\Container\Container::__destruct + * @covers \Ghostwriter\Container\Container::__get + * @covers \Ghostwriter\Container\Container::__isset + * @covers \Ghostwriter\Container\Container::__set + * @covers \Ghostwriter\Container\Container::__unset + * @covers \Ghostwriter\Container\Container::get + * @covers \Ghostwriter\Container\Container::getInstance + * @covers \Ghostwriter\Container\Container::has + * @covers \Ghostwriter\Container\Container::remove + * @covers \Ghostwriter\Container\Container::resolve + * @covers \Ghostwriter\Container\Container::set + * @dataProvider dataProviderPropertyAccessorMagicMethods + * + * @throws Throwable + */ + public function testContainerImplementsPropertyAccessorMagicMethods(string $method): void + { + self::assertTrue(method_exists($this->container, $method)); + + $this->container->{$method} = true; + + self::assertTrue(isset($this->container->{$method})); + + self::assertTrue($this->container->{$method}); + + unset($this->container->{$method}); + + self::assertFalse(isset($this->container->{$method})); + } + /** * @covers \Ghostwriter\Container\Container::__construct * @covers \Ghostwriter\Container\Container::__destruct From 30d6544ff6eb1f83a22c3c4370a86c793d80e4da Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Mon, 2 May 2022 18:26:08 -0400 Subject: [PATCH 03/21] Cleanup tests Signed-off-by: Nathanael Esayeas --- tests/Unit/ContainerTest.php | 64 ++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/tests/Unit/ContainerTest.php b/tests/Unit/ContainerTest.php index 3b9eab5..4f0d0bc 100644 --- a/tests/Unit/ContainerTest.php +++ b/tests/Unit/ContainerTest.php @@ -222,10 +222,11 @@ static function (Container $container): void { LogicException::class, LogicException::serviceExtensionAlreadyRegistered(FoobarExtension::class)->getMessage(), static function (Container $container): void { + $container->bind(stdClass::class); + $extension = $container->get(FoobarExtension::class); - $container->add('foo', $extension); - $container->add('foo', $extension); - $container->get('foo'); + $container->add(stdClass::class, $extension); + $container->add(stdClass::class, $extension); }, ]; @@ -240,7 +241,6 @@ static function (Container $container): void { */ // $serviceProvider = $container->get(FoobarServiceProvider::class); $serviceProvider = $container->build(FoobarServiceProvider::class); - // $container->register($serviceProvider); }, ]; @@ -261,6 +261,14 @@ static function (Container $container): void { }, ]; + yield 'NotFoundException::missingServiceId@extend' => [ + NotFoundException::class, + NotFoundException::notRegistered(stdClass::class)->getMessage(), + static function (Container $container): void { + $container->extend(stdClass::class, static fn () =>null); + }, + ]; + yield 'NotFoundException::missingServiceId@remove' => [ NotFoundException::class, NotFoundException::notRegistered('dose-not-exist')->getMessage(), @@ -489,19 +497,55 @@ public function testContainerConstruct(): void */ public function testContainerDestruct(): void { - $container = $this->container; - - self::assertSame($container, Container::getInstance()); - $this->container->set('test', true); self::assertTrue($this->container->has('test')); - $container->__destruct(); + $this->container->__destruct(); self::assertFalse($this->container->has('test')); } + /** + * @covers \Ghostwriter\Container\Container::__construct + * @covers \Ghostwriter\Container\Container::__destruct + * @covers \Ghostwriter\Container\Container::bind + * @covers \Ghostwriter\Container\Container::build + * @covers \Ghostwriter\Container\Container::extend + * @covers \Ghostwriter\Container\Container::get + * @covers \Ghostwriter\Container\Container::getInstance + * @covers \Ghostwriter\Container\Container::has + * @covers \Ghostwriter\Container\Container::resolve + * @covers \Ghostwriter\Container\Container::set + * + * @throws Throwable + */ + public function testContainerExtend(): void + { + $this->container->set('extend', true); + + $this->container->bind(stdClass::class); + + $this->container->extend( + stdClass::class, + static function (Container $container, object $stdClass): stdClass { + $stdClass->one = $container->get('extend'); + return $stdClass; + } + ); + + $this->container->extend( + stdClass::class, + static function (Container $container, object $stdClass): stdClass { + $stdClass->two = $container->get('extend'); + return $stdClass; + } + ); + + self::assertTrue($this->container->get(stdClass::class)->one); + self::assertTrue($this->container->get(stdClass::class)->two); + } + /** * @covers \Ghostwriter\Container\Container::__construct * @covers \Ghostwriter\Container\Container::__destruct @@ -761,7 +805,7 @@ public function testExceptionsImplementPsrContainerExceptionInterface( try { $test($this->container); } catch (Throwable $throwable) { - self::assertSame($throwable::class, $exception); + self::assertSame($exception, $throwable::class); self::assertInstanceOf(PsrContainerExceptionInterface::class, $throwable); self::assertInstanceOf(ContainerExceptionInterface::class, $throwable); From 14c2311f7be2c49c6272318eaabfce220987f196 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Mon, 2 May 2022 18:26:13 -0400 Subject: [PATCH 04/21] Update ContainerInterface.php Signed-off-by: Nathanael Esayeas --- src/Contract/ContainerInterface.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Contract/ContainerInterface.php b/src/Contract/ContainerInterface.php index 24b9b7c..72fd1fd 100644 --- a/src/Contract/ContainerInterface.php +++ b/src/Contract/ContainerInterface.php @@ -132,8 +132,10 @@ public function bind(string $abstract, ?string $concrete = null): void; * @param class-string|string $class the class name * @param array $arguments optional constructor arguments passed to build the new class instance * - * @throws CircularDependencyException if a circular dependency is detected - * @throws NotInstantiableException if $class is not instantiable; (is an interface or an abstract class) + * @throws PsrNotFoundExceptionInterface if no entry was found for **this** identifier + * @throws PsrContainerExceptionInterface if there is an error while retrieving the entry + * @throws CircularDependencyException if a circular dependency is detected + * @throws NotInstantiableException if $class is not instantiable; (is an interface or an abstract class) * * @return T */ From 535525655c9a4e248870409b7fb8f9a33ef4574d Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 01:54:30 -0400 Subject: [PATCH 05/21] Update composer.json Signed-off-by: Nathanael Esayeas --- composer.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index f335f44..91146b5 100644 --- a/composer.json +++ b/composer.json @@ -53,7 +53,10 @@ "autoload-dev": { "psr-4": { "Ghostwriter\\Container\\Tests\\": "tests/" - } + }, + "files": [ + "tests/Fixture/functions.php" + ] }, "config": { "allow-plugins": { @@ -100,7 +103,7 @@ "psalm:dry-run": "psalm --alter --issues=all --dry-run", "psalm:missing": "psalm --alter --issues=MissingReturnType", "psalm:security": "psalm --taint-analysis", - "psalm:shepherd": "psalm --shepherd --stats", + "psalm:shepherd": "psalm --shepherd --stats --no-diff --no-cache", "rector": "vendor/bin/rector process", "rector:dry-run": "vendor/bin/rector process --dry-run || true", "test": [ From df288e3453556b0ad09b07129e487925124b4980 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 01:55:22 -0400 Subject: [PATCH 06/21] Add test fixtures Signed-off-by: Nathanael Esayeas --- tests/Fixture/TestEvent.php | 20 ++++++++++++++++++++ tests/Fixture/TestEventListener.php | 29 +++++++++++++++++++++++++++++ tests/Fixture/functions.php | 15 +++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 tests/Fixture/TestEvent.php create mode 100644 tests/Fixture/TestEventListener.php create mode 100644 tests/Fixture/functions.php diff --git a/tests/Fixture/TestEvent.php b/tests/Fixture/TestEvent.php new file mode 100644 index 0000000..7d7b1ff --- /dev/null +++ b/tests/Fixture/TestEvent.php @@ -0,0 +1,20 @@ + */ + private array $events = []; + + public function collect(string $event): void + { + $this->events[] = $event; + } + + /** @return array */ + public function all(): array + { + return $this->events; + } +} diff --git a/tests/Fixture/TestEventListener.php b/tests/Fixture/TestEventListener.php new file mode 100644 index 0000000..ac6eab5 --- /dev/null +++ b/tests/Fixture/TestEventListener.php @@ -0,0 +1,29 @@ +collect(__METHOD__); + } + + public function onTest(TestEvent $event): void + { + $event->collect(__METHOD__); + } + + public static function onStatic(TestEvent $event, string $nullableWithDefault = null): void + { + $event->collect(__METHOD__); + } + + public static function onStaticCallableArray(TestEvent $event, ?string $nullable): void + { + $event->collect(__METHOD__); + } +} diff --git a/tests/Fixture/functions.php b/tests/Fixture/functions.php new file mode 100644 index 0000000..c28c7f8 --- /dev/null +++ b/tests/Fixture/functions.php @@ -0,0 +1,15 @@ +collect(__METHOD__ ); +} + +function typelessFunction($event): void +{ + $event->collect(__METHOD__ ); +} From 1966ddbee5b46c2e69ee8177725b3e0e0a8f9b1c Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 01:55:27 -0400 Subject: [PATCH 07/21] Update NotInstantiableException.php Signed-off-by: Nathanael Esayeas --- src/Exception/NotInstantiableException.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Exception/NotInstantiableException.php b/src/Exception/NotInstantiableException.php index 75ecdef..af21a04 100644 --- a/src/Exception/NotInstantiableException.php +++ b/src/Exception/NotInstantiableException.php @@ -20,12 +20,14 @@ public static function classDoseNotExist(string $class): self return new self(sprintf('Class "%s" dose not exist.', $class)); } - public static function unresolvableParameter(string $parameter, string $class): self + public static function unresolvableParameter($parameter, ?string $class, string $method = '__construct'): self { return new self(sprintf( - 'Parameter "$%s" in %s::__construct is unresolvable; does not have a default value.', + 'Unresolvable %s parameter "$%s" in "%s%s"; does not have a default value.', + null === $class ? 'function' : 'class', $parameter, - $class + $class ?? $method, + $class ? '::' . $method : '()' )); } } From 35abd437c3ef52b6b5c0b8003d19ff7fb67ff3ca Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 01:57:19 -0400 Subject: [PATCH 08/21] Update ContainerInterface.php Signed-off-by: Nathanael Esayeas --- src/Contract/ContainerInterface.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Contract/ContainerInterface.php b/src/Contract/ContainerInterface.php index 72fd1fd..f895500 100644 --- a/src/Contract/ContainerInterface.php +++ b/src/Contract/ContainerInterface.php @@ -16,6 +16,7 @@ use Psr\Container\ContainerExceptionInterface as PsrContainerExceptionInterface; use Psr\Container\ContainerInterface as PsrContainerInterface; use Psr\Container\NotFoundExceptionInterface as PsrNotFoundExceptionInterface; +use ReflectionException; /** * An extendable, closure based dependency injection container. @@ -27,6 +28,17 @@ interface ContainerInterface extends ArrayAccess, PsrContainerInterface */ public const ALIASES = 'aliases'; + /** + * @var array{ + * aliases: array, + * dependencies: array, + * extensions: array, + * factories: array, + * providers: array, + * services: array, + * tags: array>, + * } + */ public const DEFAULT_SERVICES = [ self::ALIASES => [ self::class => Container::class, @@ -141,6 +153,14 @@ public function bind(string $abstract, ?string $concrete = null): void; */ public function build(string $class, array $arguments = []): object; + /** + * Create an object using the given Container to resolve dependencies. + * + * @param array $arguments optional arguments passed to $callback + * @throws ReflectionException + */ + public function invoke(callable $callback, array $arguments = []): mixed; + /** * "Extend" a service object in the container. * From 1204bfbe127b63b8b0e3faff113b4986367bd679 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 01:57:23 -0400 Subject: [PATCH 09/21] Update ContainerTest.php Signed-off-by: Nathanael Esayeas --- tests/Unit/ContainerTest.php | 182 ++++++++++++++++++++++++++++------- 1 file changed, 147 insertions(+), 35 deletions(-) diff --git a/tests/Unit/ContainerTest.php b/tests/Unit/ContainerTest.php index 4f0d0bc..4aac791 100644 --- a/tests/Unit/ContainerTest.php +++ b/tests/Unit/ContainerTest.php @@ -5,6 +5,7 @@ namespace Ghostwriter\Container\Tests\Unit; use ArrayAccess; +use Generator; use Ghostwriter\Container\Container; use Ghostwriter\Container\Contract\ContainerExceptionInterface; use Ghostwriter\Container\Contract\ContainerInterface; @@ -41,6 +42,8 @@ use Ghostwriter\Container\Tests\Fixture\Foo; use Ghostwriter\Container\Tests\Fixture\ServiceProvider\FoobarServiceProvider; use Ghostwriter\Container\Tests\Fixture\ServiceProvider\FoobarWithDependencyServiceProvider; +use Ghostwriter\Container\Tests\Fixture\TestEvent; +use Ghostwriter\Container\Tests\Fixture\TestEventListener; use Ghostwriter\Container\Tests\Fixture\UnionTypehintWithDefaultValue; use Ghostwriter\Container\Tests\Fixture\UnionTypehintWithoutDefaultValue; use Ghostwriter\Container\Tests\Fixture\UnresolvableParameter; @@ -52,6 +55,7 @@ use Throwable; use function array_key_exists; use function is_subclass_of; +use function random_int; use function serialize; use function sprintf; use function strlen; @@ -79,9 +83,45 @@ protected function tearDown(): void } /** - * @return iterable + * @psalm-return Generator */ - public function dataProviderContainerExceptions(): iterable + public function dataProviderContainerCallables(): Generator + { + yield 'TypelessAnonymousFunctionCall' => [ + static function ($event): void { + $event->collect($event::class); + }, + [ + 'event'=>new TestEvent(), + ], + ]; + + yield 'AnonymousFunctionCall' => [static function (TestEvent $event): void { + $event->collect($event::class); + }]; + + yield 'FunctionCall@typedFunction' => ['Ghostwriter\Container\Tests\Fixture\typedFunction']; + yield 'FunctionCall@typelessFunction' => [ + 'Ghostwriter\Container\Tests\Fixture\typelessFunction', [ + 'event'=>new TestEvent(), + + ], ]; + + yield 'StaticMethodCall' => [TestEventListener::class . '::onStatic']; + + yield 'CallableArrayStaticMethodCall' => [[TestEventListener::class, 'onStaticCallableArray'], [ + 'nullable' =>null, + ]]; + + yield 'CallableArrayInstanceMethodCall' => [[new TestEventListener(), 'onTest']]; + + yield 'Invokable' => [new TestEventListener()]; + } + + /** + * @psalm-return Generator + */ + public function dataProviderContainerExceptions(): Generator { yield 'CircularDependencyException::detected' => [ CircularDependencyException::class, @@ -114,8 +154,7 @@ static function (Container $container): void { InvalidArgumentException::class, InvalidArgumentException::emptyServiceId()->getMessage(), static function (Container $container): void { - $container->extend('', static function (Container $container): void { - }); + $container->extend('', static fn (Container $container) => $container); }, ]; @@ -265,7 +304,7 @@ static function (Container $container): void { NotFoundException::class, NotFoundException::notRegistered(stdClass::class)->getMessage(), static function (Container $container): void { - $container->extend(stdClass::class, static fn () =>null); + $container->extend(stdClass::class, static fn (Container $container) => null); }, ]; @@ -295,11 +334,50 @@ static function (Container $container): void { yield 'NotInstantiableException::unresolvableParameter' => [ NotInstantiableException::class, - NotInstantiableException::unresolvableParameter('number', UnresolvableParameter::class)->getMessage(), + NotInstantiableException::unresolvableParameter( + 'number', + UnresolvableParameter::class, + '__construct' + )->getMessage(), static function (Container $container): void { $container->build(UnresolvableParameter::class); }, ]; + + yield 'NotInstantiableException::unresolvableParameter@call-function' => [ + NotInstantiableException::class, + NotInstantiableException::unresolvableParameter( + 'event', + null, + 'Ghostwriter\Container\Tests\Fixture\typelessFunction', + )->getMessage(), + static function (Container $container): void { + $container->invoke('Ghostwriter\Container\Tests\Fixture\typelessFunction'); + }, + ]; + + yield 'NotInstantiableException::unresolvableParameter@invoke-class' => [ + NotInstantiableException::class, + NotInstantiableException::unresolvableParameter( + 'nullable', + TestEventListener::class, + 'onStaticCallableArray' + )->getMessage(), + static function (Container $container): void { + $container->invoke([TestEventListener::class, 'onStaticCallableArray']); + }, + ]; + yield 'NotInstantiableException::unresolvableParameter@invoke-undefind-class' => [ + NotInstantiableException::class, + NotInstantiableException::unresolvableParameter( + 'nullable', + TestEventListener::class, + 'onStaticCallableArray' + )->getMessage(), + static function (Container $container): void { + $container->invoke(TestEventListener::class); + }, + ]; } /** @return iterable */ @@ -320,9 +398,9 @@ public function dataProviderServiceClasses(): iterable 'value' => true, ]]; yield CallableConstructor::class => [CallableConstructor::class, [ - 'value' => static fn () => null, + 'value' => static fn (Container $container) => null, ]]; - yield EmptyConstructor::class => [EmptyConstructor::class, []]; + yield EmptyConstructor::class => [EmptyConstructor::class]; yield FloatConstructor::class => [FloatConstructor::class, [ 'value' => 13.37, ]]; @@ -338,7 +416,7 @@ public function dataProviderServiceClasses(): iterable yield ObjectConstructor::class => [ObjectConstructor::class, [ 'value' => new stdClass(), ]]; - yield OptionalConstructor::class => [OptionalConstructor::class, []]; + yield OptionalConstructor::class => [OptionalConstructor::class]; yield StringConstructor::class => [StringConstructor::class, [ 'value' => 'string', ]]; @@ -348,22 +426,22 @@ public function dataProviderServiceClasses(): iterable yield UnionTypehintWithoutDefaultValue::class => [UnionTypehintWithoutDefaultValue::class, [ 'number' => 42, ]]; - yield UnionTypehintWithDefaultValue::class => [UnionTypehintWithDefaultValue::class, []]; - yield Foo::class => [Foo::class, []]; - yield Bar::class => [Bar::class, []]; - yield Baz::class => [Baz::class, []]; - yield Container::class => [Container::class, []]; - yield FoobarWithDependencyServiceProvider::class => [FoobarWithDependencyServiceProvider::class, []]; - yield FoobarServiceProvider::class => [FoobarServiceProvider::class, []]; - yield FoobarExtension::class => [FoobarExtension::class, []]; - yield self::class => [self::class, []]; + yield UnionTypehintWithDefaultValue::class => [UnionTypehintWithDefaultValue::class]; + yield Foo::class => [Foo::class]; + yield Bar::class => [Bar::class]; + yield Baz::class => [Baz::class]; + yield Container::class => [Container::class]; + yield FoobarWithDependencyServiceProvider::class => [FoobarWithDependencyServiceProvider::class]; + yield FoobarServiceProvider::class => [FoobarServiceProvider::class]; + yield FoobarExtension::class => [FoobarExtension::class]; + yield self::class => [self::class]; } /** @return iterable */ public function dataProviderServices(): iterable { $object = new stdClass(); - $closure = static fn (): string => 'closure-called'; + $closure = static fn (Container $container): string => 'closure-called'; yield 'object' => ['object', $object, $object]; yield 'null' => ['null', null, null]; yield 'int' => ['int', 42, 42]; @@ -404,20 +482,29 @@ public function testContainerAdd(): void * @covers \Ghostwriter\Container\Container::getInstance * @covers \Ghostwriter\Container\Container::resolve * @covers \Ghostwriter\Container\Container::alias + * @covers \Ghostwriter\Container\Container::bind + * @covers \Ghostwriter\Container\Container::build * @covers \Ghostwriter\Container\Container::has * @covers \Ghostwriter\Container\Container::get + * @covers \Ghostwriter\Container\Container::set * * @throws Throwable */ public function testContainerAlias(): void { - self::assertFalse($this->container->has('container')); + self::assertFalse($this->container->has(stdClass::class)); + + $this->container->bind(stdClass::class); + + self::assertTrue($this->container->has(stdClass::class)); - $this->container->alias('container', Container::class); + self::assertFalse($this->container->has('class')); - self::assertTrue($this->container->has('container')); + $this->container->alias('class', stdClass::class); - self::assertInstanceOf(ContainerInterface::class, $this->container->get('container')); + self::assertTrue($this->container->has('class')); + + self::assertInstanceOf(stdClass::class, $this->container->get('class')); } /** @@ -461,7 +548,7 @@ public function testContainerBind(): void * * @throws Throwable */ - public function testContainerBuild(string $class, array $arguments): void + public function testContainerBuild(string $class, array $arguments = []): void { $buildService = $this->container->build($class, $arguments); @@ -474,6 +561,33 @@ public function testContainerBuild(string $class, array $arguments): void } } + /** + * @covers \Ghostwriter\Container\Container::__construct + * @covers \Ghostwriter\Container\Container::__destruct + * @covers \Ghostwriter\Container\Container::invoke + * @covers \Ghostwriter\Container\Container::get + * @covers \Ghostwriter\Container\Container::getInstance + * @covers \Ghostwriter\Container\Container::resolve + * @covers \Ghostwriter\Container\Container::set + * + * @dataProvider dataProviderContainerCallables + * + * @throws Throwable + */ + public function testContainerCall(callable $callback, array $arguments = []): void + { + $this->container->set(TestEvent::class, $arguments['event'] ?? new TestEvent()); + + $actual = $expectedCount = random_int(10, 50); + + while ($actual) { + $this->container->invoke($callback, $arguments); + --$actual; + } + + self::assertCount($expectedCount, $this->container->get(TestEvent::class)->all()); + } + /** * @covers \Ghostwriter\Container\Container::__construct * @covers \Ghostwriter\Container\Container::__destruct @@ -693,12 +807,6 @@ public function testContainerRemove(): void * @covers \Ghostwriter\Container\Container::has * @covers \Ghostwriter\Container\Container::resolve * @covers \Ghostwriter\Container\Container::set - * - * @template T - * - * @param T $expected - * @param T $value - * * @dataProvider dataProviderServices * * @throws PsrNotFoundExceptionInterface @@ -730,12 +838,12 @@ public function testContainerSet(string $key, mixed $value, mixed $expected): vo */ public function testContainerTag(): void { - $this->container->set('stdclass1', static fn (): string => 'first-tag', ['tag-1']); + $this->container->set('stdclass1', static fn (Container $container): string => 'first-tag', ['tag-1']); - $this->container->set('stdclass2', static fn (): string => 'first-tag', ['tag-1']); + $this->container->set('stdclass2', static fn (Container $container): string => 'first-tag', ['tag-1']); - $this->container->set('stdclass3', static fn (): stdClass => new stdClass(), ['tag-2']); - $this->container->set('stdclass4', static fn (): stdClass => new stdClass()); + $this->container->set('stdclass3', static fn (Container $container): stdClass => new stdClass(), ['tag-2']); + $this->container->set('stdclass4', static fn (Container $container): stdClass => new stdClass()); $this->container->tag('stdclass4', ['tag-2']); self::assertNotNull($this->container->tagged('tag-1')); @@ -765,6 +873,7 @@ public function testContainerTag(): void * @covers \Ghostwriter\Container\Container::get * @covers \Ghostwriter\Container\Container::getInstance * @covers \Ghostwriter\Container\Container::has + * @covers \Ghostwriter\Container\Container::invoke * @covers \Ghostwriter\Container\Container::register * @covers \Ghostwriter\Container\Container::remove * @covers \Ghostwriter\Container\Container::resolve @@ -805,6 +914,9 @@ public function testExceptionsImplementPsrContainerExceptionInterface( try { $test($this->container); } catch (Throwable $throwable) { + if ($exception !== $throwable::class) { + self::assertSame($exception, $throwable->getMessage()); + } self::assertSame($exception, $throwable::class); self::assertInstanceOf(PsrContainerExceptionInterface::class, $throwable); @@ -826,7 +938,7 @@ public function testExceptionsImplementPsrContainerExceptionInterface( public function testNotFoundExceptionImplementsPsrContainerNotFoundExceptionInterface(): void { try { - $this->container->get(__METHOD__); + $this->container->get('not-found'); } catch (Throwable $throwable) { self::assertInstanceOf(PsrContainerExceptionInterface::class, $throwable); self::assertInstanceOf(ContainerExceptionInterface::class, $throwable); From 2a1299a88ba238fe807a2cf61196546f428b7fb1 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 01:57:45 -0400 Subject: [PATCH 10/21] Update Container.php Signed-off-by: Nathanael Esayeas --- src/Container.php | 96 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/src/Container.php b/src/Container.php index 888f09f..8cc2ed2 100644 --- a/src/Container.php +++ b/src/Container.php @@ -4,6 +4,7 @@ namespace Ghostwriter\Container; +use Closure; use Ghostwriter\Container\Contract\ContainerInterface; use Ghostwriter\Container\Contract\ExtensionInterface; use Ghostwriter\Container\Contract\ServiceProviderInterface; @@ -15,10 +16,12 @@ use Ghostwriter\Container\Exception\NotInstantiableException; use ReflectionClass; use ReflectionException; +use ReflectionFunction; use ReflectionMethod; use ReflectionNamedType; use function array_key_exists; use function class_exists; +use function is_array; use function is_callable; use function trim; @@ -36,7 +39,7 @@ final class Container implements ContainerInterface * extensions: array, * factories: array, * providers: array, - * services: array, + * services: array, * tags: array>, * } $services */ @@ -191,7 +194,8 @@ public function build(string $class, array $arguments = []): object throw NotInstantiableException::unresolvableParameter( $parameterName, $reflectionMethod->getDeclaringClass() - ->getName() + ->getName(), + $reflectionMethod->getName() ); } @@ -218,43 +222,40 @@ public function extend(string $class, callable $extension): void throw InvalidArgumentException::emptyServiceId(); } - $extensions = $this->services[self::EXTENSIONS]; - if (array_key_exists($class, $extensions)) { - $this->services[self::EXTENSIONS][$class] = - static fn (ContainerInterface $container, object $service): object => $extension($container, $extensions[$class]($container, $service)); - - return; + if (! array_key_exists($class, $this->services[self::FACTORIES])) { + throw NotFoundException::notRegistered($class); } - $this->services[self::EXTENSIONS][$class] = - static fn (ContainerInterface $container, object $service): object => $extension($container, $service); + $extensions = $this->services[self::EXTENSIONS]; + + $this->services[self::EXTENSIONS][$class] = array_key_exists($class, $extensions) ? + static fn (ContainerInterface $container, object $service): object => + $extension($container, $extensions[$class]($container, $service)) : + static fn (ContainerInterface $container, object $service): object => + $extension($container, $service); } public function get(string $id): mixed { $id = $this->resolve($id); - if (array_key_exists($id, $this->services[self::SERVICES])) { - if (self::class === $id) { - return self::$instance; - } + if (self::class === $id) { + return $this; + } + if (array_key_exists($id, $this->services[self::SERVICES])) { return $this->services[self::SERVICES][$id]; } - if (array_key_exists($id, $this->services[self::FACTORIES])) { - $service = $this->services[self::FACTORIES][$id](self::$instance); + $factories = $this->services[self::FACTORIES]; + if (array_key_exists($id, $factories) || class_exists($id)) { + $service = $factories[$id] ?? static fn (Container $container): object => $container->build($id); $extensions = $this->services[self::EXTENSIONS]; - if (array_key_exists($id, $extensions)) { - return $this->services[self::SERVICES][$id] = $extensions[$id](self::$instance, $service); - } - return $this->services[self::SERVICES][$id] = $service; - } - - if (class_exists($id, true)) { - return $this->services[self::SERVICES][$id] = $this->build($id); + return $this->services[self::SERVICES][$id] = array_key_exists($id, $extensions) ? + $extensions[$id]($this, $service($this)) : + $service($this); } throw NotFoundException::notRegistered($id); @@ -270,7 +271,43 @@ public function has(string $id): bool $id = $this->resolve($id); return array_key_exists($id, $this->services[self::SERVICES]) || - array_key_exists($id, $this->services[self::FACTORIES]); + array_key_exists($id, $this->services[self::FACTORIES]) || + array_key_exists($id, $this->services[self::ALIASES]); + } + + public function invoke(callable $callback, array $arguments = []): mixed + { + $parameters = is_array($callback) ? + (new ReflectionClass($callback[0]))->getMethod($callback[1])->getParameters() : + (new ReflectionFunction(Closure::fromCallable($callback)))->getParameters(); + + foreach ($parameters as $parameter) { + $parameterName = $parameter->getName(); + if (array_key_exists($parameterName, $arguments)) { + continue; + } + + if ($parameter->isOptional()) { + continue; + } + + $parameterType = $parameter->getType(); + if ( + ! ($parameterType) instanceof ReflectionNamedType || + $parameterType->isBuiltin() + ) { + throw NotInstantiableException::unresolvableParameter( + $parameterName, + $parameter->getDeclaringClass()?->getName(), + $parameter->getDeclaringFunction() + ->getName() + ); + } + + $arguments[$parameterName] = $this->get($parameterType->getName()); + } + + return $callback(...$arguments); } public function offsetExists(mixed $offset): bool @@ -299,7 +336,7 @@ public function register(ServiceProviderInterface $serviceProvider): void throw LogicException::serviceProviderAlreadyRegistered($serviceProvider::class); } - $serviceProvider(self::$instance); + $serviceProvider($this); $this->services[self::PROVIDERS][$serviceProvider::class] = true; } @@ -342,15 +379,12 @@ public function set(string $id, mixed $value, iterable $tags = []): void if ( array_key_exists($id, $this->services[self::SERVICES]) || - array_key_exists($id, $this->services[self::FACTORIES]) + array_key_exists($id, $this->services[self::FACTORIES]) || + array_key_exists($id, $this->services[self::ALIASES]) ) { throw LogicException::serviceAlreadyRegistered($id); } - if (array_key_exists($id, $this->services[self::ALIASES])) { - unset($this->services[self::ALIASES][$id]); - } - $this->services[is_callable($value, false) ? self::FACTORIES : self::SERVICES][$id] = $value; From 6ed910dd30d2d490ef37b2676ba9587c88346d14 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 01:57:58 -0400 Subject: [PATCH 11/21] Update psalm.xml.dist Signed-off-by: Nathanael Esayeas --- psalm.xml.dist | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/psalm.xml.dist b/psalm.xml.dist index df33335..a5a627d 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -1,18 +1,21 @@ From 1e00fa026d6724c0c0278515d2b17188d9a2b1cc Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 02:00:04 -0400 Subject: [PATCH 12/21] Update README.md Signed-off-by: Nathanael Esayeas --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f644469..6ed5522 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ $container->register(new TasksServiceProvider()); Registering a service extension on the container. ```php +$container->bind(GitHubClient::class); $container->extend(GitHubClient::class, function (Container $container, object $client) { $client->setEnterpriseUrl($client->get(GitHubClient::GITHUB_HOST)); }); @@ -110,6 +111,7 @@ class GitHubExtension implements ExtensionInterface } } +$container->bind(GitHubClient::class); $container->add(GitHubClient::class, $container->get(GitHubExtention::class)); ``` From 331dddafa8d4f963aca93771b44fa8228f1a7528 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 02:00:07 -0400 Subject: [PATCH 13/21] Update composer.lock Signed-off-by: Nathanael Esayeas --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index ae40232..fce7d37 100644 --- a/composer.lock +++ b/composer.lock @@ -1725,16 +1725,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.6.3", + "version": "1.6.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "6128620b98292e0b69ea6d799871d77163681c8e" + "reference": "e4cd0c2dd97809fcfdcd1f367ccf0be86c235168" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6128620b98292e0b69ea6d799871d77163681c8e", - "reference": "6128620b98292e0b69ea6d799871d77163681c8e", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e4cd0c2dd97809fcfdcd1f367ccf0be86c235168", + "reference": "e4cd0c2dd97809fcfdcd1f367ccf0be86c235168", "shasum": "" }, "require": { @@ -1760,7 +1760,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.6.3" + "source": "https://github.com/phpstan/phpstan/tree/1.6.4" }, "funding": [ { @@ -1780,7 +1780,7 @@ "type": "tidelift" } ], - "time": "2022-04-28T11:27:53+00:00" + "time": "2022-05-02T16:02:21+00:00" }, { "name": "phpunit/php-code-coverage", From 25a1ddaf56716204985f4160732cc4135b91aff4 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 02:09:54 -0400 Subject: [PATCH 14/21] Update ContainerTest.php Signed-off-by: Nathanael Esayeas --- tests/Unit/ContainerTest.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/Unit/ContainerTest.php b/tests/Unit/ContainerTest.php index 4aac791..43248e6 100644 --- a/tests/Unit/ContainerTest.php +++ b/tests/Unit/ContainerTest.php @@ -367,17 +367,6 @@ static function (Container $container): void { $container->invoke([TestEventListener::class, 'onStaticCallableArray']); }, ]; - yield 'NotInstantiableException::unresolvableParameter@invoke-undefind-class' => [ - NotInstantiableException::class, - NotInstantiableException::unresolvableParameter( - 'nullable', - TestEventListener::class, - 'onStaticCallableArray' - )->getMessage(), - static function (Container $container): void { - $container->invoke(TestEventListener::class); - }, - ]; } /** @return iterable */ From 2002e05ab80a06d00862f757b5d4c1e3f07a46e5 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 03:11:44 -0400 Subject: [PATCH 15/21] Delete infection.json.dist Signed-off-by: Nathanael Esayeas --- infection.json.dist | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 infection.json.dist diff --git a/infection.json.dist b/infection.json.dist deleted file mode 100644 index 9896edf..0000000 --- a/infection.json.dist +++ /dev/null @@ -1,20 +0,0 @@ -{ - "timeout": 10, - "source": { - "directories": [ - "src" - ] - }, - "logs": { - "stryker": { - "report": "/^.*$/" - }, - "text": "php:\/\/stderr", - "github": true - }, - "mutators": { - "@default": true - }, - "minMsi": 97, - "minCoveredMsi": 100 -} From c43dc21f2741362a82468617378284c5678f7386 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 03:18:29 -0400 Subject: [PATCH 16/21] Update ContainerTest.php Signed-off-by: Nathanael Esayeas --- tests/Unit/ContainerTest.php | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/tests/Unit/ContainerTest.php b/tests/Unit/ContainerTest.php index 43248e6..e641c43 100644 --- a/tests/Unit/ContainerTest.php +++ b/tests/Unit/ContainerTest.php @@ -84,6 +84,8 @@ protected function tearDown(): void /** * @psalm-return Generator + * + * @return Generator[]|TestEventListener[][]|array[]|array{nullable: null}[]|Closure():void[]|TestEventListener[]> */ public function dataProviderContainerCallables(): Generator { @@ -96,8 +98,8 @@ static function ($event): void { ], ]; - yield 'AnonymousFunctionCall' => [static function (TestEvent $event): void { - $event->collect($event::class); + yield 'AnonymousFunctionCall' => [static function (TestEvent $testEvent): void { + $testEvent->collect($testEvent::class); }]; yield 'FunctionCall@typedFunction' => ['Ghostwriter\Container\Tests\Fixture\typedFunction']; @@ -109,17 +111,23 @@ static function ($event): void { yield 'StaticMethodCall' => [TestEventListener::class . '::onStatic']; - yield 'CallableArrayStaticMethodCall' => [[TestEventListener::class, 'onStaticCallableArray'], [ + yield 'CallableArrayStaticMethodCall' => [static function (TestEvent $testEvent, ?string $nullable): void { + TestEventListener::onStaticCallableArray($testEvent, $nullable); + }, [ 'nullable' =>null, ]]; - yield 'CallableArrayInstanceMethodCall' => [[new TestEventListener(), 'onTest']]; + yield 'CallableArrayInstanceMethodCall' => [static function (TestEvent $testEvent): void { + (new TestEventListener())->onTest($testEvent); + }]; yield 'Invokable' => [new TestEventListener()]; } /** * @psalm-return Generator + * + * @return Generator */ public function dataProviderContainerExceptions(): Generator { @@ -154,7 +162,10 @@ static function (Container $container): void { InvalidArgumentException::class, InvalidArgumentException::emptyServiceId()->getMessage(), static function (Container $container): void { - $container->extend('', static fn (Container $container) => $container); + $container->extend( + '', + static fn (Container $container): Container => $container + ); }, ]; @@ -348,7 +359,7 @@ static function (Container $container): void { NotInstantiableException::class, NotInstantiableException::unresolvableParameter( 'event', - null, + '', 'Ghostwriter\Container\Tests\Fixture\typelessFunction', )->getMessage(), static function (Container $container): void { @@ -561,13 +572,17 @@ public function testContainerBuild(string $class, array $arguments = []): void * * @dataProvider dataProviderContainerCallables * + * @param callable():void|string|TestEventListener|class-string[]|TestEventListener[]|string[] $callback + * @param array $arguments + * * @throws Throwable */ public function testContainerCall(callable $callback, array $arguments = []): void { $this->container->set(TestEvent::class, $arguments['event'] ?? new TestEvent()); + $actual = random_int(10, 50); - $actual = $expectedCount = random_int(10, 50); + $expectedCount = $actual; while ($actual) { $this->container->invoke($callback, $arguments); @@ -798,6 +813,9 @@ public function testContainerRemove(): void * @covers \Ghostwriter\Container\Container::set * @dataProvider dataProviderServices * + * @param bool|Closure():null|float|int|stdClass|string|string|string[] $value + * @param bool|float|int|stdClass|string|string[] $expected + * * @throws PsrNotFoundExceptionInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface @@ -906,6 +924,7 @@ public function testExceptionsImplementPsrContainerExceptionInterface( if ($exception !== $throwable::class) { self::assertSame($exception, $throwable->getMessage()); } + self::assertSame($exception, $throwable::class); self::assertInstanceOf(PsrContainerExceptionInterface::class, $throwable); From 61c154f001d97e3ed54cbb91c18a472588d779fd Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 03:18:42 -0400 Subject: [PATCH 17/21] Update NotInstantiableException.php Signed-off-by: Nathanael Esayeas --- src/Exception/NotInstantiableException.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Exception/NotInstantiableException.php b/src/Exception/NotInstantiableException.php index af21a04..4c3e351 100644 --- a/src/Exception/NotInstantiableException.php +++ b/src/Exception/NotInstantiableException.php @@ -20,14 +20,16 @@ public static function classDoseNotExist(string $class): self return new self(sprintf('Class "%s" dose not exist.', $class)); } - public static function unresolvableParameter($parameter, ?string $class, string $method = '__construct'): self + public static function unresolvableParameter(string $parameter, string $class, string $method): self { + $isFunction = '' === $class; + return new self(sprintf( 'Unresolvable %s parameter "$%s" in "%s%s"; does not have a default value.', - null === $class ? 'function' : 'class', + $isFunction ? 'function' : 'class', $parameter, - $class ?? $method, - $class ? '::' . $method : '()' + $isFunction ? $method : $class, + $isFunction ? '()' : '::' . $method )); } } From c82f6a31f136f2816cbd57dc1b109896ddf7423f Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 03:18:49 -0400 Subject: [PATCH 18/21] Update ContainerInterface.php Signed-off-by: Nathanael Esayeas --- src/Contract/ContainerInterface.php | 37 ++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/Contract/ContainerInterface.php b/src/Contract/ContainerInterface.php index f895500..3c98da4 100644 --- a/src/Contract/ContainerInterface.php +++ b/src/Contract/ContainerInterface.php @@ -98,6 +98,14 @@ public function __destruct(); */ public function __clone(); + /** + * @throws PsrNotFoundExceptionInterface + * @throws PsrContainerExceptionInterface + */ + public function __get(string $name); + + public function __isset(string $name): bool; + /** * @throws BadMethodCallException if "__serialize()" method is called * @@ -105,6 +113,12 @@ public function __clone(); */ public function __serialize(): array; + /** + * @throws PsrNotFoundExceptionInterface + * @throws PsrContainerExceptionInterface + */ + public function __set(string $name, mixed $value): void; + /** * @throws BadMethodCallException if "__unserialize()" method is called * @@ -112,6 +126,12 @@ public function __serialize(): array; */ public function __unserialize(array $data): void; + /** + * @throws PsrNotFoundExceptionInterface + * @throws PsrContainerExceptionInterface + */ + public function __unset(string $name): void; + /** * Add a service extension. * @@ -153,14 +173,6 @@ public function bind(string $abstract, ?string $concrete = null): void; */ public function build(string $class, array $arguments = []): object; - /** - * Create an object using the given Container to resolve dependencies. - * - * @param array $arguments optional arguments passed to $callback - * @throws ReflectionException - */ - public function invoke(callable $callback, array $arguments = []): mixed; - /** * "Extend" a service object in the container. * @@ -201,6 +213,15 @@ public static function getInstance(): self; */ public function has(string $id): bool; + /** + * Create an object using the given Container to resolve dependencies. + * + * @param array $arguments optional arguments passed to $callback + * + * @throws ReflectionException + */ + public function invoke(callable $callback, array $arguments = []): mixed; + /** @param string $offset */ public function offsetExists(mixed $offset): bool; From 255fb13a8a042921ecc345f0e2306b255258e84e Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 03:18:57 -0400 Subject: [PATCH 19/21] Update Container.php Signed-off-by: Nathanael Esayeas --- src/Container.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Container.php b/src/Container.php index 8cc2ed2..1977dc2 100644 --- a/src/Container.php +++ b/src/Container.php @@ -75,7 +75,7 @@ public function __serialize(): array throw BadMethodCallException::dontSerialize(self::class); } - public function __set(string $name, $value): void + public function __set(string $name, mixed $value): void { $this->set($name, $value); } @@ -296,9 +296,11 @@ public function invoke(callable $callback, array $arguments = []): mixed ! ($parameterType) instanceof ReflectionNamedType || $parameterType->isBuiltin() ) { + $reflectionClass = $parameter->getDeclaringClass(); throw NotInstantiableException::unresolvableParameter( $parameterName, - $parameter->getDeclaringClass()?->getName(), + $reflectionClass instanceof ReflectionClass ? + $reflectionClass->getName() : '', $parameter->getDeclaringFunction() ->getName() ); From f8747d1662f32077e479927945dcd48330222c42 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 03:19:13 -0400 Subject: [PATCH 20/21] Update composer.json Signed-off-by: Nathanael Esayeas --- composer.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/composer.json b/composer.json index 91146b5..4c15934 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,6 @@ "phpunit/phpunit": "^9.5", "psalm/plugin-phpunit": "^0.16", "rector/rector": "^0.12", - "roave/infection-static-analysis-plugin": "^1.18", "roave/security-advisories": "dev-latest", "symplify/easy-coding-standard": "^10.2", "vimeo/psalm": "^4.23" @@ -80,7 +79,6 @@ "@test", "@psalm", "@rector:dry-run", - "@infection", "@psalm:security" ], "cs-check": "vendor/bin/ecs check --clear-cache || true", @@ -91,10 +89,6 @@ "@psalm", "@infection" ], - "infection": [ - "@xdebug", - "roave-infection-static-analysis-plugin" - ], "missing-returntypes": "psalm --alter --issues=MissingReturnType", "normalizer": "@composer normalize --no-check-lock", "phpunit": "phpunit --colors=always --testdox --stop-on-failure", From 6c608dd91acddec2850142c42e2e3279ba8d4bea Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 3 May 2022 03:21:12 -0400 Subject: [PATCH 21/21] Update composer.lock Signed-off-by: Nathanael Esayeas --- composer.lock | 1204 +++++-------------------------------------------- 1 file changed, 101 insertions(+), 1103 deletions(-) diff --git a/composer.lock b/composer.lock index fce7d37..f808f7e 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": "c6de38a9b91e4b4f4c0f332e00c6ba54", + "content-hash": "be0ced85ba374e94ddbfc06f16efd881", "packages": [ { "name": "psr/container", @@ -227,6 +227,79 @@ ], "time": "2021-03-30T17:13:30+00:00" }, + { + "name": "composer/package-versions-deprecated", + "version": "1.11.99.5", + "source": { + "type": "git", + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" + }, + "replace": { + "ocramius/package-versions": "1.11.99" + }, + "require-dev": { + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-17T14:14:24+00:00" + }, { "name": "composer/pcre", "version": "3.0.0", @@ -653,379 +726,6 @@ }, "time": "2022-03-02T22:36:06+00:00" }, - { - "name": "infection/abstract-testframework-adapter", - "version": "0.5.0", - "source": { - "type": "git", - "url": "https://github.com/infection/abstract-testframework-adapter.git", - "reference": "18925e20d15d1a5995bb85c9dc09e8751e1e069b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/infection/abstract-testframework-adapter/zipball/18925e20d15d1a5995bb85c9dc09e8751e1e069b", - "reference": "18925e20d15d1a5995bb85c9dc09e8751e1e069b", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "ergebnis/composer-normalize": "^2.8", - "friendsofphp/php-cs-fixer": "^2.17", - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Infection\\AbstractTestFramework\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Maks Rafalko", - "email": "maks.rafalko@gmail.com" - } - ], - "description": "Abstract Test Framework Adapter for Infection", - "support": { - "issues": "https://github.com/infection/abstract-testframework-adapter/issues", - "source": "https://github.com/infection/abstract-testframework-adapter/tree/0.5.0" - }, - "funding": [ - { - "url": "https://github.com/infection", - "type": "github" - }, - { - "url": "https://opencollective.com/infection", - "type": "open_collective" - } - ], - "time": "2021-08-17T18:49:12+00:00" - }, - { - "name": "infection/extension-installer", - "version": "0.1.2", - "source": { - "type": "git", - "url": "https://github.com/infection/extension-installer.git", - "reference": "9b351d2910b9a23ab4815542e93d541e0ca0cdcf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/infection/extension-installer/zipball/9b351d2910b9a23ab4815542e93d541e0ca0cdcf", - "reference": "9b351d2910b9a23ab4815542e93d541e0ca0cdcf", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1 || ^2.0" - }, - "require-dev": { - "composer/composer": "^1.9 || ^2.0", - "friendsofphp/php-cs-fixer": "^2.18, <2.19", - "infection/infection": "^0.15.2", - "php-coveralls/php-coveralls": "^2.4", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.10", - "phpstan/phpstan-phpunit": "^0.12.6", - "phpstan/phpstan-strict-rules": "^0.12.2", - "phpstan/phpstan-webmozart-assert": "^0.12.2", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^4.8" - }, - "type": "composer-plugin", - "extra": { - "class": "Infection\\ExtensionInstaller\\Plugin" - }, - "autoload": { - "psr-4": { - "Infection\\ExtensionInstaller\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Maks Rafalko", - "email": "maks.rafalko@gmail.com" - } - ], - "description": "Infection Extension Installer", - "support": { - "issues": "https://github.com/infection/extension-installer/issues", - "source": "https://github.com/infection/extension-installer/tree/0.1.2" - }, - "funding": [ - { - "url": "https://github.com/infection", - "type": "github" - }, - { - "url": "https://opencollective.com/infection", - "type": "open_collective" - } - ], - "time": "2021-10-20T22:08:34+00:00" - }, - { - "name": "infection/include-interceptor", - "version": "0.2.5", - "source": { - "type": "git", - "url": "https://github.com/infection/include-interceptor.git", - "reference": "0cc76d95a79d9832d74e74492b0a30139904bdf7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/infection/include-interceptor/zipball/0cc76d95a79d9832d74e74492b0a30139904bdf7", - "reference": "0cc76d95a79d9832d74e74492b0a30139904bdf7", - "shasum": "" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "infection/infection": "^0.15.0", - "phan/phan": "^2.4 || ^3", - "php-coveralls/php-coveralls": "^2.2", - "phpstan/phpstan": "^0.12.8", - "phpunit/phpunit": "^8.5", - "vimeo/psalm": "^3.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Infection\\StreamWrapper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Maks Rafalko", - "email": "maks.rafalko@gmail.com" - } - ], - "description": "Stream Wrapper: Include Interceptor. Allows to replace included (autoloaded) file with another one.", - "support": { - "issues": "https://github.com/infection/include-interceptor/issues", - "source": "https://github.com/infection/include-interceptor/tree/0.2.5" - }, - "funding": [ - { - "url": "https://github.com/infection", - "type": "github" - }, - { - "url": "https://opencollective.com/infection", - "type": "open_collective" - } - ], - "time": "2021-08-09T10:03:57+00:00" - }, - { - "name": "infection/infection", - "version": "0.26.6", - "source": { - "type": "git", - "url": "https://github.com/infection/infection.git", - "reference": "de9b6b92f00ff1cb39decddf95797a4ebec3a1ee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/infection/infection/zipball/de9b6b92f00ff1cb39decddf95797a4ebec3a1ee", - "reference": "de9b6b92f00ff1cb39decddf95797a4ebec3a1ee", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.0", - "composer/xdebug-handler": "^2.0 || ^3.0", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "infection/abstract-testframework-adapter": "^0.5.0", - "infection/extension-installer": "^0.1.0", - "infection/include-interceptor": "^0.2.5", - "justinrainbow/json-schema": "^5.2.10", - "nikic/php-parser": "^4.13.2", - "ondram/ci-detector": "^4.1.0", - "php": "^7.4.7 || ^8.0", - "sanmai/later": "^0.1.1", - "sanmai/pipeline": "^5.1 || ^6", - "sebastian/diff": "^3.0.2 || ^4.0", - "seld/jsonlint": "^1.7", - "symfony/console": "^3.4.29 || ^4.1.19 || ^5.0 || ^6.0", - "symfony/filesystem": "^3.4.29 || ^4.1.19 || ^5.0 || ^6.0", - "symfony/finder": "^3.4.29 || ^4.1.19 || ^5.0 || ^6.0", - "symfony/process": "^3.4.29 || ^4.1.19 || ^5.0 || ^6.0", - "thecodingmachine/safe": "^1.1.3", - "webmozart/assert": "^1.3", - "webmozart/path-util": "^2.3" - }, - "conflict": { - "dg/bypass-finals": "*", - "phpunit/php-code-coverage": ">9 <9.1.4" - }, - "require-dev": { - "brianium/paratest": "^6.3", - "ext-simplexml": "*", - "helmich/phpunit-json-assert": "^3.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1.1.0", - "phpstan/phpstan": "^1.2.0", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "phpstan/phpstan-webmozart-assert": "^1.0.2", - "phpunit/phpunit": "^9.3.11", - "symfony/phpunit-bridge": "^4.4.18 || ^5.1.10", - "symfony/yaml": "^5.0", - "thecodingmachine/phpstan-safe-rule": "^1.1.0" - }, - "bin": [ - "bin/infection" - ], - "type": "library", - "autoload": { - "psr-4": { - "Infection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Maks Rafalko", - "email": "maks.rafalko@gmail.com", - "homepage": "https://twitter.com/maks_rafalko" - }, - { - "name": "Oleg Zhulnev", - "homepage": "https://github.com/sidz" - }, - { - "name": "Gert de Pagter", - "homepage": "https://github.com/BackEndTea" - }, - { - "name": "Théo FIDRY", - "email": "theo.fidry@gmail.com", - "homepage": "https://twitter.com/tfidry" - }, - { - "name": "Alexey Kopytko", - "email": "alexey@kopytko.com", - "homepage": "https://www.alexeykopytko.com" - }, - { - "name": "Andreas Möller", - "email": "am@localheinz.com", - "homepage": "https://localheinz.com" - } - ], - "description": "Infection is a Mutation Testing framework for PHP. The mutation adequacy score can be used to measure the effectiveness of a test set in terms of its ability to detect faults.", - "keywords": [ - "coverage", - "mutant", - "mutation framework", - "mutation testing", - "testing", - "unit testing" - ], - "support": { - "issues": "https://github.com/infection/infection/issues", - "source": "https://github.com/infection/infection/tree/0.26.6" - }, - "funding": [ - { - "url": "https://github.com/infection", - "type": "github" - }, - { - "url": "https://opencollective.com/infection", - "type": "open_collective" - } - ], - "time": "2022-03-07T11:40:30+00:00" - }, - { - "name": "justinrainbow/json-schema", - "version": "5.2.12", - "source": { - "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", - "json-schema/json-schema-test-suite": "1.2.0", - "phpunit/phpunit": "^4.8.35" - }, - "bin": [ - "bin/validate-json" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "JsonSchema\\": "src/JsonSchema/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bruno Prieto Reis", - "email": "bruno.p.reis@gmail.com" - }, - { - "name": "Justin Rainbow", - "email": "justin.rainbow@gmail.com" - }, - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - }, - { - "name": "Robert Schönthal", - "email": "seroscho@googlemail.com" - } - ], - "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", - "keywords": [ - "json", - "schema" - ], - "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12" - }, - "time": "2022-04-13T08:02:27+00:00" - }, { "name": "myclabs/deep-copy", "version": "1.11.0", @@ -1192,146 +892,6 @@ }, "time": "2021-11-30T19:35:32+00:00" }, - { - "name": "ocramius/package-versions", - "version": "2.5.1", - "source": { - "type": "git", - "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "6707caff2e84a2368f29fdf2cb28a6b5a9e3ab53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/6707caff2e84a2368f29fdf2cb28a6b5a9e3ab53", - "reference": "6707caff2e84a2368f29fdf2cb28a6b5a9e3ab53", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.2.0", - "php": "~8.0.0 || ~8.1.0" - }, - "replace": { - "composer/package-versions-deprecated": "*" - }, - "require-dev": { - "composer/composer": "^2.2.0", - "doctrine/coding-standard": "^9.0.0", - "ext-zip": "^1.15.0", - "phpunit/phpunit": "^9.5.9", - "roave/infection-static-analysis-plugin": "^1.10.0", - "vimeo/psalm": "^4.10.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "Provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/Ocramius/PackageVersions/issues", - "source": "https://github.com/Ocramius/PackageVersions/tree/2.5.1" - }, - "funding": [ - { - "url": "https://github.com/Ocramius", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ocramius/package-versions", - "type": "tidelift" - } - ], - "time": "2022-03-05T18:04:57+00:00" - }, - { - "name": "ondram/ci-detector", - "version": "4.1.0", - "source": { - "type": "git", - "url": "https://github.com/OndraM/ci-detector.git", - "reference": "8a4b664e916df82ff26a44709942dfd593fa6f30" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/OndraM/ci-detector/zipball/8a4b664e916df82ff26a44709942dfd593fa6f30", - "reference": "8a4b664e916df82ff26a44709942dfd593fa6f30", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "ergebnis/composer-normalize": "^2.2", - "lmc/coding-standard": "^1.3 || ^2.1", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0.5", - "phpstan/phpstan": "^0.12.58", - "phpstan/phpstan-phpunit": "^0.12.16", - "phpunit/phpunit": "^7.1 || ^8.0 || ^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "OndraM\\CiDetector\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ondřej Machulda", - "email": "ondrej.machulda@gmail.com" - } - ], - "description": "Detect continuous integration environment and provide unified access to properties of current build", - "keywords": [ - "CircleCI", - "Codeship", - "Wercker", - "adapter", - "appveyor", - "aws", - "aws codebuild", - "azure", - "azure devops", - "azure pipelines", - "bamboo", - "bitbucket", - "buddy", - "ci-info", - "codebuild", - "continuous integration", - "continuousphp", - "devops", - "drone", - "github", - "gitlab", - "interface", - "jenkins", - "pipelines", - "sourcehut", - "teamcity", - "travis" - ], - "support": { - "issues": "https://github.com/OndraM/ci-detector/issues", - "source": "https://github.com/OndraM/ci-detector/tree/4.1.0" - }, - "time": "2021-04-14T09:16:52+00:00" - }, { "name": "openlss/lib-array2xml", "version": "1.0.0", @@ -2373,57 +1933,6 @@ ], "time": "2022-05-01T15:50:16+00:00" }, - { - "name": "roave/infection-static-analysis-plugin", - "version": "1.18.0", - "source": { - "type": "git", - "url": "https://github.com/Roave/infection-static-analysis-plugin.git", - "reference": "f7e2194b1390fc9fa900e0ec123edea7112d0c18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Roave/infection-static-analysis-plugin/zipball/f7e2194b1390fc9fa900e0ec123edea7112d0c18", - "reference": "f7e2194b1390fc9fa900e0ec123edea7112d0c18", - "shasum": "" - }, - "require": { - "infection/infection": "0.26.6", - "ocramius/package-versions": "^1.9.0 || ^2.0.0", - "php": "~7.4.7|~8.0.0|~8.1.0", - "sanmai/later": "^0.1.2", - "vimeo/psalm": "^4.22.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9.0.0", - "phpunit/phpunit": "^9.5.18" - }, - "bin": [ - "bin/roave-infection-static-analysis-plugin" - ], - "type": "library", - "autoload": { - "psr-4": { - "Roave\\InfectionStaticAnalysis\\": "src/Roave/InfectionStaticAnalysis" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "Static analysis on top of mutation testing - prevents escaped mutants from being invalid according to static analysis", - "support": { - "issues": "https://github.com/Roave/infection-static-analysis-plugin/issues", - "source": "https://github.com/Roave/infection-static-analysis-plugin/tree/1.18.0" - }, - "time": "2022-03-08T08:35:20+00:00" - }, { "name": "roave/security-advisories", "version": "dev-latest", @@ -2868,171 +2377,48 @@ "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", "zendframework/zendframework": "<=3", "zendframework/zendframework1": "<1.12.20", - "zendframework/zendopenid": ">=2,<2.0.2", - "zendframework/zendxml": ">=1,<1.0.1", - "zetacomponents/mail": "<1.8.2", - "zf-commons/zfc-user": "<1.2.2", - "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", - "zfr/zfr-oauth2-server-module": "<0.1.2", - "zoujingli/thinkadmin": "<6.0.22" - }, - "default-branch": true, - "type": "metapackage", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "role": "maintainer" - }, - { - "name": "Ilya Tribusean", - "email": "slash3b@gmail.com", - "role": "maintainer" - } - ], - "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", - "support": { - "issues": "https://github.com/Roave/SecurityAdvisories/issues", - "source": "https://github.com/Roave/SecurityAdvisories/tree/latest" - }, - "funding": [ - { - "url": "https://github.com/Ocramius", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/roave/security-advisories", - "type": "tidelift" - } - ], - "time": "2022-04-29T21:04:00+00:00" - }, - { - "name": "sanmai/later", - "version": "0.1.2", - "source": { - "type": "git", - "url": "https://github.com/sanmai/later.git", - "reference": "9b659fecef2030193fd02402955bc39629d5606f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sanmai/later/zipball/9b659fecef2030193fd02402955bc39629d5606f", - "reference": "9b659fecef2030193fd02402955bc39629d5606f", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.13", - "infection/infection": ">=0.10.5", - "phan/phan": ">=2", - "php-coveralls/php-coveralls": "^2.0", - "phpstan/phpstan": ">=0.10", - "phpunit/phpunit": ">=7.4", - "vimeo/psalm": ">=2" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Later\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Alexey Kopytko", - "email": "alexey@kopytko.com" - } - ], - "description": "Later: deferred wrapper object", - "support": { - "issues": "https://github.com/sanmai/later/issues", - "source": "https://github.com/sanmai/later/tree/0.1.2" - }, - "funding": [ - { - "url": "https://github.com/sanmai", - "type": "github" - } - ], - "time": "2021-01-02T10:26:44+00:00" - }, - { - "name": "sanmai/pipeline", - "version": "v6.1", - "source": { - "type": "git", - "url": "https://github.com/sanmai/pipeline.git", - "reference": "3a88f2617237e18d5cd2aa38ca3d4b22770306c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sanmai/pipeline/zipball/3a88f2617237e18d5cd2aa38ca3d4b22770306c2", - "reference": "3a88f2617237e18d5cd2aa38ca3d4b22770306c2", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "ergebnis/composer-normalize": "^2.8", - "friendsofphp/php-cs-fixer": "^3", - "infection/infection": ">=0.10.5", - "league/pipeline": "^1.0 || ^0.3", - "phan/phan": ">=1.1", - "php-coveralls/php-coveralls": "^2.4.1", - "phpstan/phpstan": ">=0.10", - "phpunit/phpunit": "^7.4 || ^8.1 || ^9.4", - "vimeo/psalm": ">=2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "v6.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Pipeline\\": "src/" - } + "zendframework/zendopenid": ">=2,<2.0.2", + "zendframework/zendxml": ">=1,<1.0.1", + "zetacomponents/mail": "<1.8.2", + "zf-commons/zfc-user": "<1.2.2", + "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", + "zfr/zfr-oauth2-server-module": "<0.1.2", + "zoujingli/thinkadmin": "<6.0.22" }, + "default-branch": true, + "type": "metapackage", "notification-url": "https://packagist.org/downloads/", "license": [ - "Apache-2.0" + "MIT" ], "authors": [ { - "name": "Alexey Kopytko", - "email": "alexey@kopytko.com" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "role": "maintainer" + }, + { + "name": "Ilya Tribusean", + "email": "slash3b@gmail.com", + "role": "maintainer" } ], - "description": "General-purpose collections pipeline", + "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", "support": { - "issues": "https://github.com/sanmai/pipeline/issues", - "source": "https://github.com/sanmai/pipeline/tree/v6.1" + "issues": "https://github.com/Roave/SecurityAdvisories/issues", + "source": "https://github.com/Roave/SecurityAdvisories/tree/latest" }, "funding": [ { - "url": "https://github.com/sanmai", + "url": "https://github.com/Ocramius", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/roave/security-advisories", + "type": "tidelift" } ], - "time": "2022-01-30T08:15:59+00:00" + "time": "2022-04-29T21:04:00+00:00" }, { "name": "sebastian/cli-parser", @@ -3998,70 +3384,6 @@ ], "time": "2020-09-28T06:39:44+00:00" }, - { - "name": "seld/jsonlint", - "version": "1.9.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "4211420d25eba80712bff236a98960ef68b866b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", - "reference": "4211420d25eba80712bff236a98960ef68b866b7", - "shasum": "" - }, - "require": { - "php": "^5.3 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.5", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" - }, - "bin": [ - "bin/jsonlint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Seld\\JsonLint\\": "src/Seld/JsonLint/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "JSON Linter", - "keywords": [ - "json", - "linter", - "parser", - "validator" - ], - "support": { - "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" - }, - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", - "type": "tidelift" - } - ], - "time": "2022-04-01T13:37:23+00:00" - }, { "name": "symfony/console", "version": "v6.0.8", @@ -4157,130 +3479,6 @@ ], "time": "2022-04-20T15:01:42+00:00" }, - { - "name": "symfony/filesystem", - "version": "v6.0.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", - "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", - "shasum": "" - }, - "require": { - "php": ">=8.0.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.7" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-04-01T12:54:51+00:00" - }, - { - "name": "symfony/finder", - "version": "v6.0.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/af7edab28d17caecd1f40a9219fc646ae751c21f", - "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f", - "shasum": "" - }, - "require": { - "php": ">=8.0.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v6.0.8" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-04-15T08:07:58+00:00" - }, { "name": "symfony/polyfill-ctype", "version": "v1.25.0", @@ -4694,67 +3892,6 @@ ], "time": "2022-03-04T08:16:47+00:00" }, - { - "name": "symfony/process", - "version": "v6.0.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d074154ea8b1443a96391f6e39f9e547b2dd01b9", - "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9", - "shasum": "" - }, - "require": { - "php": ">=8.0.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v6.0.8" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-04-12T16:11:42+00:00" - }, { "name": "symfony/service-contracts", "version": "v3.0.1", @@ -4977,145 +4114,6 @@ ], "time": "2022-04-17T10:41:19+00:00" }, - { - "name": "thecodingmachine/safe", - "version": "v1.3.3", - "source": { - "type": "git", - "url": "https://github.com/thecodingmachine/safe.git", - "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/a8ab0876305a4cdaef31b2350fcb9811b5608dbc", - "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "require-dev": { - "phpstan/phpstan": "^0.12", - "squizlabs/php_codesniffer": "^3.2", - "thecodingmachine/phpstan-strict-rules": "^0.12" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.1-dev" - } - }, - "autoload": { - "files": [ - "deprecated/apc.php", - "deprecated/libevent.php", - "deprecated/mssql.php", - "deprecated/stats.php", - "lib/special_cases.php", - "generated/apache.php", - "generated/apcu.php", - "generated/array.php", - "generated/bzip2.php", - "generated/calendar.php", - "generated/classobj.php", - "generated/com.php", - "generated/cubrid.php", - "generated/curl.php", - "generated/datetime.php", - "generated/dir.php", - "generated/eio.php", - "generated/errorfunc.php", - "generated/exec.php", - "generated/fileinfo.php", - "generated/filesystem.php", - "generated/filter.php", - "generated/fpm.php", - "generated/ftp.php", - "generated/funchand.php", - "generated/gmp.php", - "generated/gnupg.php", - "generated/hash.php", - "generated/ibase.php", - "generated/ibmDb2.php", - "generated/iconv.php", - "generated/image.php", - "generated/imap.php", - "generated/info.php", - "generated/ingres-ii.php", - "generated/inotify.php", - "generated/json.php", - "generated/ldap.php", - "generated/libxml.php", - "generated/lzf.php", - "generated/mailparse.php", - "generated/mbstring.php", - "generated/misc.php", - "generated/msql.php", - "generated/mysql.php", - "generated/mysqli.php", - "generated/mysqlndMs.php", - "generated/mysqlndQc.php", - "generated/network.php", - "generated/oci8.php", - "generated/opcache.php", - "generated/openssl.php", - "generated/outcontrol.php", - "generated/password.php", - "generated/pcntl.php", - "generated/pcre.php", - "generated/pdf.php", - "generated/pgsql.php", - "generated/posix.php", - "generated/ps.php", - "generated/pspell.php", - "generated/readline.php", - "generated/rpminfo.php", - "generated/rrd.php", - "generated/sem.php", - "generated/session.php", - "generated/shmop.php", - "generated/simplexml.php", - "generated/sockets.php", - "generated/sodium.php", - "generated/solr.php", - "generated/spl.php", - "generated/sqlsrv.php", - "generated/ssdeep.php", - "generated/ssh2.php", - "generated/stream.php", - "generated/strings.php", - "generated/swoole.php", - "generated/uodbc.php", - "generated/uopz.php", - "generated/url.php", - "generated/var.php", - "generated/xdiff.php", - "generated/xml.php", - "generated/xmlrpc.php", - "generated/yaml.php", - "generated/yaz.php", - "generated/zip.php", - "generated/zlib.php" - ], - "psr-4": { - "Safe\\": [ - "lib/", - "deprecated/", - "generated/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHP core functions that throw exceptions instead of returning FALSE on error", - "support": { - "issues": "https://github.com/thecodingmachine/safe/issues", - "source": "https://github.com/thecodingmachine/safe/tree/v1.3.3" - }, - "time": "2020-10-28T17:51:34+00:00" - }, { "name": "theseer/tokenizer", "version": "1.2.1",