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

BatchResult::key()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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