-
Notifications
You must be signed in to change notification settings - Fork 91
Fix: allow middleware dispatch to behave like controller dispatch #236
Fix: allow middleware dispatch to behave like controller dispatch #236
Conversation
@@ -91,6 +90,8 @@ public function onDispatch(MvcEvent $event) | |||
} | |||
} | |||
|
|||
$event->setError(''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this still means that the DispatchListener
will try to execute and fail. The patch is not yet done. Ideally, the DispatchListener
should check whether there is a $event->getResult()
, and bail out if there already is one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd argue both the DispatchListener
and MiddlewareListener
should act that way, with the following at the top of the listeners:
if (null !== $e->getResult()) {
return;
}
Do you want to incorporate that change in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@weierophinney done for both listeners
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this approach a ton; I think triggering events for dispatched middleware in the same way as for controllers could have a ton of benefits.
A few comments:
- This is technically new functionality (new class), and I think it would be best to do for the 3.1.0 release. As such, you'd need to rebase against develop... which has a number of changes due to me merging Modify middleware listener to use stratigility pipe #217 earlier today. I'd be happy to help with that if you wish.
- The
MiddlewareController
should also allow http-interop middleware; I have detailed comments on that below. - I agree that this and the
DispatchListener
should return early if theMvcEvent
composes a result already, and think that change should be part of this PR (as this PR is the one that demonstrates the need for that change).
@@ -91,6 +90,8 @@ public function onDispatch(MvcEvent $event) | |||
} | |||
} | |||
|
|||
$event->setError(''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd argue both the DispatchListener
and MiddlewareListener
should act that way, with the following at the top of the listeners:
if (null !== $e->getResult()) {
return;
}
Do you want to incorporate that change in this PR?
*/ | ||
private $middleware; | ||
|
||
public function __construct(callable $middleware, EventManager $eventManager, MvcEvent $event) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note: on the develop branch, we're now targeting Stratigility ^2.0.1
, which means we can have:
- callable middleware
- http-interop middleware
If this patch targets master, we would need to remove the typehint for $middleware
, and also update how middleware is invoked based on whether or not it implements Interop\Http\ServerMiddleware\MiddlewareInterface
.
} | ||
} | ||
|
||
$result = \call_user_func($this->middleware, $psr7Request, Psr7Response::fromZend($response)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous note about http-interop.
test/MiddlewareListenerTest.php
Outdated
@@ -76,6 +84,7 @@ public function testSuccessfullyDispatchesMiddleware() | |||
$application = $event->getApplication(); | |||
|
|||
$application->getEventManager()->attach(MvcEvent::EVENT_DISPATCH_ERROR, function ($e) { | |||
die(var_dump($e->getParam('exception')->getMessage())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Um, die()
? Why not just a var_dump()
or capturing that info to a variable to emit with the fail()
below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also gone :-)
…n the given `MvcEvent`
…eware produces, regardless of its shape/type, unless it is a PSR7-response
…t is mocking anything particular at this point
…ware act like a normal controller
…e useless view layer can do its terrible view model magic
…present in the dispatched event
…` already yields a non-null result
…controller wrapper
…e of a middleware is OK This is likely going to land into a separate dispatch listener instead
80200a7
to
98c6d39
Compare
Provided
That's also handled. The
Implemented/tested |
|
||
public function __construct( | ||
MiddlewarePipe $pipe, | ||
ResponseInterface $responsePrototype, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not particularly proud of this, but PSR-7's immutability makes it quite acceptable to pass in a request as a prototype. Still, this class is designed as "fire once" and "internal" specifically due to this weirdness.
…o-behave-like-controller-dispatch Fix: allow middleware dispatch to behave like controller dispatch
This patch makes sure that the successful dispatch of a middleware won't trigger exception and 404 strategies. This can happen when the return value of the
MiddlewareListener
is not aZend\Stdlib\ResponseInterface
instance, and therefore theEventManager
will not short-circuit and stop event propagation.