parseQualityAndParameters()   B
last analyzed

Complexity

Conditions 7
Paths 6

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
nc 6
nop 1
dl 0
loc 37
ccs 21
cts 21
cp 1
crap 7
rs 8.3946
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Neomerx\JsonApi\Http\Headers;
4
5
/**
6
 * Copyright 2015-2020 [email protected]
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
use Neomerx\JsonApi\Contracts\Factories\FactoryInterface;
22
use Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersParserInterface;
23
use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
24
use Neomerx\JsonApi\Exceptions\InvalidArgumentException;
25
26
/**
27
 * @package Neomerx\JsonApi
28
 */
29
class HeaderParametersParser implements HeaderParametersParserInterface
30
{
31
    /**
32
     * @var FactoryInterface
33
     */
34
    private $factory;
35
36
    /**
37
     * @param FactoryInterface $factory
38
     */
39 21
    public function __construct(FactoryInterface $factory)
40
    {
41 21
        $this->factory = $factory;
42 21
    }
43
44
    /**
45
     * @inheritdoc
46
     */
47 16
    public function parseAcceptHeader(string $value): iterable
48
    {
49 16
        if (empty($value) === true) {
50 1
            throw new InvalidArgumentException('value');
51
        }
52
53 15
        $ranges = \preg_split("/,(?=([^\"]*\"[^\"]*\")*[^\"]*$)/", $value);
54 15
        $count  = \count($ranges);
55 15
        for ($idx = 0; $idx < $count; ++$idx) {
56 15
            $fields = \explode(';', $ranges[$idx]);
57
58 15
            if (\strpos($fields[0], '/') === false) {
59 1
                throw new InvalidArgumentException('mediaType');
60
            }
61
62 14
            list($type, $subType) = \explode('/', $fields[0], 2);
63 14
            list($parameters, $quality) = $this->parseQualityAndParameters($fields);
64
65 12
            $mediaType = $this->factory->createAcceptMediaType($idx, $type, $subType, $parameters, $quality);
66
67 12
            yield $mediaType;
68
        }
69 7
    }
70
71
    /**
72
     * @inheritdoc
73
     */
74 9
    public function parseContentTypeHeader(string $mediaType): MediaTypeInterface
75
    {
76 9
        $fields = \explode(';', $mediaType);
77
78 9
        if (\strpos($fields[0], '/') === false) {
79 2
            throw new InvalidArgumentException('mediaType');
80
        }
81
82 7
        list($type, $subType) = \explode('/', $fields[0], 2);
83
84 7
        $parameters = null;
85 7
        $count      = \count($fields);
86 7
        for ($idx = 1; $idx < $count; ++$idx) {
87 6
            $fieldValue = $fields[$idx];
88 6
            if (empty($fieldValue) === true) {
89 1
                continue;
90
            }
91
92 5
            if (\strpos($fieldValue, '=') === false) {
93 3
                throw new InvalidArgumentException('mediaType');
94
            }
95
96 3
            list($key, $value) = \explode('=', $fieldValue, 2);
97 3
            $parameters[\trim($key)] = \trim($value, ' "');
98
        }
99
100 4
        return $this->factory->createMediaType($type, $subType, $parameters);
101
    }
102
103
    /**
104
     * @param array $fields
105
     *
106
     * @return array
107
     */
108 14
    private function parseQualityAndParameters(array $fields): array
109
    {
110 14
        $quality     = 1;
111 14
        $qParamFound = false;
112 14
        $parameters  = null;
113
114 14
        $count = \count($fields);
115 14
        for ($idx = 1; $idx < $count; ++$idx) {
116 13
            $fieldValue = $fields[$idx];
117 13
            if (empty($fieldValue) === true) {
118 1
                continue;
119
            }
120
121 12
            if (\strpos($fieldValue, '=') === false) {
122 2
                throw new InvalidArgumentException('mediaType');
123
            }
124
125 10
            list($key, $value) = \explode('=', $fieldValue, 2);
126
127 10
            $key   = \trim($key);
128 10
            $value = \trim($value, ' "');
129
130
            // 'q' param separates media parameters from extension parameters
131
132 10
            if ($key === 'q' && $qParamFound === false) {
133 6
                $quality     = (float)$value;
134 6
                $qParamFound = true;
135 6
                continue;
136
            }
137
138 6
            if ($qParamFound === false) {
139 6
                $parameters[$key] = $value;
140
            }
141
        }
142
143 12
        return [$parameters, $quality];
144
    }
145
}
146