Passed
Push — master ( 26093e...7ed8f5 )
by mon
02:06
created

TypeParser::parseStringPart()   D

Complexity

Conditions 24
Paths 18

Size

Total Lines 74
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 45
CRAP Score 24

Importance

Changes 0
Metric Value
cc 24
eloc 48
nc 18
nop 3
dl 0
loc 74
rs 4.1666
c 0
b 0
f 0
ccs 45
cts 45
cp 1
crap 24

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace FileEye\MimeMap;
4
5
/**
6
 * Class for parsing RFC 2045 Content-Type Header Fields.
7
 */
8
class TypeParser
9
{
10
    /**
11
     * Parse a mime-type and set the class variables.
12
     *
13
     * @param string $type_string
14
     *   MIME type string to parse.
15
     * @param Type $type
16
     *   The Type object to receive the components.
17
     *
18
     * @return void
19
     */
20 61
    public static function parse($type_string, Type $type)
21
    {
22
        // Media and SubType are separated by a slash '/'.
23 61
        $media = static::parseStringPart($type_string, 0, '/');
24
25 60
        if (!$media['string']) {
26 3
            throw new MalformedTypeException('Media type not found');
27
        }
28 57
        if (!$media['delimiter_matched']) {
29 1
            throw new MalformedTypeException('Slash \'/\' to separate media type and subtype not found');
30
        }
31
32 56
        $type->setMedia(strtolower($media['string']));
0 ignored issues
show
Bug introduced by
$media['string'] of type void is incompatible with the type string expected by parameter $str of strtolower(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

32
        $type->setMedia(strtolower(/** @scrutinizer ignore-type */ $media['string']));
Loading history...
33 56
        $type->setMediaComment($media['comment']);
34
35
        // SubType and Parameters are separated by semicolons ';'.
36 56
        $sub = static::parseStringPart($type_string, $media['end_offset'] + 1, ';');
37
38 55
        if (!$sub['string']) {
39 1
            throw new MalformedTypeException('Media subtype not found');
40
        }
41
42 54
        $type->setSubType(strtolower($sub['string']));
43 54
        $type->setSubTypeComment($sub['comment']);
44
45
        // Loops through the parameter.
46 54
        while ($sub['delimiter_matched']) {
47 27
            $sub = static::parseStringPart($type_string, $sub['end_offset'] + 1, ';');
48 27
            $tmp = explode('=', $sub['string'], 2);
49 27
            $p_name = trim($tmp[0]);
50 27
            $p_val = trim($tmp[1]);
51 27
            $p_val = str_replace('\\"', '"', $p_val);
52 27
            $type->addParameter($p_name, $p_val, $sub['comment']);
53
        }
54 54
    }
55
56
    /**
57
     * Parses a part of the content MIME type string.
58
     *
59
     * Splits string and comment until a delimiter is found.
60
     *
61
     * @param string $string
62
     *   Input string.
63
     * @param int $offset
64
     *   Offset to start parsing from.
65
     * @param string $delimiter
66
     *   Stop parsing when delimiter found.
67
     *
68
     * @return array
69
     *   An array with the following keys:
70
     *   'string' - the uncommented part of $string
71
     *   'comment' - the comment part of $string
72
     *   'delimiter_matched' - true if a $delimiter stopped the parsing, false
73
     *                         otherwise
74
     *   'end_offset' - the last position parsed in $string.
75
     */
76 61
    public static function parseStringPart($string, $offset, $delimiter)
77
    {
78 61
        $inquote   = false;
79 61
        $escaped   = false;
80 61
        $incomment = 0;
81 61
        $newstring = '';
82 61
        $comment = '';
83
84 61
        for ($n = $offset; $n < strlen($string); $n++) {
85 59
            if ($string[$n] === $delimiter && !$escaped && !$inquote && $incomment === 0) {
86 57
                break;
87
            }
88
89 58
            if ($escaped) {
90 4
                if ($incomment == 0) {
91 2
                    $newstring .= $string[$n];
92
                } else {
93 2
                    $comment .= $string[$n];
94
                }
95 4
                $escaped = false;
96 4
                continue;
97
            }
98
99 58
            if ($string[$n] == '\\') {
100 4
                if ($incomment > 0) {
101 2
                    $comment .= $string[$n];
102
                }
103 4
                $escaped = true;
104 4
                continue;
105
            }
106
107 58
            if (!$inquote && $incomment > 0 && $string[$n] == ')') {
108 21
                $incomment--;
109 21
                if ($incomment == 0) {
110 19
                    $comment .= ' ';
111
                }
112 21
                continue;
113
            }
114
115 58
            if (!$inquote && $string[$n] == '(') {
116 21
                $incomment++;
117 21
                continue;
118
            }
119
120 58
            if ($string[$n] == '"') {
121 10
                if ($incomment > 0) {
122 1
                    $comment .= $string[$n];
123
                } else {
124 9
                    if ($inquote) {
125 9
                        $inquote = false;
126
                    } else {
127 9
                        $inquote = true;
128
                    }
129
                }
130 10
                continue;
131
            }
132
133 58
            if ($incomment == 0) {
134 58
                $newstring .= $string[$n];
135 58
                continue;
136
            }
137
138 21
            $comment .= $string[$n];
139
        }
140
141 61
        if ($incomment > 0) {
142 2
            throw new MalformedTypeException('Comment closing bracket missing: ' . $comment);
143
        }
144
145
        return [
146 60
          'string' => empty($newstring) ? null : trim($newstring),
0 ignored issues
show
introduced by
The condition empty($newstring) is always true.
Loading history...
147 60
          'comment' => empty($comment) ? null : trim($comment),
0 ignored issues
show
introduced by
The condition empty($comment) is always true.
Loading history...
148 60
          'delimiter_matched' => isset($string[$n]) ? ($string[$n] === $delimiter) : false,
149 60
          'end_offset' => $n,
150
        ];
151
    }
152
}
153