Completed
Push — master ( 59559b...bc4c4e )
by Gabriel
02:27
created

Str::mask()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 10
c 0
b 0
f 0
cc 4
nc 1
nop 3
crap 4
1
<?php
2
3
namespace Nip\Utility;
4
5
/**
6
 * Class Str
7
 * @package Nip\Utility
8
 */
9
class Str
10
{
11
12
    /**
13
     * The cache of snake-cased words.
14
     *
15
     * @var array
16
     */
17
    protected static $snakeCache = [];
18
19
    /**
20
     * The cache of camel-cased words.
21
     *
22
     * @var array
23
     */
24
    protected static $camelCache = [];
25
26
    /**
27
     * The cache of studly-cased words.
28
     *
29
     * @var array
30
     */
31
    protected static $studlyCache = [];
32
33
    /**
34
     * Convert a value to camel case.
35
     *
36
     * @param  string $value
37
     * @return string
38
     */
39
    public static function camel($value)
40
    {
41
        if (isset(static::$camelCache[$value])) {
42
            return static::$camelCache[$value];
43
        }
44
        return static::$camelCache[$value] = lcfirst(static::studly($value));
45
    }
46
47
    /**
48
     * Convert a value to studly caps case.
49
     *
50
     * @param  string $value
51
     * @return string
52
     */
53
    public static function studly($value)
54
    {
55
        $key = $value;
56
        if (isset(static::$studlyCache[$key])) {
57
            return static::$studlyCache[$key];
58
        }
59
        $value = ucwords(str_replace(['-', '_'], ' ', $value));
60
        return static::$studlyCache[$key] = str_replace(' ', '', $value);
61
    }
62
63
    /**
64
     * Determine if a given string ends with a given substring.
65
     *
66
     * @param  string $haystack
67
     * @param  string|array $needles
68
     * @return bool
69
     */
70 View Code Duplication
    public static function endsWith($haystack, $needles)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
    {
72
        foreach ((array)$needles as $needle) {
73
            if (substr($haystack, -strlen($needle)) === (string)$needle) {
74
                return true;
75
            }
76
        }
77
        return false;
78
    }
79
80
    /**
81
     * Cap a string with a single instance of a given value.
82
     *
83
     * @param  string $value
84
     * @param  string $cap
85
     * @return string
86
     */
87
    public static function finish($value, $cap)
88
    {
89
        $quoted = preg_quote($cap, '/');
90
        return preg_replace('/(?:' . $quoted . ')+$/u', '', $value) . $cap;
91
    }
92
93
    /**
94
     * Determine if a given string matches a given pattern.
95
     *
96
     * @param  string $pattern
97
     * @param  string $value
98
     * @return bool
99
     */
100
    public static function is($pattern, $value)
101
    {
102
        if ($pattern == $value) {
103
            return true;
104
        }
105
        $pattern = preg_quote($pattern, '#');
106
        // Asterisks are translated into zero-or-more regular expression wildcards
107
        // to make it convenient to check if the strings starts with the given
108
        // pattern such as "library/*", making any string check convenient.
109
        $pattern = str_replace('\*', '.*', $pattern);
110
        return (bool)preg_match('#^' . $pattern . '\z#u', $value);
111
    }
112
113
    /**
114
     * Convert a string to kebab case.
115
     *
116
     * @param  string $value
117
     * @return string
118
     */
119
    public static function kebab($value)
120
    {
121
        return static::snake($value, '-');
122
    }
123
124
    /**
125
     * Convert a string to snake case.
126
     *
127
     * @param  string $value
128
     * @param  string $delimiter
129
     * @return string
130
     */
131
    public static function snake($value, $delimiter = '_')
132
    {
133
        $key = $value;
134
        if (isset(static::$snakeCache[$key][$delimiter])) {
135
            return static::$snakeCache[$key][$delimiter];
136
        }
137
        if (!ctype_lower($value)) {
138
            $value = preg_replace('/\s+/u', '', $value);
139
            $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1' . $delimiter, $value));
140
        }
141
        return static::$snakeCache[$key][$delimiter] = $value;
142
    }
143
144
    /**
145
     * Convert the given string to lower-case.
146
     *
147
     * @param  string $value
148
     * @return string
149
     */
150
    public static function lower($value)
151
    {
152
        return mb_strtolower($value, 'UTF-8');
153
    }
154
155
    /**
156
     * Limit the number of characters in a string.
157
     *
158
     * @param  string $value
159
     * @param  int $limit
160
     * @param  string $end
161
     * @return string
162
     */
163
    public static function limit($value, $limit = 100, $end = '...')
164
    {
165
        if (mb_strwidth($value, 'UTF-8') <= $limit) {
166
            return $value;
167
        }
168
        return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')) . $end;
169
    }
170
171
    /**
172
     * Limit the number of words in a string.
173
     *
174
     * @param  string $value
175
     * @param  int $words
176
     * @param  string $end
177
     * @return string
178
     */
179
    public static function words($value, $words = 100, $end = '...')
180
    {
181
        preg_match('/^\s*+(?:\S++\s*+){1,' . $words . '}/u', $value, $matches);
182
        if (!isset($matches[0]) || static::length($value) === static::length($matches[0])) {
183
            return $value;
184
        }
185
        return rtrim($matches[0]) . $end;
186
    }
187
188
    /**
189
     * Return the length of the given string.
190
     *
191
     * @param  string $value
192
     * @return int
193
     */
194
    public static function length($value)
195
    {
196
        return mb_strlen($value);
197
    }
198
199
    /**
200
     * Parse a Class@method style callback into class and method.
201
     *
202
     * @param  string $callback
203
     * @param  string|null $default
204
     * @return array
205
     */
206
    public static function parseCallback($callback, $default = null)
207
    {
208
        return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default];
209
    }
