Completed
Pull Request — master (#2)
by Fabian
14:41
created

Dispatcher::responseWithTargetHeader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace IntegerNet\CallbackProxy;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Exception\RequestException;
7
use Psr\Http\Message\RequestInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\UriInterface;
10
11
/**
12
 * Dispatches a request to multiple targets, returns first successful response (HTTP 200) or last response if none are
13
 * successful
14
 */
15
class Dispatcher
16
{
17
    /**
18
     * @var Client
19
     */
20
    private $client;
21
    /**
22
     * @var Target[]
23
     */
24
    private $targets;
25 39
26
    public function __construct(Client $client, Target ...$targets)
27 39
    {
28 39
        $this->client = $client;
29 39
        $this->targets = $targets;
30
    }
31 39
32
    public function dispatch(RequestInterface $request, ResponseInterface $response, string $action): ResponseInterface
33 39
    {
34 39
        $firstSuccessfulResponse = null;
35 39
        foreach ($this->targets as $target) {
36 39
            $response = $this->dispatchSingle($request, $target, $action);
37 39
            if ($firstSuccessfulResponse === null && $this->responseIsSuccessful($response)) {
38
                $firstSuccessfulResponse = $response;
39
            }
40 39
        }
41
        return $firstSuccessfulResponse ?? $response;
42
    }
43 39
44
    private function dispatchSingle(RequestInterface $request, Target $target, string $action): ResponseInterface
45 39
    {
46
        try {
47 39
            $response = $this->client->send($target->applyToRequest($request, $action));
48 9
            return $target->applyToResponse($response, $action);
49 9
        } catch (RequestException $e) {
50 9
            if ($e->getResponse() instanceof ResponseInterface) {
51
                return $target->applyToResponse($e->getResponse(), $action);
52
            }
53
            throw $e;
54
        }
55
    }
56 39
57
    private function responseIsSuccessful(ResponseInterface $response): bool
58 39
    {
59
        return $response->getStatusCode() >= 200 && $response->getStatusCode() < 300;
60
    }
61
}
62