Completed
Branch master (ffe81d)
by Neomerx
04:33
created

parseQualityAndParameters()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 21
nc 6
nop 1
dl 0
loc 37
ccs 21
cts 21
cp 1
crap 7
rs 6.7272
c 0
b 0
f 0
1
<?php namespace Neomerx\JsonApi\Http\Headers;
2
3
/**
4
 * Copyright 2015-2018 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use InvalidArgumentException;
20
use Neomerx\JsonApi\Contracts\Http\Headers\HeaderParametersParserInterface;
21
use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
22
use Neomerx\JsonApi\Contracts\Http\HttpFactoryInterface;
23
use Psr\Log\LoggerAwareInterface;
24
use Psr\Log\LoggerAwareTrait;
25
26
/**
27
 * @package Neomerx\JsonApi
28
 */
29
class HeaderParametersParser implements HeaderParametersParserInterface, LoggerAwareInterface
30
{
31
    use LoggerAwareTrait;
32
33
    /**
34
     * @var HttpFactoryInterface
35
     */
36
    private $factory;
37
38
    /**
39
     * @param HttpFactoryInterface $factory
40
     */
41 20
    public function __construct(HttpFactoryInterface $factory)
42
    {
43 20
        $this->factory = $factory;
44 20
    }
45
46
    /**
47
     * @inheritdoc
48
     */
49 15
    public function parseAcceptHeader(string $value): iterable
50
    {
51 15
        if (empty($value) === true) {
52 1
            throw new InvalidArgumentException('value');
53
        }
54
55 14
        $ranges = preg_split("/,(?=([^\"]*\"[^\"]*\")*[^\"]*$)/", $value);
56 14
        for ($idx = 0; $idx < count($ranges); ++$idx) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
57 14
            $fields = explode(';', $ranges[$idx]);
58
59 14
            if (strpos($fields[0], '/') === false) {
60 1
                throw new InvalidArgumentException('mediaType');
61
            }
62
63 13
            list($type, $subType) = explode('/', $fields[0], 2);
64 13
            list($parameters, $quality) = $this->parseQualityAndParameters($fields);
65
66 11
            $mediaType = $this->factory->createAcceptMediaType($idx, $type, $subType, $parameters, $quality);
67
68 11
            yield $mediaType;
69
        }
70 7
    }
71
72
    /**
73
     * @inheritdoc
74
     */
75 9
    public function parseContentTypeHeader(string $mediaType): MediaTypeInterface
76
    {
77 9
        $fields = explode(';', $mediaType);
78
79 9
        if (strpos($fields[0], '/') === false) {
80 2
            throw new InvalidArgumentException('mediaType');
81
        }
82
83 7
        list($type, $subType) = explode('/', $fields[0], 2);
84
85 7
        $parameters = null;
86 7
        $count      = count($fields);
87 7
        for ($idx = 1; $idx < $count; ++$idx) {
88 5
            if (strpos($fields[$idx], '=') === false) {
89 3
                throw new InvalidArgumentException('mediaType');
90
            }
91
92 3
            list($key, $value) = explode('=', $fields[$idx], 2);
93 3
            $parameters[trim($key)] = trim($value, ' "');
94
        }
95
96 4
        return $this->factory->createMediaType($type, $subType, $parameters);
97
    }
98
99
    /**
100
     * @param array $fields
101
     *
102
     * @return array
103
     */
104 13
    private function parseQualityAndParameters(array $fields): array
105
    {
106 13
        $quality     = 1;
107 13
        $qParamFound = false;
108 13
        $parameters  = null;
109
110 13
        $count = count($fields);
111 13
        for ($idx = 1; $idx < $count; ++$idx) {
112 12
            $fieldValue = $fields[$idx];
113 12
            if (empty($fieldValue) === true) {
114 1
                continue;
115
            }
116
117 11
            if (strpos($fieldValue, '=') === false) {
118 2
                throw new InvalidArgumentException('mediaType');
119
            }
120
121 9
            list($key, $value) = explode('=', $fieldValue, 2);
122
123 9
            $key   = trim($key);
124 9
            $value = trim($value, ' "');
125
126
            // 'q' param separates media parameters from extension parameters
127
128 9
            if ($key === 'q' && $qParamFound === false) {
129 6
                $quality     = (float)$value;
130 6
                $qParamFound = true;
131 6
                continue;
132
            }
133
134 5
            if ($qParamFound === false) {
135 5
                $parameters[$key] = $value;
136
            }
137
        }
138
139 11
        return [$parameters, $quality];
140
    }
141
}
142