210
211
    /**
212
     * Determine if a given string contains a given substring.
213
     *
214
     * @param  string $haystack
215
     * @param  string|array $needles
216
     * @return bool
217
     */
218 View Code Duplication
    public static function contains($haystack, $needles)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
219
    {
220
        foreach ((array)$needles as $needle) {
221
            if ($needle != '' && mb_strpos($haystack, $needle) !== false) {
222
                return true;
223
            }
224
        }
225
        return false;
226
    }
227
228
    /**
229
     * Get the plural form of an English word.
230
     *
231
     * @param  string $value
232
     * @param  int $count
233
     * @return string
234
     */
235
    public static function plural($value, $count = 2)
236
    {
237
        return Pluralizer::plural($value, $count);
238
    }
239
240
    /**
241
     * Generate a more truly "random" alpha-numeric string.
242
     *
243
     * @param  int $length
244
     * @return string
245
     */
246
    public static function random($length = 16)
247
    {
248
        $string = '';
249
        while (($len = strlen($string)) < $length) {
250
            $size = $length - $len;
251
            $bytes = random_bytes($size);
252
            $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
253
        }
254
        return $string;
255
    }
256
257
    /**
258
     * Replace a given value in the string sequentially with an array.
259
     *
260
     * @param  string $search
261
     * @param  array $replace
262
     * @param  string $subject
263
     * @return string
264
     */
265
    public static function replaceArray($search, array $replace, $subject)
266
    {
267
        foreach ($replace as $value) {
268
            $subject = static::replaceFirst($search, $value, $subject);
269
        }
270
        return $subject;
271
    }
272
273
    /**
274
     * Replace the first occurrence of a given value in the string.
275
     *
276
     * @param  string $search
277
     * @param  string $replace
278
     * @param  string $subject
279
     * @return string
280
     */
281 View Code Duplication
    public static function replaceFirst($search, $replace, $subject)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
282
    {
283
        $position = strpos($subject, $search);
284
        if ($position !== false) {
285
            return substr_replace($subject, $replace, $position, strlen($search));
286
        }
287
        return $subject;
288
    }
289
290
    /**
291
     * Replace the last occurrence of a given value in the string.
292
     *
293
     * @param  string $search
294
     * @param  string $replace
295
     * @param  string $subject
296
     * @return string
297
     */
298 View Code Duplication
    public static function replaceLast($search, $replace, $subject)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
299
    {
300
        $position = strrpos($subject, $search);
301
        if ($position !== false) {
302
            return substr_replace($subject, $replace, $position, strlen($search));
303
        }
304
        return $subject;
305
    }
306
307
    /**
308
     * Convert the given string to title case.
309
     *
310
     * @param  string $value
311
     * @return string
312
     */
