Rack::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Xoops\Frame;
4
5
use Psr\Http\Message\ResponseInterface;
6
use Psr\Http\Message\ServerRequestInterface;
7
use Psr\Http\Server\MiddlewareInterface;
8
use Psr\Http\Server\RequestHandlerInterface;
9
use Xoops\Frame\Exception\InvalidHandlerException;
10
use Xoops\Frame\Exception\RackExhaustedException;
11
12
/**
13
 * Class Rack
14
 *
15
 * @package Xoops\Xadr
16
 */
17
class Rack implements MiddlewareInterface, RequestHandlerInterface
18
{
19
    /** @var \SplQueue  */
20
    protected $workQueue;
21
22
    /**
23
     * Rack constructor.
24
     */
25 15
    public function __construct()
26
    {
27 15
        $this->workQueue = new \SplQueue();
28 15
    }
29
30
    /**
31
     * Add ServerMiddleware to the queue
32
     *
33
     * @param MiddlewareInterface $middleware
34
     *
35
     * @return self
36
     *
37
     * @throws InvalidHandlerException
38
     */
39 10
    public function add(MiddlewareInterface $middleware): Rack
40
    {
41 10
        if ($this === $middleware) {
42 1
            throw new InvalidHandlerException('Cannot register a Rack instance as its own middleware');
43
        }
44 9
        $this->workQueue->enqueue($middleware);
45 9
        return $this;
46
    }
47
48
    /**
49
     * Handle the request and return a response
50
     *
51
     * @param ServerRequestInterface $request an Http Request
52
     *
53
     * @return ResponseInterface
54
     *
55
     * @throws InvalidHandlerException
56
     * @throws RackExhaustedException
57
     */
58 13
    public function handle(ServerRequestInterface $request): ResponseInterface
59
    {
60
        try {
61 13
            $handler = $this->workQueue->dequeue();
62 11
            if (!($handler instanceof MiddlewareInterface)) {
63 2
                throw new InvalidHandlerException('Invalid Handler in Rack queue');
64
            }
65 9
            return $handler->process($request, $this);
66 6
        } catch (\RuntimeException $e) {
67 4
            throw new RackExhaustedException('Rack exhausted', 0, $e);
68
        }
69
    }
70
71
    /**
72
     * Process an incoming server request and return a response, optionally delegating
73
     * response creation to a handler.
74
     *
75
     * Here, we will use our own workQueue to try to handle the request, allowing stacking of
76
     * Rack instances in a middleware queue (i.e a Rack of Racks)
77
     *
78
     * @param ServerRequestInterface $request an Http Request
79
     * @param RequestHandlerInterface $handler
80
     *
81
     * @return ResponseInterface
82
     *
83
     * @throws InvalidHandlerException
84
     */
85 4
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
86
    {
87
        try {
88 4
            return $this->handle($request);
89 2
        } catch (RackExhaustedException $e) {
90
            // this rack didn't handle it, delegate it
91 2
            return $handler->handle($request);
92
        }
93
    }
94
95
    /**
96
     * Process a request using the middleware that has been add()ed to the Rack
97
     *
98
     * @param ServerRequestInterface $request
99
     *
100
     * @return ResponseInterface
101
     *
102
     * @throws InvalidHandlerException
103
     * @throws RackExhaustedException
104
     */
105 11
    public function run(ServerRequestInterface $request): ResponseInterface
106
    {
107 11
        return $this->handle($request);
108
    }
109
110
    /**
111
     * __invoke() is an alias for run()
112
     *
113
     * @param ServerRequestInterface $request
114
     *
115
     * @return ResponseInterface
116
     *
117
     * @throws InvalidHandlerException
118
     * @throws RackExhaustedException
119
     */
120 3
    public function __invoke(ServerRequestInterface $request): ResponseInterface
121
    {
122 3
        return $this->run($request);
123
    }
124
}
125