Completed
Push — master ( 10ad6d...d219c5 )
by Lars
01:34
created

Stringy::htmlDecode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 11
Ratio 100 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 11
loc 11
ccs 7
cts 7
cp 1
crap 1
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stringy;
6
7
use Defuse\Crypto\Crypto;
8
use voku\helper\AntiXSS;
9
use voku\helper\ASCII;
10
use voku\helper\EmailCheck;
11
use voku\helper\URLify;
12
use voku\helper\UTF8;
13
14
/**
15
 * @template-implements \IteratorAggregate<string>
16
 * @template-implements \ArrayAccess<array-key,string>
17
 */
18
class Stringy implements \ArrayAccess, \Countable, \IteratorAggregate, \JsonSerializable
19
{
20
    /**
21
     * An instance's string.
22
     *
23
     * @var string
24
     */
25
    protected $str;
26
27
    /**
28
     * The string's encoding, which should be one of the mbstring module's
29
     * supported encodings.
30
     *
31
     * @var string
32
     */
33
    protected $encoding;
34
35
    /**
36
     * @var UTF8
37
     */
38
    private $utf8;
39
40
    /**
41
     * @var ASCII
42
     */
43
    private $ascii;
44
45
    /**
46
     * Initializes a Stringy object and assigns both str and encoding properties
47
     * the supplied values. $str is cast to a string prior to assignment, and if
48
     * $encoding is not specified, it defaults to mb_internal_encoding(). Throws
49
     * an InvalidArgumentException if the first argument is an array or object
50
     * without a __toString method.
51
     *
52
     * @param mixed  $str      [optional] <p>Value to modify, after being cast to string. Default: ''</p>
53
     * @param string $encoding [optional] <p>The character encoding. Fallback: 'UTF-8'</p>
54
     *
55
     * @throws \InvalidArgumentException
56
     *                                   <p>if an array or object without a
57
     *                                   __toString method is passed as the first argument</p>
58
     *
59
     * @psalm-mutation-free
60
     */
61 3601
    public function __construct($str = '', string $encoding = null)
62
    {
63 3601
        if (\is_array($str)) {
64 3
            throw new \InvalidArgumentException(
65 3
                'Passed value cannot be an array'
66
            );
67
        }
68
69
        if (
70 3598
            \is_object($str)
71
            &&
72 3598
            !\method_exists($str, '__toString')
73
        ) {
74 3
            throw new \InvalidArgumentException(
75 3
                'Passed object must have a __toString method'
76
            );
77
        }
78
79 3595
        $this->str = (string) $str;
80
81 3595
        static $ASCII = null;
82 3595
        if ($ASCII === null) {
83
            $ASCII = new ASCII();
84
        }
85 3595
        $this->ascii = $ASCII;
86
87 3595
        static $UTF8 = null;
88 3595
        if ($UTF8 === null) {
89
            $UTF8 = new UTF8();
90
        }
91 3595
        $this->utf8 = $UTF8;
92
93 3595
        if ($encoding !== 'UTF-8') {
94 2425
            $this->encoding = $this->utf8::normalize_encoding($encoding, 'UTF-8');
95
        } else {
96 2685
            $this->encoding = $encoding;
97
        }
98 3595
    }
99
100
    /**
101
     * Returns the value in $str.
102
     *
103
     * @psalm-mutation-free
104
     *
105
     * @return string
106
     *                <p>The current value of the $str property.</p>
107
     */
108 1127
    public function __toString()
109
    {
110 1127
        return (string) $this->str;
111
    }
112
113
    /**
114
     * Return part of the string occurring after a specific string.
115
     *
116
     * @param string $string The delimiting string
117
     *
118
     * @psalm-mutation-free
119
     *
120
     * @return static
121
     */
122 4
    public function after(string $string): self
123
    {
124 4
        $strArray = UTF8::str_split_pattern(
125 4
            $this->str,
126 4
            $string
127
        );
128
129 4
        unset($strArray[0]);
130
131 4
        return new static(
132 4
            \implode(' ', $strArray),
133 4
            $this->encoding
134
        );
135
    }
136
137
    /**
138
     * Gets the substring after the first occurrence of a separator.
139
     * If no match is found returns new empty Stringy object.
140
     *
141
     * @param string $separator
142
     *
143
     * @psalm-mutation-free
144
     *
145
     * @return static
146
     */
147 3
    public function afterFirst(string $separator): self
148
    {
149 3
        return static::create(
150 3
            $this->utf8::str_substr_after_first_separator(
151 3
                $this->str,
152 3
                $separator,
153 3
                $this->encoding
154
            )
155
        );
156
    }
157
158
    /**
159
     * Gets the substring after the first occurrence of a separator.
160
     * If no match is found returns new empty Stringy object.
161
     *
162
     * @param string $separator
163
     *
164
     * @psalm-mutation-free
165
     *
166
     * @return static
167
     */
168 2
    public function afterFirstIgnoreCase(string $separator): self
169
    {
170 2
        return static::create(
171 2
            $this->utf8::str_isubstr_after_first_separator(
172 2
                $this->str,
173 2
                $separator,
174 2
                $this->encoding
175
            )
176
        );
177
    }
178
179
    /**
180
     * Gets the substring after the last occurrence of a separator.
181
     * If no match is found returns new empty Stringy object.
182
     *
183
     * @param string $separator
184
     *
185
     * @psalm-mutation-free
186
     *
187
     * @return static
188
     */
189 2
    public function afterLast(string $separator): self
190
    {
191 2
        return static::create(
192 2
            $this->utf8::str_substr_after_last_separator(
193 2
                $this->str,
194 2
                $separator,
195 2
                $this->encoding
196
            )
197
        );
198
    }
199
200
    /**
201
     * Gets the substring after the last occurrence of a separator.
202
     * If no match is found returns new empty Stringy object.
203
     *
204
     * @param string $separator
205
     *
206
     * @psalm-mutation-free
207
     *
208
     * @return static
209
     */
210 2
    public function afterLastIgnoreCase(string $separator): self
211
    {
212 2
        return static::create(
213 2
            $this->utf8::str_isubstr_after_last_separator(
214 2
                $this->str,
215 2
                $separator,
216 2
                $this->encoding
217
            )
218
        );
219
    }
220
221
    /**
222
     * Returns a new string with $suffix appended.
223
     *
224
     * @param string ...$suffix <p>The string to append.</p>
225
     *
226
     * @psalm-mutation-free
227
     *
228
     * @return static
229
     *                <p>Object with appended $suffix.</p>
230
     *
231
     * @noinspection PhpDocSignatureInspection
232
     */
233 14 View Code Duplication
    public function append(string ...$suffix): self
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...
234
    {
235 14
        if (\count($suffix) <= 1) {
236
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
237 13
            $suffix = $suffix[0];
238
        } else {
239
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
240 1
            $suffix = \implode('', $suffix);
241
        }
242
243 14
        return static::create($this->str . $suffix, $this->encoding);
244
    }
245
246
    /**
247
     * Append an password (limited to chars that are good readable).
248
     *
249
     * @param int $length <p>Length of the random string.</p>
250
     *
251
     * @return static
252
     *                <p>Object with appended password.</p>
253
     */
254 2
    public function appendPassword(int $length): self
255
    {
256 2
        return $this->appendRandomString(
257 2
            $length,
258 2
            '2346789bcdfghjkmnpqrtvwxyzBCDFGHJKLMNPQRTVWXYZ!?_#'
259
        );
260
    }
261
262
    /**
263
     * Append an random string.
264
     *
265
     * @param int    $length        <p>Length of the random string.</p>
266
     * @param string $possibleChars [optional] <p>Characters string for the random selection.</p>
267
     *
268
     * @return static
269
     *                <p>Object with appended random string.</p>
270
     */
271 4
    public function appendRandomString(int $length, string $possibleChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'): self
272
    {
273 4
        $str = $this->utf8::get_random_string($length, $possibleChars);
274
275 4
        return $this->append($str);
276
    }
277
278
    /**
279
     * Append an unique identifier.
280
     *
281
     * @param int|string $entropyExtra [optional] <p>Extra entropy via a string or int value.</p>
282
     * @param bool       $md5          [optional] <p>Return the unique identifier as md5-hash? Default: true</p>
283
     *
284
     * @return static
285
     *                <p>Object with appended unique identifier as md5-hash.</p>
286
     */
287 2
    public function appendUniqueIdentifier($entropyExtra = '', bool $md5 = true): self
288
    {
289 2
        return $this->append(
290 2
            $this->utf8::get_unique_string($entropyExtra, $md5)
291
        );
292
    }
293
294
    /**
295
     * Returns the character at $index, with indexes starting at 0.
296
     *
297
     * @param int $index <p>Position of the character.</p>
298
     *
299
     * @psalm-mutation-free
300
     *
301
     * @return static
302
     *                <p>The character at $index.</p>
303
     */
304 24
    public function at(int $index): self
305
    {
306 24
        return static::create($this->utf8::char_at($this->str, $index), $this->encoding);
307
    }
308
309
    /**
310
     * Decode the base64 encoded string.
311
     *
312
     * @psalm-mutation-free
313
     *
314
     * @return self
315
     */
316 2
    public function base64Decode(): self
317
    {
318 2
        return static::create(
319 2
            \base64_decode($this->str, true),
320 2
            $this->encoding
321
        );
322
    }
323
324
    /**
325
     * Encode the string to base64.
326
     *
327
     * @psalm-mutation-free
328
     *
329
     * @return self
330
     */
331 2
    public function base64Encode(): self
332
    {
333 2
        return static::create(
334 2
            \base64_encode($this->str),
335 2
            $this->encoding
336
        );
337
    }
338
339
    /**
340
     * Creates a hash from the string using the CRYPT_BLOWFISH algorithm.
341
     *
342
     * @param array<array-key, int|string> $options An array of bcrypt hasing options
343
     *
344
     * @return static
345
     */
346 3
    public function bcrypt(array $options = []): self
347
    {
348 3
        return new static(
349 3
            \password_hash(
350 3
                $this->str,
351 3
                \PASSWORD_BCRYPT,
352 3
                $options
353
            ),
354 3
            $this->encoding
355
        );
356
    }
357
358
    /**
359
     * Return part of the string occurring before a specific string.
360
     *
361
     * @param string $string The delimiting string
362
     *
363
     * @psalm-mutation-free
364
     *
365
     * @return static
366
     */
367 4
    public function before(string $string): self
368
    {
369 4
        $strArray = UTF8::str_split_pattern(
370 4
            $this->str,
371 4
            $string,
372 4
            1
373
        );
374
375 4
        return new static(
376 4
            $strArray[0] ?? '',
377 4
            $this->encoding
378
        );
379
    }
380
381
    /**
382
     * Gets the substring before the first occurrence of a separator.
383
     * If no match is found returns new empty Stringy object.
384
     *
385
     * @param string $separator
386
     *
387
     * @psalm-mutation-free
388
     *
389
     * @return static
390
     */
391 2
    public function beforeFirst(string $separator): self
392
    {
393 2
        return static::create(
394 2
            $this->utf8::str_substr_before_first_separator(
395 2
                $this->str,
396 2
                $separator,
397 2
                $this->encoding
398
            )
399
        );
400
    }
401
402
    /**
403
     * Gets the substring before the first occurrence of a separator.
404
     * If no match is found returns new empty Stringy object.
405
     *
406
     * @param string $separator
407
     *
408
     * @psalm-mutation-free
409
     *
410
     * @return static
411
     */
412 2
    public function beforeFirstIgnoreCase(string $separator): self
413
    {
414 2
        return static::create(
415 2
            $this->utf8::str_isubstr_before_first_separator(
416 2
                $this->str,
417 2
                $separator,
418 2
                $this->encoding
419
            )
420
        );
421
    }
422
423
    /**
424
     * Gets the substring before the last occurrence of a separator.
425
     * If no match is found returns new empty Stringy object.
426
     *
427
     * @param string $separator
428
     *
429
     * @psalm-mutation-free
430
     *
431
     * @return static
432
     */
433 2
    public function beforeLast(string $separator): self
434
    {
435 2
        return static::create(
436 2
            $this->utf8::str_substr_before_last_separator(
437 2
                $this->str,
438 2
                $separator,
439 2
                $this->encoding
440
            )
441
        );
442
    }
443
444
    /**
445
     * Gets the substring before the last occurrence of a separator.
446
     * If no match is found returns new empty Stringy object.
447
     *
448
     * @param string $separator
449
     *
450
     * @psalm-mutation-free
451
     *
452
     * @return static
453
     */
454 2
    public function beforeLastIgnoreCase(string $separator): self
455
    {
456 2
        return static::create(
457 2
            $this->utf8::str_isubstr_before_last_separator(
458 2
                $this->str,
459 2
                $separator,
460 2
                $this->encoding
461
            )
462
        );
463
    }
464
465
    /**
466
     * Returns the substring between $start and $end, if found, or an empty
467
     * string. An optional offset may be supplied from which to begin the
468
     * search for the start string.
469
     *
470
     * @param string $start  <p>Delimiter marking the start of the substring.</p>
471
     * @param string $end    <p>Delimiter marking the end of the substring.</p>
472
     * @param int    $offset [optional] <p>Index from which to begin the search. Default: 0</p>
473
     *
474
     * @psalm-mutation-free
475
     *
476
     * @return static
477
     *                <p>Object whose $str is a substring between $start and $end.</p>
478
     */
479 48
    public function between(string $start, string $end, int $offset = null): self
480
    {
481
        /** @noinspection UnnecessaryCastingInspection */
482 48
        $str = $this->utf8::between(
483 48
            $this->str,
484 48
            $start,
485 48
            $end,
486 48
            (int) $offset,
487 48
            $this->encoding
488
        );
489
490 48
        return static::create($str, $this->encoding);
491
    }
492
493
    /**
494
     * Returns a camelCase version of the string. Trims surrounding spaces,
495
     * capitalizes letters following digits, spaces, dashes and underscores,
496
     * and removes spaces, dashes, as well as underscores.
497
     *
498
     * @psalm-mutation-free
499
     *
500
     * @return static
501
     *                <p>Object with $str in camelCase.</p>
502
     */
503 57
    public function camelize(): self
504
    {
505 57
        return static::create(
506 57
            $this->utf8::str_camelize($this->str, $this->encoding),
507 57
            $this->encoding
508
        );
509
    }
510
511
    /**
512
     * Returns the string with the first letter of each word capitalized,
513
     * except for when the word is a name which shouldn't be capitalized.
514
     *
515
     * @psalm-mutation-free
516
     *
517
     * @return static
518
     *                <p>Object with $str capitalized.</p>
519
     */
520 78
    public function capitalizePersonalName(): self
521
    {
522 78
        return static::create(
523 78
            $this->utf8::str_capitalize_name($this->str),
524 78
            $this->encoding
525
        );
526
    }
527
528
    /**
529
     * Returns an array consisting of the characters in the string.
530
     *
531
     * @psalm-mutation-free
532
     *
533
     * @return string[]
534
     *                  <p>An array of string chars.</p>
535
     */
536 14
    public function chars(): array
537
    {
538 14
        return $this->utf8::str_split($this->str);
539
    }
540
541
    /**
542
     * Splits the string into chunks of Stringy objects.
543
     *
544
     * @param int $length
545
     *
546
     * @psalm-mutation-free
547
     *
548
     * @return CollectionStringy|static[]
549
     *                                    <p>An collection of Stringy objects.</p>
550
     *
551
     * @psalm-return CollectionStringy<int,static>
552
     */
553 13
    public function chunk(int $length = 1): CollectionStringy
554
    {
555 13
        if ($length < 1) {
556
            throw new \InvalidArgumentException('The chunk length must be greater than zero.');
557
        }
558
559 13
        if ($this->str === '') {
560
            /**
561
             * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
562
             */
563 2
            return CollectionStringy::create([]);
564
        }
565
566 11
        $chunks = $this->utf8::str_split($this->str, $length);
567 11
        foreach ($chunks as $i => &$value) {
568 11
            $value = static::create($value, $this->encoding);
569
        }
570
571
        /**
572
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
573
         */
574 11
        return CollectionStringy::create($chunks);
575
    }
576
577
    /**
578
     * Trims the string and replaces consecutive whitespace characters with a
579
     * single space. This includes tabs and newline characters, as well as
580
     * multibyte whitespace such as the thin space and ideographic space.
581
     *
582
     * @psalm-mutation-free
583
     *
584
     * @return static
585
     *                <p>Object with a trimmed $str and condensed whitespace.</p>
586
     */
587 39
    public function collapseWhitespace(): self
588
    {
589 39
        return static::create(
590 39
            $this->utf8::collapse_whitespace($this->str),
591 39
            $this->encoding
592
        );
593
    }
594
595
    /**
596
     * Returns true if the string contains $needle, false otherwise. By default
597
     * the comparison is case-sensitive, but can be made insensitive by setting
598
     * $caseSensitive to false.
599
     *
600
     * @param string $needle        <p>Substring to look for.</p>
601
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
602
     *
603
     * @psalm-mutation-free
604
     *
605
     * @return bool
606
     *              <p>Whether or not $str contains $needle.</p>
607
     */
608 63
    public function contains(string $needle, bool $caseSensitive = true): bool
609
    {
610 63
        return $this->utf8::str_contains(
611 63
            $this->str,
612 63
            $needle,
613 63
            $caseSensitive
614
        );
615
    }
616
617
    /**
618
     * Returns true if the string contains all $needles, false otherwise. By
619
     * default the comparison is case-sensitive, but can be made insensitive by
620
     * setting $caseSensitive to false.
621
     *
622
     * @param string[] $needles       <p>SubStrings to look for.</p>
623
     * @param bool     $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
624
     *
625
     * @psalm-mutation-free
626
     *
627
     * @return bool
628
     *              <p>Whether or not $str contains $needle.</p>
629
     */
630 131
    public function containsAll(array $needles, bool $caseSensitive = true): bool
631
    {
632 131
        return $this->utf8::str_contains_all(
633 131
            $this->str,
634 131
            $needles,
635 131
            $caseSensitive
636
        );
637
    }
638
639
    /**
640
     * Returns true if the string contains any $needles, false otherwise. By
641
     * default the comparison is case-sensitive, but can be made insensitive by
642
     * setting $caseSensitive to false.
643
     *
644
     * @param string[] $needles       <p>SubStrings to look for.</p>
645
     * @param bool     $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
646
     *
647
     * @psalm-mutation-free
648
     *
649
     * @return bool
650
     *              <p>Whether or not $str contains $needle.</p>
651
     */
652 129
    public function containsAny(array $needles, bool $caseSensitive = true): bool
653
    {
654 129
        return $this->utf8::str_contains_any(
655 129
            $this->str,
656 129
            $needles,
657 129
            $caseSensitive
658
        );
659
    }
660
661
    /**
662
     * Returns the length of the string, implementing the countable interface.
663
     *
664
     * @psalm-mutation-free
665
     *
666
     * @return int
667
     *             <p>The number of characters in the string, given the encoding.</p>
668
     */
669 3
    public function count(): int
670
    {
671 3
        return $this->length();
672
    }
673
674
    /**
675
     * Returns the number of occurrences of $substring in the given string.
676
     * By default, the comparison is case-sensitive, but can be made insensitive
677
     * by setting $caseSensitive to false.
678
     *
679
     * @param string $substring     <p>The substring to search for.</p>
680
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
681
     *
682
     * @psalm-mutation-free
683
     *
684
     * @return int
685
     */
686 45
    public function countSubstr(string $substring, bool $caseSensitive = true): int
687
    {
688 45
        return $this->utf8::substr_count_simple(
689 45
            $this->str,
690 45
            $substring,
691 45
            $caseSensitive,
692 45
            $this->encoding
693
        );
694
    }
695
696
    /**
697
     * Calculates the crc32 polynomial of a string.
698
     *
699
     * @psalm-mutation-free
700
     *
701
     * @return int
702
     */
703 2
    public function crc32(): int
704
    {
705 2
        return \crc32($this->str);
706
    }
707
708
    /**
709
     * Creates a Stringy object and assigns both str and encoding properties
710
     * the supplied values. $str is cast to a string prior to assignment, and if
711
     * $encoding is not specified, it defaults to mb_internal_encoding(). It
712
     * then returns the initialized object. Throws an InvalidArgumentException
713
     * if the first argument is an array or object without a __toString method.
714
     *
715
     * @param mixed  $str      [optional] <p>Value to modify, after being cast to string. Default: ''</p>
716
     * @param string $encoding [optional] <p>The character encoding. Fallback: 'UTF-8'</p>
717
     *
718
     * @throws \InvalidArgumentException
719
     *                                   <p>if an array or object without a
720
     *                                   __toString method is passed as the first argument</p>
721
     *
722
     * @return static
723
     *                <p>A Stringy object.</p>
724
     * @psalm-pure
725
     */
726 3541
    public static function create($str = '', string $encoding = null): self
727
    {
728 3541
        return new static($str, $encoding);
729
    }
730
731
    /**
732
     * Hash the string using the standard Unix DES-based algorithm or an
733
     * alternative algorithm that may be available on the system.
734
     *
735
     * @param string $salt A salt string to base the hashing on
736
     *
737
     * @return static
738
     */
739 3
    public function crypt(string $salt): self
740
    {
741 3
        return new static(
742 3
            \crypt(
743 3
                $this->str,
744 3
                $salt
745
            ),
746 3
            $this->encoding
747
        );
748
    }
749
750
    /**
751
     * Returns a lowercase and trimmed string separated by dashes. Dashes are
752
     * inserted before uppercase characters (with the exception of the first
753
     * character of the string), and in place of spaces as well as underscores.
754
     *
755
     * @psalm-mutation-free
756
     *
757
     * @return static
758
     *                <p>Object with a dasherized $str</p>
759
     */
760 57
    public function dasherize(): self
761
    {
762 57
        return static::create(
763 57
            $this->utf8::str_dasherize($this->str),
764 57
            $this->encoding
765
        );
766
    }
767
768
    /**
769
     * Decrypt the string.
770
     *
771
     * @param string $password The key for decrypting
772
     *
773
     * @return static
774
     */
775 5
    public function decrypt(string $password): self
776
    {
777 5
        return new static(
778 5
            Crypto::decryptWithPassword($this->str, $password),
779 3
            $this->encoding
780
        );
781
    }
782
783
    /**
784
     * Returns a lowercase and trimmed string separated by the given delimiter.
785
     * Delimiters are inserted before uppercase characters (with the exception
786
     * of the first character of the string), and in place of spaces, dashes,
787
     * and underscores. Alpha delimiters are not converted to lowercase.
788
     *
789
     * @param string $delimiter <p>Sequence used to separate parts of the string.</p>
790
     *
791
     * @psalm-mutation-free
792
     *
793
     * @return static
794
     *                <p>Object with a delimited $str.</p>
795
     */
796 90
    public function delimit(string $delimiter): self
797
    {
798 90
        return static::create(
799 90
            $this->utf8::str_delimit($this->str, $delimiter),
800 90
            $this->encoding
801
        );
802
    }
803
804
    /**
805
     * Set the internal character encoding.
806
     *
807
     * @param string $encoding The desired character encoding
808
     *
809
     * @psalm-mutation-free
810
     *
811
     * @return static
812
     */
813 1
    public function encoding(string $encoding): self
814
    {
815 1
        return new static($this->str, $encoding);
816
    }
817
818
    /**
819
     * Encrypt the string.
820
     *
821
     * @param string $password The key for encrypting
822
     *
823
     * @return static
824
     */
825 4
    public function encrypt(string $password): self
826
    {
827 4
        return new static(
828 4
            Crypto::encryptWithPassword($this->str, $password),
829 4
            $this->encoding
830
        );
831
    }
832
833
    /**
834
     * Returns true if the string ends with $substring, false otherwise. By
835
     * default, the comparison is case-sensitive, but can be made insensitive
836
     * by setting $caseSensitive to false.
837
     *
838
     * @param string $substring     <p>The substring to look for.</p>
839
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
840
     *
841
     * @psalm-mutation-free
842
     *
843
     * @return bool
844
     *              <p>Whether or not $str ends with $substring.</p>
845
     */
846 97
    public function endsWith(string $substring, bool $caseSensitive = true): bool
847
    {
848 97
        if ($caseSensitive) {
849 53
            return $this->utf8::str_ends_with($this->str, $substring);
850
        }
851
852 44
        return $this->utf8::str_iends_with($this->str, $substring);
853
    }
854
855
    /**
856
     * Returns true if the string ends with any of $substrings, false otherwise.
857
     * By default, the comparison is case-sensitive, but can be made insensitive
858
     * by setting $caseSensitive to false.
859
     *
860
     * @param string[] $substrings    <p>Substrings to look for.</p>
861
     * @param bool     $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
862
     *
863
     * @psalm-mutation-free
864
     *
865
     * @return bool
866
     *              <p>Whether or not $str ends with $substring.</p>
867
     */
868 33
    public function endsWithAny(array $substrings, bool $caseSensitive = true): bool
869
    {
870 33
        if ($caseSensitive) {
871 21
            return $this->utf8::str_ends_with_any($this->str, $substrings);
872
        }
873
874 12
        return $this->utf8::str_iends_with_any($this->str, $substrings);
875
    }
876
877
    /**
878
     * Ensures that the string begins with $substring. If it doesn't, it's
879
     * prepended.
880
     *
881
     * @param string $substring <p>The substring to add if not present.</p>
882
     *
883
     * @psalm-mutation-free
884
     *
885
     * @return static
886
     *                <p>Object with its $str prefixed by the $substring.</p>
887
     */
888 30
    public function ensureLeft(string $substring): self
889
    {
890 30
        return static::create(
891 30
            $this->utf8::str_ensure_left($this->str, $substring),
892 30
            $this->encoding
893
        );
894
    }
895
896
    /**
897
     * Ensures that the string ends with $substring. If it doesn't, it's appended.
898
     *
899
     * @param string $substring <p>The substring to add if not present.</p>
900
     *
901
     * @psalm-mutation-free
902
     *
903
     * @return static
904
     *                <p>Object with its $str suffixed by the $substring.</p>
905
     */
906 30
    public function ensureRight(string $substring): self
907
    {
908 30
        return static::create(
909 30
            $this->utf8::str_ensure_right($this->str, $substring),
910 30
            $this->encoding
911
        );
912
    }
913
914
    /**
915
     * Create a escape html version of the string via "htmlspecialchars()".
916
     *
917
     * @psalm-mutation-free
918
     *
919
     * @return static
920
     */
921 12
    public function escape(): self
922
    {
923 12
        return static::create(
924 12
            $this->utf8::htmlspecialchars(
925 12
                $this->str,
926 12
                \ENT_QUOTES | \ENT_SUBSTITUTE,
927 12
                $this->encoding
928
            ),
929 12
            $this->encoding
930
        );
931
    }
932
933
    /**
934
     * Split a string by a string.
935
     *
936
     * @param string $delimiter The boundary string
937
     * @param int    $limit     the maximum number of elements in the exploded collection.
938
     *
939
     *   - If limit is set and positive, the returned collection will contain a maximum of limit elements with the last
940
     *   element containing the rest of string.
941
     *   - If the limit parameter is negative, all components except the last -limit are returned.
942
     *   - If the limit parameter is zero, then this is treated as 1
943
     *
944
     * @psalm-mutation-free
945
     *
946
     * @return CollectionStringy<int,static>
0 ignored issues
show
Documentation introduced by
The doc-type CollectionStringy<int,static> could not be parsed: Expected "|" or "end of type", but got "<" at position 17. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
947
     */
948 3
    public function explode(string $delimiter, int $limit = \PHP_INT_MAX): CollectionStringy
949
    {
950 3
        $data = \explode($delimiter, $this->str, $limit);
951 3
        if ($data === false) {
952
            $data = [];
953
        }
954
955 3
        $data = \array_map(
956
            function ($str) {
957 3
                return new static($str, $this->encoding);
958 3
            },
959 3
            $data
960
        );
961
962
        /**
963
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
964
         */
965 3
        return CollectionStringy::create($data);
966
    }
967
968
    /**
969
     * Create an extract from a sentence, so if the search-string was found, it try to centered in the output.
970
     *
971
     * @param string   $search
972
     * @param int|null $length                 [optional] <p>Default: null === text->length / 2</p>
973
     * @param string   $replacerForSkippedText [optional] <p>Default: …</p>
974
     *
975
     * @psalm-mutation-free
976
     *
977
     * @return static
978
     */
979 2
    public function extractText(string $search = '', int $length = null, string $replacerForSkippedText = '…'): self
980
    {
981 2
        return static::create(
982 2
            $this->utf8::extract_text(
983 2
                $this->str,
984 2
                $search,
985 2
                $length,
986 2
                $replacerForSkippedText,
987 2
                $this->encoding
988
            ),
989 2
            $this->encoding
990
        );
991
    }
992
993
    /**
994
     * Returns the first $n characters of the string.
995
     *
996
     * @param int $n <p>Number of characters to retrieve from the start.</p>
997
     *
998
     * @psalm-mutation-free
999
     *
1000
     * @return static
1001
     *                <p>Object with its $str being the first $n chars.</p>
1002
     */
1003 37
    public function first(int $n): self
1004
    {
1005 37
        return static::create(
1006 37
            $this->utf8::first_char($this->str, $n, $this->encoding),
1007 37
            $this->encoding
1008
        );
1009
    }
1010
1011
    /**
1012
     * Return a formatted string via sprintf + named parameters via array syntax.
1013
     *
1014
     * <p>
1015
     * <br>
1016
     * It will use "sprintf()" so you can use e.g.:
1017
     * <br>
1018
     * <br><pre>s('There are %d monkeys in the %s')->format(5, 'tree');</pre>
1019
     * <br>
1020
     * <br><pre>s('There are %2$d monkeys in the %1$s')->format('tree', 5);</pre>
1021
     * <br>
1022
     * <br>
1023
     * But you can also use named parameter via array syntax e.g.:
1024
     * <br>
1025
     * <br><pre>s('There are %:count monkeys in the %:location')->format(['count' => 5, 'location' => 'tree');</pre>
1026
     * </p>
1027
     *
1028
     * @param mixed ...$args [optional]
1029
     *
1030
     * @psalm-mutation-free
1031
     *
1032
     * @return static
1033
     *                <p>A Stringy object produced according to the formatting string
1034
     *                format.</p>
1035
     */
1036 10
    public function format(...$args): self
1037
    {
1038
        // init
1039 10
        $str = $this->str;
1040
1041 10
        if (\strpos($this->str, '%:') !== false) {
1042 8
            $offset = null;
1043 8
            $replacement = null;
1044
            /** @noinspection AlterInForeachInspection */
1045 8
            foreach ($args as $key => &$arg) {
1046 8
                if (!\is_array($arg)) {
1047 4
                    continue;
1048
                }
1049
1050 8
                foreach ($arg as $name => $param) {
1051 8
                    $name = (string) $name;
1052
1053 8
                    if (\strpos($name, '%:') !== 0) {
1054 8
                        $nameTmp = '%:' . $name;
1055
                    } else {
1056
                        $nameTmp = $name;
1057
                    }
1058
1059 8
                    if ($offset === null) {
1060 8
                        $offset = \strpos($str, $nameTmp);
1061
                    } else {
1062 6
                        $offset = \strpos($str, $nameTmp, (int) $offset + \strlen((string) $replacement));
1063
                    }
1064 8
                    if ($offset === false) {
1065 4
                        continue;
1066
                    }
1067
1068 8
                    unset($arg[$name]);
1069
1070 8
                    $str = \substr_replace($str, $param, (int) $offset, \strlen($nameTmp));
1071
                }
1072
1073 8
                unset($args[$key]);
1074
            }
1075
        }
1076
1077 10
        $str = \str_replace('%:', '%%:', $str);
1078
1079 10
        return static::create(
1080 10
            \sprintf($str, ...$args),
1081 10
            $this->encoding
1082
        );
1083
    }
1084
1085
    /**
1086
     * Returns the encoding used by the Stringy object.
1087
     *
1088
     * @psalm-mutation-free
1089
     *
1090
     * @return string
1091
     *                <p>The current value of the $encoding property.</p>
1092
     */
1093 7
    public function getEncoding(): string
1094
    {
1095 7
        return $this->encoding;
1096
    }
1097
1098
    /**
1099
     * Returns a new ArrayIterator, thus implementing the IteratorAggregate
1100
     * interface. The ArrayIterator's constructor is passed an array of chars
1101
     * in the multibyte string. This enables the use of foreach with instances
1102
     * of Stringy\Stringy.
1103
     *
1104
     * @psalm-mutation-free
1105
     *
1106
     * @return \ArrayIterator
1107
     *                        <p>An iterator for the characters in the string.</p>
1108
     *
1109
     * @psalm-return \ArrayIterator<array-key,string>
1110
     */
1111 3
    public function getIterator(): \ArrayIterator
1112
    {
1113 3
        return new \ArrayIterator($this->chars());
1114
    }
1115
1116
    /**
1117
     * Wrap the string after an exact number of characters.
1118
     *
1119
     * @param int    $width Number of characters at which to wrap
1120
     * @param string $break Character used to break the string
1121
     *
1122
     * @psalm-mutation-free
1123
     *
1124
     * @return static
1125
     */
1126 2
    public function hardWrap($width, $break = "\n"): self
1127
    {
1128 2
        return $this->lineWrap($width, $break, false);
1129
    }
1130
1131
    /**
1132
     * Returns true if the string contains a lower case char, false otherwise.
1133
     *
1134
     * @psalm-mutation-free
1135
     *
1136
     * @return bool
1137
     *              <p>Whether or not the string contains a lower case character.</p>
1138
     */
1139 36
    public function hasLowerCase(): bool
1140
    {
1141 36
        return $this->utf8::has_lowercase($this->str);
1142
    }
1143
1144
    /**
1145
     * Returns true if the string contains an upper case char, false otherwise.
1146
     *
1147
     * @psalm-mutation-free
1148
     *
1149
     * @return bool
1150
     *              <p>Whether or not the string contains an upper case character.</p>
1151
     */
1152 36
    public function hasUpperCase(): bool
1153
    {
1154 36
        return $this->utf8::has_uppercase($this->str);
1155
    }
1156
1157
    /**
1158
     * Generate a hash value (message digest)
1159
     *
1160
     * @see https://php.net/manual/en/function.hash.php
1161
     *
1162
     * @param string $algorithm
1163
     *                          <p>Name of selected hashing algorithm (i.e. "md5", "sha256", "haval160,4", etc..)</p>
1164
     *
1165
     * @psalm-mutation-free
1166
     *
1167
     * @return static
1168
     */
1169 8
    public function hash($algorithm): self
1170
    {
1171 8
        return static::create(\hash($algorithm, $this->str), $this->encoding);
1172
    }
1173
1174
    /**
1175
     * Decode the string from hex.
1176
     *
1177
     * @psalm-mutation-free
1178
     *
1179
     * @return static
1180
     */
1181 2
    public function hexDecode(): self
1182
    {
1183 2
        $string = \preg_replace_callback(
1184 2
            '/\\\\x([0-9A-Fa-f]+)/',
1185
            function (array $matched) {
1186 2
                return (string) $this->utf8::hex_to_chr($matched[1]);
1187 2
            },
1188 2
            $this->str
1189
        );
1190
1191 2
        return static::create(
1192 2
            $string,
1193 2
            $this->encoding
1194
        );
1195
    }
1196
1197
    /**
1198
     * Encode string to hex.
1199
     *
1200
     * @psalm-mutation-free
1201
     *
1202
     * @return static
1203
     */
1204 2
    public function hexEncode(): self
1205
    {
1206 2
        $string = \array_reduce(
1207 2
            $this->chars(),
1208
            function (string $str, string $char) {
1209 2
                return $str . $this->utf8::chr_to_hex($char);
1210 2
            },
1211 2
            ''
1212
        );
1213
1214 2
        return static::create(
1215 2
            $string,
1216 2
            $this->encoding
1217
        );
1218
    }
1219
1220
    /**
1221
     * Convert all HTML entities to their applicable characters.
1222
     *
1223
     * @param int $flags [optional] <p>
1224
     *                   A bitmask of one or more of the following flags, which specify how to handle quotes and
1225
     *                   which document type to use. The default is ENT_COMPAT.
1226
     *                   <table>
1227
     *                   Available <i>flags</i> constants
1228
     *                   <tr valign="top">
1229
     *                   <td>Constant Name</td>
1230
     *                   <td>Description</td>
1231
     *                   </tr>
1232
     *                   <tr valign="top">
1233
     *                   <td><b>ENT_COMPAT</b></td>
1234
     *                   <td>Will convert double-quotes and leave single-quotes alone.</td>
1235
     *                   </tr>
1236
     *                   <tr valign="top">
1237
     *                   <td><b>ENT_QUOTES</b></td>
1238
     *                   <td>Will convert both double and single quotes.</td>
1239
     *                   </tr>
1240
     *                   <tr valign="top">
1241
     *                   <td><b>ENT_NOQUOTES</b></td>
1242
     *                   <td>Will leave both double and single quotes unconverted.</td>
1243
     *                   </tr>
1244
     *                   <tr valign="top">
1245
     *                   <td><b>ENT_HTML401</b></td>
1246
     *                   <td>
1247
     *                   Handle code as HTML 4.01.
1248
     *                   </td>
1249
     *                   </tr>
1250
     *                   <tr valign="top">
1251
     *                   <td><b>ENT_XML1</b></td>
1252
     *                   <td>
1253
     *                   Handle code as XML 1.
1254
     *                   </td>
1255
     *                   </tr>
1256
     *                   <tr valign="top">
1257
     *                   <td><b>ENT_XHTML</b></td>
1258
     *                   <td>
1259
     *                   Handle code as XHTML.
1260
     *                   </td>
1261
     *                   </tr>
1262
     *                   <tr valign="top">
1263
     *                   <td><b>ENT_HTML5</b></td>
1264
     *                   <td>
1265
     *                   Handle code as HTML 5.
1266
     *                   </td>
1267
     *                   </tr>
1268
     *                   </table>
1269
     *                   </p>
1270
     *
1271
     * @psalm-mutation-free
1272
     *
1273
     * @return static
1274
     *                <p>Object with the resulting $str after being html decoded.</p>
1275
     */
1276 15 View Code Duplication
    public function htmlDecode(int $flags = \ENT_COMPAT): self
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...
1277
    {
1278 15
        return static::create(
1279 15
            $this->utf8::html_entity_decode(
1280 15
                $this->str,
1281 15
                $flags,
1282 15
                $this->encoding
1283
            ),
1284 15
            $this->encoding
1285
        );
1286
    }
1287
1288
    /**
1289
     * Convert all applicable characters to HTML entities.
1290
     *
1291
     * @param int $flags [optional] <p>
1292
     *                   A bitmask of one or more of the following flags, which specify how to handle quotes and
1293
     *                   which document type to use. The default is ENT_COMPAT.
1294
     *                   <table>
1295
     *                   Available <i>flags</i> constants
1296
     *                   <tr valign="top">
1297
     *                   <td>Constant Name</td>
1298
     *                   <td>Description</td>
1299
     *                   </tr>
1300
     *                   <tr valign="top">
1301
     *                   <td><b>ENT_COMPAT</b></td>
1302
     *                   <td>Will convert double-quotes and leave single-quotes alone.</td>
1303
     *                   </tr>
1304
     *                   <tr valign="top">
1305
     *                   <td><b>ENT_QUOTES</b></td>
1306
     *                   <td>Will convert both double and single quotes.</td>
1307
     *                   </tr>
1308
     *                   <tr valign="top">
1309
     *                   <td><b>ENT_NOQUOTES</b></td>
1310
     *                   <td>Will leave both double and single quotes unconverted.</td>
1311
     *                   </tr>
1312
     *                   <tr valign="top">
1313
     *                   <td><b>ENT_HTML401</b></td>
1314
     *                   <td>
1315
     *                   Handle code as HTML 4.01.
1316
     *                   </td>
1317
     *                   </tr>
1318
     *                   <tr valign="top">
1319
     *                   <td><b>ENT_XML1</b></td>
1320
     *                   <td>
1321
     *                   Handle code as XML 1.
1322
     *                   </td>
1323
     *                   </tr>
1324
     *                   <tr valign="top">
1325
     *                   <td><b>ENT_XHTML</b></td>
1326
     *                   <td>
1327
     *                   Handle code as XHTML.
1328
     *                   </td>
1329
     *                   </tr>
1330
     *                   <tr valign="top">
1331
     *                   <td><b>ENT_HTML5</b></td>
1332
     *                   <td>
1333
     *                   Handle code as HTML 5.
1334
     *                   </td>
1335
     *                   </tr>
1336
     *                   </table>
1337
     *                   </p>
1338
     *
1339
     * @psalm-mutation-free
1340
     *
1341
     * @return static
1342
     *                <p>Object with the resulting $str after being html encoded.</p>
1343
     */
1344 15 View Code Duplication
    public function htmlEncode(int $flags = \ENT_COMPAT): self
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...
1345
    {
1346 15
        return static::create(
1347 15
            $this->utf8::htmlentities(
1348 15
                $this->str,
1349 15
                $flags,
1350 15
                $this->encoding
1351
            ),
1352 15
            $this->encoding
1353
        );
1354
    }
1355
1356
    /**
1357
     * Capitalizes the first word of the string, replaces underscores with
1358
     * spaces, and strips '_id'.
1359
     *
1360
     * @psalm-mutation-free
1361
     *
1362
     * @return static
1363
     *                <p>Object with a humanized $str.</p>
1364
     */
1365 9
    public function humanize(): self
1366
    {
1367 9
        return static::create(
1368 9
            $this->utf8::str_humanize($this->str),
1369 9
            $this->encoding
1370
        );
1371
    }
1372
1373
    /**
1374
     * Determine if the current string exists in another string. By
1375
     * default, the comparison is case-sensitive, but can be made insensitive
1376
     * by setting $caseSensitive to false.
1377
     *
1378
     * @param string $str           <p>The string to compare against.</p>
1379
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
1380
     *
1381
     * @psalm-mutation-free
1382
     *
1383
     * @return bool
1384
     */
1385 3
    public function in(string $str, bool $caseSensitive = true): bool
1386
    {
1387 3
        if ($caseSensitive) {
1388 2
            return \strpos($str, $this->str) !== false;
1389
        }
1390
1391 1
        return \stripos($str, $this->str) !== false;
1392
    }
1393
1394
    /**
1395
     * Returns the index of the first occurrence of $needle in the string,
1396
     * and false if not found. Accepts an optional offset from which to begin
1397
     * the search.
1398
     *
1399
     * @param string $needle <p>Substring to look for.</p>
1400
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1401
     *
1402
     * @psalm-mutation-free
1403
     *
1404
     * @return false|int
1405
     *                   <p>The occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1406
     */
1407 31
    public function indexOf(string $needle, int $offset = 0)
1408
    {
1409 31
        return $this->utf8::strpos(
1410 31
            $this->str,
1411 31
            $needle,
1412 31
            $offset,
1413 31
            $this->encoding
1414
        );
1415
    }
1416
1417
    /**
1418
     * Returns the index of the first occurrence of $needle in the string,
1419
     * and false if not found. Accepts an optional offset from which to begin
1420
     * the search.
1421
     *
1422
     * @param string $needle <p>Substring to look for.</p>
1423
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1424
     *
1425
     * @psalm-mutation-free
1426
     *
1427
     * @return false|int
1428
     *                   <p>The occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1429
     */
1430 20
    public function indexOfIgnoreCase(string $needle, int $offset = 0)
1431
    {
1432 20
        return $this->utf8::stripos(
1433 20
            $this->str,
1434 20
            $needle,
1435 20
            $offset,
1436 20
            $this->encoding
1437
        );
1438
    }
1439
1440
    /**
1441
     * Returns the index of the last occurrence of $needle in the string,
1442
     * and false if not found. Accepts an optional offset from which to begin
1443
     * the search. Offsets may be negative to count from the last character
1444
     * in the string.
1445
     *
1446
     * @param string $needle <p>Substring to look for.</p>
1447
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1448
     *
1449
     * @psalm-mutation-free
1450
     *
1451
     * @return false|int
1452
     *                   <p>The last occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1453
     */
1454 31
    public function indexOfLast(string $needle, int $offset = 0)
1455
    {
1456 31
        return $this->utf8::strrpos(
1457 31
            $this->str,
1458 31
            $needle,
1459 31
            $offset,
1460 31
            $this->encoding
1461
        );
1462
    }
1463
1464
    /**
1465
     * Returns the index of the last occurrence of $needle in the string,
1466
     * and false if not found. Accepts an optional offset from which to begin
1467
     * the search. Offsets may be negative to count from the last character
1468
     * in the string.
1469
     *
1470
     * @param string $needle <p>Substring to look for.</p>
1471
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1472
     *
1473
     * @psalm-mutation-free
1474
     *
1475
     * @return false|int
1476
     *                   <p>The last occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1477
     */
1478 20
    public function indexOfLastIgnoreCase(string $needle, int $offset = 0)
1479
    {
1480 20
        return $this->utf8::strripos(
1481 20
            $this->str,
1482 20
            $needle,
1483 20
            $offset,
1484 20
            $this->encoding
1485
        );
1486
    }
1487
1488
    /**
1489
     * Inserts $substring into the string at the $index provided.
1490
     *
1491
     * @param string $substring <p>String to be inserted.</p>
1492
     * @param int    $index     <p>The index at which to insert the substring.</p>
1493
     *
1494
     * @psalm-mutation-free
1495
     *
1496
     * @return static
1497
     *                <p>Object with the resulting $str after the insertion.</p>
1498
     */
1499 24
    public function insert(string $substring, int $index): self
1500
    {
1501 24
        return static::create(
1502 24
            $this->utf8::str_insert(
1503 24
                $this->str,
1504 24
                $substring,
1505 24
                $index,
1506 24
                $this->encoding
1507
            ),
1508 24
            $this->encoding
1509
        );
1510
    }
1511
1512
    /**
1513
     * Returns true if the string contains the $pattern, otherwise false.
1514
     *
1515
     * WARNING: Asterisks ("*") are translated into (".*") zero-or-more regular
1516
     * expression wildcards.
1517
     *
1518
     * @credit Originally from Laravel, thanks Taylor.
1519
     *
1520
     * @param string $pattern <p>The string or pattern to match against.</p>
1521
     *
1522
     * @psalm-mutation-free
1523
     *
1524
     * @return bool
1525
     *              <p>Whether or not we match the provided pattern.</p>
1526
     */
1527 26
    public function is(string $pattern): bool
1528
    {
1529 26
        if ($this->toString() === $pattern) {
1530 2
            return true;
1531
        }
1532
1533 24
        $quotedPattern = \preg_quote($pattern, '/');
1534 24
        $replaceWildCards = \str_replace('\*', '.*', $quotedPattern);
1535
1536 24
        return $this->matchesPattern('^' . $replaceWildCards . '\z');
1537
    }
1538
1539
    /**
1540
     * Returns true if the string contains only alphabetic chars, false otherwise.
1541
     *
1542
     * @psalm-mutation-free
1543
     *
1544
     * @return bool
1545
     *              <p>Whether or not $str contains only alphabetic chars.</p>
1546
     */
1547 30
    public function isAlpha(): bool
1548
    {
1549 30
        return $this->utf8::is_alpha($this->str);
1550
    }
1551
1552
    /**
1553
     * Returns true if the string contains only alphabetic and numeric chars, false otherwise.
1554
     *
1555
     * @psalm-mutation-free
1556
     *
1557
     * @return bool
1558
     *              <p>Whether or not $str contains only alphanumeric chars.</p>
1559
     */
1560 39
    public function isAlphanumeric(): bool
1561
    {
1562 39
        return $this->utf8::is_alphanumeric($this->str);
1563
    }
1564
1565
    /**
1566
     * Returns true if the string is base64 encoded, false otherwise.
1567
     *
1568
     * @param bool $emptyStringIsValid
1569
     *
1570
     * @psalm-mutation-free
1571
     *
1572
     * @return bool
1573
     *              <p>Whether or not $str is base64 encoded.</p>
1574
     */
1575 21
    public function isBase64($emptyStringIsValid = true): bool
1576
    {
1577 21
        return $this->utf8::is_base64($this->str, $emptyStringIsValid);
1578
    }
1579
1580
    /**
1581
     * Returns true if the string contains only whitespace chars, false otherwise.
1582
     *
1583
     * @psalm-mutation-free
1584
     *
1585
     * @return bool
1586
     *              <p>Whether or not $str contains only whitespace characters.</p>
1587
     */
1588 45
    public function isBlank(): bool
1589
    {
1590 45
        return $this->utf8::is_blank($this->str);
1591
    }
1592
1593
    /**
1594
     * Returns true if the string contains a valid E-Mail address, false otherwise.
1595
     *
1596
     * @param bool $useExampleDomainCheck   [optional] <p>Default: false</p>
1597
     * @param bool $useTypoInDomainCheck    [optional] <p>Default: false</p>
1598
     * @param bool $useTemporaryDomainCheck [optional] <p>Default: false</p>
1599
     * @param bool $useDnsCheck             [optional] <p>Default: false</p>
1600
     *
1601
     * @psalm-mutation-free
1602
     *
1603
     * @return bool
1604
     *              <p>Whether or not $str contains a valid E-Mail address.</p>
1605
     */
1606 2
    public function isEmail(
1607
        bool $useExampleDomainCheck = false,
1608
        bool $useTypoInDomainCheck = false,
1609
        bool $useTemporaryDomainCheck = false,
1610
        bool $useDnsCheck = false
1611
    ): bool {
1612
        /**
1613
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the email-check class
1614
         */
1615 2
        return EmailCheck::isValid($this->str, $useExampleDomainCheck, $useTypoInDomainCheck, $useTemporaryDomainCheck, $useDnsCheck);
1616
    }
1617
1618
    /**
1619
     * Determine whether the string is considered to be empty.
1620
     *
1621
     * A variable is considered empty if it does not exist or if its value equals FALSE.
1622
     *
1623
     * @psalm-mutation-free
1624
     *
1625
     * @return bool
1626
     *              <p>Whether or not $str is empty().</p>
1627
     */
1628 10
    public function isEmpty(): bool
1629
    {
1630 10
        return $this->utf8::is_empty($this->str);
1631
    }
1632
1633
    /**
1634
     * Determine whether the string is equals to $str.
1635
     * Alias for isEqualsCaseSensitive()
1636
     *
1637
     * @param string|Stringy ...$str
1638
     *
1639
     * @psalm-mutation-free
1640
     *
1641
     * @return bool
1642
     */
1643 13
    public function isEquals(...$str): bool
1644
    {
1645 13
        return $this->isEqualsCaseSensitive(...$str);
1646
    }
1647
1648
    /**
1649
     * Determine whether the string is equals to $str.
1650
     *
1651
     * @param float|int|string|Stringy ...$str <p>The string to compare.</p>
1652
     *
1653
     * @psalm-mutation-free
1654
     *
1655
     * @return bool
1656
     *              <p>Whether or not $str is equals.</p>
1657
     */
1658 3
    public function isEqualsCaseInsensitive(...$str): bool
1659
    {
1660 3
        $strUpper = $this->toUpperCase()->str;
1661
1662 3 View Code Duplication
        foreach ($str as $strTmp) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1663
            /**
1664
             * @psalm-suppress RedundantConditionGivenDocblockType - wait for union-types :)
1665
             */
1666 3
            if ($strTmp instanceof self) {
1667
                if ($strUpper !== $strTmp->toUpperCase()) {
1668
                    return false;
1669
                }
1670 3
            } elseif (\is_scalar($strTmp)) {
1671 3
                if ($strUpper !== $this->utf8::strtoupper((string) $strTmp, $this->encoding)) {
1672 3
                    return false;
1673
                }
1674
            } else {
1675 3
                throw new \InvalidArgumentException('expected: int|float|string|Stringy -> given: ' . \print_r($strTmp, true) . ' [' . \gettype($strTmp) . ']');
1676
            }
1677
        }
1678
1679 3
        return true;
1680
    }
1681
1682
    /**
1683
     * Determine whether the string is equals to $str.
1684
     *
1685
     * @param float|int|string|Stringy ...$str <p>The string to compare.</p>
1686
     *
1687
     * @psalm-mutation-free
1688
     *
1689
     * @return bool
1690
     *              <p>Whether or not $str is equals.</p>
1691
     */
1692 14
    public function isEqualsCaseSensitive(...$str): bool
1693
    {
1694 14 View Code Duplication
        foreach ($str as $strTmp) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1695
            /**
1696
             * @psalm-suppress RedundantConditionGivenDocblockType - wait for union-types :)
1697
             */
1698 14
            if ($strTmp instanceof self) {
1699 2
                if ($this->str !== $strTmp->str) {
1700 2
                    return false;
1701
                }
1702 12
            } elseif (\is_scalar($strTmp)) {
1703 12
                if ($this->str !== (string) $strTmp) {
1704 12
                    return false;
1705
                }
1706
            } else {
1707 3
                throw new \InvalidArgumentException('expected: int|float|string|Stringy -> given: ' . \print_r($strTmp, true) . ' [' . \gettype($strTmp) . ']');
1708
            }
1709
        }
1710
1711 3
        return true;
1712
    }
