-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Operative bridge to allow execute any psr-15 middleware transparently in laravel
- Loading branch information
Showing
15 changed files
with
629 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/vendor/ | ||
composer.lock | ||
.php_cs.cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
$finder = PhpCsFixer\Finder::create() | ||
->in(__DIR__.'/src') | ||
->in(__DIR__.'/tests') | ||
; | ||
return PhpCsFixer\Config::create() | ||
->setRules([ | ||
'@PSR2' => true, | ||
'array_syntax' => ['syntax' => 'short'], | ||
'concat_space' => ['spacing' => 'one'], | ||
'new_with_braces' => true, | ||
'no_blank_lines_after_phpdoc' => true, | ||
'no_empty_phpdoc' => true, | ||
'no_empty_comment' => true, | ||
'no_leading_import_slash' => true, | ||
'no_trailing_comma_in_singleline_array' => true, | ||
'no_unused_imports' => true, | ||
'ordered_imports' => ['importsOrder' => null, 'sortAlgorithm' => 'alpha'], | ||
'phpdoc_add_missing_param_annotation' => ['only_untyped' => true], | ||
'phpdoc_align' => true, | ||
'phpdoc_no_empty_return' => true, | ||
'phpdoc_order' => true, | ||
'phpdoc_scalar' => true, | ||
'phpdoc_separation' => true, | ||
'phpdoc_to_comment' => true, | ||
'phpdoc_types' => true, | ||
'psr0' => false, | ||
'psr4' => true, | ||
'return_type_declaration' => ['space_before' => 'none'], | ||
'single_blank_line_before_namespace' => true, | ||
'single_quote' => true, | ||
'space_after_semicolon' => true, | ||
'ternary_operator_spaces' => true, | ||
'trailing_comma_in_multiline_array' => true, | ||
'trim_array_spaces' => true, | ||
'whitespace_after_comma_in_array' => true, | ||
]) | ||
->setFinder($finder) | ||
; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
filter: | ||
paths: [src/*] | ||
excluded_paths: [tests/*] | ||
checks: | ||
php: | ||
code_rating: true | ||
tools: | ||
external_code_coverage: | ||
timeout: 600 | ||
runs: 2 | ||
php_code_coverage: false | ||
php_loc: | ||
enabled: true | ||
excluded_dirs: [tests, vendor] | ||
php_cpd: | ||
enabled: true | ||
excluded_dirs: [tests, vendor] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
language: php | ||
|
||
sudo: false | ||
|
||
matrix: | ||
include: | ||
- php: 7.1 | ||
env: COLLECT_COVERAGE=true VALIDATE_CODING_STYLE=true | ||
- php: 7.2 | ||
env: COLLECT_COVERAGE=true VALIDATE_CODING_STYLE=true | ||
- php: master | ||
env: COLLECT_COVERAGE=true VALIDATE_CODING_STYLE=false | ||
allow_failures: | ||
- php: master | ||
fast_finish: true | ||
|
||
cache: | ||
directories: | ||
- $HOME/.composer/cache | ||
|
||
before_install: | ||
- travis_retry composer self-update | ||
|
||
install: | ||
- travis_retry composer update --no-interaction --prefer-source | ||
|
||
script: | ||
- composer phpunit | ||
|
||
after_script: | ||
- if [ "$COLLECT_COVERAGE" == "true" ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover build/clover.xml; fi | ||
- if [ "$VALIDATE_CODING_STYLE" == "true" ]; then composer phpcs; fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
Laravel PSR-15 Middleware Bridge | ||
===== | ||
|
||
[](https://github.com/softonic/laravel-psr15-bridge/releases) | ||
[](LICENSE.md) | ||
[](https://travis-ci.org/softonic/laravel-psr15-bridge) | ||
[](https://scrutinizer-ci.com/g/softonic/laravel-psr15-bridge/code-structure) | ||
[](https://scrutinizer-ci.com/g/softonic/laravel-psr15-bridge) | ||
[](https://packagist.org/packages/softonic/laravel-psr15-bridge) | ||
|
||
This package provides a Laravel middleware bridge for [PSR-15](https://www.php-fig.org/psr/psr-15/) inspired in [jshannon63/laravel-psr15-middleware](https://github.com/jshannon63/laravel-psr15-middleware). | ||
|
||
Installation | ||
------- | ||
|
||
To install, use composer: | ||
|
||
``` | ||
composer require softonic/laravel-psr15-bridge | ||
``` | ||
|
||
You are ready to use it! | ||
|
||
Usage | ||
------- | ||
|
||
The bridge adapter receive a PSR-15 middleware via injection, so the bridge is transparent for Laravel and you can use | ||
it as any other middleware. | ||
|
||
|
||
Example based on [OpenApi Validation Middleware](https://github.com/hkarlstrom/openapi-validation-middleware): | ||
|
||
Wrapping [OpenApi Validation Middleware](https://github.com/hkarlstrom/openapi-validation-middleware) within the bridge. | ||
```php | ||
// app/Providers/AppServiceProvider.php | ||
|
||
use HKarlstrom\Middleware\OpenApiValidation | ||
|
||
/** | ||
* Register any application services. | ||
* | ||
* @return void | ||
*/ | ||
public function register() | ||
{ | ||
$this->app->bind(OpenApiValidation::class, function () { | ||
$validator = new \HKarlstrom\Middleware\OpenApiValidation('schema.json'); | ||
|
||
return Psr15MiddlewareAdapter::adapt($validator); | ||
} | ||
} | ||
``` | ||
|
||
Now you can use it anywhere or for example generate an alias. | ||
|
||
```php | ||
// app/Http/Kernel.php | ||
|
||
protected $routeMiddleware = [ | ||
... | ||
'openapi-validation' => OpenApiValidation::class, | ||
]; | ||
``` | ||
|
||
Check [laravel middleware](https://laravel.com/docs/5.7/middleware) for more information. | ||
|
||
How it works | ||
------------ | ||
|
||
In the next diagram you can see the request and response flow. | ||
|
||
 | ||
|
||
As you can see, when you execute `Psr15MiddlewareAdapter::adapt($validator);`, you are adding an envelop to the psr-15 | ||
middleware that converts the request and response transparently for the middleware and the laravel itself. | ||
|
||
|
||
Testing | ||
------- | ||
|
||
`softonic/laravel-psr15-bridge` has a [PHPUnit](https://phpunit.de) test suite and a coding style compliance test suite using [PHP CS Fixer](http://cs.sensiolabs.org/). | ||
|
||
To run the tests, run the following command from the project folder. | ||
|
||
``` bash | ||
$ docker-compose run test | ||
``` | ||
|
||
To run interactively using [PsySH](http://psysh.org/): | ||
``` bash | ||
$ docker-compose run psysh | ||
``` | ||
|
||
License | ||
------- | ||
|
||
The Apache 2.0 license. Please see [LICENSE](LICENSE) for more information. | ||
|
||
[PSR-2]: http://www.php-fig.org/psr/psr-2/ | ||
[PSR-4]: http://www.php-fig.org/psr/psr-4/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
* | ||
!.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
version: '3.2' | ||
|
||
services: | ||
test: | ||
volumes: | ||
- ./:/app | ||
image: ricc/composer-prestissimo:latest | ||
command: composer run test | ||
|
||
fixcs: | ||
volumes: | ||
- ./:/app | ||
image: ricc/composer-prestissimo:latest | ||
command: composer run fix-cs | ||
|
||
psysh: | ||
volumes: | ||
- ./:/app | ||
image: ricc/psysh:latest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<phpunit bootstrap="vendor/autoload.php" | ||
backupGlobals="false" | ||
backupStaticAttributes="false" | ||
colors="true" | ||
verbose="true" | ||
convertErrorsToExceptions="true" | ||
convertNoticesToExceptions="true" | ||
convertWarningsToExceptions="true" | ||
processIsolation="false" | ||
stopOnFailure="false"> | ||
|
||
<testsuites> | ||
<testsuite name="Laravel PSR-15 Middleware Bridge"> | ||
<directory>tests</directory> | ||
</testsuite> | ||
</testsuites> | ||
|
||
<filter> | ||
<whitelist> | ||
<directory suffix=".php">src</directory> | ||
</whitelist> | ||
</filter> | ||
|
||
<logging> | ||
<log type="junit" target="build/report.junit.xml"/> | ||
<log type="coverage-html" target="build/coverage" charset="UTF-8" yui="true" highlight="true"/> | ||
<log type="coverage-text" target="build/coverage.txt"/> | ||
<log type="coverage-clover" target="build/clover.xml"/> | ||
</logging> | ||
|
||
</phpunit> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?php | ||
|
||
namespace Softonic\Laravel\Middleware\Psr15Bridge; | ||
|
||
use Closure; | ||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
use Psr\Http\Server\RequestHandlerInterface; | ||
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; | ||
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; | ||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
class NextHandlerAdapter implements RequestHandlerInterface | ||
{ | ||
/** | ||
* @var Request | ||
*/ | ||
private $foundationRequest; | ||
|
||
/** | ||
* @var Closure | ||
*/ | ||
private $next; | ||
|
||
/** | ||
* @var DiactorosFactory | ||
*/ | ||
private $diactorosFactory; | ||
|
||
/** | ||
* @var HttpFoundationFactory | ||
*/ | ||
private $httpFoundationFactory; | ||
|
||
public function __construct( | ||
HttpFoundationFactory $httpFoundationFactory, | ||
DiactorosFactory $diactorosFactory, | ||
Request $foundationRequest, | ||
Closure $next | ||
) { | ||
$this->diactorosFactory = $diactorosFactory; | ||
$this->foundationRequest = $foundationRequest; | ||
$this->next = $next; | ||
$this->httpFoundationFactory = $httpFoundationFactory; | ||
} | ||
|
||
/** | ||
* Intercept communication between the PSR-15 middleware and the next middleware/controller. | ||
* | ||
* To allow the next execution we need to restore the request to a HttpFoundationRequest | ||
* and wait for a response that must be adapter to PSR-7 response to allow the | ||
* PSR-15 middleware process it. | ||
* | ||
* @return ResponseInterface | ||
*/ | ||
public function handle(ServerRequestInterface $psr7Request): ResponseInterface | ||
{ | ||
$request = $this->convertRequest($psr7Request, $this->foundationRequest); | ||
$response = ($this->next)($request); | ||
|
||
return $this->getPsr7Response($response); | ||
} | ||
|
||
private function convertRequest(ServerRequestInterface $psr7Request, $originalRequest): Request | ||
{ | ||
$foundation_request = $this->httpFoundationFactory->createRequest($psr7Request); | ||
|
||
$originalRequest->query = clone $foundation_request->query; | ||
$originalRequest->request = clone $foundation_request->request; | ||
$originalRequest->attributes = clone $foundation_request->attributes; | ||
$originalRequest->cookies = clone $foundation_request->cookies; | ||
$originalRequest->files = clone $foundation_request->files; | ||
$originalRequest->server = clone $foundation_request->server; | ||
$originalRequest->headers = clone $foundation_request->headers; | ||
|
||
return $originalRequest; | ||
} | ||
|
||
/** | ||
* @param $response | ||
* | ||
* @return ResponseInterface|DiactorosFactory|\Zend\Diactoros\Response | ||
*/ | ||
protected function getPsr7Response($response) | ||
{ | ||
return $this->diactorosFactory->createResponse($response); | ||
} | ||
} | ||
|
||
; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
namespace Softonic\Laravel\Middleware\Psr15Bridge; | ||
|
||
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory; | ||
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; | ||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
class NextHandlerFactory | ||
{ | ||
public function getHandler( | ||
HttpFoundationFactory $httpFoundationFactory, | ||
DiactorosFactory $diactorosFactory, | ||
Request $request, | ||
\Closure $next | ||
) { | ||
return new NextHandlerAdapter( | ||
$httpFoundationFactory, | ||
$diactorosFactory, | ||
$request, | ||
$next | ||
); | ||
} | ||
} |
Oops, something went wrong.