313
    public static function title($value)
314
    {
315
        return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
316
    }
317
318
    /**
319
     * Get the singular form of an English word.
320
     *
321
     * @param  string $value
322
     * @return string
323
     */
324
    public static function singular($value)
325
    {
326
        return Pluralizer::singular($value);
327
    }
328
329
    /**
330
     * Generate a URL friendly "slug" from a given string.
331
     *
332
     * @param  string $title
333
     * @param  string $separator
334
     * @return string
335
     */
336
    public static function slug($title, $separator = '-')
337
    {
338
        $title = static::ascii($title);
339
        // Convert all dashes/underscores into separator
340
        $flip = $separator == '-' ? '_' : '-';
341
        $title = preg_replace('![' . preg_quote($flip) . ']+!u', $separator, $title);
342
        // Remove all characters that are not the separator, letters, numbers, or whitespace.
343
        $title = preg_replace('![^' . preg_quote($separator) . '\pL\pN\s]+!u', '', mb_strtolower($title));
344
        // Replace all separator characters and whitespace by a single separator
345
        $title = preg_replace('![' . preg_quote($separator) . '\s]+!u', $separator, $title);
346
        return trim($title, $separator);
347
    }
348
349
    /**
350
     * Transliterate a UTF-8 value to ASCII.
351
     *
352
     * @param  string $value
353
     * @return string
354
     */
355
    public static function ascii($value)
356
    {
357
        foreach (static::charsArray() as $key => $val) {
358
            $value = str_replace($val, $key, $value);
359
        }
360
        return preg_replace('/[^\x20-\x7E]/u', '', $value);
361
    }
362
363
    /**
364
     * Returns the replacements for the ascii method.
365
     *
366
     * Note: Adapted from Stringy\Stringy.
367
     *
368
     * @see https://github.com/danielstjules/Stringy/blob/2.3.1/LICENSE.txt
369
     *
370
     * @return array
371
     */
372
    protected static function charsArray()
