Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Jan 29, 2020. It is now read-only.
/zend-mvcPublic archive

Modify middleware listener to use stratigility pipe#217

Merged
Show file tree
Hide file tree
Changes from15 commits
Commits
Show all changes
23 commits
Select commitHold shift + click to select a range
2c64d2e
Merge branch 'hotfix/232'
weierophinneyApr 27, 2017
2712a99
Require stratigility in dev, and suggestion
asgrimFeb 19, 2017
cab17a2
Added tests for handling an array of middleware to be piped
asgrimFeb 19, 2017
24201cb
Added implementation of Stratigility middleware pipe
asgrimFeb 19, 2017
ab63639
Updated RotueMatch#getParams calls to be expected in tests
asgrimFeb 19, 2017
81c5f2e
Extract logic to create middleware pipe into private method
asgrimFeb 25, 2017
6f9c271
Do not allow a null middleware
asgrimFeb 25, 2017
7e89d6a
Remove null coalesce operator because still need to support PHP 5.6
asgrimFeb 25, 2017
cebe041
Added support for HttpInterop style middlewares
asgrimApr 28, 2017
d0debca
Refactored ReachedFinalHandlerException to use named constructor
asgrimApr 28, 2017
6073ca2
Fixed typo in phpdoc for MvcEvent
asgrimApr 28, 2017
b05cd8b
Switch MiddlewareNotCallableExceptionTest assertions to be invoked on…
asgrimApr 28, 2017
7d89900
Fixed incorrectly rebased composer dependencies
asgrimApr 28, 2017
4c393f1
Use namespaced PHPUnit import
asgrimApr 28, 2017
03ffda0
Use expectException instead of deprecated setExpectedException
asgrimApr 28, 2017
4116803
Fixes @return DefaultRenderingStrategy typo at HttpDefaultRenderingSt…
samsonasikApr 29, 2017
4dbdb4b
Use mocks instead of anon classes for middlewares
asgrimApr 30, 2017
2a4a644
Merge pull request #237 from samsonasik/@return-rendering-strategy
weierophinneyMay 1, 2017
7e5c560
Added CHANGELOG for #237
weierophinneyMay 1, 2017
00bdd8c
Merge branch 'hotfix/237' into develop
weierophinneyMay 1, 2017
bf741df
Merge pull request #217 from asgrim/modify-middleware-listener-to-use…
weierophinneyMay 1, 2017
6d09019
Rename MiddlewareNotCallableException to InvalidMiddlewareException
weierophinneyMay 1, 2017
6a4bf9f
Use http-interop process()
weierophinneyMay 1, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletionscomposer.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,7 +27,8 @@
"phpunit/phpunit": "^6.0.7 || ^5.7.14",
"zendframework/zend-coding-standard": "~1.0.0",
"zendframework/zend-json": "^2.6.1 || ^3.0",
"zendframework/zend-psr7bridge": "^0.2"
"zendframework/zend-psr7bridge": "^0.2",
"zendframework/zend-stratigility": "^2.0.1"
},
"suggest": {
"zendframework/zend-json": "(^2.6.1 || ^3.0) To auto-deserialize JSON body content in AbstractRestfulController extensions, when json_decode is unavailable",
Expand All@@ -40,7 +41,8 @@
"zendframework/zend-mvc-plugin-prg": "To provide Post/Redirect/Get functionality within controllers",
"zendframework/zend-paginator": "^2.7 To provide pagination functionality via PaginatorPluginManager",
"zendframework/zend-psr7bridge": "(^0.2) To consume PSR-7 middleware within the MVC workflow",
"zendframework/zend-servicemanager-di": "zend-servicemanager-di provides utilities for integrating zend-di and zend-servicemanager in your zend-mvc application"
"zendframework/zend-servicemanager-di": "zend-servicemanager-di provides utilities for integrating zend-di and zend-servicemanager in your zend-mvc application",
"zendframework/zend-stratigility": "zend-stratigility is required to use middleware pipes in the MiddlewareListener"
},
"config": {
"sort-packages": true
Expand Down
108 changes: 107 additions & 1 deletioncomposer.lock
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

38 changes: 38 additions & 0 deletionssrc/Exception/MiddlewareNotCallableException.php
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespaceZend\Mvc\Exception;

finalclass MiddlewareNotCallableExceptionextends RuntimeException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Since we're allowing either callable or http-interop middleware, perhaps we should change this toInvalidMiddlewareException instead?

asgrim reacted with thumbs up emoji
{
/**
* @var string
*/
private$middlewareName;

/**
* @param string $middlewareName
* @return self
*/
publicstaticfunctionfromMiddlewareName($middlewareName)
{
$middlewareName = (string)$middlewareName;
$instance =newself(sprintf('Cannot dispatch middleware %s',$middlewareName));
$instance->middlewareName =$middlewareName;
return$instance;
}

/**
* @return string
*/
publicfunctiontoMiddlewareName()
{
returnnull !==$this->middlewareName ?$this->middlewareName :'';
}
}
21 changes: 21 additions & 0 deletionssrc/Exception/ReachedFinalHandlerException.php
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Mvc\Exception;

class ReachedFinalHandlerException extends RuntimeException
{
/**
* @return self
*/
public static function create()
{
return new self('Reached the final handler for middleware pipe - check the pipe configuration');
}
}
69 changes: 60 additions & 9 deletionssrc/MiddlewareListener.php
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,12 +9,19 @@

namespace Zend\Mvc;

use Interop\Container\ContainerInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as PsrServerRequestInterface;
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\Exception\MiddlewareNotCallableException;
use Zend\Mvc\Exception\ReachedFinalHandlerException;
use Zend\Psr7Bridge\Psr7ServerRequest as Psr7Request;
use Zend\Psr7Bridge\Psr7Response;
use Zend\Router\RouteMatch;
use Zend\Stratigility\MiddlewarePipe;

class MiddlewareListener extends AbstractListenerAggregate
{
Expand DownExpand Up@@ -47,15 +54,19 @@ public function onDispatch(MvcEvent $event)
$application = $event->getApplication();
$response = $application->getResponse();
$serviceManager = $application->getServiceManager();
$middlewareName = is_string($middleware) ? $middleware : get_class($middleware);

if (is_string($middleware) && $serviceManager->has($middleware)) {
$middleware = $serviceManager->get($middleware);
}
if (! is_callable($middleware)) {
$psr7ResponsePrototype = Psr7Response::fromZend($response);

try {
$pipe = $this->createPipeFromSpec(
$serviceManager,
$psr7ResponsePrototype,
is_array($middleware) ? $middleware : [$middleware]
);
} catch (MiddlewareNotCallableException $middlewareNotCallableException) {
$return = $this->marshalMiddlewareNotCallable(
$application::ERROR_MIDDLEWARE_CANNOT_DISPATCH,
$middlewareName,
$middlewareNotCallableException->toMiddlewareName(),
$event,
$application
);
Expand All@@ -69,7 +80,13 @@ public function onDispatch(MvcEvent $event)
foreach ($routeMatch->getParams() as $key => $value) {
$psr7Request = $psr7Request->withAttribute($key, $value);
}
$return = $middleware($psr7Request, Psr7Response::fromZend($response));
$return = $pipe(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@asgrim So sorry I didn't notice this earlier, but... If we're pinning to Stratigility 2, we should likely use the http-interopprocess() method here instead of__invoke(), which means using aDelegateInterface instead of a callable.

May I suggest the following:

$pipe->setResponsePrototype($psr7ResponsePrototype);$return =$pipe->process($psr7Request,new \Zend\Stratigility\Delegate\CallableDelegateDecorator(function (PsrServerRequestInterface$request,PsrResponseInterface$response) {throw ReachedFinalHandlerException::create();    }));

That would accomplish the same as what you have here, and be forwards compatible.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yes, this seems reasonable, though I note that__invoke does the wrapping in theCallableDelegateDecorator for us, but I have no strong feelings either way. If__invoke is eventually going to go, then yes the switch makes sense!

setResponsePrototype is already called increatePipeFromSpec btw, so I don't think needs calling again (unless I missed something)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Ah, okay, nice.

As noted, usingprocess() will be forwards compatible, meaning that when Stratigility adopts a finalized PSR-15, we likely can just add an|| to the constraint and not need any actual code changes. I figure, do it once. 😄

asgrim reacted with thumbs up emoji
$psr7Request,
$psr7ResponsePrototype,
function (PsrServerRequestInterface $request, PsrResponseInterface $response) {
throw ReachedFinalHandlerException::create();
}
);
} catch (\Throwable $ex) {
$caughtException = $ex;
} catch (\Exception $ex) { // @TODO clean up once PHP 7 requirement is enforced
Expand All@@ -79,8 +96,6 @@ public function onDispatch(MvcEvent $event)
if ($caughtException !== null) {
$event->setName(MvcEvent::EVENT_DISPATCH_ERROR);
$event->setError($application::ERROR_EXCEPTION);
$event->setController($middlewareName);
$event->setControllerClass(get_class($middleware));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Why are these lines removed?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

There is potentially no longer just "one" middleware name... how do we decide which is the failed one? First? Last? IIRC I don't think there's any way (outside of the exception bubble here)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Ah, right - that makes sense, then.

$event->setParam('exception', $caughtException);

$events = $application->getEventManager();
Expand All@@ -100,6 +115,42 @@ public function onDispatch(MvcEvent $event)
return $response;
}

/**
* Create a middleware pipe from the array spec given.
*
* @param ContainerInterface $serviceLocator
* @param ResponseInterface $responsePrototype
* @param array $middlewaresToBePiped
* @return MiddlewarePipe
* @throws \InvalidArgumentException
* @throws \Zend\Mvc\Exception\MiddlewareNotCallableException
*/
private function createPipeFromSpec(
ContainerInterface $serviceLocator,
ResponseInterface $responsePrototype,
array $middlewaresToBePiped
) {
$pipe = new MiddlewarePipe();
$pipe->setResponsePrototype($responsePrototype);
foreach ($middlewaresToBePiped as $middlewareToBePiped) {
if (null === $middlewareToBePiped) {
throw new \InvalidArgumentException('Middleware name cannot be null');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If we rename the exception toInvalidMiddlewareException, we could also add another named constructor:::becauseNull() (obviously, choose something better!).

asgrim reacted with thumbs up emoji
}

$middlewareName = is_string($middlewareToBePiped) ? $middlewareToBePiped : get_class($middlewareToBePiped);

if (is_string($middlewareToBePiped) && $serviceLocator->has($middlewareToBePiped)) {
$middlewareToBePiped = $serviceLocator->get($middlewareToBePiped);
}
if (! $middlewareToBePiped instanceof MiddlewareInterface && ! is_callable($middlewareToBePiped)) {
throw MiddlewareNotCallableException::fromMiddlewareName($middlewareName);
}

$pipe->pipe($middlewareToBePiped);
}
return $pipe;
}

/**
* Marshal a middleware not callable exception event
*
Expand Down
32 changes: 32 additions & 0 deletionstest/Exception/MiddlewareNotCallableExceptionTest.php
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Mvc;

use PHPUnit\Framework\TestCase;
use Zend\Mvc\Exception\MiddlewareNotCallableException;

final class MiddlewareNotCallableExceptionTest extends TestCase
{
public function testFromMiddlewareName()
{
$middlewareName = uniqid('middlewareName', true);
$exception = MiddlewareNotCallableException::fromMiddlewareName($middlewareName);

$this->assertInstanceOf(MiddlewareNotCallableException::class, $exception);
$this->assertSame('Cannot dispatch middleware ' . $middlewareName, $exception->getMessage());
$this->assertSame($middlewareName, $exception->toMiddlewareName());
}

public function testToMiddlewareNameWhenNotSet()
{
$exception = new MiddlewareNotCallableException();
$this->assertSame('', $exception->toMiddlewareName());
}
}
27 changes: 27 additions & 0 deletionstest/Exception/ReachedFinalHandlerExceptionTest.php
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Mvc;

use PHPUnit\Framework\TestCase;
use Zend\Mvc\Exception\ReachedFinalHandlerException;

final class ReachedFinalHandlerExceptionTest extends TestCase
{
public function testFromNothing()
{
$exception = ReachedFinalHandlerException::create();

$this->assertInstanceOf(ReachedFinalHandlerException::class, $exception);
$this->assertSame(
'Reached the final handler for middleware pipe - check the pipe configuration',
$exception->getMessage()
);
}
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp