Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 9935a57

Browse files
committed
Merge branch 'feature/217' into develop
Close #217 Fixes #196
2 parents 00bdd8c + 665dfbe commit 9935a57

10 files changed

+522
-24
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ All notable changes to this project will be documented in this file, in reverse
66

77
### Added
88

9-
- Nothing.
9+
- [#217](https://github.com/zendframework/zend-mvc/pull/217) adds support for
10+
middleware _pipelines_ when using the `MiddlewareListener`. You can now
11+
specify an _array` of middleware for the `middleware` attached to a route, and
12+
it will be marshaled into a `Zend\Stratigility\MiddlewarePipe` instance, using
13+
the same rules as if you specified a single middleware.
1014

1115
### Deprecated
1216

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"phpunit/phpunit": "^6.0.7 || ^5.7.14",
2828
"zendframework/zend-coding-standard": "~1.0.0",
2929
"zendframework/zend-json": "^2.6.1 || ^3.0",
30-
"zendframework/zend-psr7bridge": "^0.2"
30+
"zendframework/zend-psr7bridge": "^0.2",
31+
"zendframework/zend-stratigility": "^2.0.1"
3132
},
3233
"suggest": {
3334
"zendframework/zend-json": "(^2.6.1 || ^3.0) To auto-deserialize JSON body content in AbstractRestfulController extensions, when json_decode is unavailable",
@@ -40,7 +41,8 @@
4041
"zendframework/zend-mvc-plugin-prg": "To provide Post/Redirect/Get functionality within controllers",
4142
"zendframework/zend-paginator": "^2.7 To provide pagination functionality via PaginatorPluginManager",
4243
"zendframework/zend-psr7bridge": "(^0.2) To consume PSR-7 middleware within the MVC workflow",
43-
"zendframework/zend-servicemanager-di": "zend-servicemanager-di provides utilities for integrating zend-di and zend-servicemanager in your zend-mvc application"
44+
"zendframework/zend-servicemanager-di": "zend-servicemanager-di provides utilities for integrating zend-di and zend-servicemanager in your zend-mvc application",
45+
"zendframework/zend-stratigility": "zend-stratigility is required to use middleware pipes in the MiddlewareListener"
4446
},
4547
"config": {
4648
"sort-packages": true

composer.lock

Lines changed: 107 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/book/middleware.md

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ $route = Literal::factory([
5353

5454
Middleware may be provided as PHP callables, or as service names.
5555

56+
**As of 3.1.0** you may also specify an `array` of middleware, and middleware
57+
may be [http-interop/http-middleware](https://github.com/http-interop/http-middleware)
58+
compatible. Each item in the array must be a PHP callable, service name, or
59+
http-middleware instance. These will then be piped into a
60+
`Zend\Stratigility\MiddlewarePipe` instance in the order in which they are
61+
present in the array.
62+
5663
> ### No action required
5764
>
5865
> Unlike action controllers, middleware typically is single purpose, and, as
@@ -69,8 +76,8 @@ create an error response if non-callable middleware is indicated.
6976

7077
## Writing middleware
7178

72-
When dispatching middleware, the `MiddlewareListener` calls it with two
73-
arguments, the PSR-7 request and response, respectively. As such, your
79+
Prior to 3.1.0, when dispatching middleware, the `MiddlewareListener` calls it
80+
with two arguments, the PSR-7 request and response, respectively. As such, your
7481
middleware signature should look like the following:
7582

7683
```php
@@ -88,14 +95,55 @@ class IndexMiddleware
8895
}
8996
```
9097

91-
From there, you can pull information from the composed request, and manipulate
92-
the response.
98+
Starting in 3.1.0, the `MiddlewareListener` always adds middleware to a
99+
`Zend\Stratigility\MiddlewarePipe` instance, and invokes it as
100+
[http-interop/http-middleware](https://github.com/http-interop/http-middleware),
101+
passing it a PSR-7 `ServerRequestInterface` and an http-interop
102+
`DelegateInterface`.
103+
104+
As such, ideally your middleware should implement the `MiddlewareInterface` from
105+
[http-interop/http-middleware](https://github.com/http-interop/http-middleware):
106+
107+
```php
108+
namespace Application\Middleware;
109+
110+
use Interop\Http\ServerMiddleware\DelegateInterface;
111+
use Interop\Http\ServerMiddleware\MiddlewareInterface;
112+
use Psr\Http\Message\ServerRequestInterface;
113+
114+
class IndexMiddleware implements MiddlewareInterface
115+
{
116+
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
117+
{
118+
// do some work
119+
}
120+
}
121+
```
122+
123+
Alternately, you may still write `callable` middleware using the following
124+
signature:
125+
126+
```php
127+
function (ServerREquestInterface $request, ResponseInterface $response, callable $next)
128+
{
129+
// do some work
130+
}
131+
```
132+
133+
In the above case, the `DelegateInterface` is decorated as a callable.
134+
135+
In all versions, within your middleware, you can pull information from the
136+
composed request, and return a response.
93137

94138
> ### Routing parameters
95139
>
96-
> At the time of the 2.7.0 release, route match parameters are not yet injected
97-
> into the PSR-7 `ServerRequest` instance, and are thus not available as request
98-
> attributes..
140+
> At the time of the 2.7.0 release, route match parameters were not yet injected
141+
> into the PSR-7 `ServerRequest` instance, and thus not available as request
142+
> attributes.
143+
>
144+
> With the 3.0 release, they are pushed into the PSR-7 `ServerRequest` as
145+
> attributes, and may thus be fetched using
146+
> `$request->getAttribute($attributeName)`.
99147
100148
## Middleware return values
101149

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace Zend\Mvc\Exception;
11+
12+
final class InvalidMiddlewareException extends RuntimeException
13+
{
14+
/**
15+
* @var string
16+
*/
17+
private $middlewareName;
18+
19+
/**
20+
* @param string $middlewareName
21+
* @return self
22+
*/
23+
public static function fromMiddlewareName($middlewareName)
24+
{
25+
$middlewareName = (string)$middlewareName;
26+
$instance = new self(sprintf('Cannot dispatch middleware %s', $middlewareName));
27+
$instance->middlewareName = $middlewareName;
28+
return $instance;
29+
}
30+
31+
public static function fromNull()
32+
{
33+
$instance = new self('Middleware name cannot be null');
34+
return $instance;
35+
}
36+
37+
/**
38+
* @return string
39+
*/
40+
public function toMiddlewareName()
41+
{
42+
return null !== $this->middlewareName ? $this->middlewareName : '';
43+
}
44+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @link http://github.com/zendframework/zf2 for the canonical source repository
6+
* @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license http://framework.zend.com/license/new-bsd New BSD License
8+
*/
9+
10+
namespace Zend\Mvc\Exception;
11+
12+
class ReachedFinalHandlerException extends RuntimeException
13+
{
14+
/**
15+
* @return self
16+
*/
17+
public static function create()
18+
{
19+
return new self('Reached the final handler for middleware pipe - check the pipe configuration');
20+
}
21+
}

0 commit comments

Comments
 (0)