AcceptMediaType   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 131
ccs 38
cts 38
cp 1
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 3

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 23 4
A getPosition() 0 4 1
A getQuality() 0 4 1
A getCompare() 0 26 5
A compareQuality() 0 11 3
A compareStrings() 0 4 3
A compareParameters() 0 4 3
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 Closure;
22
use Neomerx\JsonApi\Contracts\Http\Headers\AcceptMediaTypeInterface;
23
use Neomerx\JsonApi\Exceptions\InvalidArgumentException;
24
25
/**
26
 * @package Neomerx\JsonApi
27
 */
28
class AcceptMediaType extends MediaType implements AcceptMediaTypeInterface
29
{
30
    /**
31
     * @var float [0..1]
32
     */
33
    private $quality;
34
35
    /**
36
     * @var int
37
     */
38
    private $position;
39
40
    /**
41
     * @param int    $position
42
     * @param string $type
43
     * @param string $subType
44
     * @param array<string,string>|null $parameters
45
     * @param float  $quality
46
     */
47 24
    public function __construct(
48
        int $position,
49
        string $type,
50
        string $subType,
51
        array $parameters = null,
52
        float $quality = 1.0
53
    ) {
54 24
        parent::__construct($type, $subType, $parameters);
55
56 24
        if ($position < 0) {
57 1
            throw new InvalidArgumentException('position');
58
        }
59
60 23
        if ($quality < 0 || $quality > 1) {
61 1
            throw new InvalidArgumentException('quality');
62
        }
63
64
        // rfc2616: 3 digits are meaningful (#3.9 Quality Values)
65 22
        $quality = \floor($quality * 1000) / 1000;
66
67 22
        $this->position = $position;
68 22
        $this->quality  = $quality;
69 22
    }
70
71
    /**
72
     * @inheritdoc
73
     */
74 4
    public function getPosition(): int
75
    {
76 4
        return $this->position;
77
    }
78
79
    /**
80
     * @inheritdoc
81
     */
82 16
    public function getQuality(): float
83
    {
84 16
        return $this->quality;
85
    }
86
87
    /**
88
     * @return Closure
89
     */
90 10
    public static function getCompare(): Closure
91
    {
92
        return function (AcceptMediaTypeInterface $lhs, AcceptMediaTypeInterface $rhs) {
93 10
            $qualityCompare = self::compareQuality($lhs->getQuality(), $rhs->getQuality());
94 10
            if ($qualityCompare !== 0) {
95 5
                return $qualityCompare;
96
            }
97
98 7
            $typeCompare = self::compareStrings($lhs->getType(), $rhs->getType());
99 7
            if ($typeCompare !== 0) {
100 2
                return $typeCompare;
101
            }
102
103 6
            $subTypeCompare = self::compareStrings($lhs->getSubType(), $rhs->getSubType());
104 6
            if ($subTypeCompare !== 0) {
105 2
                return $subTypeCompare;
106
            }
107
108 5
            $parametersCompare = self::compareParameters($lhs->getParameters(), $rhs->getParameters());
109 5
            if ($parametersCompare !== 0) {
110 2
                return $parametersCompare;
111
            }
112
113 3
            return ($lhs->getPosition() - $rhs->getPosition());
114 10
        };
115
    }
116
117
    /**
118
     * @param float $lhs
119
     * @param float $rhs
120
     *
121
     * @return int
122
     *
123
     * @SuppressWarnings(PHPMD.ElseExpression)
124
     */
125 10
    private static function compareQuality(float $lhs, float $rhs): int
126
    {
127 10
        $qualityDiff = $lhs - $rhs;
128
129
        // rfc2616: 3 digits are meaningful (#3.9 Quality Values)
130 10
        if (\abs($qualityDiff) < 0.001) {
131 7
            return 0;
132
        } else {
133 5
            return $lhs > $rhs ? -1 : 1;
134
        }
135
    }
136
137
    /**
138
     * @param string $lhs
139
     * @param string $rhs
140
     *
141
     * @return int
142
     */
143 7
    private static function compareStrings(string $lhs, string $rhs): int
144
    {
145 7
        return ($rhs !== '*' ? 1 : 0) - ($lhs !== '*' ? 1 : 0);
146
    }
147
148
    /**
149
     * @param array|null $lhs
150
     * @param array|null $rhs
151
     *
152
     * @return int
153
     */
154 5
    private static function compareParameters(?array $lhs, ?array $rhs): int
155
    {
156 5
        return (empty($lhs) !== false ? 1 : 0) - (empty($rhs) !== false ? 1 : 0);
157
    }
158
}
159