1713
1714
    /**
1715
     * Returns true if the string contains only hexadecimal chars, false otherwise.
1716
     *
1717
     * @psalm-mutation-free
1718
     *
1719
     * @return bool
1720
     *              <p>Whether or not $str contains only hexadecimal chars.</p>
1721
     */
1722 39
    public function isHexadecimal(): bool
1723
    {
1724 39
        return $this->utf8::is_hexadecimal($this->str);
1725
    }
1726
1727
    /**
1728
     * Returns true if the string contains HTML-Tags, false otherwise.
1729
     *
1730
     * @psalm-mutation-free
1731
     *
1732
     * @return bool
1733
     *              <p>Whether or not $str contains HTML-Tags.</p>
1734
     */
1735 2
    public function isHtml(): bool
1736
    {
1737 2
        return $this->utf8::is_html($this->str);
1738
    }
1739
1740
    /**
1741
     * Returns true if the string is JSON, false otherwise. Unlike json_decode
1742
     * in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers,
1743
     * in that an empty string is not considered valid JSON.
1744
     *
1745
     * @param bool $onlyArrayOrObjectResultsAreValid
1746
     *
1747
     * @return bool
1748
     *              <p>Whether or not $str is JSON.</p>
1749
     */
1750 60
    public function isJson($onlyArrayOrObjectResultsAreValid = false): bool