373
    {
374
        static $charsArray;
375
        if (isset($charsArray)) {
376
            return $charsArray;
377
        }
378
        return $charsArray = [
379
            '0' => ['°', '₀', '۰'],
380
            '1' => ['¹', '₁', '۱'],
381
            '2' => ['²', '₂', '۲'],
382
            '3' => ['³', '₃', '۳'],
383
            '4' => ['⁴', '₄', '۴', '٤'],
384
            '5' => ['⁵', '₅', '۵', '٥'],
385
            '6' => ['⁶', '₆', '۶', '٦'],
386
            '7' => ['⁷', '₇', '۷'],
387
            '8' => ['⁸', '₈', '۸'],
388
            '9' => ['⁹', '₉', '۹'],
389
            'a' => [
390
                'à',
391
                'á',
392
                'ả',
393
                'ã',
394
                'ạ',
395
                'ă',
396
                'ắ',
397
                'ằ',
398
                'ẳ',
399
                'ẵ',
400
                'ặ',
401
                'â',
402
                'ấ',
403
                'ầ',
404
                'ẩ',
405
                'ẫ',
406
                'ậ',
407
                'ā',
408
                'ą',
409
                'å',
410
                'α',
411
                'ά',
412
                'ἀ',
413
                'ἁ',
414
                'ἂ',
415
                'ἃ',
416
                'ἄ',
417
                'ἅ',
418
                'ἆ',
419
                'ἇ',
420
                'ᾀ',
421
                'ᾁ',
422
                'ᾂ',
423
                'ᾃ',
424
                'ᾄ',
425
                'ᾅ',
426
                'ᾆ',
427
                'ᾇ',
428
                'ὰ',
429
                'ά',
430
                'ᾰ',
431
                'ᾱ',
432
                'ᾲ',
433
                'ᾳ',
434
                'ᾴ',
435
                'ᾶ',
436
                'ᾷ',
437
                'а',
438
                'أ',
439
                'အ',
440
                'ာ',
441
                'ါ',
442
                'ǻ',
443
                'ǎ',
444
                'ª',
445
                'ა',
446
                'अ',
447
                'ا'
448
            ],
449
            'b' => ['б', 'β', 'Ъ', 'Ь', 'ب', 'ဗ', 'ბ'],
450
            'c' => ['ç', 'ć', 'č', 'ĉ', 'ċ'],
451
            'd' => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', 'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ'],
452
            'e' => [
453
                'é',
454
                'è',
455
                'ẻ',
456
                'ẽ',
457
                'ẹ',
458
                'ê',
459
                'ế',
460
                'ề',
461
                'ể',
462
                'ễ',
463
                'ệ',
464
                'ë',
465
                'ē',
466
                'ę',
467
                'ě',
468
                'ĕ',
469
                'ė',
470
                'ε',
471
                'έ',
472
                'ἐ',
473
                'ἑ',
474
                'ἒ',
475
                'ἓ',
476
                'ἔ',
477
                'ἕ',
478
                'ὲ',
479
                'έ',
480
                'е',
481
                'ё',
482
                'э',
483
                'є',
484
                'ə',
485
                'ဧ',
486
                'ေ',
487
                'ဲ',
488
                'ე',
489
                'ए',
490
                'إ',
491
                'ئ'
492
            ],
493
            'f' => ['ф', 'φ', 'ف', 'ƒ', 'ფ'],
494
            'g' => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', 'گ'],
495
            'h' => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ'],
496
            'i' => [
497
                'í',
498
                'ì',
499
                'ỉ',
500
                'ĩ',
501
                'ị',
502
                'î',
503
                'ï',
504
                'ī',
505
                'ĭ',
506
                'į',
507
                'ı',
508
                'ι',
509
                'ί',
510
                'ϊ',
511
                'ΐ',
512
                'ἰ',
513
                'ἱ',
514
                'ἲ',
515
                'ἳ',
516
                'ἴ',
517
                'ἵ',
518
                'ἶ',
519
                'ἷ',
520
                'ὶ',
521
                'ί',
522
                'ῐ',
523
                'ῑ',
524
                'ῒ',
525
                'ΐ',
526
                'ῖ',
527
                'ῗ',
528
                'і',
529
                'ї',
530
                'и',
531
                'ဣ',
532
                'ိ',
533
                'ီ',
534
                'ည်',
535
                'ǐ',
536
                'ი',
537
                'इ'
538
            ],
539
            'j' => ['ĵ', 'ј', 'Ј', 'ჯ', 'ج'],
540
            'k' => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك', 'က', 'კ', 'ქ', 'ک'],
541
            'l' => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل', 'လ', 'ლ'],
542
            'm' => ['м', 'μ', 'م', 'မ', 'მ'],
543
            'n' => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န', 'ნ'],
544
            'o' => [
545
                'ó',
546
                'ò',
547
                'ỏ',
548
                'õ',
549
                'ọ',
550
                'ô',
551
                'ố',
552
                'ồ',
553
                'ổ',
554
                'ỗ',
555
                'ộ',
556
                'ơ',
557
                'ớ',
558
                'ờ',
559
                'ở',
560
                'ỡ',
561
                'ợ',
562
                'ø',
563
                'ō',
564
                'ő',
565
                'ŏ',
566
                'ο',
567
                'ὀ',
568
                'ὁ',
569
                'ὂ',
570
                'ὃ',
571
                'ὄ',
572
                'ὅ',
573
                'ὸ',
574
                'ό',
575
                'о',
576
                'و',
577
                'θ',
578
                'ို',
579
                'ǒ',
580
                'ǿ',
581
                'º',
582
                'ო',
583
                'ओ'
584
            ],
585
            'p' => ['п', 'π', 'ပ', 'პ', 'پ'],
586
            'q' => ['ყ'],
587
            'r' => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', 'რ'],
588
            's' => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ', 'ſ', 'ს'],
589
            't' => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ', 'თ', 'ტ'],
590
            'u' => [
591
                'ú',
592
                'ù',
593
                'ủ',
594
                'ũ',
595
                'ụ',
596
                'ư',
597
                'ứ',
598
                'ừ',
599
                'ử',
600
                'ữ',
601
                'ự',
602
                'û',
603
                'ū',
604
                'ů',
605
                'ű',
606
                'ŭ',
607
                'ų',
608
                'µ',
609
                'у',
610
                'ဉ',
611
                'ု',
612
                'ူ',
613
                'ǔ',
614
                'ǖ',
615
                'ǘ',
616
                'ǚ',
617
                'ǜ',
618
                'უ',
619
                'उ'
620
            ],
621
            'v' => ['в', 'ვ', 'ϐ'],
622
            'w' => ['ŵ', 'ω', 'ώ', 'ဝ', 'ွ'],
623
            'x' => ['χ', 'ξ'],
624
            'y' => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', 'ϋ', 'ύ', 'ΰ', 'ي', 'ယ'],
625
            'z' => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ'],
626
            'aa' => ['ع', 'आ', 'آ'],
627
            'ae' => ['ä', 'æ', 'ǽ'],
628
            'ai' => ['ऐ'],
629
            'at' => ['@'],
630
            'ch' => ['ч', 'ჩ', 'ჭ', 'چ'],
631
            'dj' => ['ђ', 'đ'],
632
            'dz' => ['џ', 'ძ'],
633
            'ei' => ['ऍ'],
634
            'gh' => ['غ', 'ღ'],
635
            'ii' => ['ई'],
636
            'ij' => ['ij'],
637
            'kh' => ['х', 'خ', 'ხ'],
638
            'lj' => ['љ'],
639
            'nj' => ['њ'],
640
            'oe' => ['ö', 'œ', 'ؤ'],
641
            'oi' => ['ऑ'],
642
            'oii' => ['ऒ'],
643
            'ps' => ['ψ'],
644
            'sh' => ['ш', 'შ', 'ش'],
645
            'shch' => ['щ'],
646
            'ss' => ['ß'],
647
            'sx' => ['ŝ'],
648
            'th' => ['þ', 'ϑ', 'ث', 'ذ', 'ظ'],
649
            'ts' => ['ц', 'ც', 'წ'],
650
            'ue' => ['ü'],
651
            'uu' => ['ऊ'],
652
            'ya' => ['я'],
653
            'yu' => ['ю'],
654
            'zh' => ['ж', 'ჟ', 'ژ'],
655
            '(c)' => ['©'],
656
            'A' => [
657
                'Á',
658
                'À',
659
                'Ả',
660
                'Ã',
661
                'Ạ',
662
                'Ă',
663
                'Ắ',
664
                'Ằ',
665
                'Ẳ',
666
                'Ẵ',
667
                'Ặ',
668
                'Â',
669
                'Ấ',
670
                'Ầ',
671
                'Ẩ',
672
                'Ẫ',
673
                'Ậ',
674
                'Å',
675
                'Ā',
676
                'Ą',
677
                'Α',
678
                'Ά',
679
                'Ἀ',
680
                'Ἁ',
681
                'Ἂ',
682
                'Ἃ',
683
                'Ἄ',
684
                'Ἅ',
685
                'Ἆ',
686
                'Ἇ',
687
                'ᾈ',
688
                'ᾉ',
689
                'ᾊ',
690
                'ᾋ',
691
                'ᾌ',
692
                'ᾍ',
693
                'ᾎ',
694
                'ᾏ',
695
                'Ᾰ',
696
                'Ᾱ',
697
                'Ὰ',
698
                'Ά',
699
                'ᾼ',
700
                'А',
701
                'Ǻ',
702
                'Ǎ'
703
            ],
704
            'B' => ['Б', 'Β', 'ब'],
705
            'C' => ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ'],
706
            'D' => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ'],
707
            'E' => [
708
                'É',
709
                'È',
710
                'Ẻ',
711
                'Ẽ',
712
                'Ẹ',
713
                'Ê',
714
                'Ế',
715
                'Ề',
716
                'Ể',
717
                'Ễ',
718
                'Ệ',
719
                'Ë',
720
                'Ē',
721
                'Ę',
722
                'Ě',
723
                'Ĕ',
724
                'Ė',
725
                'Ε',
726
                'Έ',
727
                'Ἐ',
728
                'Ἑ',
729
                'Ἒ',
730
                'Ἓ',
731
                'Ἔ',
732
                'Ἕ',
733
                'Έ',
734
                'Ὲ',
735
                'Е',
736
                'Ё',
737
                'Э',
738
                'Є',
739
                'Ə'
740
            ],
741
            'F' => ['Ф', 'Φ'],
742
            'G' => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ'],
743
            'H' => ['Η', 'Ή', 'Ħ'],
744
            'I' => [
745
                'Í',
746
                'Ì',
747
                'Ỉ',
748
                'Ĩ',
749
                'Ị',
750
                'Î',
751
                'Ï',
752
                'Ī',
753
                'Ĭ',
754
                'Į',
755
                'İ',
756
                'Ι',
757
                'Ί',
758
                'Ϊ',
759
                'Ἰ',
760
                'Ἱ',
761
                'Ἳ',
762
                'Ἴ',
763
                'Ἵ',
764
                'Ἶ',
765
                'Ἷ',
766
                'Ῐ',
767
                'Ῑ',
768
                'Ὶ',
769
                'Ί',
770
                'И',
771
                'І',
772
                'Ї',
773
                'Ǐ',
774
                'ϒ'
775
            ],
776
            'K' => ['К', 'Κ'],
777
            'L' => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल'],
778
            'M' => ['М', 'Μ'],
779
            'N' => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν'],
780
            'O' => [
781
                'Ó',
782
                'Ò',
783
                'Ỏ',
784
                'Õ',
785
                'Ọ',
786
                'Ô',
787
                'Ố',
788
                'Ồ',
789
                'Ổ',
790
                'Ỗ',
791
                'Ộ',
792
                'Ơ',
793
                'Ớ',
794
                'Ờ',
795
                'Ở',
796
                'Ỡ',
797
                'Ợ',
798
                'Ø',
799
                'Ō',
800
                'Ő',
801
                'Ŏ',
802
                'Ο',
803
                'Ό',
804
                'Ὀ',
805
                'Ὁ',
806
                'Ὂ',
807
                'Ὃ',
808
                'Ὄ',
809
                'Ὅ',
810
                'Ὸ',
811
                'Ό',
812
                'О',
813
                'Θ',
814
                'Ө',
815
                'Ǒ',
816
                'Ǿ'
817
            ],
818
            'P' => ['П', 'Π'],
819
            'R' => ['Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ'],
820
            'S' => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ'],
821
            'T' => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ'],
822
            'U' => [
823
                'Ú',
824
                'Ù',
825
                'Ủ',
826
                'Ũ',
827
                'Ụ',
828
                'Ư',
829
                'Ứ',
830
                'Ừ',
831
                'Ử',
832
                'Ữ',
833
                'Ự',
834
                'Û',
835
                'Ū',
836
                'Ů',
837
                'Ű',
838
                'Ŭ',
839
                'Ų',
840
                'У',
841
                'Ǔ',
842
                'Ǖ',
843
                'Ǘ',
844
                'Ǚ',
845
                'Ǜ'
846
            ],
847
            'V' => ['В'],
848
            'W' => ['Ω', 'Ώ', 'Ŵ'],
849
            'X' => ['Χ', 'Ξ'],
850
            'Y' => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', 'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ'],
851
            'Z' => ['Ź', 'Ž', 'Ż', 'З', 'Ζ'],
852
            'AE' => ['Ä', 'Æ', 'Ǽ'],
853
            'CH' => ['Ч'],
854
            'DJ' => ['Ђ'],
855
            'DZ' => ['Џ'],
856
            'GX' => ['Ĝ'],
857
            'HX' => ['Ĥ'],
858
            'IJ' => ['IJ'],
859
            'JX' => ['Ĵ'],
860
            'KH' => ['Х'],
861
            'LJ' => ['Љ'],
862
            'NJ' => ['Њ'],
863
            'OE' => ['Ö', 'Œ'],
864
            'PS' => ['Ψ'],
865
            'SH' => ['Ш'],
866
            'SHCH' => ['Щ'],
867
            'SS' => ['ẞ'],
868
            'TH' => ['Þ'],
869
            'TS' => ['Ц'],
870
            'UE' => ['Ü'],
871
            'YA' => ['Я'],
872
            'YU' => ['Ю'],
873
            'ZH' => ['Ж'],
874
            ' ' => [
875
                "\xC2\xA0",
876
                "\xE2\x80\x80",
877
                "\xE2\x80\x81",
878
                "\xE2\x80\x82",
879
                "\xE2\x80\x83",
880
                "\xE2\x80\x84",
881
                "\xE2\x80\x85",
882
                "\xE2\x80\x86",
883
                "\xE2\x80\x87",
884
                "\xE2\x80\x88",
885
                "\xE2\x80\x89",
886
                "\xE2\x80\x8A",
887
                "\xE2\x80\xAF",
888
                "\xE2\x81\x9F",
889
                "\xE3\x80\x80"
890
            ],
891
        ];
892
    }
