Completed
Push — master ( 38b66e...6aaedf )
by David
01:26
created

PluginChain::createChain()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Http\Client\Common;
6
7
use function array_reverse;
8
use Http\Client\Common\Exception\LoopException;
9
use Http\Promise\Promise;
10
use Psr\Http\Message\RequestInterface;
11
12
final class PluginChain
13
{
14
    /** @var Plugin[] */
15
    private $plugins;
16
17
    /** @var callable */
18
    private $clientCallable;
19
20
    /** @var int */
21
    private $maxRestarts;
22
23
    /** @var int */
24
    private $restarts = 0;
25
26
    /**
27
     * @param Plugin[] $plugins        A plugin chain
28
     * @param callable $clientCallable Callable making the HTTP call
29
     * @param array    $options        {
30
     *
31
     *     @var int $max_restarts
32
     * }
33
     */
34 5
    public function __construct(array $plugins, callable $clientCallable, array $options = [])
35
    {
36 5
        $this->plugins = $plugins;
37 5
        $this->clientCallable = $clientCallable;
38 5
        $this->maxRestarts = (int) ($options['max_restarts'] ?? 0);
39 5
    }
40
41 5
    private function createChain(): callable
42
    {
43 5
        $lastCallable = $this->clientCallable;
44 5
        $reversedPlugins = array_reverse($this->plugins);
45
46 5
        foreach ($reversedPlugins as $plugin) {
47
            $lastCallable = function (RequestInterface $request) use ($plugin, $lastCallable) {
48 1
                return $plugin->handleRequest($request, $lastCallable, $this);
49 1
            };
50
        }
51
52 5
        return $lastCallable;
53
    }
54
55 5
    public function __invoke(RequestInterface $request): Promise
56
    {
57 5
        if ($this->restarts > $this->maxRestarts) {
58 1
            throw new LoopException('Too many restarts in plugin client', $request);
59
        }
60
61 5
        ++$this->restarts;
62
63 5
        return $this->createChain()($request);
64
    }
65
}
66