1751
    {
1752 60
        return $this->utf8::is_json(
1753 60
            $this->str,
1754 60
            $onlyArrayOrObjectResultsAreValid
1755
        );
1756
    }
1757
1758
    /**
1759
     * Returns true if the string contains only lower case chars, false otherwise.
1760
     *
1761
     * @psalm-mutation-free
1762
     *
1763
     * @return bool
1764
     *              <p>Whether or not $str contains only lower case characters.</p>
1765
     */
1766 24
    public function isLowerCase(): bool
1767
    {
1768 24
        return $this->utf8::is_lowercase($this->str);
1769
    }
1770
1771
    /**
1772
     * Determine whether the string is considered to be NOT empty.
1773
     *
1774
     * A variable is considered NOT empty if it does exist or if its value equals TRUE.
1775
     *
1776
     * @psalm-mutation-free
1777
     *
1778
     * @return bool
1779
     *              <p>Whether or not $str is empty().</p>
1780
     */
1781 10
    public function isNotEmpty(): bool
1782
    {
1783 10
        return !$this->utf8::is_empty($this->str);
1784
    }
1785
1786
    /**
1787
     * Returns true if the string is serialized, false otherwise.
1788
     *
1789
     * @psalm-mutation-free
1790
     *
1791
     * @return bool
1792
     *              <p>Whether or not $str is serialized.</p>
1793
     */