893
894
    /**
895
     * Determine if a given string starts with a given substring.
896
     *
897
     * @param  string $haystack
898
     * @param  string|array $needles
899
     * @return bool
900
     */
901 View Code Duplication
    public static function startsWith($haystack, $needles)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
902
    {
903
        foreach ((array)$needles as $needle) {
904
            if ($needle != '' && substr($haystack, 0, strlen($needle)) === (string)$needle) {
905
                return true;
906
            }
907
        }
908
        return false;
909
    }
910
911
    /**
912
     * Make a string's first character uppercase.
913
     *
914
     * @param  string $string
915
     * @return string
916
     */
917
    public static function ucfirst($string)
918
    {
919
        return static::upper(static::substr($string, 0, 1)) . static::substr($string, 1);
920
    }
921
922
    /**
923
     * Convert the given string to upper-case.
924
     *
925
     * @param  string $value
926
     * @return string
927
     */
928
    public static function upper($value)
929
    {
930
        return mb_strtoupper($value, 'UTF-8');
931
    }
932
933
    /**
934
     * Returns the portion of string specified by the start and length parameters.
935
     *
936
     * @param  string $string
937
     * @param  int $start
938
     * @param  int|null $length
939
     * @return string
940
     */
941
    public static function substr($string, $start, $length = null)
