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

Commit 11fa249

Browse files
committed
Merging develop to master in preparation for 3.1.0 release
2 parents 3a2eb59 + 486ff29 commit 11fa249

File tree

60 files changed

+1184
-1041
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1184
-1041
lines changed

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,37 @@
22

33
All notable changes to this project will be documented in this file, in reverse chronological order by release.
44

5+
## 3.1.0 - TBD
6+
7+
### Added
8+
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.
14+
15+
- [#236](https://github.com/zendframework/zend-mvc/pull/236) adds the ability to
16+
attach dispatch listeners to middleware when using the `MiddlewareListener`.
17+
Attach shared events to the class identifier `Zend\Mvc\Controller\MiddlewareController`.
18+
This feature helps ensure that listeners that should run for every controller
19+
(e.g., authentication or authorization listeners) will run even for
20+
middleware.
21+
22+
### Deprecated
23+
24+
- Nothing.
25+
26+
### Removed
27+
28+
- [#211](https://github.com/zendframework/zend-mvc/pull/211) Removed unused
29+
zend-servicemanager v2 and zend-eventmanager v2 compatibility code since
30+
zend-mvc requires v3 of those components.
31+
32+
### Fixed
33+
34+
- Nothing.
35+
536
## 3.0.5 - TBD
637

738
### Added

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

src/Controller/ControllerManager.php

Lines changed: 10 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use Interop\Container\ContainerInterface;
1313
use Zend\EventManager\EventManagerAwareInterface;
1414
use Zend\EventManager\SharedEventManagerInterface;
15-
use Zend\Mvc\Exception;
1615
use Zend\ServiceManager\AbstractPluginManager;
1716
use Zend\ServiceManager\ConfigInterface;
1817
use Zend\ServiceManager\Exception\InvalidServiceException;
@@ -46,17 +45,17 @@ class ControllerManager extends AbstractPluginManager
4645
* event manager and plugin manager.
4746
*
4847
* @param ConfigInterface|ContainerInterface $container
49-
* @param array $v3config
48+
* @param array $config
5049
*/
51-
public function __construct($configOrContainerInstance, array $v3config = [])
50+
public function __construct($configOrContainerInstance, array $config = [])
5251
{
5352
$this->addInitializer([$this, 'injectEventManager']);
5453
$this->addInitializer([$this, 'injectPluginManager']);
55-
parent::__construct($configOrContainerInstance, $v3config);
54+
parent::__construct($configOrContainerInstance, $config);
5655
}
5756

5857
/**
59-
* Validate a plugin (v3)
58+
* Validate a plugin
6059
*
6160
* {@inheritDoc}
6261
*/
@@ -71,26 +70,6 @@ public function validate($plugin)
7170
}
7271
}
7372

74-
/**
75-
* Validate a plugin (v2)
76-
*
77-
* {@inheritDoc}
78-
*
79-
* @throws Exception\InvalidControllerException
80-
*/
81-
public function validatePlugin($plugin)
82-
{
83-
try {
84-
$this->validate($plugin);
85-
} catch (InvalidServiceException $e) {
86-
throw new Exception\InvalidControllerException(
87-
$e->getMessage(),
88-
$e->getCode(),
89-
$e
90-
);
91-
}
92-
}
93-
9473
/**
9574
* Initializer: inject EventManager instance
9675
*
@@ -101,63 +80,33 @@ public function validatePlugin($plugin)
10180
* the shared EM injection needs to happen; the conditional will always
10281
* pass.
10382
*
104-
* @param ContainerInterface|DispatchableInterface $first Container when
105-
* using zend-servicemanager v3; controller under v2.
106-
* @param DispatchableInterface|ContainerInterface $second Controller when
107-
* using zend-servicemanager v3; container under v2.
83+
* @param ContainerInterface $container
84+
* @param DispatchableInterface $controller
10885
*/
109-
public function injectEventManager($first, $second)
86+
public function injectEventManager(ContainerInterface $container, $controller)
11087
{
111-
if ($first instanceof ContainerInterface) {
112-
$container = $first;
113-
$controller = $second;
114-
} else {
115-
$container = $second;
116-
$controller = $first;
117-
}
118-
11988
if (! $controller instanceof EventManagerAwareInterface) {
12089
return;
12190
}
12291

12392
$events = $controller->getEventManager();
12493
if (! $events || ! $events->getSharedManager() instanceof SharedEventManagerInterface) {
125-
// For v2, we need to pull the parent service locator
126-
if (! method_exists($container, 'configure')) {
127-
$container = $container->getServiceLocator() ?: $container;
128-
}
129-
13094
$controller->setEventManager($container->get('EventManager'));
13195
}
13296
}
13397

13498
/**
13599
* Initializer: inject plugin manager
136100
*
137-
* @param ContainerInterface|DispatchableInterface $first Container when
138-
* using zend-servicemanager v3; controller under v2.
139-
* @param DispatchableInterface|ContainerInterface $second Controller when
140-
* using zend-servicemanager v3; container under v2.
101+
* @param ContainerInterface $container
102+
* @param DispatchableInterface $controller
141103
*/
142-
public function injectPluginManager($first, $second)
104+
public function injectPluginManager(ContainerInterface $container, $controller)
143105
{
144-
if ($first instanceof ContainerInterface) {
145-
$container = $first;
146-
$controller = $second;
147-
} else {
148-
$container = $second;
149-
$controller = $first;
150-
}
151-
152106
if (! method_exists($controller, 'setPluginManager')) {
153107
return;
154108
}
155109

156-
// For v2, we need to pull the parent service locator
157-
if (! method_exists($container, 'configure')) {
158-
$container = $container->getServiceLocator() ?: $container;
159-
}
160-
161110
$controller->setPluginManager($container->get('ControllerPluginManager'));
162111
}
163112
}

0 commit comments

Comments
 (0)