1794 21
    public function isSerialized(): bool
1795
    {
1796 21
        return $this->utf8::is_serialized($this->str);
1797
    }
1798
1799
    /**
1800
     * Check if two strings are similar.
1801
     *
1802
     * @param string $str
1803
     * @param float  $minPercentForSimilarity
1804
     *
1805
     * @psalm-mutation-free
1806
     *
1807
     * @return bool
1808
     */
1809 2
    public function isSimilar(string $str, float $minPercentForSimilarity = 80.0): bool
1810
    {
1811 2
        return $this->similarity($str) >= $minPercentForSimilarity;
1812
    }
1813
1814
    /**
1815
     * Returns true if the string contains only lower case chars, false
1816
     * otherwise.
1817
     *
1818
     * @psalm-mutation-free
1819
     *
1820
     * @return bool
1821
     *              <p>Whether or not $str contains only lower case characters.</p>
1822
     */
1823 24
    public function isUpperCase(): bool
1824
    {
1825 24
        return $this->utf8::is_uppercase($this->str);
1826
    }
1827
1828
    /**
1829
     * Returns true if the string contains only whitespace chars, false otherwise.
1830
     *
1831
     * @psalm-mutation-free
1832
     *
1833
     * @return bool
1834
     *              <p>Whether or not $str contains only whitespace characters.</p>
1835
     */
1836 30
    public function isWhitespace(): bool
1837
    {
1838 30
        return $this->isBlank();
1839
    }
1840
1841
    /**
1842
     * Returns value which can be serialized by json_encode().
1843
     *
1844
     * @noinspection ReturnTypeCanBeDeclaredInspection
1845
     *
1846
     * @psalm-mutation-free
1847
     *
1848
     * @return string The current value of the $str property
1849
     */
1850 2
    public function jsonSerialize()
1851
    {
1852 2
        return (string) $this;
1853
    }
1854
1855
    /**
1856
     * Returns the last $n characters of the string.
1857
     *
1858
     * @param int $n <p>Number of characters to retrieve from the end.</p>
1859
     *
1860
     * @psalm-mutation-free
1861
     *
1862
     * @return static
1863
     *                <p>Object with its $str being the last $n chars.</p>
1864
     */
1865 36
    public function last(int $n): self
1866
    {
1867 36
        return static::create(
1868 36
            $this->utf8::str_last_char(
1869 36
                $this->str,
1870 36
                $n,
1871 36
                $this->encoding
1872
            ),
1873 36
            $this->encoding
1874
        );
1875
    }
1876
1877
    /**
1878
     * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle".
1879
     * If no match is found returns new empty Stringy object.
1880
     *
1881
     * @param string $needle       <p>The string to look for.</p>
1882
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1883
     *
1884
     * @psalm-mutation-free
1885
     *
1886
     * @return static
1887
     */
1888 4 View Code Duplication
    public function lastSubstringOf(string $needle, bool $beforeNeedle = false): self
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...
1889
    {
1890 4
        return static::create(
1891 4
            $this->utf8::str_substr_last(
1892 4
                $this->str,
1893 4
                $needle,
1894 4
                $beforeNeedle,
1895 4
                $this->encoding
1896
            ),
1897 4
            $this->encoding
1898
        );
1899
    }
1900
1901
    /**
1902
     * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle".
1903
     * If no match is found returns new empty Stringy object.
1904
     *
1905
     * @param string $needle       <p>The string to look for.</p>
1906
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1907
     *
1908
     * @psalm-mutation-free
1909
     *
1910
     * @return static
1911
     */
1912 2 View Code Duplication
    public function lastSubstringOfIgnoreCase(string $needle, bool $beforeNeedle = false): self
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...
1913
    {
1914 2
        return static::create(
1915 2
            $this->utf8::str_isubstr_last(
1916 2
                $this->str,
1917 2
                $needle,
1918 2
                $beforeNeedle,
1919 2
                $this->encoding
1920
            ),
1921 2
            $this->encoding
1922
        );
1923
    }
1924
1925
    /**
1926
     * Returns the length of the string.
1927
     *
1928
     * @psalm-mutation-free
1929
     *
1930
     * @return int
1931
     *             <p>The number of characters in $str given the encoding.</p>
1932
     */
1933 17
    public function length(): int