942
    {
943
        return mb_substr($string, $start, $length, 'UTF-8');
944
    }
945
946
    /**
947
     * @param $data
948
     * @param bool $strict
949
     * @return bool
950
     */
951
    public static function isSerialized($data, $strict = true)
952
    {
953
        // if it isn't a string, it isn't serialized.
954
        if (!is_string($data)) {
955
            return false;
956
        }
957
        $data = trim($data);
958
        if ('N;' == $data) {
959
            return true;
960
        }
961
        if (strlen($data) < 4) {
962
            return false;
963
        }
964
        if (':' !== $data[1]) {
965
            return false;
966
        }
967
        if ($strict) {
968
            $lastc = substr($data, -1);
969
            if (';' !== $lastc && '}' !== $lastc) {
970
                return false;
971
            }
972
        } else {
973
            $semicolon = strpos($data, ';');
974
            $brace = strpos($data, '}');
975
            // Either ; or } must exist.
976
            if (false === $semicolon && false === $brace) {
977
                return false;
978
            }
979
            // But neither must be in the first X characters.
980
            if (false !== $semicolon && $semicolon < 3) {
981
                return false;
982
            }
983
            if (false !== $brace && $brace < 4) {
984
                return false;
985
            }
986
        }
987
        $token = $data[0];
988
        switch ($token) {
989
            case 's':
990
                if ($strict) {
991
                    if ('"' !== substr($data, -2, 1)) {
992
                        return false;
993
                    }
994
                } elseif (false === strpos($data, '"')) {
995
                    return false;
996
                }
997
            // or else fall through
998
            case 'a':
999
            case 'O':
1000
                return (bool)preg_match("/^{$token}:[0-9]+:/s", $data);
1001
            case 'b':
1002
            case 'i':
1003
            case 'd':
1004
                $end = $strict ? '$' : '';
1005
                return (bool)preg_match("/^{$token}:[0-9.E-]+;$end/", $data);
1006
        }
1007
        return false;
1008
    }
1009
1010
    /**
1011
     * @param $str
1012
     * @param $first
1013
     * @param $last
1014
     * @return string
1015
     */
1016 9
    public static function mask($str, $first = 0, $last = 0)
1017
    {
1018 9
        $len = strlen($str);
1019 9
        $toShow = $first + $last;
1020 9
        return substr($str, 0, $len <= $toShow ? 0 : $first)
1021 9
            . str_repeat("*", $len - ($len <= $toShow ? 0 : $toShow))
1022 9
            . substr($str, $len - $last, $len <= $toShow ? 0 : $last);
1023
    }
1024
}
1025