From 99ef1f07d4a3b7675d257ad7ccbc149ae22e8b8e Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Mon, 13 May 2024 18:10:38 +0200 Subject: [PATCH 1/5] feat: Introduce Service Firewall Part of #5 --- config/foo.yml | 1 - include/Firewall.php | 17 ++++++++++++++ include/MyConfiguration.php | 36 ----------------------------- include/MyEvent.php | 36 ----------------------------- include/MyService.php | 28 ----------------------- tests/unit/FirewallTest.php | 27 ++++++++++++++++++++++ tests/unit/MyServiceTest.php | 44 ------------------------------------ 7 files changed, 44 insertions(+), 145 deletions(-) delete mode 100644 config/foo.yml create mode 100644 include/Firewall.php delete mode 100644 include/MyConfiguration.php delete mode 100644 include/MyEvent.php delete mode 100644 include/MyService.php create mode 100644 tests/unit/FirewallTest.php delete mode 100644 tests/unit/MyServiceTest.php diff --git a/config/foo.yml b/config/foo.yml deleted file mode 100644 index c17f189..0000000 --- a/config/foo.yml +++ /dev/null @@ -1 +0,0 @@ -name: 'hello' \ No newline at end of file diff --git a/include/Firewall.php b/include/Firewall.php new file mode 100644 index 0000000..b754060 --- /dev/null +++ b/include/Firewall.php @@ -0,0 +1,17 @@ +configuration; - } - - #[ListeningEvent] - public function listenToMyEvent(MyEvent $event): void - { - $event->has_been_called = true; - } -} diff --git a/tests/unit/FirewallTest.php b/tests/unit/FirewallTest.php new file mode 100644 index 0000000..e88c14a --- /dev/null +++ b/tests/unit/FirewallTest.php @@ -0,0 +1,27 @@ +load(); + $this->service_manager = $core->service_manager; + } + + public function testMyServiceIsLoaded(): void + { + self::assertTrue($this->service_manager->has(Firewall::class)); + self::assertInstanceOf(Firewall::class, $this->service_manager->get(Firewall::class)); + } +} diff --git a/tests/unit/MyServiceTest.php b/tests/unit/MyServiceTest.php deleted file mode 100644 index 553f313..0000000 --- a/tests/unit/MyServiceTest.php +++ /dev/null @@ -1,44 +0,0 @@ -load(); - $this->service_manager = $core->service_manager; - } - - public function testMyServiceIsLoaded(): void - { - self::assertTrue($this->service_manager->has(MyService::class)); - self::assertInstanceOf(MyService::class, $this->service_manager->get(MyService::class)); - } - - public function testMyServiceListenMyEvent(): void - { - $dispatcher = $this->service_manager->get(EventDispatcher::class); - self::assertNotNull($dispatcher); - $event = $dispatcher->dispatch(new MyEvent(false)); - self::assertInstanceOf(MyEvent::class, $event); - self::assertTrue($event->has_been_called); - } - - public function testConfigurationIsLoaded(): void - { - $service = $this->service_manager->get(MyService::class); - self::assertInstanceOf(MyService::class, $service); - self::assertSame('hello', $service->getConfiguration()->name); - } -} From c13b8f3fdd6dcccfd2179e50ff383500c0f6469c Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Tue, 14 May 2024 18:01:30 +0200 Subject: [PATCH 2/5] feat: Introduce configuration of Firewall Part of #5 --- .gitignore | 3 +- composer.lock | 12 ++--- config/firewall.yml | 1 + .../Config/AccessControlRepresentation.php | 48 +++++++++++++++++++ include/Config/FirewallConfiguration.php | 44 +++++++++++++++++ include/Firewall.php | 7 ++- tests/unit/FirewallTest.php | 6 ++- 7 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 config/firewall.yml create mode 100644 include/Config/AccessControlRepresentation.php create mode 100644 include/Config/FirewallConfiguration.php diff --git a/.gitignore b/.gitignore index bc99dba..645750e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea .vscode -vendor \ No newline at end of file +vendor +cache \ No newline at end of file diff --git a/composer.lock b/composer.lock index 4820f9d..f1a7b0d 100644 --- a/composer.lock +++ b/composer.lock @@ -210,16 +210,16 @@ }, { "name": "archict/core", - "version": "v0.2.0", + "version": "v0.2.1", "source": { "type": "git", "url": "https://github.com/Archict/core.git", - "reference": "ccbc5d5453c5d4ce07eb7e4772f656b9f680c91d" + "reference": "8c18791403f1596a5762753e89fa3c2d99ed5a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Archict/core/zipball/ccbc5d5453c5d4ce07eb7e4772f656b9f680c91d", - "reference": "ccbc5d5453c5d4ce07eb7e4772f656b9f680c91d", + "url": "https://api.github.com/repos/Archict/core/zipball/8c18791403f1596a5762753e89fa3c2d99ed5a1d", + "reference": "8c18791403f1596a5762753e89fa3c2d99ed5a1d", "shasum": "" }, "require": { @@ -253,9 +253,9 @@ "description": "Heart of Archict, this library load and manage Bricks", "support": { "issues": "https://github.com/Archict/core/issues", - "source": "https://github.com/Archict/core/tree/v0.2.0" + "source": "https://github.com/Archict/core/tree/v0.2.1" }, - "time": "2024-04-25T16:32:59+00:00" + "time": "2024-05-14T06:54:08+00:00" }, { "name": "azjezz/psl", diff --git a/config/firewall.yml b/config/firewall.yml new file mode 100644 index 0000000..025130f --- /dev/null +++ b/config/firewall.yml @@ -0,0 +1 @@ +# Empty by default \ No newline at end of file diff --git a/include/Config/AccessControlRepresentation.php b/include/Config/AccessControlRepresentation.php new file mode 100644 index 0000000..0946e50 --- /dev/null +++ b/include/Config/AccessControlRepresentation.php @@ -0,0 +1,48 @@ + $providers + * @param AccessControlRepresentation[] $access_control + */ + public function __construct( + public array $providers = [], + public array $access_control = [], + ) { + } +} diff --git a/include/Firewall.php b/include/Firewall.php index b754060..7cc070e 100644 --- a/include/Firewall.php +++ b/include/Firewall.php @@ -5,13 +5,18 @@ namespace Archict\Firewall; use Archict\Brick\Service; +use Archict\Firewall\Config\FirewallConfiguration; /** * This service doesn't need to be used outside of this Brick. * But it needs to be loaded with a configuration file and event listeners. * @internal */ -#[Service] +#[Service(FirewallConfiguration::class)] final readonly class Firewall { + public function __construct( + public FirewallConfiguration $configuration, + ) { + } } diff --git a/tests/unit/FirewallTest.php b/tests/unit/FirewallTest.php index e88c14a..e8ffc28 100644 --- a/tests/unit/FirewallTest.php +++ b/tests/unit/FirewallTest.php @@ -19,9 +19,11 @@ protected function setUp(): void $this->service_manager = $core->service_manager; } - public function testMyServiceIsLoaded(): void + public function testFirewallServiceIsLoaded(): void { self::assertTrue($this->service_manager->has(Firewall::class)); - self::assertInstanceOf(Firewall::class, $this->service_manager->get(Firewall::class)); + $firewall = $this->service_manager->get(Firewall::class); + self::assertInstanceOf(Firewall::class, $firewall); + var_dump($firewall->configuration); } } From 42c96a42d6b1a51f10c14545acf95788e5de81a2 Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Wed, 15 May 2024 18:45:16 +0200 Subject: [PATCH 3/5] feat: Validate config file Part of #5 Big commit as there is many things to check and many different exception to throw --- README.md | 6 +- composer.json | 5 +- composer.lock | 65 +++++++- .../Config/AccessControlRepresentation.php | 6 +- include/Config/AccessControlValidator.php | 104 ++++++++++++ include/Config/ConfigValidator.php | 56 +++++++ .../ClassMustImplementInterfaceException.php | 36 +++++ .../Exception/ClassNotFoundException.php | 36 +++++ .../EmptyProviderClassNameException.php | 36 +++++ .../Exception/EmptyProviderNameException.php | 36 +++++ .../Exception/EmptyRulePathException.php | 36 +++++ .../Config/Exception/FirewallException.php | 34 ++++ .../Exception/InvalidHttpCodeException.php | 36 +++++ .../Exception/MissingBehaviorTagException.php | 36 +++++ .../Exception/MissingRoleTagException.php | 36 +++++ .../Exception/MissingRolesException.php | 36 +++++ .../Exception/UnknownProviderException.php | 36 +++++ include/Config/ProviderValidator.php | 71 ++++++++ include/Firewall.php | 21 +++ include/FirewallAccessChecker.php | 41 +++++ include/UserAccessChecker.php | 35 ++++ include/UserProvider.php | 35 ++++ include/UserWithRoles.php | 36 +++++ phpcs.xml | 1 - psalm.xml | 11 ++ tests/lib/UserAccessCheckerStub.php | 53 ++++++ tests/lib/UserProviderStub.php | 48 ++++++ tests/lib/UserWithRolesStub.php | 49 ++++++ .../Config/AccessControlValidatorTest.php | 153 ++++++++++++++++++ tests/unit/Config/ProviderValidatorTest.php | 70 ++++++++ tests/unit/FirewallTest.php | 1 - 31 files changed, 1246 insertions(+), 15 deletions(-) create mode 100644 include/Config/AccessControlValidator.php create mode 100644 include/Config/ConfigValidator.php create mode 100644 include/Config/Exception/ClassMustImplementInterfaceException.php create mode 100644 include/Config/Exception/ClassNotFoundException.php create mode 100644 include/Config/Exception/EmptyProviderClassNameException.php create mode 100644 include/Config/Exception/EmptyProviderNameException.php create mode 100644 include/Config/Exception/EmptyRulePathException.php create mode 100644 include/Config/Exception/FirewallException.php create mode 100644 include/Config/Exception/InvalidHttpCodeException.php create mode 100644 include/Config/Exception/MissingBehaviorTagException.php create mode 100644 include/Config/Exception/MissingRoleTagException.php create mode 100644 include/Config/Exception/MissingRolesException.php create mode 100644 include/Config/Exception/UnknownProviderException.php create mode 100644 include/Config/ProviderValidator.php create mode 100644 include/FirewallAccessChecker.php create mode 100644 include/UserAccessChecker.php create mode 100644 include/UserProvider.php create mode 100644 include/UserWithRoles.php create mode 100644 tests/lib/UserAccessCheckerStub.php create mode 100644 tests/lib/UserProviderStub.php create mode 100644 tests/lib/UserWithRolesStub.php create mode 100644 tests/unit/Config/AccessControlValidatorTest.php create mode 100644 tests/unit/Config/ProviderValidatorTest.php diff --git a/README.md b/README.md index 8f03722..f907678 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ namespace Archict\Firewall; interface UserProvider { - public function getCurrentUser(ServerRequestInterface $request): User; + public function getCurrentUser(ServerRequestInterface $request): UserWithRoles; } ``` @@ -50,7 +50,7 @@ The class you pass in the config must implement this interface. namespace Archict\Firewall; -interface User +interface UserWithRoles { /** * @return string[] @@ -74,7 +74,7 @@ roles), or implement your own checker. If you choose to use firewall checker, then you must provide these 2 tags: - `provider` ➡ One of the previously defined provider -- `roles` ➡ An array of string. User must have one these roles to access resource +- `roles` ➡ An array of string. User must have one of these roles to access resource Then you can define the behavior with one these rules (only one): diff --git a/composer.json b/composer.json index 03f8968..8ee197b 100644 --- a/composer.json +++ b/composer.json @@ -10,11 +10,12 @@ }, "require": { "php": ">= 8.2", - "archict/brick": "^0" + "archict/brick": "^0", + "psr/http-message": "^2.0" }, "autoload-dev": { "psr-4": { - "Archict\\Firewall\\": "tests/unit" + "Archict\\Firewall\\": ["tests/unit", "tests/lib"] } }, "require-dev": { diff --git a/composer.lock b/composer.lock index f1a7b0d..d47b77a 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": "61a4d2fd716fb3613a8d7c1288370e6d", + "content-hash": "c77680a27c4e04360940c4b19ef3a154", "packages": [ { "name": "archict/brick", @@ -45,6 +45,59 @@ "source": "https://github.com/Archict/brick/tree/v0.2.0" }, "time": "2024-04-18T16:07:42+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" } ], "packages-dev": [ @@ -1664,16 +1717,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.67", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493" + "reference": "666cb1703742cea9cc80fee631f0940e1592fa6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/16ddbe776f10da6a95ebd25de7c1dbed397dc493", - "reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/666cb1703742cea9cc80fee631f0940e1592fa6e", + "reference": "666cb1703742cea9cc80fee631f0940e1592fa6e", "shasum": "" }, "require": { @@ -1718,7 +1771,7 @@ "type": "github" } ], - "time": "2024-04-16T07:22:02+00:00" + "time": "2024-05-13T06:02:22+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/include/Config/AccessControlRepresentation.php b/include/Config/AccessControlRepresentation.php index 0946e50..95702ee 100644 --- a/include/Config/AccessControlRepresentation.php +++ b/include/Config/AccessControlRepresentation.php @@ -27,6 +27,8 @@ namespace Archict\Firewall\Config; +use Archict\Firewall\FirewallAccessChecker; + /** * @internal */ @@ -34,7 +36,7 @@ { /** * @param string[]|null $roles - * @param ?class-string $checker + * @param class-string $checker */ public function __construct( public string $path, @@ -42,7 +44,7 @@ public function __construct( public ?array $roles = null, public ?int $error = null, public ?string $redirect_to = null, - public ?string $checker = null, + public string $checker = FirewallAccessChecker::class, ) { } } diff --git a/include/Config/AccessControlValidator.php b/include/Config/AccessControlValidator.php new file mode 100644 index 0000000..26cf66a --- /dev/null +++ b/include/Config/AccessControlValidator.php @@ -0,0 +1,104 @@ + $providers + * @throws FirewallException + */ + public function validate(AccessControlRepresentation $representation, array $providers): void + { + if ($representation->path === '') { + throw new EmptyRulePathException(); + } + + if ($representation->provider !== null) { + if (!isset($providers[$representation->provider])) { + throw new UnknownProviderException($representation->provider); + } + + if ($representation->roles === null) { + throw new MissingRoleTagException(); + } + + if ($representation->roles === []) { + throw new MissingRolesException(); + } + + $this->validateBehavior($representation); + + return; // Representation is valid + } + + if (!class_exists($representation->checker)) { + throw new ClassNotFoundException($representation->checker); + } + + $reflection = new ReflectionClass($representation->checker); + if (!$reflection->implementsInterface(UserAccessChecker::class)) { + throw new ClassMustImplementInterfaceException($representation->checker, UserAccessChecker::class); + } + + $this->validateBehavior($representation); + + // Representation is valid + } + + /** + * @throws FirewallException + */ + private function validateBehavior(AccessControlRepresentation $representation): void + { + if ($representation->error !== null && $representation->redirect_to === null + && ($representation->error < 100 || $representation->error >= 600) + ) { + throw new InvalidHttpCodeException($representation->error); + } else if (($representation->error === null && $representation->redirect_to === null) + || ($representation->error !== null && $representation->redirect_to !== null) + ) { + throw new MissingBehaviorTagException(); + } + } +} diff --git a/include/Config/ConfigValidator.php b/include/Config/ConfigValidator.php new file mode 100644 index 0000000..2314e6c --- /dev/null +++ b/include/Config/ConfigValidator.php @@ -0,0 +1,56 @@ +providers as $name => $class_name) { + $this->provider_validator->validate($name, $class_name); + } + + foreach ($configuration->access_control as $representation) { + $this->access_control_validator->validate($representation, $configuration->providers); + } + } +} diff --git a/include/Config/Exception/ClassMustImplementInterfaceException.php b/include/Config/Exception/ClassMustImplementInterfaceException.php new file mode 100644 index 0000000..9725a28 --- /dev/null +++ b/include/Config/Exception/ClassMustImplementInterfaceException.php @@ -0,0 +1,36 @@ +implementsInterface(UserProvider::class)) { + throw new ClassMustImplementInterfaceException($class_name, UserProvider::class); + } + + // Provider is valid + } +} diff --git a/include/Firewall.php b/include/Firewall.php index 7cc070e..23fe8d8 100644 --- a/include/Firewall.php +++ b/include/Firewall.php @@ -5,7 +5,11 @@ namespace Archict\Firewall; use Archict\Brick\Service; +use Archict\Firewall\Config\AccessControlValidator; +use Archict\Firewall\Config\ConfigValidator; +use Archict\Firewall\Config\Exception\FirewallException; use Archict\Firewall\Config\FirewallConfiguration; +use Archict\Firewall\Config\ProviderValidator; /** * This service doesn't need to be used outside of this Brick. @@ -15,8 +19,25 @@ #[Service(FirewallConfiguration::class)] final readonly class Firewall { + /** + * @throws FirewallException + */ public function __construct( public FirewallConfiguration $configuration, ) { + $this->validateConfiguration(); + } + + /** + * @throws FirewallException + */ + private function validateConfiguration(): void + { + $validator = new ConfigValidator( + new ProviderValidator(), + new AccessControlValidator(), + ); + + $validator->validate($this->configuration); } } diff --git a/include/FirewallAccessChecker.php b/include/FirewallAccessChecker.php new file mode 100644 index 0000000..900a10e --- /dev/null +++ b/include/FirewallAccessChecker.php @@ -0,0 +1,41 @@ + - diff --git a/psalm.xml b/psalm.xml index 535dc07..77a296d 100644 --- a/psalm.xml +++ b/psalm.xml @@ -13,5 +13,16 @@ + + + + + + + + + + + diff --git a/tests/lib/UserAccessCheckerStub.php b/tests/lib/UserAccessCheckerStub.php new file mode 100644 index 0000000..ac8ab57 --- /dev/null +++ b/tests/lib/UserAccessCheckerStub.php @@ -0,0 +1,53 @@ +has_access; + } +} diff --git a/tests/lib/UserProviderStub.php b/tests/lib/UserProviderStub.php new file mode 100644 index 0000000..b8e610d --- /dev/null +++ b/tests/lib/UserProviderStub.php @@ -0,0 +1,48 @@ +user; + } +} diff --git a/tests/lib/UserWithRolesStub.php b/tests/lib/UserWithRolesStub.php new file mode 100644 index 0000000..20c6cce --- /dev/null +++ b/tests/lib/UserWithRolesStub.php @@ -0,0 +1,49 @@ +roles; + } +} diff --git a/tests/unit/Config/AccessControlValidatorTest.php b/tests/unit/Config/AccessControlValidatorTest.php new file mode 100644 index 0000000..b3f5e1c --- /dev/null +++ b/tests/unit/Config/AccessControlValidatorTest.php @@ -0,0 +1,153 @@ +validate( + new AccessControlRepresentation(''), + [], + ); + } + + public function testItThrowsProviderNotExists(): void + { + self::expectException(UnknownProviderException::class); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', 'provider'), + [], + ); + } + + public function testItThrowsIfRolesAreNotSuppliedWhenUsingFirewallChecker(): void + { + self::expectException(MissingRoleTagException::class); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', 'provider'), + ['provider' => UserProviderStub::class], + ); + } + + public function testItThrowsIfRolesAreEmptyWhenUsingFirewallChecker(): void + { + self::expectException(MissingRolesException::class); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', 'provider', []), + ['provider' => UserProviderStub::class], + ); + } + + public function testItThrowsIfErrorCodeIsInvalidWhenUsingFirewallChecker(): void + { + self::expectException(InvalidHttpCodeException::class); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', 'provider', ['role'], 50), + ['provider' => UserProviderStub::class], + ); + } + + public function testItThrowsIfBehaviorNotSuppliedWhenUsingFirewallChecker(): void + { + self::expectException(MissingBehaviorTagException::class); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', 'provider', ['role']), + ['provider' => UserProviderStub::class], + ); + } + + public function testItThrowsIfAllBehaviorAreSuppliedWhenUsingFirewallChecker(): void + { + self::expectException(MissingBehaviorTagException::class); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', 'provider', ['role'], 404, '/login'), + ['provider' => UserProviderStub::class], + ); + } + + public function testItAcceptAValidRepresentationWhenUsingFirewallChecker(): void + { + self::expectNotToPerformAssertions(); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', 'provider', ['role'], 404), + ['provider' => UserProviderStub::class], + ); + } + + public function testItThrowsIfClassNameNotExistsWhenUsingOwnChecker(): void + { + self::expectException(ClassNotFoundException::class); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', null, null, null, null, 'non-existing'), // @phpstan-ignore-line + [], + ); + } + + public function testItThrowsIfClassNotImplementUserAccessCheckerWhenUsingOwnChecker(): void + { + self::expectException(ClassMustImplementInterfaceException::class); + $obj = new class { + }; + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', null, null, null, null, $obj::class), + [], + ); + } + + public function testItThrowsIfBehaviorIsInvalidWhenUsingOwnChecker(): void + { + self::expectException(MissingBehaviorTagException::class); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', null, null, null, null, UserAccessCheckerStub::class), + [], + ); + } + + public function testItAcceptAValidRepresentationWhenUsingOwnChecker(): void + { + self::expectNotToPerformAssertions(); + (new AccessControlValidator())->validate( + new AccessControlRepresentation('path', null, null, null, '/path', UserAccessCheckerStub::class), + [], + ); + } +} diff --git a/tests/unit/Config/ProviderValidatorTest.php b/tests/unit/Config/ProviderValidatorTest.php new file mode 100644 index 0000000..5d3a29a --- /dev/null +++ b/tests/unit/Config/ProviderValidatorTest.php @@ -0,0 +1,70 @@ +validate(' ', UserProviderStub::class); + } + + public function testItThrowsIfClassNameIsEmpty(): void + { + self::expectException(EmptyProviderClassNameException::class); + (new ProviderValidator())->validate('my_provider', ' '); // @phpstan-ignore-line + } + + public function testItThrowsIfClassDoesntExists(): void + { + self::expectException(ClassNotFoundException::class); + (new ProviderValidator())->validate('my_provider', 'non-existing-class'); // @phpstan-ignore-line + } + + public function testItThrowsIfClassNotImplementUserProvider(): void + { + self::expectException(ClassMustImplementInterfaceException::class); + $obj = new class { + }; + (new ProviderValidator())->validate('my_provider', $obj::class); + } + + public function testItAcceptAValidProvider(): void + { + self::expectNotToPerformAssertions(); + (new ProviderValidator())->validate('my_provider', UserProviderStub::class); + } +} diff --git a/tests/unit/FirewallTest.php b/tests/unit/FirewallTest.php index e8ffc28..a5da06e 100644 --- a/tests/unit/FirewallTest.php +++ b/tests/unit/FirewallTest.php @@ -24,6 +24,5 @@ public function testFirewallServiceIsLoaded(): void self::assertTrue($this->service_manager->has(Firewall::class)); $firewall = $this->service_manager->get(Firewall::class); self::assertInstanceOf(Firewall::class, $firewall); - var_dump($firewall->configuration); } } From 13325a87411813dcab1aef30305ddb5a600c6127 Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Sat, 18 May 2024 10:08:06 +0200 Subject: [PATCH 4/5] feat: Implement FirewallAccessChecker Part of #5 --- include/FirewallAccessChecker.php | 21 ++++++++- tests/lib/NullRequest.php | 38 +++++++++++++++ tests/lib/UserWithRolesStub.php | 5 ++ tests/unit/FirewallAccessCheckerTest.php | 60 ++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 tests/lib/NullRequest.php create mode 100644 tests/unit/FirewallAccessCheckerTest.php diff --git a/include/FirewallAccessChecker.php b/include/FirewallAccessChecker.php index 900a10e..b69de62 100644 --- a/include/FirewallAccessChecker.php +++ b/include/FirewallAccessChecker.php @@ -32,10 +32,27 @@ /** * @internal */ -final class FirewallAccessChecker implements UserAccessChecker +final readonly class FirewallAccessChecker implements UserAccessChecker { + /** + * @param string[] $allowed_roles + */ + public function __construct( + private UserProvider $provider, + private array $allowed_roles, + ) { + } + public function canUserAccessResource(ServerRequestInterface $request): bool { - return true; + $user = $this->provider->getCurrentUser($request); + + foreach ($user->getRoles() as $role) { + if (in_array($role, $this->allowed_roles)) { + return true; + } + } + + return false; } } diff --git a/tests/lib/NullRequest.php b/tests/lib/NullRequest.php new file mode 100644 index 0000000..40f0b99 --- /dev/null +++ b/tests/lib/NullRequest.php @@ -0,0 +1,38 @@ +roles; diff --git a/tests/unit/FirewallAccessCheckerTest.php b/tests/unit/FirewallAccessCheckerTest.php new file mode 100644 index 0000000..c1ead07 --- /dev/null +++ b/tests/unit/FirewallAccessCheckerTest.php @@ -0,0 +1,60 @@ +canUserAccessResource(new NullRequest())); + } + + public function testItDisallowUserWithWrongRole(): void + { + $checker = new FirewallAccessChecker( + UserProviderStub::buildWithUser(UserWithRolesStub::buildWithRoles('USER', 'TEST')), + ['ADMIN', 'ROLE_ADMIN'], + ); + self::assertFalse($checker->canUserAccessResource(new NullRequest())); + } + + public function testItAllowUserWithRightRole(): void + { + $checker = new FirewallAccessChecker( + UserProviderStub::buildWithUser(UserWithRolesStub::buildWithRoles('ADMIN')), + ['ADMIN'], + ); + self::assertTrue($checker->canUserAccessResource(new NullRequest())); + } +} From 9b31e57fcd7b21610dc256de0b581d64058fe9b8 Mon Sep 17 00:00:00 2001 From: Kevin Traini Date: Sat, 18 May 2024 10:40:49 +0200 Subject: [PATCH 5/5] feat: Firewall add middlewares to Router Part of #5 --- composer.json | 6 +- composer.lock | 3210 +++++++++-------- .../Config/AccessControlRepresentation.php | 1 + include/Firewall.php | 87 +- phpstan.neon | 5 +- 5 files changed, 1831 insertions(+), 1478 deletions(-) diff --git a/composer.json b/composer.json index 8ee197b..0d811b0 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ "require": { "php": ">= 8.2", "archict/brick": "^0", - "psr/http-message": "^2.0" + "psr/http-message": "^2.0", + "archict/router": "^0" }, "autoload-dev": { "psr-4": { @@ -24,7 +25,8 @@ "phpunit/phpunit": "^10", "squizlabs/php_codesniffer": "^3.9", "slevomat/coding-standard": "^8.15", - "archict/core": "^0" + "archict/core": "^0", + "guzzlehttp/psr7": "^2.6" }, "scripts": { "unit-test": "phpunit --testsuite unit", diff --git a/composer.lock b/composer.lock index d47b77a..f38d7cb 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": "c77680a27c4e04360940c4b19ef3a154", + "content-hash": "cee968430ece34b47aa7528e7382a24d", "packages": [ { "name": "archict/brick", @@ -47,244 +47,76 @@ "time": "2024-04-18T16:07:42+00:00" }, { - "name": "psr/http-message", - "version": "2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" - }, - "time": "2023-04-04T09:54:51+00:00" - } - ], - "packages-dev": [ - { - "name": "amphp/amp", - "version": "v2.6.4", - "source": { - "type": "git", - "url": "https://github.com/amphp/amp.git", - "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", - "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^7 | ^8 | ^9", - "react/promise": "^2", - "vimeo/psalm": "^3.12" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php", - "lib/Internal/functions.php" - ], - "psr-4": { - "Amp\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "https://amphp.org/amp", - "keywords": [ - "async", - "asynchronous", - "awaitable", - "concurrency", - "event", - "event-loop", - "future", - "non-blocking", - "promise" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.4" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-03-21T18:52:26+00:00" - }, - { - "name": "amphp/byte-stream", - "version": "v1.8.2", + "name": "archict/core", + "version": "v0.2.1", "source": { "type": "git", - "url": "https://github.com/amphp/byte-stream.git", - "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc" + "url": "https://github.com/Archict/core.git", + "reference": "8c18791403f1596a5762753e89fa3c2d99ed5a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/4f0e968ba3798a423730f567b1b50d3441c16ddc", - "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc", + "url": "https://api.github.com/repos/Archict/core/zipball/8c18791403f1596a5762753e89fa3c2d99ed5a1d", + "reference": "8c18791403f1596a5762753e89fa3c2d99ed5a1d", "shasum": "" }, "require": { - "amphp/amp": "^2", - "php": ">=7.1" + "archict/brick": "^0", + "azjezz/psl": "^2.9", + "composer-runtime-api": "^2.2", + "composer/class-map-generator": "^1.1", + "cuyz/valinor": "^1.12", + "php": ">= 8.2", + "psr/simple-cache": "^3.0", + "symfony/yaml": "^7.0", + "vlucas/phpdotenv": "^5.6" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.4", - "friendsofphp/php-cs-fixer": "^2.3", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^6 || ^7 || ^8", - "psalm/phar": "^3.11.4" + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10", + "slevomat/coding-standard": "^8.15", + "squizlabs/php_codesniffer": "^3.9", + "vimeo/psalm": "^5.22" }, "type": "library", "autoload": { - "files": [ - "lib/functions.php" - ], "psr-4": { - "Amp\\ByteStream\\": "lib" + "Archict\\Core\\": "include/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "https://amphp.org/byte-stream", - "keywords": [ - "amp", - "amphp", - "async", - "io", - "non-blocking", - "stream" - ], + "description": "Heart of Archict, this library load and manage Bricks", "support": { - "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.2" + "issues": "https://github.com/Archict/core/issues", + "source": "https://github.com/Archict/core/tree/v0.2.1" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-04-13T18:00:56+00:00" + "time": "2024-05-14T06:54:08+00:00" }, { - "name": "archict/core", - "version": "v0.2.1", + "name": "archict/router", + "version": "v0.1.0", "source": { "type": "git", - "url": "https://github.com/Archict/core.git", - "reference": "8c18791403f1596a5762753e89fa3c2d99ed5a1d" + "url": "https://github.com/Archict/router.git", + "reference": "26f8cc51ca4c59eb3e0a09b2838ead26e2dd7263" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Archict/core/zipball/8c18791403f1596a5762753e89fa3c2d99ed5a1d", - "reference": "8c18791403f1596a5762753e89fa3c2d99ed5a1d", + "url": "https://api.github.com/repos/Archict/router/zipball/26f8cc51ca4c59eb3e0a09b2838ead26e2dd7263", + "reference": "26f8cc51ca4c59eb3e0a09b2838ead26e2dd7263", "shasum": "" }, "require": { "archict/brick": "^0", - "azjezz/psl": "^2.9", - "composer-runtime-api": "^2.2", - "composer/class-map-generator": "^1.1", + "archict/core": "^0.2", "cuyz/valinor": "^1.12", + "ext-simplexml": "*", + "guzzlehttp/psr7": "^2.6", "php": ">= 8.2", - "psr/simple-cache": "^3.0", - "symfony/yaml": "^7.0", - "vlucas/phpdotenv": "^5.6" + "psr/http-message": "^2.0" }, "require-dev": { "phpstan/phpstan": "^1.10", @@ -293,22 +125,22 @@ "squizlabs/php_codesniffer": "^3.9", "vimeo/psalm": "^5.22" }, - "type": "library", + "type": "archict-brick", "autoload": { "psr-4": { - "Archict\\Core\\": "include/" + "Archict\\Router\\": "include/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Heart of Archict, this library load and manage Bricks", + "description": "Simple HTTP router", "support": { - "issues": "https://github.com/Archict/core/issues", - "source": "https://github.com/Archict/core/tree/v0.2.1" + "issues": "https://github.com/Archict/router/issues", + "source": "https://github.com/Archict/router/tree/v0.1.0" }, - "time": "2024-05-14T06:54:08+00:00" + "time": "2024-05-08T07:32:06+00:00" }, { "name": "azjezz/psl", @@ -529,35 +361,40 @@ "time": "2024-03-19T10:26:25+00:00" }, { - "name": "composer/semver", - "version": "3.4.0", + "name": "cuyz/valinor", + "version": "1.12.0", "source": { "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + "url": "https://github.com/CuyZ/Valinor.git", + "reference": "3bc40798a5ff64aee8a28509b73f7f84d5c66ac9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "url": "https://api.github.com/repos/CuyZ/Valinor/zipball/3bc40798a5ff64aee8a28509b73f7f84d5c66ac9", + "reference": "3bc40798a5ff64aee8a28509b73f7f84d5c66ac9", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "composer-runtime-api": "^2.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } + "friendsofphp/php-cs-fixer": "^3.4", + "infection/infection": "^0.27", + "marcocesarato/php-conventional-changelog": "^1.12", + "mikey179/vfsstream": "^1.6.10", + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^10.5", + "rector/rector": "^1.0", + "vimeo/psalm": "^5.0" }, + "type": "library", "autoload": { "psr-4": { - "Composer\\Semver\\": "src" + "CuyZ\\Valinor\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -566,77 +403,61 @@ ], "authors": [ { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" + "name": "Romain Canon", + "email": "romain.hydrocanon@gmail.com", + "homepage": "https://github.com/romm" } ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", + "description": "Library that helps to map any input into a strongly-typed value object structure.", + "homepage": "https://github.com/CuyZ/Valinor", "keywords": [ - "semantic", - "semver", - "validation", - "versioning" + "array", + "conversion", + "hydrator", + "json", + "mapper", + "mapping", + "object", + "tree", + "yaml" ], "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" + "issues": "https://github.com/CuyZ/Valinor/issues", + "source": "https://github.com/CuyZ/Valinor/tree/1.12.0" }, "funding": [ { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", + "url": "https://github.com/romm", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2023-08-31T09:50:34+00:00" + "time": "2024-04-04T16:42:55+00:00" }, { - "name": "composer/xdebug-handler", - "version": "3.0.5", + "name": "graham-campbell/result-type", + "version": "v1.1.2", "source": { "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", - "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", "shasum": "" }, "require": { - "composer/pcre": "^1 || ^2 || ^3", "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" + "phpoption/phpoption": "^1.9.2" }, "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" }, "type": "library", "autoload": { "psr-4": { - "Composer\\XdebugHandler\\": "src" + "GrahamCampbell\\ResultType\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -645,71 +466,77 @@ ], "authors": [ { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" } ], - "description": "Restarts a process without Xdebug.", + "description": "An Implementation Of The Result Type", "keywords": [ - "Xdebug", - "performance" + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" ], "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" }, "funding": [ { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", + "url": "https://github.com/GrahamCampbell", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", "type": "tidelift" } ], - "time": "2024-05-06T16:37:16+00:00" + "time": "2023-11-12T22:16:48+00:00" }, { - "name": "cuyz/valinor", - "version": "1.12.0", + "name": "guzzlehttp/psr7", + "version": "2.6.2", "source": { "type": "git", - "url": "https://github.com/CuyZ/Valinor.git", - "reference": "3bc40798a5ff64aee8a28509b73f7f84d5c66ac9" + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CuyZ/Valinor/zipball/3bc40798a5ff64aee8a28509b73f7f84d5c66ac9", - "reference": "3bc40798a5ff64aee8a28509b73f7f84d5c66ac9", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", "shasum": "" }, "require": { - "composer-runtime-api": "^2.0", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.4", - "infection/infection": "^0.27", - "marcocesarato/php-conventional-changelog": "^1.12", - "mikey179/vfsstream": "^1.6.10", - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^10.5", - "rector/rector": "^1.0", - "vimeo/psalm": "^5.0" + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { "psr-4": { - "CuyZ\\Valinor\\": "src" + "GuzzleHttp\\Psr7\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -718,332 +545,332 @@ ], "authors": [ { - "name": "Romain Canon", - "email": "romain.hydrocanon@gmail.com", - "homepage": "https://github.com/romm" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], - "description": "Library that helps to map any input into a strongly-typed value object structure.", - "homepage": "https://github.com/CuyZ/Valinor", + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ - "array", - "conversion", - "hydrator", - "json", - "mapper", - "mapping", - "object", - "tree", - "yaml" + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" ], "support": { - "issues": "https://github.com/CuyZ/Valinor/issues", - "source": "https://github.com/CuyZ/Valinor/tree/1.12.0" + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" }, "funding": [ { - "url": "https://github.com/romm", + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" } ], - "time": "2024-04-04T16:42:55+00:00" + "time": "2023-12-03T20:05:35+00:00" }, { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v1.0.0", + "name": "phpoption/phpoption", + "version": "1.9.2", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "4be43904336affa5c2f70744a348312336afd0da" + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", - "reference": "4be43904336affa5c2f70744a348312336afd0da", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.4", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "composer/composer": "*", - "ext-json": "*", - "ext-zip": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0", - "yoast/phpunit-polyfills": "^1.0" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" }, - "type": "composer-plugin", + "type": "library", "extra": { - "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } }, "autoload": { "psr-4": { - "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + "PhpOption\\": "src/PhpOption/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "Apache-2.0" ], "authors": [ { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" }, { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" } ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", + "description": "Option Type for PHP", "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" + "language", + "option", + "php", + "type" ], "support": { - "issues": "https://github.com/PHPCSStandards/composer-installer/issues", - "source": "https://github.com/PHPCSStandards/composer-installer" - }, - "time": "2023-01-05T11:28:13+00:00" - }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "v0.1.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" }, - "type": "library", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" ], - "description": "implementation of xdg base directory specification for php", - "support": { - "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", - "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" - }, - "time": "2019-12-04T15:06:13+00:00" + "time": "2023-11-12T21:59:55+00:00" }, { - "name": "doctrine/deprecations", - "version": "1.1.3", + "name": "psr/http-factory", + "version": "1.1.0", "source": { "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Psr\\Http\\Message\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2024-01-30T19:34:25+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { - "name": "felixfbecker/advanced-json-rpc", - "version": "v3.2.1", + "name": "psr/http-message", + "version": "2.0", "source": { "type": "git", - "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "php": "^7.1 || ^8.0", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^7.0 || ^8.0" + "php": "^7.2 || ^8.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { - "AdvancedJsonRpc\\": "lib/" + "Psr\\Http\\Message\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "ISC" + "MIT" ], "authors": [ { - "name": "Felix Becker", - "email": "felix.b@outlook.com" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "A more advanced JSONRPC implementation", + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], "support": { - "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", - "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + "source": "https://github.com/php-fig/http-message/tree/2.0" }, - "time": "2021-06-11T22:34:44+00:00" + "time": "2023-04-04T09:54:51+00:00" }, { - "name": "felixfbecker/language-server-protocol", - "version": "v1.5.2", + "name": "psr/simple-cache", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/felixfbecker/php-language-server-protocol.git", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpstan/phpstan": "*", - "squizlabs/php_codesniffer": "^3.1", - "vimeo/psalm": "^4.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { "psr-4": { - "LanguageServerProtocol\\": "src/" + "Psr\\SimpleCache\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "ISC" + "MIT" ], "authors": [ { - "name": "Felix Becker", - "email": "felix.b@outlook.com" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "PHP classes for the Language Server Protocol", + "description": "Common interfaces for simple caching", "keywords": [ - "language", - "microsoft", - "php", - "server" + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" ], "support": { - "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", - "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2" + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" }, - "time": "2022-03-02T22:36:06+00:00" + "time": "2021-10-29T13:26:27+00:00" }, { - "name": "fidry/cpu-core-counter", - "version": "1.1.0", + "name": "ralouphie/getallheaders", + "version": "3.0.3", "source": { "type": "git", - "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": ">=5.6" }, "require-dev": { - "fidry/makefile": "^0.2.0", - "fidry/php-cs-fixer-config": "^1.1.2", - "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.9.2", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.2.2", - "phpstan/phpstan-strict-rules": "^1.4.4", - "phpunit/phpunit": "^8.5.31 || ^9.5.26", - "webmozarts/strict-phpunit": "^7.5" + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" }, "type": "library", "autoload": { - "psr-4": { - "Fidry\\CpuCoreCounter\\": "src/" - } + "files": [ + "src/getallheaders.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1051,88 +878,1179 @@ ], "authors": [ { - "name": "Théo FIDRY", - "email": "theo.fidry@gmail.com" + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" } ], - "description": "Tiny utility to get the number of CPU cores.", - "keywords": [ - "CPU", - "core" - ], + "description": "A polyfill for getallheaders.", "support": { - "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" }, - "funding": [ - { - "url": "https://github.com/theofidry", - "type": "github" - } - ], - "time": "2024-02-07T09:43:46+00:00" + "time": "2019-03-08T08:55:37+00:00" }, { - "name": "graham-campbell/result-type", - "version": "v1.1.2", + "name": "revolt/event-loop", + "version": "v1.0.6", "source": { "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" + "url": "https://github.com/revoltphp/event-loop.git", + "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", - "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/25de49af7223ba039f64da4ae9a28ec2d10d0254", + "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.2" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.15" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, "autoload": { "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" + "Revolt\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Rock-solid event loop for concurrent PHP applications.", + "keywords": [ + "async", + "asynchronous", + "concurrency", + "event", + "event-loop", + "non-blocking", + "scheduler" + ], + "support": { + "issues": "https://github.com/revoltphp/event-loop/issues", + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.6" + }, + "time": "2023-11-30T05:34:44+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/4d58f0f4fe95a30d7b538d71197135483560b97c", + "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "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/v7.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": "2024-04-28T11:44:19+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + }, + "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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + }, + "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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + }, + "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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", + "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.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": "2024-04-28T11:44:19+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.2", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], "authors": [ { "name": "Graham Campbell", "email": "hello@gjcampbell.co.uk", "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:43:29+00:00" + } + ], + "packages-dev": [ + { + "name": "amphp/amp", + "version": "v2.6.4", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", + "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^7 | ^8 | ^9", + "react/promise": "^2", + "vimeo/psalm": "^3.12" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ], + "psr-4": { + "Amp\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "https://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v2.6.4" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-03-21T18:52:26+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.8.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/4f0e968ba3798a423730f567b1b50d3441c16ddc", + "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc", + "shasum": "" + }, + "require": { + "amphp/amp": "^2", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1.4", + "friendsofphp/php-cs-fixer": "^2.3", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^6 || ^7 || ^8", + "psalm/phar": "^3.11.4" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Amp\\ByteStream\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "https://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "support": { + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/v1.8.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-13T18:00:56+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.0" + }, + "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": "2023-08-31T09:50:34+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.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": "2024-05-06T16:37:16+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" + }, + "time": "2023-01-05T11:28:13+00:00" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, + "time": "2019-12-04T15:06:13+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + }, + "time": "2024-01-30T19:34:25+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.5.2", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", + "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/phpstan": "*", + "squizlabs/php_codesniffer": "^3.1", + "vimeo/psalm": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2" + }, + "time": "2022-03-02T22:36:06+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" } ], - "description": "An Implementation Of The Result Type", + "description": "Tiny utility to get the number of CPU cores.", "keywords": [ - "Graham Campbell", - "GrahamCampbell", - "Result Type", - "Result-Type", - "result" + "CPU", + "core" ], "support": { - "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" }, "funding": [ { - "url": "https://github.com/GrahamCampbell", + "url": "https://github.com/theofidry", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" } ], - "time": "2023-11-12T22:16:48+00:00" + "time": "2024-02-07T09:43:46+00:00" }, { "name": "myclabs/deep-copy", @@ -1593,81 +2511,6 @@ }, "time": "2024-02-23T11:10:43+00:00" }, - { - "name": "phpoption/phpoption", - "version": "1.9.2", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", - "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": true - }, - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpOption\\": "src/PhpOption/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh" - }, - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "Option Type for PHP", - "keywords": [ - "language", - "option", - "php", - "type" - ], - "support": { - "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "time": "2023-11-12T21:59:55+00:00" - }, { "name": "phpstan/phpdoc-parser", "version": "1.29.0", @@ -1717,16 +2560,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "666cb1703742cea9cc80fee631f0940e1592fa6e" + "reference": "e524358f930e41a2b4cca1320e3b04fc26b39e0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/666cb1703742cea9cc80fee631f0940e1592fa6e", - "reference": "666cb1703742cea9cc80fee631f0940e1592fa6e", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e524358f930e41a2b4cca1320e3b04fc26b39e0b", + "reference": "e524358f930e41a2b4cca1320e3b04fc26b39e0b", "shasum": "" }, "require": { @@ -1771,7 +2614,7 @@ "type": "github" } ], - "time": "2024-05-13T06:02:22+00:00" + "time": "2024-05-15T08:00:59+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2286,140 +3129,17 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" - }, - "time": "2021-07-14T16:46:02+00:00" - }, - { - "name": "psr/simple-cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "time": "2021-10-29T13:26:27+00:00" - }, - { - "name": "revolt/event-loop", - "version": "v1.0.6", - "source": { - "type": "git", - "url": "https://github.com/revoltphp/event-loop.git", - "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/25de49af7223ba039f64da4ae9a28ec2d10d0254", - "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.15" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Revolt\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "ceesjank@gmail.com" - }, - { - "name": "Christian Lück", - "email": "christian@clue.engineering" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "Rock-solid event loop for concurrent PHP applications.", + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ - "async", - "asynchronous", - "concurrency", - "event", - "event-loop", - "non-blocking", - "scheduler" + "log", + "psr", + "psr-3" ], "support": { - "issues": "https://github.com/revoltphp/event-loop/issues", - "source": "https://github.com/revoltphp/event-loop/tree/v1.0.6" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, - "time": "2023-11-30T05:34:44+00:00" + "time": "2021-07-14T16:46:02+00:00" }, { "name": "sebastian/cli-parser", @@ -3208,536 +3928,233 @@ { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:05:40+00:00" - }, - { - "name": "sebastian/type", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:10:45+00:00" - }, - { - "name": "sebastian/version", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-07T11:34:05+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "8.15.0", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "7d1d957421618a3803b593ec31ace470177d7817" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/7d1d957421618a3803b593ec31ace470177d7817", - "reference": "7d1d957421618a3803b593ec31ace470177d7817", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.23.1", - "squizlabs/php_codesniffer": "^3.9.0" - }, - "require-dev": { - "phing/phing": "2.17.4", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.10.60", - "phpstan/phpstan-deprecation-rules": "1.1.4", - "phpstan/phpstan-phpunit": "1.3.16", - "phpstan/phpstan-strict-rules": "1.5.2", - "phpunit/phpunit": "8.5.21|9.6.8|10.5.11" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "8.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "keywords": [ - "dev", - "phpcs" - ], - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.15.0" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2024-03-09T15:20:58+00:00" - }, - { - "name": "spatie/array-to-xml", - "version": "3.3.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/array-to-xml.git", - "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/f56b220fe2db1ade4c88098d83413ebdfc3bf876", - "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "php": "^8.0" - }, - "require-dev": { - "mockery/mockery": "^1.2", - "pestphp/pest": "^1.21", - "spatie/pest-plugin-snapshots": "^1.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Spatie\\ArrayToXml\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://freek.dev", - "role": "Developer" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Convert an array to xml", - "homepage": "https://github.com/spatie/array-to-xml", - "keywords": [ - "array", - "convert", - "xml" - ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "source": "https://github.com/spatie/array-to-xml/tree/3.3.0" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - }, - { - "url": "https://github.com/spatie", + "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2024-05-01T10:20:27+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { - "name": "squizlabs/php_codesniffer", - "version": "3.9.2", + "name": "sebastian/type", + "version": "4.0.0", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/aac1f6f347a5c5ac6bc98ad395007df00990f480", - "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + "phpunit/phpunit": "^10.0" }, - "bin": [ - "bin/phpcbf", - "bin/phpcs" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-main": "4.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { - "name": "Greg Sherwood", - "role": "Former lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "Current lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", - "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", - "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { - "url": "https://github.com/PHPCSStandards", - "type": "github" - }, - { - "url": "https://github.com/jrfnl", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" } ], - "time": "2024-04-23T20:25:34+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { - "name": "symfony/console", - "version": "v7.0.7", + "name": "sebastian/version", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "c981e0e9380ce9f146416bde3150c79197ce9986" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c981e0e9380ce9f146416bde3150c79197ce9986", - "reference": "c981e0e9380ce9f146416bde3150c79197ce9986", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "php": ">=8.1" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command-line", - "console", - "terminal" - ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "source": "https://github.com/symfony/console/tree/v7.0.7" + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "name": "slevomat/coding-standard", + "version": "8.15.0", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "7d1d957421618a3803b593ec31ace470177d7817" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/7d1d957421618a3803b593ec31ace470177d7817", + "reference": "7d1d957421618a3803b593ec31ace470177d7817", "shasum": "" }, "require": { - "php": ">=8.1" + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", + "php": "^7.2 || ^8.0", + "phpstan/phpdoc-parser": "^1.23.1", + "squizlabs/php_codesniffer": "^3.9.0" }, - "type": "library", + "require-dev": { + "phing/phing": "2.17.4", + "php-parallel-lint/php-parallel-lint": "1.3.2", + "phpstan/phpstan": "1.10.60", + "phpstan/phpstan-deprecation-rules": "1.1.4", + "phpstan/phpstan-phpunit": "1.3.16", + "phpstan/phpstan-strict-rules": "1.5.2", + "phpunit/phpunit": "8.5.21|9.6.8|10.5.11" + }, + "type": "phpcodesniffer-standard", "extra": { "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "dev-master": "8.x-dev" } }, "autoload": { - "files": [ - "function.php" - ] + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/8.15.0" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/kukulich", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-03-09T15:20:58+00:00" }, { - "name": "symfony/filesystem", - "version": "v7.0.7", + "name": "spatie/array-to-xml", + "version": "3.3.0", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5" + "url": "https://github.com/spatie/array-to-xml.git", + "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/cc168be6fbdcdf3401f50ae863ee3818ed4338f5", - "reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/f56b220fe2db1ade4c88098d83413ebdfc3bf876", + "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8", - "symfony/process": "^6.4|^7.0" + "ext-dom": "*", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "pestphp/pest": "^1.21", + "spatie/pest-plugin-snapshots": "^1.1" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Spatie\\ArrayToXml\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3745,136 +4162,165 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://freek.dev", + "role": "Developer" } ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", + "description": "Convert an array to xml", + "homepage": "https://github.com/spatie/array-to-xml", + "keywords": [ + "array", + "convert", + "xml" + ], "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.0.7" + "source": "https://github.com/spatie/array-to-xml/tree/3.3.0" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://spatie.be/open-source/support-us", "type": "custom" }, { - "url": "https://github.com/fabpot", + "url": "https://github.com/spatie", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-05-01T10:20:27+00:00" }, { - "name": "symfony/finder", - "version": "v7.0.7", + "name": "squizlabs/php_codesniffer", + "version": "3.9.2", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/4d58f0f4fe95a30d7b538d71197135483560b97c", - "reference": "4d58f0f4fe95a30d7b538d71197135483560b97c", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/aac1f6f347a5c5ac6bc98ad395007df00990f480", + "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480", "shasum": "" }, "require": { - "php": ">=8.2" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" }, "require-dev": { - "symfony/filesystem": "^6.4|^7.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Greg Sherwood", + "role": "Former lead" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], "support": { - "source": "https://github.com/symfony/finder/tree/v7.0.7" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" + "url": "https://github.com/PHPCSStandards", + "type": "github" }, { - "url": "https://github.com/fabpot", + "url": "https://github.com/jrfnl", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-04-23T20:25:34+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "name": "symfony/console", + "version": "v7.0.7", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "url": "https://github.com/symfony/console.git", + "reference": "c981e0e9380ce9f146416bde3150c79197ce9986" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/console/zipball/c981e0e9380ce9f146416bde3150c79197ce9986", + "reference": "c981e0e9380ce9f146416bde3150c79197ce9986", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { - "ext-ctype": "*" + "psr/log-implementation": "1.0|2.0|3.0" }, - "suggest": { - "ext-ctype": "For best performance" + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3882,24 +4328,24 @@ ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" + "cli", + "command-line", + "console", + "terminal" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/console/tree/v7.0.7" }, "funding": [ { @@ -3915,42 +4361,39 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", + "name": "symfony/deprecation-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=8.1" }, "type": "library", "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } + "function.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3966,18 +4409,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's grapheme_* functions", + "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -3993,44 +4428,35 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-04-18T09:32:20+00:00" }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", + { + "name": "symfony/filesystem", + "version": "v7.0.7", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "url": "https://github.com/symfony/filesystem.git", + "reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/cc168be6fbdcdf3401f50ae863ee3818ed4338f5", + "reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/process": "^6.4|^7.0" }, "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + "Symfony\\Component\\Filesystem\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -4039,26 +4465,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/filesystem/tree/v7.0.7" }, "funding": [ { @@ -4074,30 +4492,27 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-04-18T09:29:19+00:00" }, { - "name": "symfony/polyfill-mbstring", + "name": "symfony/polyfill-intl-grapheme", "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", "shasum": "" }, "require": { "php": ">=7.1" }, - "provide": { - "ext-mbstring": "*" - }, "suggest": { - "ext-mbstring": "For best performance" + "ext-intl": "For best performance" }, "type": "library", "extra": { @@ -4111,7 +4526,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -4128,17 +4543,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for the Mbstring extension", + "description": "Symfony polyfill for intl's grapheme_* functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "mbstring", + "grapheme", + "intl", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" }, "funding": [ { @@ -4157,22 +4573,25 @@ "time": "2024-01-29T20:11:03+00:00" }, { - "name": "symfony/polyfill-php80", + "name": "symfony/polyfill-intl-normalizer", "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", "shasum": "" }, "require": { "php": ">=7.1" }, + "suggest": { + "ext-intl": "For best performance" + }, "type": "library", "extra": { "thanks": { @@ -4185,7 +4604,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, "classmap": [ "Resources/stubs" @@ -4196,10 +4615,6 @@ "MIT" ], "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -4209,16 +4624,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", + "intl", + "normalizer", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" }, "funding": [ { @@ -4466,77 +4883,6 @@ ], "time": "2024-04-18T09:29:19+00:00" }, - { - "name": "symfony/yaml", - "version": "v7.0.7", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", - "reference": "0d3916ae69ea28b59d94b60c4f2b50f4e25adb5c", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "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": "Loads and dumps YAML files", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v7.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": "2024-04-28T11:44:19+00:00" - }, { "name": "theseer/tokenizer", "version": "1.2.3", @@ -4697,90 +5043,6 @@ }, "time": "2024-05-01T19:32:08+00:00" }, - { - "name": "vlucas/phpdotenv", - "version": "v5.6.0", - "source": { - "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", - "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.2", - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.2", - "symfony/polyfill-ctype": "^1.24", - "symfony/polyfill-mbstring": "^1.24", - "symfony/polyfill-php80": "^1.24" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "ext-filter": "*", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "suggest": { - "ext-filter": "Required to use the boolean validator." - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": true - }, - "branch-alias": { - "dev-master": "5.6-dev" - } - }, - "autoload": { - "psr-4": { - "Dotenv\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://github.com/vlucas" - } - ], - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", - "keywords": [ - "dotenv", - "env", - "environment" - ], - "support": { - "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", - "type": "tidelift" - } - ], - "time": "2023-11-12T22:43:29+00:00" - }, { "name": "webmozart/assert", "version": "1.11.0", diff --git a/include/Config/AccessControlRepresentation.php b/include/Config/AccessControlRepresentation.php index 95702ee..cf5d746 100644 --- a/include/Config/AccessControlRepresentation.php +++ b/include/Config/AccessControlRepresentation.php @@ -35,6 +35,7 @@ final readonly class AccessControlRepresentation { /** + * @param class-string|null $provider * @param string[]|null $roles * @param class-string $checker */ diff --git a/include/Firewall.php b/include/Firewall.php index 23fe8d8..d77adaf 100644 --- a/include/Firewall.php +++ b/include/Firewall.php @@ -4,12 +4,22 @@ namespace Archict\Firewall; +use Archict\Brick\ListeningEvent; use Archict\Brick\Service; +use Archict\Firewall\Config\AccessControlRepresentation; use Archict\Firewall\Config\AccessControlValidator; use Archict\Firewall\Config\ConfigValidator; use Archict\Firewall\Config\Exception\FirewallException; use Archict\Firewall\Config\FirewallConfiguration; use Archict\Firewall\Config\ProviderValidator; +use Archict\Router\Exception\HTTP\HTTPException; +use Archict\Router\HTTPExceptionFactory; +use Archict\Router\Method; +use Archict\Router\Middleware; +use Archict\Router\RouteCollectorEvent; +use Psr\Http\Message\ServerRequestInterface; +use ReflectionClass; +use ReflectionException; /** * This service doesn't need to be used outside of this Brick. @@ -23,7 +33,7 @@ * @throws FirewallException */ public function __construct( - public FirewallConfiguration $configuration, + private FirewallConfiguration $configuration, ) { $this->validateConfiguration(); } @@ -40,4 +50,79 @@ private function validateConfiguration(): void $validator->validate($this->configuration); } + + /** + * @throws ReflectionException + */ + #[ListeningEvent] + public function addMiddlewares(RouteCollectorEvent $collector): void + { + foreach ($this->configuration->access_control as $access_control) { + $collector->addMiddleware( + Method::ALL, + $access_control->path, + $this->createMiddlewareFromRepresentation($access_control), + ); + } + } + + /** + * @throws ReflectionException + */ + private function createMiddlewareFromRepresentation(AccessControlRepresentation $representation): Middleware + { + if ($representation->checker === FirewallAccessChecker::class) { + assert(is_string($representation->provider)); + assert(is_array($representation->roles)); + $checker = new FirewallAccessChecker( + $this->instantiateProvider($representation->provider), + $representation->roles, + ); + } else { + $checker = $this->instantiateChecker($representation->checker); + } + + $exception = HTTPExceptionFactory::Forbidden(); + + return new class($checker, $exception) implements Middleware { + public function __construct( + private readonly UserAccessChecker $checker, + private readonly HTTPException $exception, + ) { + } + + public function process(ServerRequestInterface $request): ServerRequestInterface + { + if ($this->checker->canUserAccessResource($request)) { + return $request; + } + + throw $this->exception; + } + }; + } + + /** + * @param class-string $class_name + * @throws ReflectionException + */ + private function instantiateProvider(string $class_name): UserProvider + { + $reflection = new ReflectionClass($class_name); + $instance = $reflection->newInstance(); + assert($instance instanceof UserProvider); + return $instance; + } + + /** + * @param class-string $class_name + * @throws ReflectionException + */ + private function instantiateChecker(string $class_name): UserAccessChecker + { + $reflection = new ReflectionClass($class_name); + $instance = $reflection->newInstance(); + assert($instance instanceof UserAccessChecker); + return $instance; + } } diff --git a/phpstan.neon b/phpstan.neon index dbb68aa..6d08b6e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,4 +2,7 @@ parameters: level: 9 paths: - include - - tests \ No newline at end of file + - tests + ignoreErrors: + - identifier: argument.type + path: tests/unit/Config/AccessControlValidatorTest.php \ No newline at end of file