Passed
Pull Request — master (#7)
by Sandro
02:02
created

BatchResult::next()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * Sandro Keil (https://sandro-keil.de)
4
 *
5
 * @link      http://github.com/sandrokeil/arangodb-php-client for the canonical source repository
6
 * @copyright Copyright (c) 2018-2019 Sandro Keil
7
 * @license   http://github.com/sandrokeil/arangodb-php-client/blob/master/LICENSE.md New BSD License
8
 */
9
10
declare(strict_types=1);
11
12
namespace ArangoDb\Http;
13
14
use ArangoDb\Exception\InvalidArgumentException;
15
use ArangoDb\Exception\LogicException;
16
use ArangoDb\Guard\Guard;
17
use ArangoDb\Http\HttpHelper;
18
use ArangoDb\Type\BatchType;
19
use Countable;
20
use Iterator;
21
use Psr\Http\Message\ResponseFactoryInterface;
22
use Psr\Http\Message\ResponseInterface;
23
use Psr\Http\Message\StreamFactoryInterface;
24
25
final class BatchResult implements Countable, Iterator
26
{
27
    /**
28
     * responses
29
     *
30
     * @var ResponseInterface[]
31
     */
32
    private $responses = [];
33
34
    /**
35
     * @var ResponseFactoryInterface
36
     */
37
    private $responseFactory;
38
39 4
    private function __construct(ResponseFactoryInterface $responseFactory)
40
    {
41 4
        $this->responseFactory = $responseFactory;
42 4
    }
43
44 5
    public static function fromResponse(
45
        ResponseInterface $batchResponse,
46
        ResponseFactoryInterface $responseFactory,
47
        StreamFactoryInterface $streamFactory
48
    ): BatchResult {
49 5
        if ('multipart/form-data' !== ($batchResponse->getHeader('Content-Type')[0] ?? '')) {
50 1
            throw new InvalidArgumentException('Provided $batchResponse must have content type "multipart/form-data".');
51
        }
52
53 4
        $batches = explode(
54 4
            '--' . BatchType::MIME_BOUNDARY . BatchType::EOL,
55 4
            trim($batchResponse->getBody()->getContents(), '--' . BatchType::MIME_BOUNDARY . '--')
56
        );
57
58 4
        $self = new self($responseFactory);
59
60 4
        foreach ($batches as $batch) {
61 4
            $data = HttpHelper::parseMessage($batch);
62 4
            [$httpCode, $headers, $body] = HttpHelper::parseMessage($data[2] ?? '');
63
64 4
            $response = $self->responseFactory->createResponse($httpCode);
65
66 4
            foreach ($headers as $headerName => $header) {
67 4
                $response = $response->withAddedHeader($headerName, $header);
68
            }
69 4
            $response = $response->withBody($streamFactory->createStream($body));
70
71 4
            if (isset($data[1]['Content-Id'][0])) {
72 4
                $self->responses[$data[1]['Content-Id'][0]] = $response;
73
            } else {
74
                $self->responses[] = $response;
75
            }
76
        }
77 4
        return $self;
78
    }
79
80 1
    public function validateBatch(BatchType $batch): void
81
    {
82 1
        $guards = $batch->guards();
83
84 1
        if ($guards === null) {
85 1
            throw new LogicException('No guards are provided in Batch.');
86
        }
87
88
        $this->validate(... $guards);
89
    }
90
91 3
    public function validate(Guard ...$guards): void
92
    {
93 3
        foreach ($guards as $guard) {
94 3
            if ($guard->contentId() === null) {
95 1
                foreach ($this->responses as $response) {
96 1
                    $guard($response);
97
                }
98 1
                continue;
99
            }
100 2
            if (null !== ($response = $this->responses[$guard->contentId()] ?? null)) {
101 2
                $guard($response);
102
            }
103
        }
104 3
    }
105
106
    public function response(string $contentId): ?ResponseInterface
107
    {
108
        return $this->responses[$contentId] ?? null;
109
    }
110
111 1
    public function responses(): array
112
    {
113 1
        return $this->responses;
114
    }
115
116 1
    public function count(): int
117
    {
118 1
        return count($this->responses);
119
    }
120
121 1
    public function current(): ResponseInterface
122
    {
123 1
        return current($this->responses);
124
    }
125
126 1
    public function next(): void
127
    {
128 1
        next($this->responses);
129 1
    }
130
131
    /**
132
     * @return int|string|null
133
     */
134 1
    public function key()
135
    {
136 1
        return key($this->responses);
137
    }
138
139 1
    public function valid(): bool
140
    {
141 1
        return $this->key() !== null;
142
    }
143
144 1
    public function rewind(): void
145
    {
146 1
        reset($this->responses);
147 1
    }
148
}
149