diff --git a/README.md b/README.md index 12abbf1..37ef641 100644 --- a/README.md +++ b/README.md @@ -64,23 +64,59 @@ class Handler } } ``` +...or special PHP attributes: +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Articus\PathHandler\Exception; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route('/entity')] //This is how you set path for handler operations +class Handler +{ + #[PHA\Post()] //This is how you declare HTTP method of the operation + #[PHA\Consumer('application/json', 'Json')] //This is how you consume request body + #[PHA\Attribute('Transfer', ['type'=>'My\DTO','objectAttr'=>'dto','errorAttr'=>'errors'])] //This is how you attribute request + #[PHA\Producer('application/json', 'Json')] //This is how you produce response body from returned value + public function handlePost(ServerRequestInterface $request): \My\DTO + { + $errors = $request->getAttribute('errors'); + if (!empty($errors)) + { + //This is how you can return non-200 responses + throw new Exception\UnprocessableEntity($errors); + } + /* @var \My\DTO $dto */ + $dto = $request->getAttribute('dto'); + return $dto; + } +} +``` Finally you need to configure special factory for router service. Here is a sample configuration for [Laminas Service Manager](https://docs.laminas.dev/laminas-servicemanager/) (example is in YAML just for readability): ```YAML dependencies: factories: - Mezzio\Router\RouterInterface: Articus\PathHandler\RouteInjection\Factory - -Articus\PathHandler\RouteInjection\Factory: + Mezzio\Router\RouterInterface: Articus\PathHandler\RouteInjectionFactory + Articus\PathHandler\MetadataProviderInterface: Articus\PathHandler\MetadataProvider\Factory\Annotation + # Replace previous line with this one if you want use PHP attributes as metadata source + #Articus\PathHandler\MetadataProviderInterface: Articus\PathHandler\MetadataProvider\Factory\PhpAttribute + Articus\PathHandler\Handler\PluginManager: Articus\PathHandler\Handler\Factory\PluginManager + Articus\PathHandler\Consumer\PluginManager: Articus\PathHandler\Consumer\Factory\PluginManager + Articus\PathHandler\Attribute\PluginManager: Articus\PathHandler\Attribute\Factory\PluginManager + Articus\PathHandler\Producer\PluginManager: Articus\PathHandler\Producer\Factory\PluginManager + +Articus\PathHandler\RouteInjectionFactory: paths: '': # List of your handlers - My\Handler - # Configuration for handler plugin manager - sub-container dedicated for handlers - handlers: - factories: - My\Handler: My\HandlerFactory +# Configuration for handler plugin manager - sub-container dedicated for handlers +Articus\PathHandler\Handler\PluginManager: + factories: + My\Handler: My\HandlerFactory ``` For more details check [documentation](http://pathhandler.readthedocs.io/en/latest/). diff --git a/composer.json b/composer.json index 2f9ebc1..c56af75 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "psr/simple-cache": "^1.0", "laminas/laminas-stdlib": "^3.2", "nikic/fast-route": "^1.3", - "articus/data-transfer": "^0.4", + "articus/data-transfer": "^0.5", "ext-json": "*", "ext-uopz": "*", "phpspec/phpspec": "^5.1|^6.1|^7.0", diff --git a/composer.lock b/composer.lock index bac90ae..5fedc7e 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": "2cebe35d428c4961b2fb7e119ef51bc5", + "content-hash": "9f3ed4046ac059711fdc7026027ae3aa", "packages": [ { "name": "container-interop/container-interop", @@ -332,16 +332,16 @@ }, { "name": "laminas/laminas-servicemanager", - "version": "3.6.3", + "version": "3.6.4", "source": { "type": "git", "url": "https://github.com/laminas/laminas-servicemanager.git", - "reference": "04a0118731d9f3ee865c7ceb5342551491adebc1" + "reference": "b1445e1a7077c21b0fad0974a1b7a11b9dbe0828" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/04a0118731d9f3ee865c7ceb5342551491adebc1", - "reference": "04a0118731d9f3ee865c7ceb5342551491adebc1", + "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/b1445e1a7077c21b0fad0974a1b7a11b9dbe0828", + "reference": "b1445e1a7077c21b0fad0974a1b7a11b9dbe0828", "shasum": "" }, "require": { @@ -415,7 +415,7 @@ "type": "community_bridge" } ], - "time": "2021-01-25T00:14:52+00:00" + "time": "2021-02-03T08:44:41+00:00" }, { "name": "laminas/laminas-stdlib", @@ -561,24 +561,26 @@ }, { "name": "laminas/laminas-zendframework-bridge", - "version": "1.1.1", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-zendframework-bridge.git", - "reference": "6ede70583e101030bcace4dcddd648f760ddf642" + "reference": "6cccbddfcfc742eb02158d6137ca5687d92cee32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642", - "reference": "6ede70583e101030bcace4dcddd648f760ddf642", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6cccbddfcfc742eb02158d6137ca5687d92cee32", + "reference": "6cccbddfcfc742eb02158d6137ca5687d92cee32", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0 || ^8.0" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", - "squizlabs/php_codesniffer": "^3.5" + "psalm/plugin-phpunit": "^0.15.1", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.6" }, "type": "library", "extra": { @@ -617,7 +619,7 @@ "type": "community_bridge" } ], - "time": "2020-09-14T14:23:00+00:00" + "time": "2021-02-25T21:54:58+00:00" }, { "name": "mezzio/mezzio", @@ -874,27 +876,22 @@ }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -907,7 +904,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -921,9 +918,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/master" + "source": "https://github.com/php-fig/container/tree/1.1.1" }, - "time": "2017-02-14T16:28:37+00:00" + "time": "2021-03-05T17:36:06+00:00" }, { "name": "psr/http-factory", @@ -1151,16 +1148,16 @@ "packages-dev": [ { "name": "articus/data-transfer", - "version": "0.4.1", + "version": "0.5", "source": { "type": "git", "url": "https://github.com/Articus/DataTransfer.git", - "reference": "66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a" + "reference": "0f9618ee9407c1df49cd26b552a62485e31d073e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Articus/DataTransfer/zipball/66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a", - "reference": "66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a", + "url": "https://api.github.com/repos/Articus/DataTransfer/zipball/0f9618ee9407c1df49cd26b552a62485e31d073e", + "reference": "0f9618ee9407c1df49cd26b552a62485e31d073e", "shasum": "" }, "require": { @@ -1212,22 +1209,22 @@ ], "support": { "issues": "https://github.com/Articus/DataTransfer/issues", - "source": "https://github.com/Articus/DataTransfer/tree/0.4.1" + "source": "https://github.com/Articus/DataTransfer/tree/0.5" }, - "time": "2021-01-10T17:45:00+00:00" + "time": "2021-03-21T19:49:06+00:00" }, { "name": "doctrine/annotations", - "version": "1.11.1", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad" + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/ce77a7ba1770462cd705a91a151b6c3746f9c6ad", - "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/b17c5014ef81d212ac539f07a1001832df1b6d3b", + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b", "shasum": "" }, "require": { @@ -1242,11 +1239,6 @@ "phpunit/phpunit": "^7.5 || ^9.1.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" @@ -1287,9 +1279,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.11.1" + "source": "https://github.com/doctrine/annotations/tree/1.12.1" }, - "time": "2020-10-26T10:28:16+00:00" + "time": "2021-02-21T21:00:45+00:00" }, { "name": "doctrine/instantiator", @@ -1442,16 +1434,16 @@ }, { "name": "friends-of-phpspec/phpspec-code-coverage", - "version": "v6.0.0", + "version": "v6.1.0", "source": { "type": "git", "url": "https://github.com/friends-of-phpspec/phpspec-code-coverage.git", - "reference": "d1957ce0f380c2f8b5b19b7ed7cd6e0a1b15f91e" + "reference": "cb6177eb8ce45cdde990ff3e6db3b44fbbb17364" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/friends-of-phpspec/phpspec-code-coverage/zipball/d1957ce0f380c2f8b5b19b7ed7cd6e0a1b15f91e", - "reference": "d1957ce0f380c2f8b5b19b7ed7cd6e0a1b15f91e", + "url": "https://api.github.com/repos/friends-of-phpspec/phpspec-code-coverage/zipball/cb6177eb8ce45cdde990ff3e6db3b44fbbb17364", + "reference": "cb6177eb8ce45cdde990ff3e6db3b44fbbb17364", "shasum": "" }, "require": { @@ -1463,7 +1455,8 @@ "sebastian/comparator": "< 2.0" }, "require-dev": { - "drupol/php-conventions": "^1.7.1 || ^1.8.16" + "drupol/php-conventions": "^3.0", + "vimeo/psalm": "^4.7" }, "suggest": { "ext-pcov": "Install PCov extension to generate code coverage.", @@ -1508,7 +1501,7 @@ }, { "name": "Jay Linski", - "homepage": "https://twitter.com/jay_linski" + "homepage": "https://github.com/jaylinski" } ], "description": "Generate Code Coverage reports for PhpSpec tests", @@ -1527,7 +1520,7 @@ "issues": "https://github.com/friends-of-phpspec/phpspec-code-coverage/issues", "source": "https://github.com/friends-of-phpspec/phpspec-code-coverage" }, - "time": "2020-11-30T10:53:05+00:00" + "time": "2021-03-30T20:51:42+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -1582,16 +1575,16 @@ }, { "name": "mockery/mockery", - "version": "1.4.2", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "20cab678faed06fac225193be281ea0fddb43b93" + "reference": "d1339f64479af1bee0e82a0413813fe5345a54ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/20cab678faed06fac225193be281ea0fddb43b93", - "reference": "20cab678faed06fac225193be281ea0fddb43b93", + "url": "https://api.github.com/repos/mockery/mockery/zipball/d1339f64479af1bee0e82a0413813fe5345a54ea", + "reference": "d1339f64479af1bee0e82a0413813fe5345a54ea", "shasum": "" }, "require": { @@ -1648,9 +1641,9 @@ ], "support": { "issues": "https://github.com/mockery/mockery/issues", - "source": "https://github.com/mockery/mockery/tree/master" + "source": "https://github.com/mockery/mockery/tree/1.4.3" }, - "time": "2020-08-11T18:10:13+00:00" + "time": "2021-02-24T09:51:49+00:00" }, { "name": "nikic/fast-route", @@ -2047,16 +2040,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.12.2", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "245710e971a030f42e08f4912863805570f23d39" + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", - "reference": "245710e971a030f42e08f4912863805570f23d39", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", "shasum": "" }, "require": { @@ -2108,22 +2101,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.12.2" + "source": "https://github.com/phpspec/prophecy/tree/1.13.0" }, - "time": "2020-12-19T10:15:11+00:00" + "time": "2021-03-17T13:42:18+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.5", + "version": "9.2.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" + "reference": "f6293e1b30a2354e8428e004689671b83871edde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", - "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde", + "reference": "f6293e1b30a2354e8428e004689671b83871edde", "shasum": "" }, "require": { @@ -2179,7 +2172,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6" }, "funding": [ { @@ -2187,7 +2180,7 @@ "type": "github" } ], - "time": "2020-11-28T06:44:49+00:00" + "time": "2021-03-28T07:26:59+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2976,16 +2969,16 @@ }, { "name": "symfony/console", - "version": "v5.2.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d62ec79478b55036f65e2602e282822b8eaaff0a" + "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d62ec79478b55036f65e2602e282822b8eaaff0a", - "reference": "d62ec79478b55036f65e2602e282822b8eaaff0a", + "url": "https://api.github.com/repos/symfony/console/zipball/35f039df40a3b335ebf310f244cb242b3a83ac8d", + "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d", "shasum": "" }, "require": { @@ -3053,7 +3046,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.2.2" + "source": "https://github.com/symfony/console/tree/v5.2.6" }, "funding": [ { @@ -3069,7 +3062,7 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:15:41+00:00" + "time": "2021-03-28T09:42:18+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3140,16 +3133,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v5.2.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "4f9760f8074978ad82e2ce854dff79a71fe45367" + "reference": "d08d6ec121a425897951900ab692b612a61d6240" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4f9760f8074978ad82e2ce854dff79a71fe45367", - "reference": "4f9760f8074978ad82e2ce854dff79a71fe45367", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d08d6ec121a425897951900ab692b612a61d6240", + "reference": "d08d6ec121a425897951900ab692b612a61d6240", "shasum": "" }, "require": { @@ -3205,7 +3198,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.4" }, "funding": [ { @@ -3221,7 +3214,7 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:36:42+00:00" + "time": "2021-02-18T17:12:37+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -3304,16 +3297,16 @@ }, { "name": "symfony/finder", - "version": "v5.2.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "196f45723b5e618bf0e23b97e96d11652696ea9e" + "reference": "0d639a0943822626290d169965804f79400e6a04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/196f45723b5e618bf0e23b97e96d11652696ea9e", - "reference": "196f45723b5e618bf0e23b97e96d11652696ea9e", + "url": "https://api.github.com/repos/symfony/finder/zipball/0d639a0943822626290d169965804f79400e6a04", + "reference": "0d639a0943822626290d169965804f79400e6a04", "shasum": "" }, "require": { @@ -3345,7 +3338,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.2.2" + "source": "https://github.com/symfony/finder/tree/v5.2.4" }, "funding": [ { @@ -3361,11 +3354,11 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:01:46+00:00" + "time": "2021-02-15T18:55:04+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -3424,7 +3417,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" }, "funding": [ { @@ -3444,16 +3437,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "267a9adeb8ecb8071040a740930e077cdfb987af" + "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af", - "reference": "267a9adeb8ecb8071040a740930e077cdfb987af", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170", + "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170", "shasum": "" }, "require": { @@ -3505,7 +3498,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1" }, "funding": [ { @@ -3521,20 +3514,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "6e971c891537eb617a00bb07a43d182a6915faba" + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba", - "reference": "6e971c891537eb617a00bb07a43d182a6915faba", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "" }, "require": { @@ -3589,7 +3582,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" }, "funding": [ { @@ -3605,20 +3598,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T17:09:11+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", - "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "shasum": "" }, "require": { @@ -3669,7 +3662,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" }, "funding": [ { @@ -3685,11 +3678,11 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", @@ -3748,7 +3741,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1" }, "funding": [ { @@ -3768,7 +3761,7 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", @@ -3831,7 +3824,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" }, "funding": [ { @@ -3851,7 +3844,7 @@ }, { "name": "symfony/process", - "version": "v5.2.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -3893,7 +3886,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.2.2" + "source": "https://github.com/symfony/process/tree/v5.2.4" }, "funding": [ { @@ -3992,16 +3985,16 @@ }, { "name": "symfony/string", - "version": "v5.2.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "c95468897f408dd0aca2ff582074423dd0455122" + "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/c95468897f408dd0aca2ff582074423dd0455122", - "reference": "c95468897f408dd0aca2ff582074423dd0455122", + "url": "https://api.github.com/repos/symfony/string/zipball/ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572", + "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572", "shasum": "" }, "require": { @@ -4055,7 +4048,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.2.2" + "source": "https://github.com/symfony/string/tree/v5.2.6" }, "funding": [ { @@ -4071,20 +4064,20 @@ "type": "tidelift" } ], - "time": "2021-01-25T15:14:59+00:00" + "time": "2021-03-17T17:12:15+00:00" }, { "name": "symfony/yaml", - "version": "v5.2.2", + "version": "v5.2.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "6bb8b36c6dea8100268512bf46e858c8eb5c545e" + "reference": "298a08ddda623485208506fcee08817807a251dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/6bb8b36c6dea8100268512bf46e858c8eb5c545e", - "reference": "6bb8b36c6dea8100268512bf46e858c8eb5c545e", + "url": "https://api.github.com/repos/symfony/yaml/zipball/298a08ddda623485208506fcee08817807a251dd", + "reference": "298a08ddda623485208506fcee08817807a251dd", "shasum": "" }, "require": { @@ -4130,7 +4123,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.2.2" + "source": "https://github.com/symfony/yaml/tree/v5.2.5" }, "funding": [ { @@ -4146,7 +4139,7 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:01:46+00:00" + "time": "2021-03-06T07:59:01+00:00" }, { "name": "theseer/tokenizer", @@ -4200,30 +4193,35 @@ }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -4247,9 +4245,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.9.1" + "source": "https://github.com/webmozarts/assert/tree/1.10.0" }, - "time": "2020-07-08T17:02:28+00:00" + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], diff --git a/composer.lock.7.1 b/composer.lock.7.1 index 35f115e..86d2dc0 100644 --- a/composer.lock.7.1 +++ b/composer.lock.7.1 @@ -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": "2cebe35d428c4961b2fb7e119ef51bc5", + "content-hash": "9f3ed4046ac059711fdc7026027ae3aa", "packages": [ { "name": "container-interop/container-interop", @@ -1147,16 +1147,16 @@ "packages-dev": [ { "name": "articus/data-transfer", - "version": "0.4.1", + "version": "0.5", "source": { "type": "git", "url": "https://github.com/Articus/DataTransfer.git", - "reference": "66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a" + "reference": "0f9618ee9407c1df49cd26b552a62485e31d073e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Articus/DataTransfer/zipball/66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a", - "reference": "66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a", + "url": "https://api.github.com/repos/Articus/DataTransfer/zipball/0f9618ee9407c1df49cd26b552a62485e31d073e", + "reference": "0f9618ee9407c1df49cd26b552a62485e31d073e", "shasum": "" }, "require": { @@ -1208,22 +1208,22 @@ ], "support": { "issues": "https://github.com/Articus/DataTransfer/issues", - "source": "https://github.com/Articus/DataTransfer/tree/0.4.1" + "source": "https://github.com/Articus/DataTransfer/tree/0.5" }, - "time": "2021-01-10T17:45:00+00:00" + "time": "2021-03-21T19:49:06+00:00" }, { "name": "doctrine/annotations", - "version": "1.11.1", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad" + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/ce77a7ba1770462cd705a91a151b6c3746f9c6ad", - "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/b17c5014ef81d212ac539f07a1001832df1b6d3b", + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b", "shasum": "" }, "require": { @@ -1238,11 +1238,6 @@ "phpunit/phpunit": "^7.5 || ^9.1.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" @@ -1283,9 +1278,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.11.1" + "source": "https://github.com/doctrine/annotations/tree/1.12.1" }, - "time": "2020-10-26T10:28:16+00:00" + "time": "2021-02-21T21:00:45+00:00" }, { "name": "doctrine/instantiator", @@ -1562,16 +1557,16 @@ }, { "name": "mockery/mockery", - "version": "1.3.3", + "version": "1.3.4", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "60fa2f67f6e4d3634bb4a45ff3171fa52215800d" + "reference": "31467aeb3ca3188158613322d66df81cedd86626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/60fa2f67f6e4d3634bb4a45ff3171fa52215800d", - "reference": "60fa2f67f6e4d3634bb4a45ff3171fa52215800d", + "url": "https://api.github.com/repos/mockery/mockery/zipball/31467aeb3ca3188158613322d66df81cedd86626", + "reference": "31467aeb3ca3188158613322d66df81cedd86626", "shasum": "" }, "require": { @@ -1625,9 +1620,9 @@ ], "support": { "issues": "https://github.com/mockery/mockery/issues", - "source": "https://github.com/mockery/mockery/tree/1.3.3" + "source": "https://github.com/mockery/mockery/tree/1.3.4" }, - "time": "2020-08-11T18:10:21+00:00" + "time": "2021-02-24T09:51:00+00:00" }, { "name": "nikic/fast-route", @@ -2762,16 +2757,16 @@ }, { "name": "symfony/console", - "version": "v4.4.19", + "version": "v4.4.21", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "24026c44fc37099fa145707fecd43672831b837a" + "reference": "1ba4560dbbb9fcf5ae28b61f71f49c678086cf23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/24026c44fc37099fa145707fecd43672831b837a", - "reference": "24026c44fc37099fa145707fecd43672831b837a", + "url": "https://api.github.com/repos/symfony/console/zipball/1ba4560dbbb9fcf5ae28b61f71f49c678086cf23", + "reference": "1ba4560dbbb9fcf5ae28b61f71f49c678086cf23", "shasum": "" }, "require": { @@ -2831,7 +2826,7 @@ "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/console/tree/v4.4.19" + "source": "https://github.com/symfony/console/tree/v4.4.21" }, "funding": [ { @@ -2847,11 +2842,11 @@ "type": "tidelift" } ], - "time": "2021-01-27T09:09:26+00:00" + "time": "2021-03-26T09:23:24+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.19", + "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -2914,7 +2909,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.19" + "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.20" }, "funding": [ { @@ -3013,16 +3008,16 @@ }, { "name": "symfony/finder", - "version": "v4.4.19", + "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "25d79cfccfc12e84e7a63a248c3f0720fdd92db6" + "reference": "2543795ab1570df588b9bbd31e1a2bd7037b94f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/25d79cfccfc12e84e7a63a248c3f0720fdd92db6", - "reference": "25d79cfccfc12e84e7a63a248c3f0720fdd92db6", + "url": "https://api.github.com/repos/symfony/finder/zipball/2543795ab1570df588b9bbd31e1a2bd7037b94f6", + "reference": "2543795ab1570df588b9bbd31e1a2bd7037b94f6", "shasum": "" }, "require": { @@ -3054,7 +3049,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v4.4.19" + "source": "https://github.com/symfony/finder/tree/v4.4.20" }, "funding": [ { @@ -3070,11 +3065,11 @@ "type": "tidelift" } ], - "time": "2021-01-27T09:09:26+00:00" + "time": "2021-02-12T10:48:09+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -3133,7 +3128,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" }, "funding": [ { @@ -3153,16 +3148,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", - "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "shasum": "" }, "require": { @@ -3213,7 +3208,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" }, "funding": [ { @@ -3229,11 +3224,11 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", @@ -3292,7 +3287,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1" }, "funding": [ { @@ -3312,7 +3307,7 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", @@ -3375,7 +3370,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" }, "funding": [ { @@ -3395,7 +3390,7 @@ }, { "name": "symfony/process", - "version": "v4.4.19", + "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -3436,7 +3431,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v4.4.19" + "source": "https://github.com/symfony/process/tree/v4.4.20" }, "funding": [ { @@ -3535,16 +3530,16 @@ }, { "name": "symfony/yaml", - "version": "v4.4.19", + "version": "v4.4.21", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "17ed9f14c1aa05b1a5cf2e2c5ef2d0be28058ef9" + "reference": "3871c720871029f008928244e56cf43497da7e9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/17ed9f14c1aa05b1a5cf2e2c5ef2d0be28058ef9", - "reference": "17ed9f14c1aa05b1a5cf2e2c5ef2d0be28058ef9", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3871c720871029f008928244e56cf43497da7e9d", + "reference": "3871c720871029f008928244e56cf43497da7e9d", "shasum": "" }, "require": { @@ -3586,7 +3581,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v4.4.19" + "source": "https://github.com/symfony/yaml/tree/v4.4.21" }, "funding": [ { @@ -3602,7 +3597,7 @@ "type": "tidelift" } ], - "time": "2021-01-27T09:09:26+00:00" + "time": "2021-03-05T17:58:50+00:00" }, { "name": "theseer/tokenizer", diff --git a/composer.lock.7.2 b/composer.lock.7.2 index 0cb35c4..f2622bb 100644 --- a/composer.lock.7.2 +++ b/composer.lock.7.2 @@ -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": "2cebe35d428c4961b2fb7e119ef51bc5", + "content-hash": "9f3ed4046ac059711fdc7026027ae3aa", "packages": [ { "name": "container-interop/container-interop", @@ -870,27 +870,22 @@ }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -903,7 +898,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -917,9 +912,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/master" + "source": "https://github.com/php-fig/container/tree/1.1.1" }, - "time": "2017-02-14T16:28:37+00:00" + "time": "2021-03-05T17:36:06+00:00" }, { "name": "psr/http-factory", @@ -1147,16 +1142,16 @@ "packages-dev": [ { "name": "articus/data-transfer", - "version": "0.4.1", + "version": "0.5", "source": { "type": "git", "url": "https://github.com/Articus/DataTransfer.git", - "reference": "66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a" + "reference": "0f9618ee9407c1df49cd26b552a62485e31d073e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Articus/DataTransfer/zipball/66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a", - "reference": "66be0cf3d6b2d629c3cfecf83c4bb31e9c539e1a", + "url": "https://api.github.com/repos/Articus/DataTransfer/zipball/0f9618ee9407c1df49cd26b552a62485e31d073e", + "reference": "0f9618ee9407c1df49cd26b552a62485e31d073e", "shasum": "" }, "require": { @@ -1208,22 +1203,22 @@ ], "support": { "issues": "https://github.com/Articus/DataTransfer/issues", - "source": "https://github.com/Articus/DataTransfer/tree/0.4.1" + "source": "https://github.com/Articus/DataTransfer/tree/0.5" }, - "time": "2021-01-10T17:45:00+00:00" + "time": "2021-03-21T19:49:06+00:00" }, { "name": "doctrine/annotations", - "version": "1.11.1", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad" + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/ce77a7ba1770462cd705a91a151b6c3746f9c6ad", - "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/b17c5014ef81d212ac539f07a1001832df1b6d3b", + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b", "shasum": "" }, "require": { @@ -1238,11 +1233,6 @@ "phpunit/phpunit": "^7.5 || ^9.1.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" @@ -1283,9 +1273,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.11.1" + "source": "https://github.com/doctrine/annotations/tree/1.12.1" }, - "time": "2020-10-26T10:28:16+00:00" + "time": "2021-02-21T21:00:45+00:00" }, { "name": "doctrine/instantiator", @@ -1578,16 +1568,16 @@ }, { "name": "mockery/mockery", - "version": "1.3.3", + "version": "1.3.4", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "60fa2f67f6e4d3634bb4a45ff3171fa52215800d" + "reference": "31467aeb3ca3188158613322d66df81cedd86626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/60fa2f67f6e4d3634bb4a45ff3171fa52215800d", - "reference": "60fa2f67f6e4d3634bb4a45ff3171fa52215800d", + "url": "https://api.github.com/repos/mockery/mockery/zipball/31467aeb3ca3188158613322d66df81cedd86626", + "reference": "31467aeb3ca3188158613322d66df81cedd86626", "shasum": "" }, "require": { @@ -1641,9 +1631,9 @@ ], "support": { "issues": "https://github.com/mockery/mockery/issues", - "source": "https://github.com/mockery/mockery/tree/1.3.3" + "source": "https://github.com/mockery/mockery/tree/1.3.4" }, - "time": "2020-08-11T18:10:21+00:00" + "time": "2021-02-24T09:51:00+00:00" }, { "name": "nikic/fast-route", @@ -1984,16 +1974,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.12.2", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "245710e971a030f42e08f4912863805570f23d39" + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", - "reference": "245710e971a030f42e08f4912863805570f23d39", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", "shasum": "" }, "require": { @@ -2045,9 +2035,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.12.2" + "source": "https://github.com/phpspec/prophecy/tree/1.13.0" }, - "time": "2020-12-19T10:15:11+00:00" + "time": "2021-03-17T13:42:18+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2835,16 +2825,16 @@ }, { "name": "symfony/console", - "version": "v5.2.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d62ec79478b55036f65e2602e282822b8eaaff0a" + "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d62ec79478b55036f65e2602e282822b8eaaff0a", - "reference": "d62ec79478b55036f65e2602e282822b8eaaff0a", + "url": "https://api.github.com/repos/symfony/console/zipball/35f039df40a3b335ebf310f244cb242b3a83ac8d", + "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d", "shasum": "" }, "require": { @@ -2912,7 +2902,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.2.2" + "source": "https://github.com/symfony/console/tree/v5.2.6" }, "funding": [ { @@ -2928,7 +2918,7 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:15:41+00:00" + "time": "2021-03-28T09:42:18+00:00" }, { "name": "symfony/deprecation-contracts", @@ -2999,16 +2989,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v5.2.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "4f9760f8074978ad82e2ce854dff79a71fe45367" + "reference": "d08d6ec121a425897951900ab692b612a61d6240" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4f9760f8074978ad82e2ce854dff79a71fe45367", - "reference": "4f9760f8074978ad82e2ce854dff79a71fe45367", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d08d6ec121a425897951900ab692b612a61d6240", + "reference": "d08d6ec121a425897951900ab692b612a61d6240", "shasum": "" }, "require": { @@ -3064,7 +3054,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.4" }, "funding": [ { @@ -3080,7 +3070,7 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:36:42+00:00" + "time": "2021-02-18T17:12:37+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -3163,16 +3153,16 @@ }, { "name": "symfony/finder", - "version": "v5.2.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "196f45723b5e618bf0e23b97e96d11652696ea9e" + "reference": "0d639a0943822626290d169965804f79400e6a04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/196f45723b5e618bf0e23b97e96d11652696ea9e", - "reference": "196f45723b5e618bf0e23b97e96d11652696ea9e", + "url": "https://api.github.com/repos/symfony/finder/zipball/0d639a0943822626290d169965804f79400e6a04", + "reference": "0d639a0943822626290d169965804f79400e6a04", "shasum": "" }, "require": { @@ -3204,7 +3194,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.2.2" + "source": "https://github.com/symfony/finder/tree/v5.2.4" }, "funding": [ { @@ -3220,11 +3210,11 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:01:46+00:00" + "time": "2021-02-15T18:55:04+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -3283,7 +3273,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" }, "funding": [ { @@ -3303,16 +3293,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "267a9adeb8ecb8071040a740930e077cdfb987af" + "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af", - "reference": "267a9adeb8ecb8071040a740930e077cdfb987af", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170", + "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170", "shasum": "" }, "require": { @@ -3364,7 +3354,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1" }, "funding": [ { @@ -3380,20 +3370,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "6e971c891537eb617a00bb07a43d182a6915faba" + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba", - "reference": "6e971c891537eb617a00bb07a43d182a6915faba", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "" }, "require": { @@ -3448,7 +3438,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" }, "funding": [ { @@ -3464,20 +3454,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T17:09:11+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", - "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "shasum": "" }, "require": { @@ -3528,7 +3518,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" }, "funding": [ { @@ -3544,11 +3534,11 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", @@ -3607,7 +3597,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1" }, "funding": [ { @@ -3627,7 +3617,7 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.22.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", @@ -3690,7 +3680,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" }, "funding": [ { @@ -3710,7 +3700,7 @@ }, { "name": "symfony/process", - "version": "v5.2.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -3752,7 +3742,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.2.2" + "source": "https://github.com/symfony/process/tree/v5.2.4" }, "funding": [ { @@ -3851,16 +3841,16 @@ }, { "name": "symfony/string", - "version": "v5.2.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "c95468897f408dd0aca2ff582074423dd0455122" + "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/c95468897f408dd0aca2ff582074423dd0455122", - "reference": "c95468897f408dd0aca2ff582074423dd0455122", + "url": "https://api.github.com/repos/symfony/string/zipball/ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572", + "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572", "shasum": "" }, "require": { @@ -3914,7 +3904,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.2.2" + "source": "https://github.com/symfony/string/tree/v5.2.6" }, "funding": [ { @@ -3930,20 +3920,20 @@ "type": "tidelift" } ], - "time": "2021-01-25T15:14:59+00:00" + "time": "2021-03-17T17:12:15+00:00" }, { "name": "symfony/yaml", - "version": "v5.2.2", + "version": "v5.2.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "6bb8b36c6dea8100268512bf46e858c8eb5c545e" + "reference": "298a08ddda623485208506fcee08817807a251dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/6bb8b36c6dea8100268512bf46e858c8eb5c545e", - "reference": "6bb8b36c6dea8100268512bf46e858c8eb5c545e", + "url": "https://api.github.com/repos/symfony/yaml/zipball/298a08ddda623485208506fcee08817807a251dd", + "reference": "298a08ddda623485208506fcee08817807a251dd", "shasum": "" }, "require": { @@ -3989,7 +3979,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.2.2" + "source": "https://github.com/symfony/yaml/tree/v5.2.5" }, "funding": [ { @@ -4005,7 +3995,7 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:01:46+00:00" + "time": "2021-03-06T07:59:01+00:00" }, { "name": "theseer/tokenizer", @@ -4059,30 +4049,35 @@ }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -4106,9 +4101,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.9.1" + "source": "https://github.com/webmozarts/assert/tree/1.10.0" }, - "time": "2020-07-08T17:02:28+00:00" + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], diff --git a/composer.phar b/composer.phar index 9efd41a..90a0eb4 100644 Binary files a/composer.phar and b/composer.phar differ diff --git a/docs/attributing.md b/docs/attributing.md index dafc07a..325f58c 100644 --- a/docs/attributing.md +++ b/docs/attributing.md @@ -20,11 +20,10 @@ class Attribute implements AttributeInterface ... and is registered in configuration: ```YAML -Articus\PathHandler\RouteInjection\Factory: - #Add entry in attribute plugin manager - attributes: - invokables: - MyAttribute: My\Attribute +#Add entry in attribute plugin manager +Articus\PathHandler\Attribute\PluginManager: + invokables: + MyAttribute: My\Attribute ``` To use attribute for operation in your handler you just need to annotate operation method: @@ -46,7 +45,24 @@ class Handler */ public function handlePost(ServerRequestInterface $request) { - $value = $request->getAttribute('some'); + $value = $request->getAttribute('some'); + } +} +``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +class Handler +{ + #[PHA\Post()] + #[PHA\Attribute("MyAttribute")] + public function handlePost(ServerRequestInterface $request) + { + $value = $request->getAttribute('some'); } } ``` @@ -74,6 +90,23 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +class Handler +{ + #[PHA\Post()] + #[PHA\Attribute("MyAttribute", ["key" => "value"])] + public function handlePost(ServerRequestInterface $request) + { + $value = $request->getAttribute('some'); + } +} +``` If all operations in your handler need same attribute you can just annotate handler class insteadof annotating each method: @@ -105,6 +138,28 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +#[PHA\Attribute("MyAttribute")] +class Handler +{ + #[PHA\Post()] + public function handlePost(ServerRequestInterface $request) + { + $value = $request->getAttribute('some'); + } + #[PHA\Patch()] + public function handlePatch(ServerRequestInterface $request) + { + $value = $request->getAttribute('some'); + } +} +``` If you set multiple attributes for operation they will be invoked in the same order they appear in annotations: @@ -131,6 +186,25 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +#[PHA\Attribute("First")] +#[PHA\Attribute("Second")] +class Handler +{ + #[PHA\Post()] + #[PHA\Attribute("Third")] + #[PHA\Attribute("Fourth")] + public function handlePost(ServerRequestInterface $request) + { + } +} +``` Or you can adjust this order with priority setting (default value is 1). Attributes with higher priority will be executed earlier: @@ -155,6 +229,23 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +class Handler +{ + #[PHA\Post()] + #[PHA\Attribute("Second")] + #[PHA\Attribute("First", priority: 10)] + public function handlePost(ServerRequestInterface $request) + { + } +} +``` Library provides just one attribute out of the box - `Transfer` that uses [Data Transfer library](https://github.com/Articus/DataTransfer) to construct DTO and fill it with request data only if this data is valid. @@ -179,7 +270,29 @@ class Handler if (empty($errors)) { /** @var DTO $dto */ - $dto = $this->getAttribute('dto');//Valid DTO filled with data from query params + $dto = $request->getAttribute('dto');//Valid DTO filled with data from query params + } + } +} +``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +class Handler +{ + #[PHA\Post()] + #[PHA\Attribute("Transfer", ["type"=>DTO::class,"subset"=>"part","source"=>"get","objectAttr"=>"dto","errorAttr"=>"errors"])] + public function handlePost(ServerRequestInterface $request) + { + $errors = $request->getAttribute('errors');//This attribute will store validation errors + if (empty($errors)) + { + /** @var DTO $dto */ + $dto = $request->getAttribute('dto');//Valid DTO filled with data from query params } } } diff --git a/docs/consuming.md b/docs/consuming.md index d7022fd..c52c337 100644 --- a/docs/consuming.md +++ b/docs/consuming.md @@ -3,11 +3,10 @@ To consume request body you need a **consumer** - class that implements `Articus\PathHandler\Consumer\ConsumerInterface` and is registered in configuration: ```YAML -Articus\PathHandler\RouteInjection\Factory: - #Add entry in consumer plugin manager - consumers: - invokables: - MyConsumer: My\Consumer +#Add entry in consumer plugin manager +Articus\PathHandler\Consumer\Factory\PluginManager: + invokables: + MyConsumer: My\Consumer ``` Library provides two consumers out of the box: @@ -38,6 +37,23 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +class Handler +{ + #[PHA\Post()] + #[PHA\Consumer("*/*", "Json")] + public function handlePost(ServerRequestInterface $request) + { + $data = $request->getParsedBody(); + } +} +``` Each operation method can have several consumers. Just specify media range to determine when each of them should be called according request content type: @@ -63,6 +79,24 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +class Handler +{ + #[PHA\Post()] + #[PHA\Consumer("application/json", "Json")] + #[PHA\Consumer("multipart/form-data", "Internal")] + public function handlePost(ServerRequestInterface $request) + { + $data = $request->getParsedBody(); + } +} +``` It is recommended to always specify `mediaRange` to enforce anyone calling your API to supply a valid content type. If all operations in your handler need same consumer you can just annotate handler class insteadof annotating each method: @@ -94,3 +128,25 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +#[PHA\Consumer("application/json", "Json")] +class Handler +{ + #[PHA\Post()] + public function handlePost(ServerRequestInterface $request) + { + $data = $request->getParsedBody(); + } + #[PHA\Patch()] + public function handlePatch(ServerRequestInterface $request) + { + $data = $request->getParsedBody(); + } +} +``` diff --git a/docs/index.md b/docs/index.md index 966ed9e..eeda723 100644 --- a/docs/index.md +++ b/docs/index.md @@ -58,23 +58,59 @@ class Handler } } ``` +...or special PHP attributes: +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Articus\PathHandler\Exception; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route('/entity')] //This is how you set path for handler operations +class Handler +{ + #[PHA\Post()] //This is how you declare HTTP method of the operation + #[PHA\Consumer('application/json', 'Json')] //This is how you consume request body + #[PHA\Attribute('Transfer', ['type'=>'My\DTO','objectAttr'=>'dto','errorAttr'=>'errors'])] //This is how you attribute request + #[PHA\Producer('application/json', 'Json')] //This is how you produce response body from returned value + public function handlePost(ServerRequestInterface $request): \My\DTO + { + $errors = $request->getAttribute('errors'); + if (!empty($errors)) + { + //This is how you can return non-200 responses + throw new Exception\UnprocessableEntity($errors); + } + /* @var \My\DTO $dto */ + $dto = $request->getAttribute('dto'); + return $dto; + } +} +``` Finally you need to configure special factory for router service. Here is a sample configuration for [Laminas Service Manager](https://docs.laminas.dev/laminas-servicemanager/) (example is in YAML just for readability): ```YAML dependencies: factories: - Mezzio\Router\RouterInterface: Articus\PathHandler\RouteInjection\Factory - -Articus\PathHandler\RouteInjection\Factory: + Mezzio\Router\RouterInterface: Articus\PathHandler\RouteInjectionFactory + Articus\PathHandler\MetadataProviderInterface: Articus\PathHandler\MetadataProvider\Factory\Annotation + # Replace previous line with this one if you want use PHP attributes as metadata source + #Articus\PathHandler\MetadataProviderInterface: Articus\PathHandler\MetadataProvider\Factory\PhpAttribute + Articus\PathHandler\Handler\PluginManager: Articus\PathHandler\Handler\Factory\PluginManager + Articus\PathHandler\Consumer\PluginManager: Articus\PathHandler\Consumer\Factory\PluginManager + Articus\PathHandler\Attribute\PluginManager: Articus\PathHandler\Attribute\Factory\PluginManager + Articus\PathHandler\Producer\PluginManager: Articus\PathHandler\Producer\Factory\PluginManager + +Articus\PathHandler\RouteInjectionFactory: paths: '': # List of your handlers - My\Handler - # Configuration for handler plugin manager - sub-container dedicated for handlers - handlers: - factories: - My\Handler: My\HandlerFactory +# Configuration for handler plugin manager - sub-container dedicated for handlers +Articus\PathHandler\Handler\PluginManager: + factories: + My\Handler: My\HandlerFactory ``` ## Production configuration @@ -82,16 +118,20 @@ Articus\PathHandler\RouteInjection\Factory: In production environment you may want to activate persistent handler metadata cache via configuration: ```YAML -Articus\PathHandler\RouteInjection\Factory: - metadata: - cache: - directory: data/cache +# Activate simple file cache either for annotation-based metadata provider +Articus\PathHandler\MetadataProvider\Annotation: + cache: + directory: data/cache +# or for attribute-based metadata provider +Articus\PathHandler\MetadataProvider\PhpAttribute: + cache: + directory: data/cache ``` If you use default router you may also want to activate persistent routing table cache: ```YAML -Articus\PathHandler\RouteInjection\Factory: +Articus\PathHandler\RouteInjectionFactory: router: cache: directory: data/cache diff --git a/docs/producing.md b/docs/producing.md index 8d03a7e..522bae8 100644 --- a/docs/producing.md +++ b/docs/producing.md @@ -3,11 +3,10 @@ To produce response body you need a **producer** - class that implements `Articus\PathHandler\Producer\ProducerInterface` and is registered in configuration: ```YAML -Articus\PathHandler\RouteInjection\Factory: - #Add entry in producer plugin manager - producers: - invokables: - MyProducer: My\Producer +#Add entry in producer plugin manager +Articus\PathHandler\Producer\PluginManager: + invokables: + MyProducer: My\Producer ``` Library provides three producers out of the box: @@ -39,6 +38,23 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +class Handler +{ + #[PHA\Get()] + #[PHA\Producer("application/json", "Json")] + public function handleGet(ServerRequestInterface $request): array + { + return ['some' => 'thing']; + } +} +``` Setting `mediaType` is used for both matching against request `Accept` header and as a value for response `Content-Type` header. Specify several producers if you want to allow client to choose how content will be encoded: @@ -65,6 +81,24 @@ class Handler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +class Handler +{ + #[PHA\Get()] + #[PHA\Producer("application/json", "Json")] + #[PHA\Producer("text/html", "Template")] + public function handleGet(ServerRequestInterface $request): array + { + return ['success', ['some' => 'thing']]; + } +} +``` If all operations in your handler need same producer you can just annotate handler class insteadof annotating each method: @@ -95,4 +129,26 @@ class Handler return ['some' => 'thing']; } } +``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity")] +#[PHA\Producer("application/json", "Json")] +class Handler +{ + #[PHA\Post()] + public function handlePost(ServerRequestInterface $request): array + { + return ['some' => 'thing']; + } + #[PHA\Patch()] + public function handlePatch(ServerRequestInterface $request): array + { + return ['some' => 'thing']; + } +} ``` \ No newline at end of file diff --git a/docs/routing.md b/docs/routing.md index 13e1fa4..3fb5789 100644 --- a/docs/routing.md +++ b/docs/routing.md @@ -7,7 +7,7 @@ PathHandler provides several neat improvements for [standard Mezzio routing regi You can easily add common path prefix for a group of handlers via router factory configuration: ```YAML -Articus\PathHandler\RouteInjection\Factory: +Articus\PathHandler\RouteInjectionFactory: paths: '': # List of handlers that should not be prefixed @@ -29,7 +29,6 @@ Each handler should have at least one path declaration. Each path declaration ma namespace My; use Articus\PathHandler\Annotation as PHA; -use Articus\PathHandler\Exception; /** * @PHA\Route(pattern="/some/path") @@ -41,16 +40,29 @@ class Handler //... } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; + +#[PHA\Route("/some/path")] +#[PHA\Route("/another/path", name: "another_path_name")] +#[PHA\Route("/another/path", ["some_param" => 123, "another_param" => "another param value"])] +class Handler +{ +//... +} +``` Path pattern syntax depends on router you choose. Default one is `Articus\PathHandler\Router\FastRoute` based on [FastRoute](https://packagist.org/packages/nikic/fast-route). You can switch to your favourite router implementation via router factory configuration: ```YAML dependencies: factories: - Mezzio\Router\RouterInterface: Articus\PathHandler\RouteInjection\Factory + Mezzio\Router\RouterInterface: Articus\PathHandler\RouteInjectionFactory my_router: My\RouterFactory -Articus\PathHandler\RouteInjection\Factory: +Articus\PathHandler\RouteInjectionFactory: router: my_router ``` @@ -62,7 +74,6 @@ Each handler should have at least one class method with HTTP method declaration. namespace My; use Articus\PathHandler\Annotation as PHA; -use Articus\PathHandler\Exception; use Psr\Http\Message\ServerRequestInterface; /** @@ -103,3 +114,37 @@ class DeleteHandler } } ``` +```PHP +namespace My; + +use Articus\PathHandler\PhpAttribute as PHA; +use Psr\Http\Message\ServerRequestInterface; + +#[PHA\Route("/entity/{id}")] +class Handler +{ + #[PHA\HttpMethod("HEAD")] + #[PHA\Get()] + public function read(ServerRequestInterface $request) + { + //... + } + + #[PHA\Put()] + #[PHA\Patch()] + public function update(ServerRequestInterface $request) + { + //... + } +} + +#[PHA\Route("/entity/{id}")] +class DeleteHandler +{ + #[PHA\Delete()] + public function delete(ServerRequestInterface $request) + { + //... + } +} +``` diff --git a/spec/Articus/PathHandler/MetadataProvider/AnnotationSpec.php b/spec/Articus/PathHandler/MetadataProvider/AnnotationSpec.php index b983c05..1714ec1 100644 --- a/spec/Articus/PathHandler/MetadataProvider/AnnotationSpec.php +++ b/spec/Articus/PathHandler/MetadataProvider/AnnotationSpec.php @@ -46,7 +46,7 @@ public function it_returns_http_methods_for_handler_and_saves_them_to_cache_on_d $handlerName = 'test'; $handlerClassName = Example\Handler\ValidHttpMethods::class; $handler = new Example\Handler\ValidHttpMethods(); - $httpMethods = ['GET', 'HEAD', 'POST', 'PATCH', 'PUT', 'DELETE']; + $httpMethods = ['GET', 'HEAD', 'POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS', 'CUSTOM_METHOD']; $cacheChecker = function (array $cacheData) use ($handlerClassName, $httpMethods) { return ((!empty($cacheData[2][$handlerClassName])) diff --git a/spec/Articus/PathHandler/MetadataProvider/PhpAttributeSpec.php b/spec/Articus/PathHandler/MetadataProvider/PhpAttributeSpec.php index 57d40a3..0d9ab23 100644 --- a/spec/Articus/PathHandler/MetadataProvider/PhpAttributeSpec.php +++ b/spec/Articus/PathHandler/MetadataProvider/PhpAttributeSpec.php @@ -55,7 +55,7 @@ public function it_returns_http_methods_for_handler_and_saves_them_to_cache_on_d $handlerName = 'test'; $handlerClassName = Example\Handler\ValidHttpMethods::class; $handler = new Example\Handler\ValidHttpMethods(); - $httpMethods = ['GET', 'HEAD', 'POST', 'PATCH', 'PUT', 'DELETE']; + $httpMethods = ['GET', 'HEAD', 'POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS', 'CUSTOM_METHOD']; $cacheChecker = function (array $cacheData) use ($handlerClassName, $httpMethods) { return ((!empty($cacheData[2][$handlerClassName])) diff --git a/spec/Example/Handler/ValidHttpMethods.php b/spec/Example/Handler/ValidHttpMethods.php index 54f6cb5..226bfba 100644 --- a/spec/Example/Handler/ValidHttpMethods.php +++ b/spec/Example/Handler/ValidHttpMethods.php @@ -45,6 +45,15 @@ public function delete(Request $request) { } + /** + * @PHA\HttpMethod("OPTIONS") + * @PHA\HttpMethod("CUSTOM_METHOD") + * @param Request $request + */ + public function monitor(Request $request) + { + } + public function publicMethod() { } diff --git a/spec/ExampleForPhp8/Handler/ValidHttpMethods.php b/spec/ExampleForPhp8/Handler/ValidHttpMethods.php index 657d87b..34bde6b 100644 --- a/spec/ExampleForPhp8/Handler/ValidHttpMethods.php +++ b/spec/ExampleForPhp8/Handler/ValidHttpMethods.php @@ -31,6 +31,12 @@ public function delete(Request $request) { } + #[PHA\HttpMethod("OPTIONS")] + #[PHA\HttpMethod("CUSTOM_METHOD")] + public function monitor(Request $request) + { + } + public function publicMethod() { } diff --git a/src/Articus/PathHandler/PhpAttribute/HttpMethod.php b/src/Articus/PathHandler/PhpAttribute/HttpMethod.php index 8dae3e0..dcb5191 100644 --- a/src/Articus/PathHandler/PhpAttribute/HttpMethod.php +++ b/src/Articus/PathHandler/PhpAttribute/HttpMethod.php @@ -6,7 +6,7 @@ /** * PHP attribute to declare that marked handler class method should be used to handle requests with specified HTTP method */ -#[\Attribute(\Attribute::TARGET_METHOD)] +#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class HttpMethod { public function __construct(