1934
    {
1935 17
        return (int) $this->utf8::strlen($this->str, $this->encoding);
1936
    }
1937
1938
    /**
1939
     * Line-Wrap the string after $limit, but also after the next word.
1940
     *
1941
     * @param int         $limit           [optional] <p>The column width.</p>
1942
     * @param string      $break           [optional] <p>The line is broken using the optional break parameter.</p>
1943
     * @param bool        $add_final_break [optional] <p>
1944
     *                                     If this flag is true, then the method will add a $break at the end
1945
     *                                     of the result string.
1946
     *                                     </p>
1947
     * @param string|null $delimiter       [optional] <p>
1948
     *                                     You can change the default behavior, where we split the string by newline.
1949
     *                                     </p>
1950
     *
1951
     * @psalm-mutation-free
1952
     *
1953
     * @return static
1954
     */
1955 3 View Code Duplication
    public function lineWrap(
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...
1956
        int $limit,
1957
        string $break = "\n",
1958
        bool $add_final_break = true,
1959
        string $delimiter = null
1960
    ): self {
1961 3
        return static::create(
1962 3
            $this->utf8::wordwrap_per_line(
1963 3
                $this->str,
1964 3
                $limit,
1965 3
                $break,
1966 3
                true,
1967 3
                $add_final_break,
1968 3
                $delimiter
1969
            ),
1970 3
            $this->encoding
1971
        );
1972
    }
1973
1974
    /**
1975
     * Line-Wrap the string after $limit, but also after the next word.
1976
     *
1977
     * @param int         $limit           [optional] <p>The column width.</p>
1978
     * @param string      $break           [optional] <p>The line is broken using the optional break parameter.</p>
1979
     * @param bool        $add_final_break [optional] <p>
1980
     *                                     If this flag is true, then the method will add a $break at the end
1981
     *                                     of the result string.
1982
     *                                     </p>
1983
     * @param string|null $delimiter       [optional] <p>
1984
     *                                     You can change the default behavior, where we split the string by newline.
1985
     *                                     </p>
1986
     *
1987
     * @psalm-mutation-free
1988
     *
1989
     * @return static
1990
     */
1991 4 View Code Duplication
    public function lineWrapAfterWord(
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...
1992
        int $limit,
1993
        string $break = "\n",
1994
        bool $add_final_break = true,
1995
        string $delimiter = null
1996
    ): self {
1997 4
        return static::create(
1998 4
            $this->utf8::wordwrap_per_line(
1999 4
                $this->str,
2000 4
                $limit,
2001 4
                $break,
2002 4
                false,
2003 4
                $add_final_break,
2004 4
                $delimiter
2005
            ),
2006 4
            $this->encoding
2007
        );
2008
    }
2009
2010
    /**
2011
     * Splits on newlines and carriage returns, returning an array of Stringy
2012
     * objects corresponding to the lines in the string.
2013
     *
2014
     * @psalm-mutation-free
2015
     *
2016
     * @return CollectionStringy|static[]
2017
     *                                    <p>An collection of Stringy objects.</p>
2018
     *
2019
     * @psalm-return CollectionStringy<int,static>
2020
     */
2021 51
    public function lines(): CollectionStringy
2022
    {
2023 51
        $array = $this->utf8::str_to_lines($this->str);
2024
        /** @noinspection AlterInForeachInspection */
2025 51
        foreach ($array as $i => &$value) {
2026 51
            $value = static::create($value, $this->encoding);
2027
        }
2028
2029
        /** @noinspection PhpSillyAssignmentInspection */
2030
        /** @var static[] $array */
2031 51
        $array = $array;
0 ignored issues
show
Bug introduced by
Why assign $array to itself?

This checks looks for cases where a variable has been assigned to itself.

This assignement can be removed without consequences.

Loading history...
2032
2033
        /**
2034
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
2035
         */
2036 51
        return CollectionStringy::create($array);
2037
    }
2038
2039
    /**
2040
     * Returns the longest common prefix between the string and $otherStr.
2041
     *
2042
     * @param string $otherStr <p>Second string for comparison.</p>
2043
     *
2044
     * @psalm-mutation-free
2045
     *
2046
     * @return static
2047
     *                <p>Object with its $str being the longest common prefix.</p>
2048
     */
2049 30
    public function longestCommonPrefix(string $otherStr): self
2050
    {
2051 30
        return static::create(
2052 30
            $this->utf8::str_longest_common_prefix(
2053 30
                $this->str,
2054 30
                $otherStr,
2055 30
                $this->encoding
2056
            ),
2057 30
            $this->encoding
2058
        );
2059
    }
2060
2061
    /**
2062
     * Returns the longest common substring between the string and $otherStr.
2063
     * In the case of ties, it returns that which occurs first.
2064
     *
2065
     * @param string $otherStr <p>Second string for comparison.</p>
2066
     *
2067
     * @psalm-mutation-free
2068
     *
2069
     * @return static
2070
     *                <p>Object with its $str being the longest common substring.</p>
2071
     */
2072 30
    public function longestCommonSubstring(string $otherStr): self
2073
    {
2074 30
        return static::create(
2075 30
            $this->utf8::str_longest_common_substring(
2076 30
                $this->str,
2077 30
                $otherStr,
2078 30
                $this->encoding
2079
            ),
2080 30
            $this->encoding
2081
        );
2082
    }
2083
2084
    /**
2085
     * Returns the longest common suffix between the string and $otherStr.
2086
     *
2087
     * @param string $otherStr <p>Second string for comparison.</p>
2088
     *
2089
     * @psalm-mutation-free
2090
     *
2091
     * @return static
2092
     *                <p>Object with its $str being the longest common suffix.</p>
2093
     */
2094 30
    public function longestCommonSuffix(string $otherStr): self
2095
    {
2096 30
        return static::create(
2097 30
            $this->utf8::str_longest_common_suffix(
2098 30
                $this->str,
2099 30
                $otherStr,
2100 30
                $this->encoding
2101
            ),
2102 30
            $this->encoding
2103
        );
2104
    }
2105
2106
    /**
2107
     * Converts the first character of the string to lower case.
2108
     *
2109
     * @psalm-mutation-free
2110
     *
2111
     * @return static
2112
     *                <p>Object with the first character of $str being lower case.</p>
2113
     */
2114 15
    public function lowerCaseFirst(): self
2115
    {
2116 15
        return static::create(
2117 15
            $this->utf8::lcfirst($this->str, $this->encoding),
2118 15
            $this->encoding
2119
        );
2120
    }
2121
2122
    /**
2123
     * Determine if the string matches another string regardless of case.
2124
     * Alias for isEqualsCaseInsensitive()
2125
     *
2126
     * @psalm-mutation-free
2127
     *
2128
     * @param string|Stringy ...$str
2129
     *                               <p>The string to compare against.</p>
2130
     *
2131
     * @psalm-mutation-free
2132
     *
2133
     * @return bool
2134
     */
2135 3
    public function matchCaseInsensitive(...$str): bool
2136
    {
2137 3
        return $this->isEqualsCaseInsensitive(...$str);
2138
    }
2139
2140
    /**
2141
     * Determine if the string matches another string.
2142
     * Alias for isEqualsCaseSensitive()
2143
     *
2144
     * @psalm-mutation-free
2145
     *
2146
     * @param string|Stringy ...$str
2147
     *                               <p>The string to compare against.</p>
2148
     *
2149
     * @psalm-mutation-free
2150
     *
2151
     * @return bool
2152
     */
2153 7
    public function matchCaseSensitive(...$str): bool
2154
    {
2155 7
        return $this->isEqualsCaseSensitive(...$str);
2156
    }
2157
2158
    /**
2159
     * Create a md5 hash from the current string.
2160
     *
2161
     * @psalm-mutation-free
2162
     *
2163
     * @return static
2164
     */
2165 2
    public function md5(): self
2166
    {
2167 2
        return static::create($this->hash('md5'), $this->encoding);
2168
    }
2169
2170
    /**
2171
     * Get every nth character of the string.
2172
     *
2173
     * @param int $step   The number of characters to step
2174
     * @param int $offset The string offset to start at
2175
     *
2176
     * @psalm-mutation-free
2177
     *
2178
     * @return static
2179
     */
2180 4
    public function nth(int $step, int $offset = 0): self
2181
    {
2182 4
        $length = $step - 1;
2183 4
        $substring = $this->substr($offset)->toString();
2184
2185 4
        if ($substring === '') {
2186
            return new static('', $this->encoding);
2187
        }
2188
2189 4
        \preg_match_all(
2190 4
            "/(?:^|(?:.|\p{L}|\w){" . $length . "})(.|\p{L}|\w)/u",
2191 4
            $substring,
2192 4
            $matches
2193
        );
2194
2195 4
        return new static(\implode('', $matches[1] ?? []), $this->encoding);
2196
    }
2197
2198
    /**
2199
     * Returns whether or not a character exists at an index. Offsets may be
2200
     * negative to count from the last character in the string. Implements
2201
     * part of the ArrayAccess interface.
2202
     *
2203
     * @param int $offset <p>The index to check.</p>
2204
     *
2205
     * @psalm-mutation-free
2206
     *
2207
     * @return bool
2208
     *              <p>Whether or not the index exists.</p>
2209
     */
2210 18
    public function offsetExists($offset): bool
2211
    {
2212 18
        return $this->utf8::str_offset_exists(
2213 18
            $this->str,
2214 18
            $offset,
2215 18
            $this->encoding
2216
        );
2217
    }
2218
2219
    /**
2220
     * Returns the character at the given index. Offsets may be negative to
2221
     * count from the last character in the string. Implements part of the
2222
     * ArrayAccess interface, and throws an OutOfBoundsException if the index
2223
     * does not exist.
2224
     *
2225
     * @param int $offset <p>The <strong>index</strong> from which to retrieve the char.</p>
2226
     *
2227
     * @throws \OutOfBoundsException
2228
     *                               <p>If the positive or negative offset does not exist.</p>
2229
     *
2230
     * @return string
2231
     *                <p>The character at the specified index.</p>
2232
     *
2233
     * @psalm-mutation-free
2234
     */
2235 6
    public function offsetGet($offset): string
2236
    {
2237 6
        return $this->utf8::str_offset_get($this->str, $offset, $this->encoding);
2238
    }
2239
2240
    /**
2241
     * Implements part of the ArrayAccess interface, but throws an exception
2242
     * when called. This maintains the immutability of Stringy objects.
2243
     *
2244
     * @param int   $offset <p>The index of the character.</p>
2245
     * @param mixed $value  <p>Value to set.</p>
2246
     *
2247
     * @throws \Exception
2248
     *                    <p>When called.</p>
2249
     *
2250
     * @return void
2251
     */
2252 3
    public function offsetSet($offset, $value)
2253
    {
2254
        // Stringy is immutable, cannot directly set char
2255
        /** @noinspection ThrowRawExceptionInspection */
2256 3
        throw new \Exception('Stringy object is immutable, cannot modify char');
2257
    }
2258
2259
    /**
2260
     * Implements part of the ArrayAccess interface, but throws an exception
2261
     * when called. This maintains the immutability of Stringy objects.
2262
     *
2263
     * @param int $offset <p>The index of the character.</p>
2264
     *
2265
     * @throws \Exception
2266
     *                    <p>When called.</p>
2267
     *
2268
     * @return void
2269
     */
2270 3
    public function offsetUnset($offset)
2271
    {
2272
        // Don't allow directly modifying the string
2273
        /** @noinspection ThrowRawExceptionInspection */
2274 3
        throw new \Exception('Stringy object is immutable, cannot unset char');
2275
    }
2276
2277
    /**
2278
     * Pads the string to a given length with $padStr. If length is less than
2279
     * or equal to the length of the string, no padding takes places. The
2280
     * default string used for padding is a space, and the default type (one of
2281
     * 'left', 'right', 'both') is 'right'. Throws an InvalidArgumentException
2282
     * if $padType isn't one of those 3 values.
2283
     *
2284
     * @param int    $length  <p>Desired string length after padding.</p>
2285
     * @param string $padStr  [optional] <p>String used to pad, defaults to space. Default: ' '</p>
2286
     * @param string $padType [optional] <p>One of 'left', 'right', 'both'. Default: 'right'</p>
2287
     *
2288
     * @throws \InvalidArgumentException
2289
     *                                   <p>If $padType isn't one of 'right', 'left' or 'both'.</p>
2290
     *
2291
     * @return static
2292
     *                <p>Object with a padded $str.</p>
2293
     *
2294
     * @psalm-mutation-free
2295
     */
2296 39
    public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self
2297
    {
2298 39
        return static::create(
2299 39
            $this->utf8::str_pad(
2300 39
                $this->str,
2301 39
                $length,
2302 39
                $padStr,
2303 39
                $padType,
2304 39
                $this->encoding
2305
            )
2306
        );
2307
    }
2308
2309
    /**
2310
     * Returns a new string of a given length such that both sides of the
2311
     * string are padded. Alias for pad() with a $padType of 'both'.
2312
     *
2313
     * @param int    $length <p>Desired string length after padding.</p>
2314
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
2315
     *
2316
     * @psalm-mutation-free
2317
     *
2318
     * @return static
2319
     *                <p>String with padding applied.</p>
2320
     */
2321 33
    public function padBoth(int $length, string $padStr = ' '): self
2322
    {
2323 33
        return static::create(
2324 33
            $this->utf8::str_pad_both(
2325 33
                $this->str,
2326 33
                $length,
2327 33
                $padStr,
2328 33
                $this->encoding
2329
            )
2330
        );
2331
    }
2332
2333
    /**
2334
     * Returns a new string of a given length such that the beginning of the
2335
     * string is padded. Alias for pad() with a $padType of 'left'.
2336
     *
2337
     * @param int    $length <p>Desired string length after padding.</p>
2338
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
2339
     *
2340
     * @psalm-mutation-free
2341
     *
2342
     * @return static
2343
     *                <p>String with left padding.</p>
2344
     */
2345 21
    public function padLeft(int $length, string $padStr = ' '): self
2346
    {
2347 21
        return static::create(
2348 21
            $this->utf8::str_pad_left(
2349 21
                $this->str,
2350 21
                $length,
2351 21
                $padStr,
2352 21
                $this->encoding
2353
            )
2354
        );
2355
    }
2356
2357
    /**
2358
     * Returns a new string of a given length such that the end of the string
2359
     * is padded. Alias for pad() with a $padType of 'right'.
2360
     *
2361
     * @param int    $length <p>Desired string length after padding.</p>
2362
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
2363
     *
2364
     * @psalm-mutation-free
2365
     *
2366
     * @return static
2367
     *                <p>String with right padding.</p>
2368
     */
2369 21
    public function padRight(int $length, string $padStr = ' '): self
2370
    {
2371 21
        return static::create(
2372 21
            $this->utf8::str_pad_right(
2373 21
                $this->str,
2374 21
                $length,
2375 21
                $padStr,
2376 21
                $this->encoding
2377
            )
2378
        );
2379
    }
2380
2381
    /**
2382
     * Returns a new string starting with $prefix.
2383
     *
2384
     * @param string ...$prefix <p>The string to append.</p>
2385
     *
2386
     * @psalm-mutation-free
2387
     *
2388
     * @return static
2389
     *                <p>Object with appended $prefix.</p>
2390
     *
2391
     * @noinspection PhpDocSignatureInspection
2392
     */
