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.

CollationInfo   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 256
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 83
dl 0
loc 256
ccs 67
cts 67
cp 1
rs 9.92
c 4
b 0
f 0
wmc 31

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 3
A isBinaryCharset() 0 6 2
A setCharset() 0 14 4
A isDefaultCollation() 0 6 2
A getCharset() 0 6 2
A isSpecified() 0 3 1
A getCollation() 0 12 4
A getCharsetCollations() 0 5 2
A getCollationCharset() 0 8 3
A getCharsetDefaultCollation() 0 7 2
A setCollation() 0 19 5
A setBinaryCollation() 0 3 1
1
<?php
2
namespace Graze\Morphism\Parse;
3
4
use LogicException;
5
use RuntimeException;
6
7
/**
8
 * Handles the specification of character set and collation.
9
 */
10
class CollationInfo
11
{
12
    // only bothering to detail the charsets + collations we're actually likely to use
13
    /** @var array */
14
    private static $data = [
15
        // In the list of collations for each charset, the entry
16
        // for the default collation must come first, and the
17
        // binary collation last:
18
        'latin1' => [
19
            'latin1_swedish_ci',
20
            'latin1_german1_ci',
21
            'latin1_german2_ci',
22
            'latin1_spanish_ci',
23
            'latin1_danish_ci',
24
            'latin1_general_ci',
25
            'latin1_general_cs',
26
            'latin1_bin',
27
        ],
28
        'utf8' => [
29
            'utf8_general_ci',
30
            'utf8_unicode_ci',
31
            'utf8_bin',
32
        ],
33
        'utf8mb3' => [
34
            'utf8mb3_general_ci',
35
            'utf8mb3_unicode_ci',
36
            'utf8mb3_bin',
37
        ],
38
        'utf8mb4' => [
39
            'utf8mb4_general_ci',
40
            'utf8mb4_unicode_ci',
41
            'utf8mb4_bin',
42
            'utf8mb4_0900_ai_ci',
43
        ],
44
        'binary' => [
45
            'binary',
46
        ],
47
    ];
48
49
    /** @var string|null */
50
    private $charset = null;
51
    /** @var string|null */
52
    private $collation = null;
53
    /** @var bool|null */
54
    private $isBinaryCollation = null;
55
56
    /**
57
     * If neither parameter is specified, creates an object representing an
58
     * unspecified collation.
59
     * If only $charset is provided, its default collation will be selected.
60
     * If only $collation is provided, the charset will be derived from it.
61
     * If both are provided, $collation must be a valid collation for the
62 473
     * charset.
63
     *
64 473
     * @param string|null $charset    name of a character set, e.g. latin1, utf8, binary
65 26
     * @param string|null $collation  name of a collation, e.g. latin1_general_ci, utf8_unicode_ci, binary
66
     */
67 472
    public function __construct($charset = null, $collation = null)
68 18
    {
69
        if (!is_null($charset)) {
70 471
            $this->setCharset($charset);
71
        }
72
        if (!is_null($collation)) {
73
            $this->setCollation($collation);
74
        }
75
    }
76
77 217
    /**
78
     * Returns true if a charset or collation has not yet been specified.
79 217
     *
80
     * @return bool
81
     */
82
    public function isSpecified()
83
    {
84
        return !is_null($this->charset);
85
    }
86
87
    /**
88
     * Returns the name of the character set.
89 33
     * Throws an exception if a charset or collation has not yet been specified.
90
     *
91 33
     * @throws LogicException
92 1
     * @return string
93
     */
94 32
    public function getCharset()
95
    {
96
        if (is_null($this->charset)) {
97
            throw new LogicException("getCharset called when charset is unspecified");
98
        }
99
        return $this->charset;
100
    }
101
102
    /**
103
     * Returns the name of the collation.
104 45
     * Throws an exception if a charset or collation has not yet been specified.
105
     *
106 45
     * @throws LogicException
107 1
     * @return string
108
     */
109 44
    public function getCollation()
110 2
    {
111 2
        if (is_null($this->charset)) {
112 2
            throw new LogicException("getCollation called when collation is unspecified");
113
        }
114
        if ($this->isBinaryCollation) {
115 43
            $collations = self::getCharsetCollations($this->charset);
116
            if (null !== $collations) {
117
                return $collations[count($collations) - 1];
118
            }
119
        }
120
        return $this->collation;
121
    }
122
123
    /**
124
     * Returns true if the selected charset is 'binary'.
125 10
     * Throws an exception if a charset or collation has not yet been specified.
126
     *
127 10
     * @throws LogicException
128 1
     * @return bool
129
     */
130 9
    public function isBinaryCharset()
131
    {
132
        if (is_null($this->charset)) {
133
            throw new LogicException("isBinaryCharset called when collation is unspecified");
134
        }
135
        return $this->charset === 'binary';
136
    }
137
138
    /**
139
     * Returns true if the selected collation is the default for the charset.
140 17
     * Throws an exception if a charset or collation has not yet been specified.
141
     *
142 17
     * @throws LogicException
143 1
     * @return bool
144
     */
145 16
    public function isDefaultCollation()
146
    {
147
        if (is_null($this->charset)) {
148
            throw new LogicException("isDefaultCollation called when collation is unspecified");
149
        }
150
        return $this->getCollation() === self::getCharsetDefaultCollation($this->charset);
151
    }
152
153
    /**
154
     * Sets the character set.
155
     *
156
     * Throws a RuntimeException if $charset is in conflict with an already
157
     * specified character set or collation.
158
     *
159
     * Hidden side effect: Also sets the collation. :(
160 37
     *
161
     * @param string $charset
162 37
     * @throws RuntimeException
163 37
     * @return void
164 37
     */
165 1
    public function setCharset($charset)
166
    {
167 36
        $charset = strtolower($charset);
168 36
        $defaultCollation = self::getCharsetDefaultCollation($charset);
169
        if (is_null($defaultCollation)) {
170 1
            throw new RuntimeException("unknown character set '$charset'");
171
        }
172 36
        if (!is_null($this->charset) &&
173 36
            $this->charset !== $charset
174 36
        ) {
175
            throw new RuntimeException("Conflicting CHARACTER SET declarations");
176
        }
177
        $this->charset = $charset;
178
        $this->collation = $defaultCollation;
179
    }
180
181
    /**
182
     * Sets the collation.
183
     *
184
     * Throws a RuntimeException if a character set has already been specified,
185
     * but $collation is not compatible with it.
186
     *
187
     * Hidden side effect: Also sets the character set. :(
188 34
     *
189
     * @param string $collation
190 34
     * @throws RuntimeException
191 34
     * @return void
192 34
     */
193 1
    public function setCollation($collation)
194
    {
195 33
        $collation = strtolower($collation);
196 33
        if (str_contains($collation, 'utf8mb3')) {
197
            $collation = str_replace('utf8mb3', 'utf8', $collation);
198 1
            $this->charset =  str_replace('utf8mb3', 'utf8', $this->charset);
199
        }
200 32
201 32
        $charset = self::getCollationCharset($collation);
202 32
        if (is_null($charset)) {
203
            throw new RuntimeException("unknown collation '$collation'");
204
        }
205
        if (!is_null($this->charset) &&
206
            $this->charset !== $charset
207
        ) {
208
            throw new RuntimeException("COLLATION '$collation' is not valid for CHARACTER SET '$charset'");
209
        }
210
        $this->charset = $charset;
211 3
        $this->collation = $collation;
212
    }
213 3
214 3
    /**
215
     * Ensures that the character set's binary collation will be returned
216
     * by getCollation() in future (on this object), regardless of any prior
217
     * or subsequent call to setCollation().
218
     *
219
     * @return void
220
     */
221
    public function setBinaryCollation()
222 45
    {
223
        $this->isBinaryCollation = true;
224 45
    }
225 44
226 45
    /**
227
     * Get all the available collations for the given character set.
228
     *
229
     * @param string $charset
230
     * @return array|null
231
     */
232
    private static function getCharsetCollations($charset)
233
    {
234
        return array_key_exists($charset, self::$data)
235 44
            ? self::$data[$charset]
236
            : null;
237 44
    }
238 44
239 43
    /**
240
     * Get the default collation for the given character set.
241 1
     *
242
     * @param string $charset
243
     * @return string|null
244
     */
245
    private static function getCharsetDefaultCollation($charset)
246
    {
247
        $collations = self::getCharsetCollations($charset);
248 34
        if (null !== $collations) {
249
            return $collations[0];
250 34
        }
251 34
        return null;
252 33
    }
253
254
    /**
255 1
     * @param string $collation
256
     * @return string|null
257
     */
258
    private static function getCollationCharset($collation)
259
    {
260
        foreach (self::$data as $charset => $collations) {
261
            if (in_array($collation, $collations)) {
262
                return $charset;
263
            }
264
        }
265
        return null;
266
    }
267
}
268