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

AcceptMediaType::compareStrings()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

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