GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Mimeparse   B
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 230
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 26
Bugs 3 Features 1
Metric Value
wmc 37
c 26
b 3
f 1
lcom 1
cbo 0
dl 0
loc 230
rs 8.6

7 Methods

Rating   Name   Duplication   Size   Complexity  
B parseMediaRange() 0 35 6
B parseAndNormalizeMediaRange() 0 15 5
D qualityAndFitnessParsed() 0 32 17
A qualityParsed() 0 5 1
A quality() 0 10 2
B bestMatch() 0 30 5
A __construct() 0 3 1
1
<?php
2
/**
3
 * Mimeparse class. Provides basic functions for handling mime-types. It can
4
 * match mime-types against a list of media-ranges. See section 14.1 of the
5
 * HTTP specification [RFC 2616] for a complete explanation.
6
 *
7
 * It's a PHP port of the original Python code
8
 * (http://code.google.com/p/mimeparse/).
9
 *
10
 * Ported from version 0.1.2. Comments are mostly excerpted from the original.
11
 *
12
 * @author Joe Gregorio
13
 * @author Andrew "Venom" K.
14
 * @author Ben Ramsey
15
 */
16
namespace Bitworking;
17
18
class Mimeparse
19
{
20
    /**
21
     * Parses a media-range and returns an array with its components.
22
     *
23
     * The returned array contains:
24
     *
25
     * 1. type: The type categorization.
26
     * 2. subtype: The subtype categorization.
27
     * 3. params: An associative array of all the parameters for the
28
     *    media-range.
29
     * 4. generic subtype: A more generic subtype, if one is present. See
30
     *    http://tools.ietf.org/html/rfc3023#appendix-A.12
31
     *
32
     * For example, the media-range "application/xhtml+xml;q=0.5" would get
33
     * parsed into:
34
     *
35
     * array("application", "xhtml+xml", array( "q" => "0.5" ), "xml")
36
     *
37
     * @param string $mediaRange
38
     * @return array ($type, $subtype, $params, $genericSubtype)
39
     * @throws UnexpectedValueException when $mediaRange does not include a
40
     * valid subtype
41
     */
42
    public static function parseMediaRange($mediaRange)
43
    {
44
        $parts = explode(';', $mediaRange);
45
46
        $params = array();
47
        foreach ($parts as $i => $param) {
48
            if (strpos($param, '=') !== false) {
49
                list($k, $v) = explode('=', trim($param));
50
                $params[$k] = $v;
51
            }
52
        }
53
54
        $fullType = trim($parts[0]);
55
56
        // Java URLConnection class sends an Accept header that includes a
57
        // single "*". Turn it into a legal wildcard.
58
        if ($fullType == '*') {
59
            $fullType = '*/*';
60
        }
61
62
        list($type, $subtype) = explode('/', $fullType);
63
64
        if (!$subtype) {
65
            throw new \UnexpectedValueException('Malformed media-range: '.$mediaRange);
66
        }
67
68
        $plusPos = strpos($subtype, '+');
69
        if (false !== $plusPos) {
70
            $genericSubtype = substr($subtype, $plusPos + 1);
71
        } else {
72
            $genericSubtype = $subtype;
73
        }
74
75
        return array(trim($type), trim($subtype), $params, $genericSubtype);
76
    }
77
78
79
    /**
80
     * Parses a media-range via Mimeparse::parseMediaRange() and guarantees that
81
     * there is a value for the "q" param, filling it in with a proper default
82
     * if necessary.
83
     *
84
     * @param string $mediaRange
85
     * @return array ($type, $subtype, $params, $genericSubtype)
86
     */
87
    protected static function parseAndNormalizeMediaRange($mediaRange)
88
    {
89
        $parsedMediaRange = self::parseMediaRange($mediaRange);
90
        $params = $parsedMediaRange[2];
91
92
        if (!isset($params['q'])
93
            || !is_numeric($params['q'])
94
            || floatval($params['q']) > 1
95
            || floatval($params['q']) < 0
96
        ) {
97
            $parsedMediaRange[2]['q'] = '1';
98
        }
99
100
        return $parsedMediaRange;
101
    }
102
103
    /**
104
     * Find the best match for a given mime-type against a list of
105
     * media-ranges that have already been parsed by
106
     * Mimeparse::parseAndNormalizeMediaRange()
107
     *
108
     * Returns the fitness and the "q" quality parameter of the best match, or
109
     * an array [-1, 0] if no match was found. Just as for
110
     * Mimeparse::quality(), $parsedRanges must be an array of parsed
111
     * media-ranges.
112
     *
113
     * @param string $mimeType
114
     * @param array  $parsedRanges
115
     * @return array ($bestFitQuality, $bestFitness)
116
     */
117
    protected static function qualityAndFitnessParsed($mimeType, $parsedRanges)
118
    {
119
        $bestFitness = -1;
120
        $bestFitQuality = 0;
121
        list($targetType, $targetSubtype, $targetParams) = self::parseAndNormalizeMediaRange($mimeType);
122
123
        foreach ($parsedRanges as $item) {
124
            list($type, $subtype, $params) = $item;
125
126
            if (($type == $targetType || $type == '*' || $targetType == '*')
127
                && ($subtype == $targetSubtype || $subtype == '*' || $targetSubtype == '*')
128
            ) {
129
                $paramMatches = 0;
130
                foreach ($targetParams as $k => $v) {
131
                    if ($k != 'q' && isset($params[$k]) && $v == $params[$k]) {
132
                        $paramMatches++;
133
                    }
134
                }
135
136
                $fitness  = ($type == $targetType && $targetType != '*') ? 100 : 0;
137
                $fitness += ($subtype == $targetSubtype && $targetSubtype != '*') ? 10 : 0;
138
                $fitness += $paramMatches;
139
140
                if ($fitness > $bestFitness) {
141
                    $bestFitness = $fitness;
142
                    $bestFitQuality = $params['q'];
143
                }
144
            }
145
        }
146
147
        return array((float) $bestFitQuality, $bestFitness);
148
    }
149
150
    /**
151
     * Find the best match for a given mime-type against a list of
152
     * media-ranges that have already been parsed by
153
     * Mimeparse::parseAndNormalizeMediaRange()
154
     *
155
     * Returns the "q" quality parameter of the best match, 0 if no match was
156
     * found. This function behaves the same as Mimeparse::quality() except
157
     * that $parsedRanges must be an array of parsed media-ranges.
158
     *
159
     * @param string $mimeType
160
     * @param array  $parsedRanges
161
     * @return float $q
162
     */
163
    protected static function qualityParsed($mimeType, $parsedRanges)
164
    {
165
        list($q, $fitness) = self::qualityAndFitnessParsed($mimeType, $parsedRanges);
0 ignored issues
show
Unused Code introduced by
The assignment to $fitness is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
166
        return $q;
167
    }
168
169
    /**
170
     * Returns the quality "q" of a mime-type when compared against the
171
     * media-ranges in ranges. For example:
172
     *
173
     * Mimeparse::quality("text/html", "text/*;q=0.3, text/html;q=0.7,
174
     * text/html;level=1, text/html;level=2;q=0.4, *\/*;q=0.5")
175
     * => 0.7
176
     *
177
     * @param string $mimeType
178
     * @param string $ranges
179
     * @return float
180
     */
181
    public static function quality($mimeType, $ranges)
182
    {
183
        $parsedRanges = explode(',', $ranges);
184
185
        foreach ($parsedRanges as $i => $r) {
186
            $parsedRanges[$i] = self::parseAndNormalizeMediaRange($r);
187
        }
188
189
        return self::qualityParsed($mimeType, $parsedRanges);
190
    }
191
192
    /**
193
     * Takes a list of supported mime-types and finds the best match for all
194
     * the media-ranges listed in header. The value of $header must be a
195
     * string that conforms to the format of the HTTP Accept: header. The
196
     * value of $supported is an array of mime-types.
197
     *
198
     * In case of ties the mime-type with the lowest index in $supported will
199
     * be used.
200
     *
201
     * Mimeparse::bestMatch(array("application/xbel+xml", "text/xml"), "text/*;q=0.5,*\/*; q=0.1")
202
     * => "text/xml"
203
     *
204
     * @param  array  $supported
205
     * @param  string $header
206
     * @return mixed  $mimeType or NULL
207
     */
208
    public static function bestMatch($supported, $header)
209
    {
210
        $parsedHeader = explode(',', $header);
211
212
        foreach ($parsedHeader as $i => $r) {
213
            $parsedHeader[$i] = self::parseAndNormalizeMediaRange($r);
214
        }
215
216
        $weightedMatches = array();
217
        foreach ($supported as $index => $mimeType) {
218
            list($quality, $fitness) = self::qualityAndFitnessParsed($mimeType, $parsedHeader);
219
            if (!empty($quality)) {
220
                // Mime-types closer to the beginning of the array are
221
                // preferred. This preference score is used to break ties.
222
                $preference = 0 - $index;
223
                $weightedMatches[] = array(
224
                    array($quality, $fitness, $preference),
225
                    $mimeType
226
                );
227
            }
228
        }
229
230
        // Note that since fitness and preference are present in
231
        // $weightedMatches they will also be used when sorting (after quality
232
        // level).
233
        array_multisort($weightedMatches);
234
        $firstChoice = array_pop($weightedMatches);
235
236
        return (empty($firstChoice[0][0]) ? null : $firstChoice[1]);
237
    }
238
239
    /**
240
     * Disable access to constructor
241
     *
242
     * @codeCoverageIgnore
243
     */
244
    private function __construct()
245
    {
246
    }
247
}
248