2393 7 View Code Duplication
    public function prepend(string ...$prefix): self
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...
2394
    {
2395 7
        if (\count($prefix) <= 1) {
2396
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
2397 6
            $prefix = $prefix[0];
2398
        } else {
2399
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
2400 1
            $prefix = \implode('', $prefix);
2401
        }
2402
2403 7
        return static::create($prefix . $this->str, $this->encoding);
2404
    }
2405
2406
    /**
2407
     * Replaces all occurrences of $pattern in $str by $replacement.
2408
     *
2409
     * @param string $pattern     <p>The regular expression pattern.</p>
2410
     * @param string $replacement <p>The string to replace with.</p>
2411
     * @param string $options     [optional] <p>Matching conditions to be used.</p>
2412
     * @param string $delimiter   [optional] <p>Delimiter the the regex. Default: '/'</p>
2413
     *
2414
     * @psalm-mutation-free
2415
     *
2416
     * @return static
2417
     *                <p>Object with the result2ing $str after the replacements.</p>
2418
     */
2419 29
    public function regexReplace(string $pattern, string $replacement, string $options = '', string $delimiter = '/'): self
2420
    {
2421 29
        return static::create(
2422 29
            $this->utf8::regex_replace(
2423 29
                $this->str,
2424 29
                $pattern,
2425 29
                $replacement,
2426 29
                $options,
2427 29
                $delimiter
2428
            ),
2429 29
            $this->encoding
2430
        );
2431
    }
2432
2433
    /**
2434
     * Remove html via "strip_tags()" from the string.
2435
     *
2436
     * @param string $allowableTags [optional] <p>You can use the optional second parameter to specify tags which should
2437
     *                              not be stripped. Default: null
2438
     *                              </p>
2439
     *
2440
     * @psalm-mutation-free
2441
     *
2442
     * @return static
2443
     */
2444 12
    public function removeHtml(string $allowableTags = ''): self
2445
    {
2446 12
        return static::create(
2447 12
            $this->utf8::remove_html($this->str, $allowableTags),
2448 12
            $this->encoding
2449
        );
2450
    }
2451
2452
    /**
2453
     * Remove all breaks [<br> | \r\n | \r | \n | ...] from the string.
2454
     *
2455
     * @param string $replacement [optional] <p>Default is a empty string.</p>
2456
     *
2457
     * @psalm-mutation-free
2458
     *
2459
     * @return static
2460
     */
2461 12
    public function removeHtmlBreak(string $replacement = ''): self
2462
    {
2463 12
        return static::create(
2464 12
            $this->utf8::remove_html_breaks($this->str, $replacement),
2465 12
            $this->encoding
2466
        );
2467
    }
2468
2469
    /**
2470
     * Returns a new string with the prefix $substring removed, if present.
2471
     *
2472
     * @param string $substring <p>The prefix to remove.</p>
2473
     *
2474
     * @psalm-mutation-free
2475
     *
2476
     * @return static
2477
     *                <p>Object having a $str without the prefix $substring.</p>
2478
     */
2479 36
    public function removeLeft(string $substring): self
2480
    {
2481 36
        return static::create(
2482 36
            $this->utf8::remove_left($this->str, $substring, $this->encoding),
2483 36
            $this->encoding
2484
        );
2485
    }
2486
2487
    /**
2488
     * Returns a new string with the suffix $substring removed, if present.
2489
     *
2490
     * @param string $substring <p>The suffix to remove.</p>
2491
     *
2492
     * @psalm-mutation-free
2493
     *
2494
     * @return static
2495
     *                <p>Object having a $str without the suffix $substring.</p>
2496
     */
2497 36
    public function removeRight(string $substring): self
2498
    {
2499 36
        return static::create(
2500 36
            $this->utf8::remove_right($this->str, $substring, $this->encoding),
2501 36
            $this->encoding
2502
        );
2503
    }
2504
2505
    /**
2506
     * Try to remove all XSS-attacks from the string.
2507
     *
2508
     * @psalm-mutation-free
2509
     *
2510
     * @return static
2511
     */
2512 12
    public function removeXss(): self
2513
    {
2514
        /**
2515
         * @var AntiXSS|null
2516
         *
2517
         * @psalm-suppress ImpureStaticVariable
2518
         */
2519 12
        static $antiXss = null;
2520
2521 12
        if ($antiXss === null) {
2522 1
            $antiXss = new AntiXSS();
2523
        }
2524
2525
        /**
2526
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the anti-xss class
2527
         */
2528 12
        $str = $antiXss->xss_clean($this->str);
2529
2530 12
        return static::create($str, $this->encoding);
2531
    }
2532
2533
    /**
2534
     * Returns a repeated string given a multiplier.
2535
     *
2536
     * @param int $multiplier <p>The number of times to repeat the string.</p>
2537
     *
2538
     * @psalm-mutation-free
2539
     *
2540
     * @return static
2541
     *                <p>Object with a repeated str.</p>
2542
     */
2543 21
    public function repeat(int $multiplier): self
2544
    {
2545 21
        return static::create(
2546 21
            \str_repeat($this->str, $multiplier),
2547 21
            $this->encoding
2548
        );
2549
    }
2550
2551
    /**
2552
     * Replaces all occurrences of $search in $str by $replacement.
2553
     *
2554
     * @param string $search        <p>The needle to search for.</p>
2555
     * @param string $replacement   <p>The string to replace with.</p>
2556
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2557
     *
2558
     * @psalm-mutation-free
2559
     *
2560
     * @return static
2561
     *                <p>Object with the resulting $str after the replacements.</p>
2562
     */
2563 76
    public function replace(string $search, string $replacement, bool $caseSensitive = true): self
2564
    {
2565 76
        if ($search === '' && $replacement === '') {
2566 16
            return static::create($this->str, $this->encoding);
2567
        }
2568
2569 60
        if ($this->str === '' && $search === '') {
2570 2
            return static::create($replacement, $this->encoding);
2571
        }
2572
2573 58
        if ($caseSensitive) {
2574 48
            return static::create(
2575 48
                $this->utf8::str_replace($search, $replacement, $this->str),
2576 48
                $this->encoding
2577
            );
2578
        }
2579
2580 10
        return static::create(
2581 10
            $this->utf8::str_ireplace($search, $replacement, $this->str),
2582 10
            $this->encoding
2583
        );
2584
    }
2585
2586
    /**
2587
     * Replaces all occurrences of $search in $str by $replacement.
2588
     *
2589
     * @param string[]        $search        <p>The elements to search for.</p>
2590
     * @param string|string[] $replacement   <p>The string to replace with.</p>
2591
     * @param bool            $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2592
     *
2593
     * @psalm-mutation-free
2594
     *
2595
     * @return static
2596
     *                <p>Object with the resulting $str after the replacements.</p>
2597
     */
2598 61
    public function replaceAll(array $search, $replacement, bool $caseSensitive = true): self
2599
    {
2600 61
        if ($caseSensitive) {
2601 47
            return static::create(
2602 47
                $this->utf8::str_replace($search, $replacement, $this->str),
2603 47
                $this->encoding
2604
            );
2605
        }
2606
2607 14
        return static::create(
2608 14
            $this->utf8::str_ireplace($search, $replacement, $this->str),
2609 14
            $this->encoding
2610
        );
2611
    }
2612
2613
    /**
2614
     * Replaces all occurrences of $search from the beginning of string with $replacement.
2615
     *
2616
     * @param string $search      <p>The string to search for.</p>
2617
     * @param string $replacement <p>The replacement.</p>
2618
     *
2619
     * @psalm-mutation-free
2620
     *
2621
     * @return static
2622
     *                <p>Object with the resulting $str after the replacements.</p>
2623
     */
2624 32
    public function replaceBeginning(string $search, string $replacement): self
2625
    {
2626 32
        return static::create(
2627 32
            $this->utf8::str_replace_beginning($this->str, $search, $replacement),
2628 32
            $this->encoding
2629
        );
2630
    }
2631
2632
    /**
2633
     * Replaces all occurrences of $search from the ending of string with $replacement.
2634
     *
2635
     * @param string $search      <p>The string to search for.</p>
2636
     * @param string $replacement <p>The replacement.</p>
2637
     *
2638
     * @psalm-mutation-free
2639
     *
2640
     * @return static
2641
     *                <p>Object with the resulting $str after the replacements.</p>
2642
     */
2643 32
    public function replaceEnding(string $search, string $replacement): self
2644
    {
2645 32
        return static::create(
2646 32
            $this->utf8::str_replace_ending($this->str, $search, $replacement),
2647 32
            $this->encoding
2648
        );
2649
    }
2650
2651
    /**
2652
     * Replaces first occurrences of $search from the beginning of string with $replacement.
2653
     *
2654
     * @param string $search      <p>The string to search for.</p>
2655
     * @param string $replacement <p>The replacement.</p>
2656
     *
2657
     * @psalm-mutation-free
2658
     *
2659
     * @return static
2660
     *                <p>Object with the resulting $str after the replacements.</p>
2661
     */
2662 32
    public function replaceFirst(string $search, string $replacement): self
2663
    {
2664 32
        return static::create(
2665 32
            $this->utf8::str_replace_first($search, $replacement, $this->str),
2666 32
            $this->encoding
2667
        );
2668
    }
2669
2670
    /**
2671
     * Replaces last occurrences of $search from the ending of string with $replacement.
2672
     *
2673
     * @param string $search      <p>The string to search for.</p>
2674
     * @param string $replacement <p>The replacement.</p>
2675
     *
2676
     * @psalm-mutation-free
2677
     *
2678
     * @return static
2679
     *                <p>Object with the resulting $str after the replacements.</p>
2680
     */
2681 30
    public function replaceLast(string $search, string $replacement): self
2682
    {
2683 30
        return static::create(
2684 30
            $this->utf8::str_replace_last($search, $replacement, $this->str),
2685 30
            $this->encoding
2686
        );
2687
    }
2688
2689
    /**
2690
     * Returns a reversed string. A multibyte version of strrev().
2691
     *
2692
     * @psalm-mutation-free
2693
     *
2694
     * @return static
2695
     *                <p>Object with a reversed $str.</p>
2696
     */
2697 15
    public function reverse(): self
2698
    {
2699 15
        return static::create($this->utf8::strrev($this->str), $this->encoding);
2700
    }
2701
2702
    /**
2703
     * Truncates the string to a given length, while ensuring that it does not
2704
     * split words. If $substring is provided, and truncating occurs, the
2705
     * string is further truncated so that the substring may be appended without
2706
     * exceeding the desired length.
2707
     *
2708
     * @param int    $length                          <p>Desired length of the truncated string.</p>
2709
     * @param string $substring                       [optional] <p>The substring to append if it can fit. Default: ''</p>
2710
     * @param bool   $ignoreDoNotSplitWordsForOneWord
2711
     *
2712
     * @psalm-mutation-free
2713
     *
2714
     * @return static
2715
     *                <p>Object with the resulting $str after truncating.</p>
2716
     */
2717 68
    public function safeTruncate(
2718
        int $length,
2719
        string $substring = '',
2720
        bool $ignoreDoNotSplitWordsForOneWord = true
2721
    ): self {
2722 68
        return static::create(
2723 68
            $this->utf8::str_truncate_safe(
2724 68
                $this->str,
2725 68
                $length,
2726 68
                $substring,
2727 68
                $this->encoding,
2728 68
                $ignoreDoNotSplitWordsForOneWord
2729
            ),
2730 68
            $this->encoding
2731
        );
2732
    }
2733
2734
    /**
2735
     * Create a sha1 hash from the current string.
2736
     *
2737
     * @psalm-mutation-free
2738
     *
2739
     * @return static
2740
     */
2741 2
    public function sha1(): self
2742
    {
2743 2
        return static::create($this->hash('sha1'), $this->encoding);
2744
    }
2745
2746
    /**
2747
     * Create a sha256 hash from the current string.
2748
     *
2749
     * @psalm-mutation-free
2750
     *
2751
     * @return static
2752
     */
2753 2
    public function sha256(): self
2754
    {
2755 2
        return static::create($this->hash('sha256'), $this->encoding);
2756
    }
2757
2758
    /**
2759
     * Create a sha512 hash from the current string.
2760
     *
2761
     * @psalm-mutation-free
2762
     *
2763
     * @return static
2764
     */
2765 2
    public function sha512(): self
2766
    {
2767 2
        return static::create($this->hash('sha512'), $this->encoding);
2768
    }
2769
2770
    /**
2771
     * Shorten the string after $length, but also after the next word.
2772
     *
2773
     * @param int    $length
2774
     * @param string $strAddOn [optional] <p>Default: '…'</p>
2775
     *
2776
     * @psalm-mutation-free
2777
     *
2778
     * @return static
2779
     */
2780 8
    public function shortenAfterWord(int $length, string $strAddOn = '…'): self
2781
    {
2782 8
        return static::create(
2783 8
            $this->utf8::str_limit_after_word($this->str, $length, $strAddOn),
2784 8
            $this->encoding
2785
        );
2786
    }
2787
2788
    /**
2789
     * A multibyte string shuffle function. It returns a string with its
2790
     * characters in random order.
2791
     *
2792
     * @psalm-mutation-free
2793
     *
2794
     * @return static
2795
     *                <p>Object with a shuffled $str.</p>
2796
     */
2797 9
    public function shuffle(): self
2798
    {
2799 9
        return static::create($this->utf8::str_shuffle($this->str), $this->encoding);
2800
    }
2801
2802
    /**
2803
     * Calculate the similarity between two strings.
2804
     *
2805
     * @param string $str
2806
     *
2807
     * @psalm-mutation-free
2808
     *
2809
     * @return float
2810
     */
2811 2
    public function similarity(string $str): float
2812
    {
2813 2
        \similar_text($this->str, $str, $percent);
2814
2815 2
        return $percent;
2816
    }
2817
2818
    /**
2819
     * Returns the substring beginning at $start, and up to, but not including
2820
     * the index specified by $end. If $end is omitted, the function extracts
2821
     * the remaining string. If $end is negative, it is computed from the end
2822
     * of the string.
2823
     *
2824
     * @param int $start <p>Initial index from which to begin extraction.</p>
2825
     * @param int $end   [optional] <p>Index at which to end extraction. Default: null</p>
2826
     *
2827
     * @psalm-mutation-free
2828
     *
2829
     * @return static
2830
     *                <p>Object with its $str being the extracted substring.</p>
2831
     */
2832 50
    public function slice(int $start, int $end = null): self
2833
    {
2834 50
        return static::create(
2835 50
            $this->utf8::str_slice($this->str, $start, $end, $this->encoding),
2836 50
            $this->encoding
2837
        );
2838
    }
