Completed
Pull Request — master (#25)
by Dawid
03:13
created

MiddlewarePipe   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Test Coverage

Coverage 80%

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 60
ccs 16
cts 20
cp 0.8
rs 10
c 0
b 0
f 0
wmc 9

6 Methods

Rating   Name   Duplication   Size   Complexity  
A add() 0 4 2
A __construct() 0 3 2
A __clone() 0 3 1
A process() 0 5 1
A __invoke() 0 3 1
A handle() 0 10 2
1
<?php declare(strict_types=1);
2
3
namespace Igni\Http\Middleware;
4
5
use Igni\Http\Exception\MiddlewareException;
6
use Psr\Http\Message\ResponseInterface;
7
use Psr\Http\Message\ServerRequestInterface;
8
use Psr\Http\Server\MiddlewareInterface;
9
use Psr\Http\Server\RequestHandlerInterface;
10
use SplQueue;
11
12
/**
13
 * Variation of zend stratigility's pipe.
14
 */
15
class MiddlewarePipe implements MiddlewareInterface, RequestHandlerInterface
16
{
17
    protected $pipeline;
18
19 12
    public function __construct(SplQueue $pipeline = null)
20
    {
21 12
        $this->pipeline = $pipeline ?: new SplQueue();
22 12
    }
23
24 12
    public function __clone()
25
    {
26 12
        $this->pipeline = clone $this->pipeline;
27 12
    }
28
29 1
    public function __invoke(ServerRequestInterface $request): ResponseInterface
30
    {
31 1
        return $this->handle($request);
32
    }
33
34
    /**
35
     * De-queues and executes middleware from the top of the cloned pipeline.
36
     *
37
     * @param ServerRequestInterface $request
38
     * @return ResponseInterface
39
     */
40 12
    public function handle(ServerRequestInterface $request): ResponseInterface
41
    {
42 12
        if ($this->pipeline->isEmpty()) {
43
            throw MiddlewareException::forEmptyMiddlewarePipeline();
44
        }
45
46 12
        $pipeline = clone $this;
47 12
        $middleware = $pipeline->pipeline->dequeue();
48
49 12
        return $middleware->process($request, $pipeline);
50
    }
51
52
    /**
53
     * PSR-15 Middleware invocation
54
     *
55
     * @param ServerRequestInterface $request
56
     * @param RequestHandlerInterface $handler
57
     * @return ResponseInterface
58
     */
59
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
60
    {
61
        $next = new Next($this->pipeline, $handler);
62
63
        return $next($request);
64
    }
65
66
    /**
67
     * Attach middleware to the pipeline.
68
     *
69
     * @param MiddlewareInterface|callable ...$middleware
70
     */
71 12
    public function add(MiddlewareInterface ...$middleware): void
72
    {
73 12
        foreach ($middleware as $item) {
74 12
            $this->pipeline->enqueue($item);
75
        }
76 12
    }
77
}
78