Collation::getNameForLevel1()   F
last analyzed

Complexity

Conditions 67
Paths 69

Size

Total Lines 160
Code Lines 144

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 143
CRAP Score 67

Importance

Changes 0
Metric Value
cc 67
eloc 144
nc 69
nop 5
dl 0
loc 160
ccs 143
cts 143
cp 1
crap 67
rs 3.3333
c 0
b 0
f 0

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
 * Value object class for a collation
4
 */
5
6
declare(strict_types=1);
7
8
namespace PhpMyAdmin\Charsets;
9
10
use function __;
11
use function _pgettext;
12
use function explode;
13
use function implode;
14
15
/**
16
 * Value object class for a collation
17
 */
18
final class Collation
19
{
20
    /**
21
     * A description of the collation
22
     */
23
    private string $description;
24
25
    /**
26
     * @param string $name         The collation name
27
     * @param string $charset      The name of the character set with which the collation is associated
28
     * @param int    $id           The collation ID
29
     * @param bool   $isDefault    Whether the collation is the default for its character set
30
     * @param bool   $isCompiled   Whether the character set is compiled into the server
31
     * @param int    $sortLength   Used for determining the memory used to sort strings in this collation
32
     * @param string $padAttribute The collation pad attribute
33
     */
34 392
    private function __construct(
35
        private string $name,
36
        private string $charset,
37
        private int $id,
38
        private bool $isDefault,
39
        private bool $isCompiled,
40
        private int $sortLength,
41
        private string $padAttribute,
42
    ) {
43 392
        $this->description = $this->buildDescription();
44
    }
45
46
    /** @param string[] $state State obtained from the database server */
47 392
    public static function fromServer(array $state): self
48
    {
49 392
        return new self(
50 392
            $state['Collation'] ?? '',
51 392
            $state['Charset'] ?? '',
52 392
            (int) ($state['Id'] ?? 0),
53 392
            isset($state['Default']) && ($state['Default'] === 'Yes' || $state['Default'] === '1'),
54 392
            isset($state['Compiled']) && ($state['Compiled'] === 'Yes' || $state['Compiled'] === '1'),
55 392
            (int) ($state['Sortlen'] ?? 0),
56 392
            $state['Pad_attribute'] ?? '',
57 392
        );
58
    }
59
60 392
    public function getName(): string
61
    {
62 392
        return $this->name;
63
    }
64
65 392
    public function getDescription(): string
66
    {
67 392
        return $this->description;
68
    }
69
70 4
    public function getCharset(): string
71
    {
72 4
        return $this->charset;
73
    }
74
75 4
    public function getId(): int
76
    {
77 4
        return $this->id;
78
    }
79
80 4
    public function isDefault(): bool
81
    {
82 4
        return $this->isDefault;
83
    }
84
85 4
    public function isCompiled(): bool
86
    {
87 4
        return $this->isCompiled;
88
    }
89
90 4
    public function getSortLength(): int
91
    {
92 4
        return $this->sortLength;
93
    }
94
95 4
    public function getPadAttribute(): string
96
    {
97 4
        return $this->padAttribute;
98
    }
99
100
    /**
101
     * Returns description for given collation
102
     *
103
     * @return string collation description
104
     */
105 392
    private function buildDescription(): string
106
    {
107 392
        $parts = explode('_', $this->getName());
108
109 392
        $name = __('Unknown');
110 392
        $variant = null;
111 392
        $suffixes = [];
112 392
        $unicode = false;
113 392
        $unknown = false;
114
115 392
        $level = 0;
116 392
        foreach ($parts as $part) {
117 392
            if ($level === 0) {
118
                /* Next will be language */
119 392
                $level = 1;
120
                /* First should be charset */
121 392
                [$name, $unicode, $unknown, $variant] = $this->getNameForLevel0($unicode, $unknown, $part, $variant);
122 392
                continue;
123
            }
124
125 244
            if ($level === 1) {
126
                /* Next will be variant unless changed later */
127 244
                $level = 4;
128
                /* Locale name or code */
129 244
                [$name, $level, $found] = $this->getNameForLevel1($unicode, $unknown, $part, $name, $level);
130 244
                if ($found) {
131 224
                    continue;
132
                }
133
                // Not parsed token, fall to next level
134
            }
135
136 232
            if ($level === 2) {
137
                /* Next will be variant */
138 8
                $level = 4;
139
                /* Germal variant */
140 8
                if ($part === 'pb') {
141 4
                    $name = _pgettext('Collation', 'German (phone book order)');
142 4
                    continue;
143
                }
144
145 4
                $name = _pgettext('Collation', 'German (dictionary order)');
146
                // Not parsed token, fall to next level
147
            }
148
149 232
            if ($level === 3) {
150
                /* Next will be variant */
151 8
                $level = 4;
152
                /* Spanish variant */
153 8
                if ($part === 'trad') {
154 4
                    $name = _pgettext('Collation', 'Spanish (traditional)');
155 4
                    continue;
156
                }
157
158 4
                $name = _pgettext('Collation', 'Spanish (modern)');
159
                // Not parsed token, fall to next level
160
            }
161
162 232
            if ($level === 4) {
163
                /* Next will be suffix */
164 232
                $level = 5;
165
                /* Variant */
166 232
                $variantFound = $this->getVariant($part);
167 232
                if ($variantFound !== null) {
168 56
                    $variant = $variantFound;
169 56
                    continue;
170
                }
171
                // Not parsed token, fall to next level
172
            }
173
174 232
            if ($level < 5) {
175
                continue;
176
            }
177
178
            /* Suffixes */
179 232
            $suffix = $this->addSuffixes($part);
180 232
            if ($suffix === null) {
181 124
                continue;
182
            }
183
184 116
            $suffixes[] = $suffix;
185
        }
186
187 392
        return $this->buildName($name, $variant, $suffixes);
188
    }
189
190
    /** @param string[] $suffixes */
191 392
    private function buildName(string $result, string|null $variant, array $suffixes): string
192
    {
193 392
        if ($variant !== null) {
194 72
            $result .= ' (' . $variant . ')';
195
        }
196
197 392
        if ($suffixes !== []) {
198 116
            $result .= ', ' . implode(', ', $suffixes);
199
        }
200
201 392
        return $result;
202
    }
203
204 232
    private function getVariant(string $part): string|null
205
    {
206 232
        return match ($part) {
207 232
            '0900' => 'UCA 9.0.0',
208 232
            '520' => 'UCA 5.2.0',
209 232
            'mysql561' => 'MySQL 5.6.1',
210 232
            'mysql500' => 'MySQL 5.0.0',
211 232
            default => null,
212 232
        };
213
    }
214
215 232
    private function addSuffixes(string $part): string|null
216
    {
217 232
        return match ($part) {
218 232
            'ci' => _pgettext('Collation variant', 'case-insensitive'),
219 232
            'cs' => _pgettext('Collation variant', 'case-sensitive'),
220 232
            'ai' => _pgettext('Collation variant', 'accent-insensitive'),
221 232
            'as' => _pgettext('Collation variant', 'accent-sensitive'),
222 232
            'ks' => _pgettext('Collation variant', 'kana-sensitive'),
223 232
            'w2','l2' => _pgettext('Collation variant', 'multi-level'),
224 232
            'bin' => _pgettext('Collation variant', 'binary'),
225 232
            'nopad' => _pgettext('Collation variant', 'no-pad'),
226 232
            default => null,
227 232
        };
228
    }
229
230
    /**
231
     * @return array<int, bool|string|null>
232
     * @psalm-return array{string, bool, bool, string|null}
233
     */
234 392
    private function getNameForLevel0(
235
        bool $unicode,
236
        bool $unknown,
237
        string $part,
238
        string|null $variant,
239
    ): array {
240
        switch ($part) {
241 392
            case 'binary':
242 4
                $name = _pgettext('Collation', 'Binary');
243 4
                break;
244
            // Unicode charsets
245 388
            case 'utf8mb4':
246 64
                $variant = 'UCA 4.0.0';
247
                // Fall through to other unicode
248 324
            case 'ucs2':
249 316
            case 'utf8':
250 296
            case 'utf8mb3':
251 296
            case 'utf16':
252 296
            case 'utf16le':
253 296
            case 'utf16be':
254 296
            case 'utf32':
255 100
                $name = _pgettext('Collation', 'Unicode');
256 100
                $unicode = true;
257 100
                break;
258
            // West European charsets
259 288
            case 'ascii':
260 284
            case 'cp850':
261 280
            case 'dec8':
262 276
            case 'hp8':
263 272
            case 'latin1':
264 264
            case 'macroman':
265 24
                $name = _pgettext('Collation', 'West European');
266 24
                break;
267
            // Central European charsets
268 264
            case 'cp1250':
269 256
            case 'cp852':
270 252
            case 'latin2':
271 248
            case 'macce':
272 20
                $name = _pgettext('Collation', 'Central European');
273 20
                break;
274
            // Russian charsets
275 244
            case 'cp866':
276 240
            case 'koi8r':
277 8
                $name = _pgettext('Collation', 'Russian');
278 8
                break;
279
            // Chinese charsets
280 236
            case 'gb2312':
281 228
            case 'gbk':
282 16
                $name = _pgettext('Collation', 'Simplified Chinese');
283 16
                break;
284 220
            case 'big5':
285 12
                $name = _pgettext('Collation', 'Traditional Chinese');
286 12
                break;
287 208
            case 'gb18030':
288 4
                $name = _pgettext('Collation', 'Chinese');
289 4
                $unicode = true;
290 4
                break;
291
            // Japanese charsets
292 204
            case 'sjis':
293 200
            case 'ujis':
294 196
            case 'cp932':
295 192
            case 'eucjpms':
296 16
                $name = _pgettext('Collation', 'Japanese');
297 16
                break;
298
            // Baltic charsets
299 188
            case 'cp1257':
300 184
            case 'latin7':
301 8
                $name = _pgettext('Collation', 'Baltic');
302 8
                break;
303
            // Other
304 180
            case 'armscii8':
305 176
            case 'armscii':
306 8
                $name = _pgettext('Collation', 'Armenian');
307 8
                break;
308 172
            case 'cp1251':
309 4
                $name = _pgettext('Collation', 'Cyrillic');
310 4
                break;
311 168
            case 'cp1256':
312 4
                $name = _pgettext('Collation', 'Arabic');
313 4
                break;
314 164
            case 'euckr':
315 4
                $name = _pgettext('Collation', 'Korean');
316 4
                break;
317 160
            case 'hebrew':
318 4
                $name = _pgettext('Collation', 'Hebrew');
319 4
                break;
320 156
            case 'geostd8':
321 4
                $name = _pgettext('Collation', 'Georgian');
322 4
                break;
323 152
            case 'greek':
324 4
                $name = _pgettext('Collation', 'Greek');
325 4
                break;
326 148
            case 'keybcs2':
327 4
                $name = _pgettext('Collation', 'Czech-Slovak');
328 4
                break;
329 144
            case 'koi8u':
330 4
                $name = _pgettext('Collation', 'Ukrainian');
331 4
                break;
332 140
            case 'latin5':
333 4
                $name = _pgettext('Collation', 'Turkish');
334 4
                break;
335 136
            case 'swe7':
336 4
                $name = _pgettext('Collation', 'Swedish');
337 4
                break;
338 132
            case 'tis620':
339 4
                $name = _pgettext('Collation', 'Thai');
340 4
                break;
341
            default:
342 128
                $name = _pgettext('Collation', 'Unknown');
343 128
                $unknown = true;
344 128
                break;
345
        }
346
347 392
        return [$name, $unicode, $unknown, $variant];
348
    }
349
350
    /**
351
     * @return array<int, bool|int|string>
352
     * @psalm-return array{string, int, bool}
353
     */
354 244
    private function getNameForLevel1(
355
        bool $unicode,
356
        bool $unknown,
357
        string $part,
358
        string $name,
359
        int $level,
360
    ): array {
361 244
        $found = true;
362
363
        switch ($part) {
364 244
            case 'general':
365 16
                break;
366 228
            case 'bulgarian':
367 224
            case 'bg':
368 4
                $name = _pgettext('Collation', 'Bulgarian');
369 4
                break;
370 224
            case 'chinese':
371 204
            case 'cn':
372 204
            case 'zh':
373 20
                if ($unicode) {
374 4
                    $name = _pgettext('Collation', 'Chinese');
375
                }
376
377 20
                break;
378 204
            case 'croatian':
379 196
            case 'hr':
380 8
                $name = _pgettext('Collation', 'Croatian');
381 8
                break;
382 196
            case 'czech':
383 184
            case 'cs':
384 12
                $name = _pgettext('Collation', 'Czech');
385 12
                break;
386 184
            case 'danish':
387 180
            case 'da':
388 4
                $name = _pgettext('Collation', 'Danish');
389 4
                break;
390 180
            case 'english':
391 176
            case 'en':
392 4
                $name = _pgettext('Collation', 'English');
393 4
                break;
394 176
            case 'esperanto':
395 172
            case 'eo':
396 4
                $name = _pgettext('Collation', 'Esperanto');
397 4
                break;
398 172
            case 'estonian':
399 168
            case 'et':
400 4
                $name = _pgettext('Collation', 'Estonian');
401 4
                break;
402 168
            case 'german1':
403 4
                $name = _pgettext('Collation', 'German (dictionary order)');
404 4
                break;
405 164
            case 'german2':
406 4
                $name = _pgettext('Collation', 'German (phone book order)');
407 4
                break;
408 160
            case 'german':
409 160
            case 'de':
410
                /* Name is set later */
411 8
                $level = 2;
412 8
                break;
413 152
            case 'hungarian':
414 148
            case 'hu':
415 4
                $name = _pgettext('Collation', 'Hungarian');
416 4
                break;
417 148
            case 'icelandic':
418 144
            case 'is':
419 4
                $name = _pgettext('Collation', 'Icelandic');
420 4
                break;
421 144
            case 'japanese':
422 140
            case 'ja':
423 8
                $name = _pgettext('Collation', 'Japanese');
424 8
                break;
425 136
            case 'la':
426 4
                $name = _pgettext('Collation', 'Classical Latin');
427 4
                break;
428 132
            case 'latvian':
429 128
            case 'lv':
430 4
                $name = _pgettext('Collation', 'Latvian');
431 4
                break;
432 128
            case 'lithuanian':
433 124
            case 'lt':
434 4
                $name = _pgettext('Collation', 'Lithuanian');
435 4
                break;
436 124
            case 'korean':
437 120
            case 'ko':
438 4
                $name = _pgettext('Collation', 'Korean');
439 4
                break;
440 120
            case 'myanmar':
441 116
            case 'my':
442 4
                $name = _pgettext('Collation', 'Burmese');
443 4
                break;
444 116
            case 'persian':
445 4
                $name = _pgettext('Collation', 'Persian');
446 4
                break;
447 112
            case 'polish':
448 108
            case 'pl':
449 4
                $name = _pgettext('Collation', 'Polish');
450 4
                break;
451 108
            case 'roman':
452 4
                $name = _pgettext('Collation', 'West European');
453 4
                break;
454 104
            case 'romanian':
455 100
            case 'ro':
456 4
                $name = _pgettext('Collation', 'Romanian');
457 4
                break;
458 100
            case 'ru':
459 4
                $name = _pgettext('Collation', 'Russian');
460 4
                break;
461 96
            case 'si':
462 96
            case 'sinhala':
463 4
                $name = _pgettext('Collation', 'Sinhalese');
464 4
                break;
465 92
            case 'slovak':
466 88
            case 'sk':
467 4
                $name = _pgettext('Collation', 'Slovak');
468 4
                break;
469 88
            case 'slovenian':
470 84
            case 'sl':
471 4
                $name = _pgettext('Collation', 'Slovenian');
472 4
                break;
473 84
            case 'spanish':
474 4
                $name = _pgettext('Collation', 'Spanish (modern)');
475 4
                break;
476 80
            case 'es':
477
                /* Name is set later */
478 8
                $level = 3;
479 8
                break;
480 72
            case 'spanish2':
481 4
                $name = _pgettext('Collation', 'Spanish (traditional)');
482 4
                break;
483 68
            case 'swedish':
484 64
            case 'sv':
485 4
                $name = _pgettext('Collation', 'Swedish');
486 4
                break;
487 64
            case 'thai':
488 56
            case 'th':
489 8
                $name = _pgettext('Collation', 'Thai');
490 8
                break;
491 56
            case 'turkish':
492 48
            case 'tr':
493 12
                $name = _pgettext('Collation', 'Turkish');
494 12
                break;
495 44
            case 'ukrainian':
496 40
            case 'uk':
497 4
                $name = _pgettext('Collation', 'Ukrainian');
498 4
                break;
499 40
            case 'vietnamese':
500 36
            case 'vi':
501 4
                $name = _pgettext('Collation', 'Vietnamese');
502 4
                break;
503 36
            case 'unicode':
504 16
                if ($unknown) {
505 4
                    $name = _pgettext('Collation', 'Unicode');
506
                }
507
508 16
                break;
509
            default:
510 20
                $found = false;
511
        }
512
513 244
        return [$name, $level, $found];
514
    }
515
}
516