2839
2840
    /**
2841
     * Converts the string into an URL slug. This includes replacing non-ASCII
2842
     * characters with their closest ASCII equivalents, removing remaining
2843
     * non-ASCII and non-alphanumeric characters, and replacing whitespace with
2844
     * $separator. The separator defaults to a single dash, and the string
2845
     * is also converted to lowercase. The language of the source string can
2846
     * also be supplied for language-specific transliteration.
2847
     *
2848
     * @param string                $separator             [optional] <p>The string used to replace whitespace.</p>
2849
     * @param string                $language              [optional] <p>Language of the source string.</p>
2850
     * @param array<string, string> $replacements          [optional] <p>A map of replaceable strings.</p>
2851
     * @param bool                  $replace_extra_symbols [optional]  <p>Add some more replacements e.g. "£" with "
2852
     *                                                     pound ".</p>
2853
     * @param bool                  $use_str_to_lower      [optional] <p>Use "string to lower" for the input.</p>
2854
     * @param bool                  $use_transliterate     [optional]  <p>Use ASCII::to_transliterate() for unknown
2855
     *                                                     chars.</p>
2856
     *
2857
     * @psalm-mutation-free
2858
     *
2859
     * @return static
2860
     *                <p>Object whose $str has been converted to an URL slug.</p>
2861
     *
2862
     * @noinspection PhpTooManyParametersInspection
2863
     */
2864 17
    public function slugify(
2865
        string $separator = '-',
2866
        string $language = 'en',
2867
        array $replacements = [],
2868
        bool $replace_extra_symbols = true,
2869
        bool $use_str_to_lower = true,
2870
        bool $use_transliterate = false
2871
    ): self {
2872 17
        return static::create(
2873 17
            $this->ascii::to_slugify(
2874 17
                $this->str,
2875 17
                $separator,
2876 17
                $language,
2877 17
                $replacements,
2878 17
                $replace_extra_symbols,
2879 17
                $use_str_to_lower,
2880 17
                $use_transliterate
2881
            ),
2882 17
            $this->encoding
2883
        );
2884
    }
2885
2886
    /**
2887
     * Convert a string to e.g.: "snake_case"
2888
     *
2889
     * @psalm-mutation-free
2890
     *
2891
     * @return static
2892
     *                <p>Object with $str in snake_case.</p>
2893
     */
2894 40
    public function snakeize(): self
2895
    {
2896 40
        return static::create(
2897 40
            $this->utf8::str_snakeize($this->str, $this->encoding),
2898 40
            $this->encoding
2899
        );
2900
    }
2901
2902
    /**
2903
     * Wrap the string after the first whitespace character after a given number
2904
     * of characters.
2905
     *
2906
     * @param int    $width Number of characters at which to wrap
2907
     * @param string $break Character used to break the string
2908
     *
2909
     * @psalm-mutation-free
2910
     *
2911
     * @return static
2912
     */
2913 2
    public function softWrap(int $width, string $break = "\n"): self
2914
    {
2915 2
        return $this->lineWrapAfterWord($width, $break, false);
2916
    }
2917
2918
    /**
2919
     * Splits the string with the provided regular expression, returning an
2920
     * array of Stringy objects. An optional integer $limit will truncate the
2921
     * results.
2922
     *
2923
     * @param string $pattern <p>The regex with which to split the string.</p>
2924
     * @param int    $limit   [optional] <p>Maximum number of results to return. Default: -1 === no limit</p>
2925
     *
2926
     * @psalm-mutation-free
2927
     *
2928
     * @return CollectionStringy|static[]
2929
     *                                    <p>An collection of Stringy objects.</p>
2930
     *
2931
     * @psalm-return CollectionStringy<int,static>
2932
     */
2933 51
    public function split(string $pattern, int $limit = null): CollectionStringy
2934
    {
2935 51
        if ($limit === null) {
2936 7
            $limit = -1;
2937
        }
2938
2939 51
        $array = $this->utf8::str_split_pattern($this->str, $pattern, $limit);
2940
        /** @noinspection AlterInForeachInspection */
2941 51
        foreach ($array as $i => &$value) {
2942 45
            $value = static::create($value, $this->encoding);
2943
        }
2944
2945
        /** @noinspection PhpSillyAssignmentInspection */
2946
        /** @var static[] $array */
2947 51
        $array = $array;
0 ignored issues
show
Bug introduced by
Why assign $array to itself?

This checks looks for cases where a variable has been assigned to itself.

This assignement can be removed without consequences.

Loading history...
2948
2949
        /**
2950
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
2951
         */
2952 51
        return CollectionStringy::create($array);
2953
    }
2954
2955
    /**
2956
     * Returns true if the string begins with $substring, false otherwise. By
2957
     * default, the comparison is case-sensitive, but can be made insensitive
2958
     * by setting $caseSensitive to false.
2959
     *
2960
     * @param string $substring     <p>The substring to look for.</p>
2961
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2962
     *
2963
     * @psalm-mutation-free
2964
     *
2965
     * @return bool
2966
     *              <p>Whether or not $str starts with $substring.</p>
2967
     */
2968 99
    public function startsWith(string $substring, bool $caseSensitive = true): bool
2969
    {
2970 99
        if ($caseSensitive) {
2971 53
            return $this->utf8::str_starts_with($this->str, $substring);
2972
        }
2973
2974 46
        return $this->utf8::str_istarts_with($this->str, $substring);
2975
    }
2976
2977
    /**
2978
     * Returns true if the string begins with any of $substrings, false otherwise.
2979
     * By default the comparison is case-sensitive, but can be made insensitive by
2980
     * setting $caseSensitive to false.
2981
     *
2982
     * @param string[] $substrings    <p>Substrings to look for.</p>
2983
     * @param bool     $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2984
     *
2985
     * @psalm-mutation-free
2986
     *
2987
     * @return bool
2988
     *              <p>Whether or not $str starts with $substring.</p>
2989
     */
2990 35
    public function startsWithAny(array $substrings, bool $caseSensitive = true): bool
2991
    {
2992 35
        if ($caseSensitive) {
2993 23
            return $this->utf8::str_starts_with_any($this->str, $substrings);
2994
        }
2995
2996 12
        return $this->utf8::str_istarts_with_any($this->str, $substrings);
2997
    }
2998
2999
    /**
3000
     * Remove one or more strings from the string.
3001
     *
3002
     * @param string|string[] $search One or more strings to be removed
3003
     *
3004
     * @psalm-mutation-free
3005
     *
3006
     * @return static
3007
     */
3008 3
    public function strip($search): self
3009
    {
3010 3
        if (\is_array($search)) {
3011 1
            return $this->replaceAll($search, '');
3012
        }
3013
3014 2
        return $this->replace($search, '');
3015
    }
3016
3017
    /**
3018
     * Strip all whitespace characters. This includes tabs and newline characters,
3019
     * as well as multibyte whitespace such as the thin space and ideographic space.
3020
     *
3021
     * @psalm-mutation-free
3022
     *
3023
     * @return static
3024
     */
3025 36
    public function stripWhitespace(): self
3026
    {
3027 36
        return static::create(
3028 36
            $this->utf8::strip_whitespace($this->str),
3029 36
            $this->encoding
3030
        );
3031
    }
3032
3033
    /**
3034
     * Remove css media-queries.
3035
     *
3036
     * @psalm-mutation-free
3037
     *
3038
     * @return static
3039
     */
3040 2
    public function stripeCssMediaQueries(): self
3041
    {
3042 2
        return static::create(
3043 2
            $this->utf8::css_stripe_media_queries($this->str),
3044 2
            $this->encoding
3045
        );
3046
    }
3047
3048
    /**
3049
     * Remove empty html-tag.
3050
     *
3051
     * e.g.: <tag></tag>
3052
     *
3053
     * @psalm-mutation-free
3054
     *
3055
     * @return static
3056
     */
3057 2
    public function stripeEmptyHtmlTags(): self
3058
    {
3059 2
        return static::create(
3060 2
            $this->utf8::html_stripe_empty_tags($this->str),
3061 2
            $this->encoding
3062
        );
3063
    }
3064
3065
    /**
3066
     * Returns the substring beginning at $start with the specified $length.
3067
     * It differs from the $this->utf8::substr() function in that providing a $length of
3068
     * null will return the rest of the string, rather than an empty string.
3069
     *
3070
     * @param int $start  <p>Position of the first character to use.</p>
3071
     * @param int $length [optional] <p>Maximum number of characters used. Default: null</p>
3072
     *
3073
     * @psalm-mutation-free
3074
     *
3075
     * @return static
3076
     *                <p>Object with its $str being the substring.</p>
3077
     */
3078 31
    public function substr(int $start, int $length = null): self
3079
    {
3080 31
        return static::create(
3081 31
            $this->utf8::substr(
3082 31
                $this->str,
3083 31
                $start,
3084 31
                $length,
3085 31
                $this->encoding
3086
            ),
3087 31
            $this->encoding
3088
        );
3089
    }
3090
3091
    /**
3092
     * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle".
3093
     * If no match is found returns new empty Stringy object.
3094
     *
3095
     * @param string $needle       <p>The string to look for.</p>
3096
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
3097
     *
3098
     * @psalm-mutation-free
3099
     *
3100
     * @return static
3101
     */
3102 4 View Code Duplication
    public function substringOf(string $needle, bool $beforeNeedle = false): self
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...
3103
    {
3104 4
        return static::create(
3105 4
            $this->utf8::str_substr_first(
3106 4
                $this->str,
3107 4
                $needle,
3108 4
                $beforeNeedle,
3109 4
                $this->encoding
3110
            ),
3111 4
            $this->encoding
3112
        );
3113
    }
3114
3115
    /**
3116
     * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle".
3117
     * If no match is found returns new empty Stringy object.
3118
     *
3119
     * @param string $needle       <p>The string to look for.</p>
3120
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
3121
     *
3122
     * @psalm-mutation-free
3123
     *
3124
     * @return static
3125
     */
3126 4 View Code Duplication
    public function substringOfIgnoreCase(string $needle, bool $beforeNeedle = false): self
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...
3127
    {
3128 4
        return static::create(
3129 4
            $this->utf8::str_isubstr_first(
3130 4
                $this->str,
3131 4
                $needle,
3132 4
                $beforeNeedle,
3133 4
                $this->encoding
3134
            ),
3135 4
            $this->encoding
3136
        );
3137
    }
3138
3139
    /**
3140
     * Surrounds $str with the given substring.
3141
     *
3142
     * @param string $substring <p>The substring to add to both sides.</P>
3143
     *
3144
     * @psalm-mutation-free
3145
     *
3146
     * @return static
3147
     *                <p>Object whose $str had the substring both prepended and appended.</p>
3148
     */
3149 15
    public function surround(string $substring): self
3150
    {
3151 15
        return static::create(
3152 15
            $substring . $this->str . $substring,
3153 15
            $this->encoding
3154
        );
3155
    }
3156
3157
    /**
3158
     * Returns a case swapped version of the string.
3159
     *
3160
     * @psalm-mutation-free
3161
     *
3162
     * @return static
3163
     *                <p>Object whose $str has each character's case swapped.</P>
3164
     */
3165 15
    public function swapCase(): self
3166
    {
3167 15
        return static::create(
3168 15
            $this->utf8::swapCase($this->str, $this->encoding),
3169 15
            $this->encoding
3170
        );
3171
    }
3172
3173
    /**
3174
     * Returns a string with smart quotes, ellipsis characters, and dashes from
3175
     * Windows-1252 (commonly used in Word documents) replaced by their ASCII
3176
     * equivalents.
3177
     *
3178
     * @psalm-mutation-free
3179
     *
3180
     * @return static
3181
     *                <p>Object whose $str has those characters removed.</p>
3182
     */
3183 12
    public function tidy(): self
3184
    {
3185 12
        return static::create(
3186 12
            $this->ascii::normalize_msword($this->str),
3187 12
            $this->encoding
3188
        );
3189
    }
3190
3191
    /**
3192
     * Returns a trimmed string with the first letter of each word capitalized.
3193
     * Also accepts an array, $ignore, allowing you to list words not to be
3194
     * capitalized.
3195
     *
3196
     * @param array|string[]|null $ignore            [optional] <p>An array of words not to capitalize or null.
3197
     *                                               Default: null</p>
3198
     * @param string|null         $word_define_chars [optional] <p>An string of chars that will be used as whitespace
3199
     *                                               separator === words.</p>
3200
     * @param string|null         $language          [optional] <p>Language of the source string.</p>
3201
     *
3202
     * @psalm-mutation-free
3203
     *
3204
     * @return static
3205
     *                <p>Object with a titleized $str.</p>
3206
     */
3207 23
    public function titleize(
3208
        array $ignore = null,
3209
        string $word_define_chars = null,
3210
        string $language = null
3211
    ): self {
3212 23
        return static::create(
3213 23
            $this->utf8::str_titleize(
3214 23
                $this->str,
3215 23
                $ignore,
3216 23
                $this->encoding,
3217 23
                false,
3218 23
                $language,
3219 23
                false,
3220 23
                true,
3221 23
                $word_define_chars
3222
            ),
3223 23
            $this->encoding
3224
        );
3225
    }
3226
3227
    /**
3228
     * Returns a trimmed string in proper title case.
3229
     *
3230
     * Also accepts an array, $ignore, allowing you to list words not to be
3231
     * capitalized.
3232
     *
3233
     * Adapted from John Gruber's script.
3234
     *
3235
     * @see https://gist.github.com/gruber/9f9e8650d68b13ce4d78
3236
     *
3237
     * @param string[] $ignore <p>An array of words not to capitalize.</p>
3238
     *
3239
     * @psalm-mutation-free
3240
     *
3241
     * @return static
3242
     *                <p>Object with a titleized $str</p>
3243
     */
3244 70
    public function titleizeForHumans(array $ignore = []): self
3245
    {
3246 70
        return static::create(
3247 70
            $this->utf8::str_titleize_for_humans(
3248 70
                $this->str,
3249 70
                $ignore,
3250 70
                $this->encoding
3251
            ),
3252 70
            $this->encoding
3253
        );
3254
    }
3255
3256
    /**
3257
     * Returns an ASCII version of the string. A set of non-ASCII characters are
3258
     * replaced with their closest ASCII counterparts, and the rest are removed
3259
     * by default. The language or locale of the source string can be supplied
3260
     * for language-specific transliteration in any of the following formats:
3261
     * en, en_GB, or en-GB. For example, passing "de" results in "äöü" mapping
3262
     * to "aeoeue" rather than "aou" as in other languages.
3263
     *
3264
     * @param string $language          [optional] <p>Language of the source string.</p>
3265
     * @param bool   $removeUnsupported [optional] <p>Whether or not to remove the
3266
     *                                  unsupported characters.</p>
3267
     *
3268
     * @psalm-mutation-free
3269
     *
3270
     * @return static
3271
     *                <p>Object whose $str contains only ASCII characters.</p>
3272
     */
3273 23
    public function toAscii(string $language = 'en', bool $removeUnsupported = true): self
3274
    {
3275 23
        return static::create(
3276 23
            $this->ascii::to_ascii(
3277 23
                $this->str,
3278 23
                $language,
3279 23
                $removeUnsupported
3280
            ),
3281 23
            $this->encoding
3282
        );
3283
    }
