This repository was archived by the owner on Jan 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 196
/
Copy pathMiddlewareFactory.php
145 lines (128 loc) · 4.74 KB
/
MiddlewareFactory.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?php
/**
* @see https://github.com/zendframework/zend-expressive for the canonical source repository
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-expressive/blob/master/LICENSE.md New BSD License
*/
declare(strict_types=1);
namespace Zend\Expressive;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Stratigility\Middleware\CallableMiddlewareDecorator;
use Zend\Stratigility\Middleware\RequestHandlerMiddleware;
use Zend\Stratigility\MiddlewarePipe;
use function array_shift;
use function count;
use function is_array;
use function is_callable;
use function is_string;
/**
* Marshal middleware for use in the application.
*
* This class provides a number of methods for preparing and returning
* middleware for use within an application.
*
* If any middleware provided is already a MiddlewareInterface, it can be used
* verbatim or decorated as-is. Other middleware types acceptable are:
*
* - PSR-15 RequestHandlerInterface instances; these will be decorated as
* RequestHandlerMiddleware instances.
* - string service names resolving to middleware
* - arrays of service names and/or MiddlewareInterface instances
* - PHP callables that follow the PSR-15 signature
*
* Additionally, the class provides the following decorator/utility methods:
*
* - callable() will decorate the callable middleware passed to it using
* CallableMiddlewareDecorator.
* - handler() will decorate the request handler passed to it using
* RequestHandlerMiddleware.
* - lazy() will decorate the string service name passed to it, along with the
* factory instance, as a LazyLoadingMiddleware instance.
* - pipeline() will create a MiddlewarePipe instance from the array of
* middleware passed to it, after passing each first to prepare().
*/
class MiddlewareFactory
{
/**
* @var MiddlewareContainer
*/
private $container;
public function __construct(MiddlewareContainer $container)
{
$this->container = $container;
}
/**
* @param string|array|callable|MiddlewareInterface|RequestHandlerInterface $middleware
* @throws Exception\InvalidMiddlewareException if argument is not one of
* the specified types.
*/
public function prepare($middleware) : MiddlewareInterface
{
if ($middleware instanceof MiddlewareInterface) {
return $middleware;
}
if ($middleware instanceof RequestHandlerInterface) {
return $this->handler($middleware);
}
if (is_callable($middleware)) {
return $this->callable($middleware);
}
if (is_array($middleware)) {
return $this->pipeline(...$middleware);
}
if (! is_string($middleware) || $middleware === '') {
throw Exception\InvalidMiddlewareException::forMiddleware($middleware);
}
return $this->lazy($middleware);
}
/**
* Decorate callable standards-signature middleware via a CallableMiddlewareDecorator.
*/
public function callable(callable $middleware) : CallableMiddlewareDecorator
{
return new CallableMiddlewareDecorator($middleware);
}
/**
* Decorate a RequestHandlerInterface as middleware via RequestHandlerMiddleware.
*/
public function handler(RequestHandlerInterface $handler) : RequestHandlerMiddleware
{
return new RequestHandlerMiddleware($handler);
}
/**
* Create lazy loading middleware based on a service name.
*/
public function lazy(string $middleware) : Middleware\LazyLoadingMiddleware
{
return new Middleware\LazyLoadingMiddleware($this->container, $middleware);
}
/**
* Create a middleware pipeline from an array of middleware.
*
* This method allows passing an array of middleware as either:
*
* - discrete arguments
* - an array of middleware, using the splat operator: pipeline(...$array)
* - an array of middleware as the sole argument: pipeline($array)
*
* Each item is passed to prepare() before being passed to the
* MiddlewarePipe instance the method returns.
*
* @param string|array|callable|MiddlewareInterface|RequestHandlerInterface ...$middleware
*/
public function pipeline(...$middleware) : MiddlewarePipe
{
// Allow passing arrays of middleware or individual lists of middleware
if (is_array($middleware[0])
&& count($middleware) === 1
) {
$middleware = array_shift($middleware);
}
$pipeline = new MiddlewarePipe();
foreach ($middleware as $m) {
$pipeline->pipe($this->prepare($m));
}
return $pipeline;
}
}