3284
3285
    /**
3286
     * Returns a boolean representation of the given logical string value.
3287
     * For example, 'true', '1', 'on' and 'yes' will return true. 'false', '0',
3288
     * 'off', and 'no' will return false. In all instances, case is ignored.
3289
     * For other numeric strings, their sign will determine the return value.
3290
     * In addition, blank strings consisting of only whitespace will return
3291
     * false. For all other strings, the return value is a result of a
3292
     * boolean cast.
3293
     *
3294
     * @psalm-mutation-free
3295
     *
3296
     * @return bool
3297
     *              <p>A boolean value for the string.</p>
3298
     */
3299 45
    public function toBoolean(): bool
3300
    {
3301 45
        return $this->utf8::to_boolean($this->str);
3302
    }
3303
3304
    /**
3305
     * Converts all characters in the string to lowercase.
3306
     *
3307
     * @param bool        $tryToKeepStringLength [optional] <p>true === try to keep the string length: e.g. ẞ -> ß</p>
3308
     * @param string|null $lang                  [optional] <p>Set the language for special cases: az, el, lt, tr</p>
3309
     *
3310
     * @psalm-mutation-free
3311
     *
3312
     * @return static
3313
     *                <p>Object with all characters of $str being lowercase.</p>
3314
     */
3315 17 View Code Duplication
    public function toLowerCase($tryToKeepStringLength = false, $lang = null): self
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...
3316
    {
3317 17
        return static::create(
3318 17
            $this->utf8::strtolower(
3319 17
                $this->str,
3320 17
                $this->encoding,
3321 17
                false,
3322 17
                $lang,
3323 17
                $tryToKeepStringLength
3324
            ),
3325 17
            $this->encoding
3326
        );
3327
    }
3328
3329
    /**
3330
     * Converts each tab in the string to some number of spaces, as defined by
3331
     * $tabLength. By default, each tab is converted to 4 consecutive spaces.
3332
     *
3333
     * @param int $tabLength [optional] <p>Number of spaces to replace each tab with. Default: 4</p>
3334
     *
3335
     * @psalm-mutation-free
3336
     *
3337
     * @return static
3338
     *                <p>Object whose $str has had tabs switched to spaces.</p>
3339
     */
3340 18 View Code Duplication
    public function toSpaces(int $tabLength = 4): self
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...
3341
    {
3342 18
        if ($tabLength === 4) {
3343 9
            $tab = '    ';
3344 9
        } elseif ($tabLength === 2) {
3345 3
            $tab = '  ';
3346
        } else {
3347 6
            $tab = \str_repeat(' ', $tabLength);
3348
        }
3349
3350 18
        return static::create(
3351 18
            \str_replace("\t", $tab, $this->str),
3352 18
            $this->encoding
3353
        );
3354
    }
3355
3356
    /**
3357
     * Return Stringy object as string, but you can also use (string) for automatically casting the object into a
3358
     * string.
3359
     *
3360
     * @psalm-mutation-free
3361
     *
3362
     * @return string
3363
     */
3364 2180
    public function toString(): string
3365
    {
3366 2180
        return (string) $this->str;
3367
    }
3368
3369
    /**
3370
     * Converts each occurrence of some consecutive number of spaces, as
3371
     * defined by $tabLength, to a tab. By default, each 4 consecutive spaces
3372
     * are converted to a tab.
3373
     *
3374
     * @param int $tabLength [optional] <p>Number of spaces to replace with a tab. Default: 4</p>
3375
     *
3376
     * @psalm-mutation-free
3377
     *
3378
     * @return static
3379
     *                <p>Object whose $str has had spaces switched to tabs.</p>
3380
     */
3381 15 View Code Duplication
    public function toTabs(int $tabLength = 4): self
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...
3382
    {
3383 15
        if ($tabLength === 4) {
3384 9
            $tab = '    ';
3385 6
        } elseif ($tabLength === 2) {
3386 3
            $tab = '  ';
3387
        } else {
3388 3
            $tab = \str_repeat(' ', $tabLength);
3389
        }
3390
3391 15
        return static::create(
3392 15
            \str_replace($tab, "\t", $this->str),
3393 15
            $this->encoding
3394
        );
3395
    }
3396
3397
    /**
3398
     * Converts the first character of each word in the string to uppercase
3399
     * and all other chars to lowercase.
3400
     *
3401
     * @psalm-mutation-free
3402
     *
3403
     * @return static
3404
     *                <p>Object with all characters of $str being title-cased.</p>
3405
     */
3406 15
    public function toTitleCase(): self
3407
    {
3408 15
        return static::create(
3409 15
            $this->utf8::titlecase($this->str, $this->encoding),
3410 15
            $this->encoding
3411
        );
3412
    }
3413
3414
    /**
3415
     * Returns an ASCII version of the string. A set of non-ASCII characters are
3416
     * replaced with their closest ASCII counterparts, and the rest are removed
3417
     * unless instructed otherwise.
3418
     *
3419
     * @param bool   $strict  [optional] <p>Use "transliterator_transliterate()" from PHP-Intl | WARNING: bad
3420
     *                        performance | Default: false</p>
3421
     * @param string $unknown [optional] <p>Character use if character unknown. (default is ?)</p>
3422
     *
3423
     * @psalm-mutation-free
3424
     *
3425
     * @return static
3426
     *                <p>Object whose $str contains only ASCII characters.</p>
3427
     */
3428 34
    public function toTransliterate(bool $strict = false, string $unknown = '?'): self
3429
    {
3430 34
        return static::create(
3431 34
            $this->ascii::to_transliterate($this->str, $unknown, $strict),
3432 34
            $this->encoding
3433
        );
3434
    }
3435
3436
    /**
3437
     * Converts all characters in the string to uppercase.
3438
     *
3439
     * @param bool        $tryToKeepStringLength [optional] <p>true === try to keep the string length: e.g. ẞ -> ß</p>
3440
     * @param string|null $lang                  [optional] <p>Set the language for special cases: az, el, lt, tr</p>
3441
     *
3442
     * @psalm-mutation-free
3443
     *
3444
     * @return static
3445
     *                <p>Object with all characters of $str being uppercase.</p>
3446
     */
3447 20 View Code Duplication
    public function toUpperCase($tryToKeepStringLength = false, $lang = null): self
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...
3448
    {
3449 20
        return static::create(
3450 20
            $this->utf8::strtoupper($this->str, $this->encoding, false, $lang, $tryToKeepStringLength),
3451 20
            $this->encoding
3452
        );
3453
    }
3454
3455
    /**
3456
     * Returns a string with whitespace removed from the start and end of the
3457
     * string. Supports the removal of unicode whitespace. Accepts an optional
3458
     * string of characters to strip instead of the defaults.
3459
     *
3460
     * @param string $chars [optional] <p>String of characters to strip. Default: null</p>
3461
     *
3462
     * @psalm-mutation-free
3463
     *
3464
     * @return static
3465
     *                <p>Object with a trimmed $str.</p>
3466
     */
3467 36
    public function trim(string $chars = null): self
3468
    {
3469 36
        return static::create(
3470 36
            $this->utf8::trim($this->str, $chars),
3471 36
            $this->encoding
3472
        );
3473
    }
3474
3475
    /**
3476
     * Returns a string with whitespace removed from the start of the string.
3477
     * Supports the removal of unicode whitespace. Accepts an optional
3478
     * string of characters to strip instead of the defaults.
3479
     *
3480
     * @param string $chars [optional] <p>Optional string of characters to strip. Default: null</p>
3481
     *
3482
     * @psalm-mutation-free
3483
     *
3484
     * @return static
3485
     *                <p>Object with a trimmed $str.</p>
3486
     */
3487 39
    public function trimLeft(string $chars = null): self
3488
    {
3489 39
        return static::create(
3490 39
            $this->utf8::ltrim($this->str, $chars),
3491 39
            $this->encoding
3492
        );
3493
    }
3494
3495
    /**
3496
     * Returns a string with whitespace removed from the end of the string.
3497
     * Supports the removal of unicode whitespace. Accepts an optional
3498
     * string of characters to strip instead of the defaults.
3499
     *
3500
     * @param string $chars [optional] <p>Optional string of characters to strip. Default: null</p>
3501
     *
3502
     * @psalm-mutation-free
3503
     *
3504
     * @return static
3505
     *                <p>Object with a trimmed $str.</p>
3506
     */
3507 39
    public function trimRight(string $chars = null): self
3508
    {
3509 39
        return static::create(
3510 39
            $this->utf8::rtrim($this->str, $chars),
3511 39
            $this->encoding
3512
        );
3513
    }
3514
3515
    /**
3516
     * Truncates the string to a given length. If $substring is provided, and
3517
     * truncating occurs, the string is further truncated so that the substring
3518
     * may be appended without exceeding the desired length.
3519
     *
3520
     * @param int    $length    <p>Desired length of the truncated string.</p>
3521
     * @param string $substring [optional] <p>The substring to append if it can fit. Default: ''</p>
3522
     *
3523
     * @psalm-mutation-free
3524
     *
3525
     * @return static
3526
     *                <p>Object with the resulting $str after truncating.</p>
3527
     */
3528 66
    public function truncate(int $length, string $substring = ''): self
3529
    {
3530 66
        return static::create(
3531 66
            $this->utf8::str_truncate($this->str, $length, $substring, $this->encoding),
3532 66
            $this->encoding
3533
        );
3534
    }
3535
3536
    /**
3537
     * Returns a lowercase and trimmed string separated by underscores.
3538
     * Underscores are inserted before uppercase characters (with the exception
3539
     * of the first character of the string), and in place of spaces as well as
3540
     * dashes.
3541
     *
3542
     * @psalm-mutation-free
3543
     *
3544
     * @return static
3545
     *                <p>Object with an underscored $str.</p>
3546
     */
3547 48
    public function underscored(): self
3548
    {
3549 48
        return $this->delimit('_');
3550
    }
3551
3552
    /**
3553
     * Returns an UpperCamelCase version of the supplied string. It trims
3554
     * surrounding spaces, capitalizes letters following digits, spaces, dashes
3555
     * and underscores, and removes spaces, dashes, underscores.
3556
     *
3557
     * @psalm-mutation-free
3558
     *
3559
     * @return static
3560
     *                <p>Object with $str in UpperCamelCase.</p>
3561
     */
3562 39
    public function upperCamelize(): self
3563
    {
3564 39
        return static::create(
3565 39
            $this->utf8::str_upper_camelize($this->str, $this->encoding),
3566 39
            $this->encoding
3567
        );
3568
    }
3569
3570
    /**
3571
     * Converts the first character of the supplied string to upper case.
3572
     *
3573
     * @psalm-mutation-free
3574
     *
3575
     * @return static
3576
     *                <p>Object with the first character of $str being upper case.</p>
3577
     */
3578 18
    public function upperCaseFirst(): self
3579
    {
3580 18
        return static::create($this->utf8::ucfirst($this->str, $this->encoding), $this->encoding);
3581
    }
3582
3583
    /**
3584
     * Converts the string into an URL slug. This includes replacing non-ASCII
3585
     * characters with their closest ASCII equivalents, removing remaining
3586
     * non-ASCII and non-alphanumeric characters, and replacing whitespace with
3587
     * $separator. The separator defaults to a single dash, and the string
3588
     * is also converted to lowercase.
3589
     *
3590
     * @param string                $separator    [optional] <p>The string used to replace whitespace. Default: '-'</p>
3591
     * @param string                $language     [optional] <p>The language for the url. Default: 'en'</p>
3592
     * @param array<string, string> $replacements [optional] <p>A map of replaceable strings.</p>
3593
     * @param bool                  $strToLower   [optional] <p>string to lower. Default: true</p>
3594
     *
3595
     * @psalm-mutation-free
3596
     *
3597
     * @return static
3598
     *                <p>Object whose $str has been converted to an URL slug.</p>
3599
     *
3600
     * @psalm-suppress ImpureMethodCall :/
3601
     */
3602 32
    public function urlify(
3603
        string $separator = '-',
3604
        string $language = 'en',
3605
        array $replacements = [],
3606
        bool $strToLower = true
3607
    ): self {
3608
        // init
3609 32
        $str = $this->str;
3610
3611 32
        foreach ($replacements as $from => $to) {
3612 32
            $str = \str_replace($from, $to, $str);
3613
        }
3614
3615 32
        return static::create(
3616 32
            URLify::slug(
3617 32
                $str,
3618 32
                $language,
3619 32
                $separator,
3620 32
                $strToLower
3621
            ),
3622 32
            $this->encoding
3623
        );
3624
    }
3625
3626
    /**
3627
     * Converts the string into an valid UTF-8 string.
3628
     *
3629
     * @psalm-mutation-free
3630
     *
3631
     * @return static
3632
     */
3633 2
    public function utf8ify(): self
3634
    {
3635 2
        return static::create($this->utf8::cleanup($this->str), $this->encoding);
3636
    }
3637
3638
    /**
3639
     * Convert a string into an array of words.
3640
     *
3641
     * @param string   $char_list           <p>Additional chars for the definition of "words".</p>
3642
     * @param bool     $remove_empty_values <p>Remove empty values.</p>
3643
     * @param int|null $remove_short_values <p>The min. string length or null to disable</p>
3644
     *
3645
     * @psalm-mutation-free
3646
     *
3647
     * @return CollectionStringy|static[]
3648
     *
3649
     * @psalm-return CollectionStringy<int,static>
3650
     */
3651 2
    public function words(
3652
        string $char_list = '',
3653
        bool $remove_empty_values = false,
3654
        int $remove_short_values = null
3655
    ): CollectionStringy {
3656
        /**
3657
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
3658
         */
3659 2
        return CollectionStringy::createFromStrings(
3660 2
            $this->utf8::str_to_words(
3661 2
                $this->str,
3662 2
                $char_list,
3663 2
                $remove_empty_values,
3664 2
                $remove_short_values
3665
            )
3666
        );
3667
    }
3668
3669
    /**
3670
     * Surrounds $str with the given substring.
3671
     *
3672
     * @param string $substring <p>The substring to add to both sides.</P>
3673
     *
3674
     * @psalm-mutation-free
3675
     *
3676
     * @return static
3677
     *                <p>Object whose $str had the substring both prepended and appended.</p>
3678
     */
3679 10
    public function wrap(string $substring): self
3680
    {
3681 10
        return $this->surround($substring);
3682
    }
3683
3684
    /**
3685
     * Returns the replacements for the toAscii() method.
3686
     *
3687
     * @noinspection PhpUnused
3688
     *
3689
     * @psalm-mutation-free
3690
     *
3691
     * @return array<string, array<int, string>>
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
3692
     *                       <p>An array of replacements.</p>
3693
     *
3694
     * @deprecated   this is only here for backward-compatibly reasons
3695
     */
3696 1
    protected function charsArray(): array
3697
    {
3698 1
        return $this->ascii::charsArrayWithMultiLanguageValues();
3699
    }
3700
3701
    /**
3702
     * Returns true if $str matches the supplied pattern, false otherwise.
3703
     *
3704
     * @param string $pattern <p>Regex pattern to match against.</p>
3705
     *
3706
     * @psalm-mutation-free
3707
     *
3708
     * @return bool
3709
     *              <p>Whether or not $str matches the pattern.</p>
3710
     */
3711 24
    protected function matchesPattern(string $pattern): bool
3712
    {
3713 24
        return $this->utf8::str_matches_pattern($this->str, $pattern);
3714
    }
3715
}
3716