Completed
Push — master ( 42172e...10ad6d )
by Lars
03:29
created

Stringy::decrypt()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 10
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 3600
    public function __construct($str = '', string $encoding = null)
62
    {
63 3600
        if (\is_array($str)) {
64 3
            throw new \InvalidArgumentException(
65 3
                'Passed value cannot be an array'
66
            );
67
        }
68
69
        if (
70 3597
            \is_object($str)
71
            &&
72 3597
            !\method_exists($str, '__toString')
73
        ) {
74 3
            throw new \InvalidArgumentException(
75 3
                'Passed object must have a __toString method'
76
            );
77
        }
78
79 3594
        $this->str = (string) $str;
80
81 3594
        static $ASCII = null;
82 3594
        if ($ASCII === null) {
83
            $ASCII = new ASCII();
84
        }
85 3594
        $this->ascii = $ASCII;
86
87 3594
        static $UTF8 = null;
88 3594
        if ($UTF8 === null) {
89
            $UTF8 = new UTF8();
90
        }
91 3594
        $this->utf8 = $UTF8;
92
93 3594
        if ($encoding !== 'UTF-8') {
94 2424
            $this->encoding = $this->utf8::normalize_encoding($encoding, 'UTF-8');
95
        } else {
96 2685
            $this->encoding = $encoding;
97
        }
98 3594
    }
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
     * Encrypt the string.
806
     *
807
     * @param string $password The key for encrypting
808
     *
809
     * @return static
810
     */
811 4
    public function encrypt(string $password): self
812
    {
813 4
        return new static(
814 4
            Crypto::encryptWithPassword($this->str, $password),
815 4
            $this->encoding
816
        );
817
    }
818
819
    /**
820
     * Returns true if the string ends with $substring, false otherwise. By
821
     * default, the comparison is case-sensitive, but can be made insensitive
822
     * by setting $caseSensitive to false.
823
     *
824
     * @param string $substring     <p>The substring to look for.</p>
825
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
826
     *
827
     * @psalm-mutation-free
828
     *
829
     * @return bool
830
     *              <p>Whether or not $str ends with $substring.</p>
831
     */
832 97
    public function endsWith(string $substring, bool $caseSensitive = true): bool
833
    {
834 97
        if ($caseSensitive) {
835 53
            return $this->utf8::str_ends_with($this->str, $substring);
836
        }
837
838 44
        return $this->utf8::str_iends_with($this->str, $substring);
839
    }
840
841
    /**
842
     * Returns true if the string ends with any of $substrings, false otherwise.
843
     * By default, the comparison is case-sensitive, but can be made insensitive
844
     * by setting $caseSensitive to false.
845
     *
846
     * @param string[] $substrings    <p>Substrings to look for.</p>
847
     * @param bool     $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
848
     *
849
     * @psalm-mutation-free
850
     *
851
     * @return bool
852
     *              <p>Whether or not $str ends with $substring.</p>
853
     */
854 33
    public function endsWithAny(array $substrings, bool $caseSensitive = true): bool
855
    {
856 33
        if ($caseSensitive) {
857 21
            return $this->utf8::str_ends_with_any($this->str, $substrings);
858
        }
859
860 12
        return $this->utf8::str_iends_with_any($this->str, $substrings);
861
    }
862
863
    /**
864
     * Ensures that the string begins with $substring. If it doesn't, it's
865
     * prepended.
866
     *
867
     * @param string $substring <p>The substring to add if not present.</p>
868
     *
869
     * @psalm-mutation-free
870
     *
871
     * @return static
872
     *                <p>Object with its $str prefixed by the $substring.</p>
873
     */
874 30
    public function ensureLeft(string $substring): self
875
    {
876 30
        return static::create(
877 30
            $this->utf8::str_ensure_left($this->str, $substring),
878 30
            $this->encoding
879
        );
880
    }
881
882
    /**
883
     * Ensures that the string ends with $substring. If it doesn't, it's appended.
884
     *
885
     * @param string $substring <p>The substring to add if not present.</p>
886
     *
887
     * @psalm-mutation-free
888
     *
889
     * @return static
890
     *                <p>Object with its $str suffixed by the $substring.</p>
891
     */
892 30
    public function ensureRight(string $substring): self
893
    {
894 30
        return static::create(
895 30
            $this->utf8::str_ensure_right($this->str, $substring),
896 30
            $this->encoding
897
        );
898
    }
899
900
    /**
901
     * Create a escape html version of the string via "htmlspecialchars()".
902
     *
903
     * @psalm-mutation-free
904
     *
905
     * @return static
906
     */
907 12
    public function escape(): self
908
    {
909 12
        return static::create(
910 12
            $this->utf8::htmlspecialchars(
911 12
                $this->str,
912 12
                \ENT_QUOTES | \ENT_SUBSTITUTE,
913 12
                $this->encoding
914
            ),
915 12
            $this->encoding
916
        );
917
    }
918
919
    /**
920
     * Split a string by a string.
921
     *
922
     * @param string $delimiter The boundary string
923
     * @param int    $limit     the maximum number of elements in the exploded collection.
924
     *
925
     *   - If limit is set and positive, the returned collection will contain a maximum of limit elements with the last
926
     *   element containing the rest of string.
927
     *   - If the limit parameter is negative, all components except the last -limit are returned.
928
     *   - If the limit parameter is zero, then this is treated as 1
929
     *
930
     * @psalm-mutation-free
931
     *
932
     * @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...
933
     */
934 3
    public function explode(string $delimiter, int $limit = \PHP_INT_MAX): CollectionStringy
935
    {
936 3
        $data = \explode($delimiter, $this->str, $limit);
937 3
        if ($data === false) {
938
            $data = [];
939
        }
940
941 3
        $data = \array_map(
942
            function ($str) {
943 3
                return new static($str, $this->encoding);
944 3
            },
945 3
            $data
946
        );
947
948
        /**
949
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
950
         */
951 3
        return CollectionStringy::create($data);
952
    }
953
954
    /**
955
     * Create an extract from a sentence, so if the search-string was found, it try to centered in the output.
956
     *
957
     * @param string   $search
958
     * @param int|null $length                 [optional] <p>Default: null === text->length / 2</p>
959
     * @param string   $replacerForSkippedText [optional] <p>Default: …</p>
960
     *
961
     * @psalm-mutation-free
962
     *
963
     * @return static
964
     */
965 2
    public function extractText(string $search = '', int $length = null, string $replacerForSkippedText = '…'): self
966
    {
967 2
        return static::create(
968 2
            $this->utf8::extract_text(
969 2
                $this->str,
970 2
                $search,
971 2
                $length,
972 2
                $replacerForSkippedText,
973 2
                $this->encoding
974
            ),
975 2
            $this->encoding
976
        );
977
    }
978
979
    /**
980
     * Returns the first $n characters of the string.
981
     *
982
     * @param int $n <p>Number of characters to retrieve from the start.</p>
983
     *
984
     * @psalm-mutation-free
985
     *
986
     * @return static
987
     *                <p>Object with its $str being the first $n chars.</p>
988
     */
989 37
    public function first(int $n): self
990
    {
991 37
        return static::create(
992 37
            $this->utf8::first_char($this->str, $n, $this->encoding),
993 37
            $this->encoding
994
        );
995
    }
996
997
    /**
998
     * Return a formatted string via sprintf + named parameters via array syntax.
999
     *
1000
     * <p>
1001
     * <br>
1002
     * It will use "sprintf()" so you can use e.g.:
1003
     * <br>
1004
     * <br><pre>s('There are %d monkeys in the %s')->format(5, 'tree');</pre>
1005
     * <br>
1006
     * <br><pre>s('There are %2$d monkeys in the %1$s')->format('tree', 5);</pre>
1007
     * <br>
1008
     * <br>
1009
     * But you can also use named parameter via array syntax e.g.:
1010
     * <br>
1011
     * <br><pre>s('There are %:count monkeys in the %:location')->format(['count' => 5, 'location' => 'tree');</pre>
1012
     * </p>
1013
     *
1014
     * @param mixed ...$args [optional]
1015
     *
1016
     * @psalm-mutation-free
1017
     *
1018
     * @return static
1019
     *                <p>A Stringy object produced according to the formatting string
1020
     *                format.</p>
1021
     */
1022 10
    public function format(...$args): self
1023
    {
1024
        // init
1025 10
        $str = $this->str;
1026
1027 10
        if (\strpos($this->str, '%:') !== false) {
1028 8
            $offset = null;
1029 8
            $replacement = null;
1030
            /** @noinspection AlterInForeachInspection */
1031 8
            foreach ($args as $key => &$arg) {
1032 8
                if (!\is_array($arg)) {
1033 4
                    continue;
1034
                }
1035
1036 8
                foreach ($arg as $name => $param) {
1037 8
                    $name = (string) $name;
1038
1039 8
                    if (\strpos($name, '%:') !== 0) {
1040 8
                        $nameTmp = '%:' . $name;
1041
                    } else {
1042
                        $nameTmp = $name;
1043
                    }
1044
1045 8
                    if ($offset === null) {
1046 8
                        $offset = \strpos($str, $nameTmp);
1047
                    } else {
1048 6
                        $offset = \strpos($str, $nameTmp, (int) $offset + \strlen((string) $replacement));
1049
                    }
1050 8
                    if ($offset === false) {
1051 4
                        continue;
1052
                    }
1053
1054 8
                    unset($arg[$name]);
1055
1056 8
                    $str = \substr_replace($str, $param, (int) $offset, \strlen($nameTmp));
1057
                }
1058
1059 8
                unset($args[$key]);
1060
            }
1061
        }
1062
1063 10
        $str = \str_replace('%:', '%%:', $str);
1064
1065 10
        return static::create(
1066 10
            \sprintf($str, ...$args),
1067 10
            $this->encoding
1068
        );
1069
    }
1070
1071
    /**
1072
     * Returns the encoding used by the Stringy object.
1073
     *
1074
     * @psalm-mutation-free
1075
     *
1076
     * @return string
1077
     *                <p>The current value of the $encoding property.</p>
1078
     */
1079 7
    public function getEncoding(): string
1080
    {
1081 7
        return $this->encoding;
1082
    }
1083
1084
    /**
1085
     * Returns a new ArrayIterator, thus implementing the IteratorAggregate
1086
     * interface. The ArrayIterator's constructor is passed an array of chars
1087
     * in the multibyte string. This enables the use of foreach with instances
1088
     * of Stringy\Stringy.
1089
     *
1090
     * @psalm-mutation-free
1091
     *
1092
     * @return \ArrayIterator
1093
     *                        <p>An iterator for the characters in the string.</p>
1094
     *
1095
     * @psalm-return \ArrayIterator<array-key,string>
1096
     */
1097 3
    public function getIterator(): \ArrayIterator
1098
    {
1099 3
        return new \ArrayIterator($this->chars());
1100
    }
1101
1102
    /**
1103
     * Wrap the string after an exact number of characters.
1104
     *
1105
     * @param int    $width Number of characters at which to wrap
1106
     * @param string $break Character used to break the string
1107
     *
1108
     * @psalm-mutation-free
1109
     *
1110
     * @return static
1111
     */
1112 2
    public function hardWrap($width, $break = "\n"): self
1113
    {
1114 2
        return $this->lineWrap($width, $break, false);
1115
    }
1116
1117
    /**
1118
     * Returns true if the string contains a lower case char, false otherwise.
1119
     *
1120
     * @psalm-mutation-free
1121
     *
1122
     * @return bool
1123
     *              <p>Whether or not the string contains a lower case character.</p>
1124
     */
1125 36
    public function hasLowerCase(): bool
1126
    {
1127 36
        return $this->utf8::has_lowercase($this->str);
1128
    }
1129
1130
    /**
1131
     * Returns true if the string contains an upper case char, false otherwise.
1132
     *
1133
     * @psalm-mutation-free
1134
     *
1135
     * @return bool
1136
     *              <p>Whether or not the string contains an upper case character.</p>
1137
     */
1138 36
    public function hasUpperCase(): bool
1139
    {
1140 36
        return $this->utf8::has_uppercase($this->str);
1141
    }
1142
1143
    /**
1144
     * Generate a hash value (message digest)
1145
     *
1146
     * @see https://php.net/manual/en/function.hash.php
1147
     *
1148
     * @param string $algorithm
1149
     *                          <p>Name of selected hashing algorithm (i.e. "md5", "sha256", "haval160,4", etc..)</p>
1150
     *
1151
     * @psalm-mutation-free
1152
     *
1153
     * @return static
1154
     */
1155 8
    public function hash($algorithm): self
1156
    {
1157 8
        return static::create(\hash($algorithm, $this->str), $this->encoding);
1158
    }
1159
1160
    /**
1161
     * Decode the string from hex.
1162
     *
1163
     * @psalm-mutation-free
1164
     *
1165
     * @return static
1166
     */
1167 2
    public function hexDecode(): self
1168
    {
1169 2
        $string = \preg_replace_callback(
1170 2
            '/\\\\x([0-9A-Fa-f]+)/',
1171
            function (array $matched) {
1172 2
                return (string) $this->utf8::hex_to_chr($matched[1]);
1173 2
            },
1174 2
            $this->str
1175
        );
1176
1177 2
        return static::create(
1178 2
            $string,
1179 2
            $this->encoding
1180
        );
1181
    }
1182
1183
    /**
1184
     * Encode string to hex.
1185
     *
1186
     * @psalm-mutation-free
1187
     *
1188
     * @return static
1189
     */
1190 2
    public function hexEncode(): self
1191
    {
1192 2
        $string = \array_reduce(
1193 2
            $this->chars(),
1194
            function (string $str, string $char) {
1195 2
                return $str . $this->utf8::chr_to_hex($char);
1196 2
            },
1197 2
            ''
1198
        );
1199
1200 2
        return static::create(
1201 2
            $string,
1202 2
            $this->encoding
1203
        );
1204
    }
1205
1206
    /**
1207
     * Convert all HTML entities to their applicable characters.
1208
     *
1209
     * @param int $flags [optional] <p>
1210
     *                   A bitmask of one or more of the following flags, which specify how to handle quotes and
1211
     *                   which document type to use. The default is ENT_COMPAT.
1212
     *                   <table>
1213
     *                   Available <i>flags</i> constants
1214
     *                   <tr valign="top">
1215
     *                   <td>Constant Name</td>
1216
     *                   <td>Description</td>
1217
     *                   </tr>
1218
     *                   <tr valign="top">
1219
     *                   <td><b>ENT_COMPAT</b></td>
1220
     *                   <td>Will convert double-quotes and leave single-quotes alone.</td>
1221
     *                   </tr>
1222
     *                   <tr valign="top">
1223
     *                   <td><b>ENT_QUOTES</b></td>
1224
     *                   <td>Will convert both double and single quotes.</td>
1225
     *                   </tr>
1226
     *                   <tr valign="top">
1227
     *                   <td><b>ENT_NOQUOTES</b></td>
1228
     *                   <td>Will leave both double and single quotes unconverted.</td>
1229
     *                   </tr>
1230
     *                   <tr valign="top">
1231
     *                   <td><b>ENT_HTML401</b></td>
1232
     *                   <td>
1233
     *                   Handle code as HTML 4.01.
1234
     *                   </td>
1235
     *                   </tr>
1236
     *                   <tr valign="top">
1237
     *                   <td><b>ENT_XML1</b></td>
1238
     *                   <td>
1239
     *                   Handle code as XML 1.
1240
     *                   </td>
1241
     *                   </tr>
1242
     *                   <tr valign="top">
1243
     *                   <td><b>ENT_XHTML</b></td>
1244
     *                   <td>
1245
     *                   Handle code as XHTML.
1246
     *                   </td>
1247
     *                   </tr>
1248
     *                   <tr valign="top">
1249
     *                   <td><b>ENT_HTML5</b></td>
1250
     *                   <td>
1251
     *                   Handle code as HTML 5.
1252
     *                   </td>
1253
     *                   </tr>
1254
     *                   </table>
1255
     *                   </p>
1256
     *
1257
     * @psalm-mutation-free
1258
     *
1259
     * @return static
1260
     *                <p>Object with the resulting $str after being html decoded.</p>
1261
     */
1262 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...
1263
    {
1264 15
        return static::create(
1265 15
            $this->utf8::html_entity_decode(
1266 15
                $this->str,
1267 15
                $flags,
1268 15
                $this->encoding
1269
            ),
1270 15
            $this->encoding
1271
        );
1272
    }
1273
1274
    /**
1275
     * Convert all applicable characters to HTML entities.
1276
     *
1277
     * @param int $flags [optional] <p>
1278
     *                   A bitmask of one or more of the following flags, which specify how to handle quotes and
1279
     *                   which document type to use. The default is ENT_COMPAT.
1280
     *                   <table>
1281
     *                   Available <i>flags</i> constants
1282
     *                   <tr valign="top">
1283
     *                   <td>Constant Name</td>
1284
     *                   <td>Description</td>
1285
     *                   </tr>
1286
     *                   <tr valign="top">
1287
     *                   <td><b>ENT_COMPAT</b></td>
1288
     *                   <td>Will convert double-quotes and leave single-quotes alone.</td>
1289
     *                   </tr>
1290
     *                   <tr valign="top">
1291
     *                   <td><b>ENT_QUOTES</b></td>
1292
     *                   <td>Will convert both double and single quotes.</td>
1293
     *                   </tr>
1294
     *                   <tr valign="top">
1295
     *                   <td><b>ENT_NOQUOTES</b></td>
1296
     *                   <td>Will leave both double and single quotes unconverted.</td>
1297
     *                   </tr>
1298
     *                   <tr valign="top">
1299
     *                   <td><b>ENT_HTML401</b></td>
1300
     *                   <td>
1301
     *                   Handle code as HTML 4.01.
1302
     *                   </td>
1303
     *                   </tr>
1304
     *                   <tr valign="top">
1305
     *                   <td><b>ENT_XML1</b></td>
1306
     *                   <td>
1307
     *                   Handle code as XML 1.
1308
     *                   </td>
1309
     *                   </tr>
1310
     *                   <tr valign="top">
1311
     *                   <td><b>ENT_XHTML</b></td>
1312
     *                   <td>
1313
     *                   Handle code as XHTML.
1314
     *                   </td>
1315
     *                   </tr>
1316
     *                   <tr valign="top">
1317
     *                   <td><b>ENT_HTML5</b></td>
1318
     *                   <td>
1319
     *                   Handle code as HTML 5.
1320
     *                   </td>
1321
     *                   </tr>
1322
     *                   </table>
1323
     *                   </p>
1324
     *
1325
     * @psalm-mutation-free
1326
     *
1327
     * @return static
1328
     *                <p>Object with the resulting $str after being html encoded.</p>
1329
     */
1330 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...
1331
    {
1332 15
        return static::create(
1333 15
            $this->utf8::htmlentities(
1334 15
                $this->str,
1335 15
                $flags,
1336 15
                $this->encoding
1337
            ),
1338 15
            $this->encoding
1339
        );
1340
    }
1341
1342
    /**
1343
     * Capitalizes the first word of the string, replaces underscores with
1344
     * spaces, and strips '_id'.
1345
     *
1346
     * @psalm-mutation-free
1347
     *
1348
     * @return static
1349
     *                <p>Object with a humanized $str.</p>
1350
     */
1351 9
    public function humanize(): self
1352
    {
1353 9
        return static::create(
1354 9
            $this->utf8::str_humanize($this->str),
1355 9
            $this->encoding
1356
        );
1357
    }
1358
1359
    /**
1360
     * Determine if the current string exists in another string. By
1361
     * default, the comparison is case-sensitive, but can be made insensitive
1362
     * by setting $caseSensitive to false.
1363
     *
1364
     * @param string $str           <p>The string to compare against.</p>
1365
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
1366
     *
1367
     * @psalm-mutation-free
1368
     *
1369
     * @return bool
1370
     */
1371 3
    public function in(string $str, bool $caseSensitive = true): bool
1372
    {
1373 3
        if ($caseSensitive) {
1374 2
            return \strpos($str, $this->str) !== false;
1375
        }
1376
1377 1
        return \stripos($str, $this->str) !== false;
1378
    }
1379
1380
    /**
1381
     * Returns the index of the first occurrence of $needle in the string,
1382
     * and false if not found. Accepts an optional offset from which to begin
1383
     * the search.
1384
     *
1385
     * @param string $needle <p>Substring to look for.</p>
1386
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1387
     *
1388
     * @psalm-mutation-free
1389
     *
1390
     * @return false|int
1391
     *                   <p>The occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1392
     */
1393 31
    public function indexOf(string $needle, int $offset = 0)
1394
    {
1395 31
        return $this->utf8::strpos(
1396 31
            $this->str,
1397 31
            $needle,
1398 31
            $offset,
1399 31
            $this->encoding
1400
        );
1401
    }
1402
1403
    /**
1404
     * Returns the index of the first occurrence of $needle in the string,
1405
     * and false if not found. Accepts an optional offset from which to begin
1406
     * the search.
1407
     *
1408
     * @param string $needle <p>Substring to look for.</p>
1409
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1410
     *
1411
     * @psalm-mutation-free
1412
     *
1413
     * @return false|int
1414
     *                   <p>The occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1415
     */
1416 20
    public function indexOfIgnoreCase(string $needle, int $offset = 0)
1417
    {
1418 20
        return $this->utf8::stripos(
1419 20
            $this->str,
1420 20
            $needle,
1421 20
            $offset,
1422 20
            $this->encoding
1423
        );
1424
    }
1425
1426
    /**
1427
     * Returns the index of the last occurrence of $needle in the string,
1428
     * and false if not found. Accepts an optional offset from which to begin
1429
     * the search. Offsets may be negative to count from the last character
1430
     * in the string.
1431
     *
1432
     * @param string $needle <p>Substring to look for.</p>
1433
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1434
     *
1435
     * @psalm-mutation-free
1436
     *
1437
     * @return false|int
1438
     *                   <p>The last occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1439
     */
1440 31
    public function indexOfLast(string $needle, int $offset = 0)
1441
    {
1442 31
        return $this->utf8::strrpos(
1443 31
            $this->str,
1444 31
            $needle,
1445 31
            $offset,
1446 31
            $this->encoding
1447
        );
1448
    }
1449
1450
    /**
1451
     * Returns the index of the last occurrence of $needle in the string,
1452
     * and false if not found. Accepts an optional offset from which to begin
1453
     * the search. Offsets may be negative to count from the last character
1454
     * in the string.
1455
     *
1456
     * @param string $needle <p>Substring to look for.</p>
1457
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1458
     *
1459
     * @psalm-mutation-free
1460
     *
1461
     * @return false|int
1462
     *                   <p>The last occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1463
     */
1464 20
    public function indexOfLastIgnoreCase(string $needle, int $offset = 0)
1465
    {
1466 20
        return $this->utf8::strripos(
1467 20
            $this->str,
1468 20
            $needle,
1469 20
            $offset,
1470 20
            $this->encoding
1471
        );
1472
    }
1473
1474
    /**
1475
     * Inserts $substring into the string at the $index provided.
1476
     *
1477
     * @param string $substring <p>String to be inserted.</p>
1478
     * @param int    $index     <p>The index at which to insert the substring.</p>
1479
     *
1480
     * @psalm-mutation-free
1481
     *
1482
     * @return static
1483
     *                <p>Object with the resulting $str after the insertion.</p>
1484
     */
1485 24
    public function insert(string $substring, int $index): self
1486
    {
1487 24
        return static::create(
1488 24
            $this->utf8::str_insert(
1489 24
                $this->str,
1490 24
                $substring,
1491 24
                $index,
1492 24
                $this->encoding
1493
            ),
1494 24
            $this->encoding
1495
        );
1496
    }
1497
1498
    /**
1499
     * Returns true if the string contains the $pattern, otherwise false.
1500
     *
1501
     * WARNING: Asterisks ("*") are translated into (".*") zero-or-more regular
1502
     * expression wildcards.
1503
     *
1504
     * @credit Originally from Laravel, thanks Taylor.
1505
     *
1506
     * @param string $pattern <p>The string or pattern to match against.</p>
1507
     *
1508
     * @psalm-mutation-free
1509
     *
1510
     * @return bool
1511
     *              <p>Whether or not we match the provided pattern.</p>
1512
     */
1513 26
    public function is(string $pattern): bool
1514
    {
1515 26
        if ($this->toString() === $pattern) {
1516 2
            return true;
1517
        }
1518
1519 24
        $quotedPattern = \preg_quote($pattern, '/');
1520 24
        $replaceWildCards = \str_replace('\*', '.*', $quotedPattern);
1521
1522 24
        return $this->matchesPattern('^' . $replaceWildCards . '\z');
1523
    }
1524
1525
    /**
1526
     * Returns true if the string contains only alphabetic chars, false otherwise.
1527
     *
1528
     * @psalm-mutation-free
1529
     *
1530
     * @return bool
1531
     *              <p>Whether or not $str contains only alphabetic chars.</p>
1532
     */
1533 30
    public function isAlpha(): bool
1534
    {
1535 30
        return $this->utf8::is_alpha($this->str);
1536
    }
1537
1538
    /**
1539
     * Returns true if the string contains only alphabetic and numeric chars, false otherwise.
1540
     *
1541
     * @psalm-mutation-free
1542
     *
1543
     * @return bool
1544
     *              <p>Whether or not $str contains only alphanumeric chars.</p>
1545
     */
1546 39
    public function isAlphanumeric(): bool
1547
    {
1548 39
        return $this->utf8::is_alphanumeric($this->str);
1549
    }
1550
1551
    /**
1552
     * Returns true if the string is base64 encoded, false otherwise.
1553
     *
1554
     * @param bool $emptyStringIsValid
1555
     *
1556
     * @psalm-mutation-free
1557
     *
1558
     * @return bool
1559
     *              <p>Whether or not $str is base64 encoded.</p>
1560
     */
1561 21
    public function isBase64($emptyStringIsValid = true): bool
1562
    {
1563 21
        return $this->utf8::is_base64($this->str, $emptyStringIsValid);
1564
    }
1565
1566
    /**
1567
     * Returns true if the string contains only whitespace chars, false otherwise.
1568
     *
1569
     * @psalm-mutation-free
1570
     *
1571
     * @return bool
1572
     *              <p>Whether or not $str contains only whitespace characters.</p>
1573
     */
1574 45
    public function isBlank(): bool
1575
    {
1576 45
        return $this->utf8::is_blank($this->str);
1577
    }
1578
1579
    /**
1580
     * Returns true if the string contains a valid E-Mail address, false otherwise.
1581
     *
1582
     * @param bool $useExampleDomainCheck   [optional] <p>Default: false</p>
1583
     * @param bool $useTypoInDomainCheck    [optional] <p>Default: false</p>
1584
     * @param bool $useTemporaryDomainCheck [optional] <p>Default: false</p>
1585
     * @param bool $useDnsCheck             [optional] <p>Default: false</p>
1586
     *
1587
     * @psalm-mutation-free
1588
     *
1589
     * @return bool
1590
     *              <p>Whether or not $str contains a valid E-Mail address.</p>
1591
     */
1592 2
    public function isEmail(
1593
        bool $useExampleDomainCheck = false,
1594
        bool $useTypoInDomainCheck = false,
1595
        bool $useTemporaryDomainCheck = false,
1596
        bool $useDnsCheck = false
1597
    ): bool {
1598
        /**
1599
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the email-check class
1600
         */
1601 2
        return EmailCheck::isValid($this->str, $useExampleDomainCheck, $useTypoInDomainCheck, $useTemporaryDomainCheck, $useDnsCheck);
1602
    }
1603
1604
    /**
1605
     * Determine whether the string is considered to be empty.
1606
     *
1607
     * A variable is considered empty if it does not exist or if its value equals FALSE.
1608
     *
1609
     * @psalm-mutation-free
1610
     *
1611
     * @return bool
1612
     *              <p>Whether or not $str is empty().</p>
1613
     */
1614 10
    public function isEmpty(): bool
1615
    {
1616 10
        return $this->utf8::is_empty($this->str);
1617
    }
1618
1619
    /**
1620
     * Determine whether the string is equals to $str.
1621
     * Alias for isEqualsCaseSensitive()
1622
     *
1623
     * @param string|Stringy ...$str
1624
     *
1625
     * @psalm-mutation-free
1626
     *
1627
     * @return bool
1628
     */
1629 13
    public function isEquals(...$str): bool
1630
    {
1631 13
        return $this->isEqualsCaseSensitive(...$str);
1632
    }
1633
1634
    /**
1635
     * Determine whether the string is equals to $str.
1636
     *
1637
     * @param float|int|string|Stringy ...$str <p>The string to compare.</p>
1638
     *
1639
     * @psalm-mutation-free
1640
     *
1641
     * @return bool
1642
     *              <p>Whether or not $str is equals.</p>
1643
     */
1644 3
    public function isEqualsCaseInsensitive(...$str): bool
1645
    {
1646 3
        $strUpper = $this->toUpperCase()->str;
1647
1648 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...
1649
            /**
1650
             * @psalm-suppress RedundantConditionGivenDocblockType - wait for union-types :)
1651
             */
1652 3
            if ($strTmp instanceof self) {
1653
                if ($strUpper !== $strTmp->toUpperCase()) {
1654
                    return false;
1655
                }
1656 3
            } elseif (\is_scalar($strTmp)) {
1657 3
                if ($strUpper !== $this->utf8::strtoupper((string) $strTmp, $this->encoding)) {
1658 3
                    return false;
1659
                }
1660
            } else {
1661
                throw new \InvalidArgumentException('expected: int|float|string|Stringy -> given: ' . \print_r($strTmp, true) . ' [' . \gettype($strTmp) . ']');
1662
            }
1663
        }
1664
1665 3
        return true;
1666
    }
1667
1668
    /**
1669
     * Determine whether the string is equals to $str.
1670
     *
1671
     * @param float|int|string|Stringy ...$str <p>The string to compare.</p>
1672
     *
1673
     * @psalm-mutation-free
1674
     *
1675
     * @return bool
1676
     *              <p>Whether or not $str is equals.</p>
1677
     */
1678 14
    public function isEqualsCaseSensitive(...$str): bool
1679
    {
1680 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...
1681
            /**
1682
             * @psalm-suppress RedundantConditionGivenDocblockType - wait for union-types :)
1683
             */
1684 14
            if ($strTmp instanceof self) {
1685 2
                if ($this->str !== $strTmp->str) {
1686 2
                    return false;
1687
                }
1688 12
            } elseif (\is_scalar($strTmp)) {
1689 12
                if ($this->str !== (string) $strTmp) {
1690 12
                    return false;
1691
                }
1692
            } else {
1693
                throw new \InvalidArgumentException('expected: int|float|string|Stringy -> given: ' . \print_r($strTmp, true) . ' [' . \gettype($strTmp) . ']');
1694
            }
1695
        }
1696
1697 3
        return true;
1698
    }
1699
1700
    /**
1701
     * Returns true if the string contains only hexadecimal chars, false otherwise.
1702
     *
1703
     * @psalm-mutation-free
1704
     *
1705
     * @return bool
1706
     *              <p>Whether or not $str contains only hexadecimal chars.</p>
1707
     */
1708 39
    public function isHexadecimal(): bool
1709
    {
1710 39
        return $this->utf8::is_hexadecimal($this->str);
1711
    }
1712
1713
    /**
1714
     * Returns true if the string contains HTML-Tags, false otherwise.
1715
     *
1716
     * @psalm-mutation-free
1717
     *
1718
     * @return bool
1719
     *              <p>Whether or not $str contains HTML-Tags.</p>
1720
     */
1721 2
    public function isHtml(): bool
1722
    {
1723 2
        return $this->utf8::is_html($this->str);
1724
    }
1725
1726
    /**
1727
     * Returns true if the string is JSON, false otherwise. Unlike json_decode
1728
     * in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers,
1729
     * in that an empty string is not considered valid JSON.
1730
     *
1731
     * @param bool $onlyArrayOrObjectResultsAreValid
1732
     *
1733
     * @return bool
1734
     *              <p>Whether or not $str is JSON.</p>
1735
     */
1736 60
    public function isJson($onlyArrayOrObjectResultsAreValid = false): bool
1737
    {
1738 60
        return $this->utf8::is_json(
1739 60
            $this->str,
1740 60
            $onlyArrayOrObjectResultsAreValid
1741
        );
1742
    }
1743
1744
    /**
1745
     * Returns true if the string contains only lower case chars, false otherwise.
1746
     *
1747
     * @psalm-mutation-free
1748
     *
1749
     * @return bool
1750
     *              <p>Whether or not $str contains only lower case characters.</p>
1751
     */
1752 24
    public function isLowerCase(): bool
1753
    {
1754 24
        return $this->utf8::is_lowercase($this->str);
1755
    }
1756
1757
    /**
1758
     * Determine whether the string is considered to be NOT empty.
1759
     *
1760
     * A variable is considered NOT empty if it does exist or if its value equals TRUE.
1761
     *
1762
     * @psalm-mutation-free
1763
     *
1764
     * @return bool
1765
     *              <p>Whether or not $str is empty().</p>
1766
     */
1767 10
    public function isNotEmpty(): bool
1768
    {
1769 10
        return !$this->utf8::is_empty($this->str);
1770
    }
1771
1772
    /**
1773
     * Returns true if the string is serialized, false otherwise.
1774
     *
1775
     * @psalm-mutation-free
1776
     *
1777
     * @return bool
1778
     *              <p>Whether or not $str is serialized.</p>
1779
     */
1780 21
    public function isSerialized(): bool
1781
    {
1782 21
        return $this->utf8::is_serialized($this->str);
1783
    }
1784
1785
    /**
1786
     * Check if two strings are similar.
1787
     *
1788
     * @param string $str
1789
     * @param float  $minPercentForSimilarity
1790
     *
1791
     * @psalm-mutation-free
1792
     *
1793
     * @return bool
1794
     */
1795 2
    public function isSimilar(string $str, float $minPercentForSimilarity = 80.0): bool
1796
    {
1797 2
        return $this->similarity($str) >= $minPercentForSimilarity;
1798
    }
1799
1800
    /**
1801
     * Returns true if the string contains only lower case chars, false
1802
     * otherwise.
1803
     *
1804
     * @psalm-mutation-free
1805
     *
1806
     * @return bool
1807
     *              <p>Whether or not $str contains only lower case characters.</p>
1808
     */
1809 24
    public function isUpperCase(): bool
1810
    {
1811 24
        return $this->utf8::is_uppercase($this->str);
1812
    }
1813
1814
    /**
1815
     * Returns true if the string contains only whitespace chars, false otherwise.
1816
     *
1817
     * @psalm-mutation-free
1818
     *
1819
     * @return bool
1820
     *              <p>Whether or not $str contains only whitespace characters.</p>
1821
     */
1822 30
    public function isWhitespace(): bool
1823
    {
1824 30
        return $this->isBlank();
1825
    }
1826
1827
    /**
1828
     * Returns value which can be serialized by json_encode().
1829
     *
1830
     * @noinspection ReturnTypeCanBeDeclaredInspection
1831
     *
1832
     * @psalm-mutation-free
1833
     *
1834
     * @return string The current value of the $str property
1835
     */
1836 2
    public function jsonSerialize()
1837
    {
1838 2
        return (string) $this;
1839
    }
1840
1841
    /**
1842
     * Returns the last $n characters of the string.
1843
     *
1844
     * @param int $n <p>Number of characters to retrieve from the end.</p>
1845
     *
1846
     * @psalm-mutation-free
1847
     *
1848
     * @return static
1849
     *                <p>Object with its $str being the last $n chars.</p>
1850
     */
1851 36
    public function last(int $n): self
1852
    {
1853 36
        return static::create(
1854 36
            $this->utf8::str_last_char(
1855 36
                $this->str,
1856 36
                $n,
1857 36
                $this->encoding
1858
            ),
1859 36
            $this->encoding
1860
        );
1861
    }
1862
1863
    /**
1864
     * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle".
1865
     * If no match is found returns new empty Stringy object.
1866
     *
1867
     * @param string $needle       <p>The string to look for.</p>
1868
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1869
     *
1870
     * @psalm-mutation-free
1871
     *
1872
     * @return static
1873
     */
1874 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...
1875
    {
1876 4
        return static::create(
1877 4
            $this->utf8::str_substr_last(
1878 4
                $this->str,
1879 4
                $needle,
1880 4
                $beforeNeedle,
1881 4
                $this->encoding
1882
            ),
1883 4
            $this->encoding
1884
        );
1885
    }
1886
1887
    /**
1888
     * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle".
1889
     * If no match is found returns new empty Stringy object.
1890
     *
1891
     * @param string $needle       <p>The string to look for.</p>
1892
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1893
     *
1894
     * @psalm-mutation-free
1895
     *
1896
     * @return static
1897
     */
1898 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...
1899
    {
1900 2
        return static::create(
1901 2
            $this->utf8::str_isubstr_last(
1902 2
                $this->str,
1903 2
                $needle,
1904 2
                $beforeNeedle,
1905 2
                $this->encoding
1906
            ),
1907 2
            $this->encoding
1908
        );
1909
    }
1910
1911
    /**
1912
     * Returns the length of the string.
1913
     *
1914
     * @psalm-mutation-free
1915
     *
1916
     * @return int
1917
     *             <p>The number of characters in $str given the encoding.</p>
1918
     */
1919 17
    public function length(): int
1920
    {
1921 17
        return (int) $this->utf8::strlen($this->str, $this->encoding);
1922
    }
1923
1924
    /**
1925
     * Line-Wrap the string after $limit, but also after the next word.
1926
     *
1927
     * @param int         $limit           [optional] <p>The column width.</p>
1928
     * @param string      $break           [optional] <p>The line is broken using the optional break parameter.</p>
1929
     * @param bool        $add_final_break [optional] <p>
1930
     *                                     If this flag is true, then the method will add a $break at the end
1931
     *                                     of the result string.
1932
     *                                     </p>
1933
     * @param string|null $delimiter       [optional] <p>
1934
     *                                     You can change the default behavior, where we split the string by newline.
1935
     *                                     </p>
1936
     *
1937
     * @psalm-mutation-free
1938
     *
1939
     * @return static
1940
     */
1941 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...
1942
        int $limit,
1943
        string $break = "\n",
1944
        bool $add_final_break = true,
1945
        string $delimiter = null
1946
    ): self {
1947 3
        return static::create(
1948 3
            $this->utf8::wordwrap_per_line(
1949 3
                $this->str,
1950 3
                $limit,
1951 3
                $break,
1952 3
                true,
1953 3
                $add_final_break,
1954 3
                $delimiter
1955
            ),
1956 3
            $this->encoding
1957
        );
1958
    }
1959
1960
    /**
1961
     * Line-Wrap the string after $limit, but also after the next word.
1962
     *
1963
     * @param int         $limit           [optional] <p>The column width.</p>
1964
     * @param string      $break           [optional] <p>The line is broken using the optional break parameter.</p>
1965
     * @param bool        $add_final_break [optional] <p>
1966
     *                                     If this flag is true, then the method will add a $break at the end
1967
     *                                     of the result string.
1968
     *                                     </p>
1969
     * @param string|null $delimiter       [optional] <p>
1970
     *                                     You can change the default behavior, where we split the string by newline.
1971
     *                                     </p>
1972
     *
1973
     * @psalm-mutation-free
1974
     *
1975
     * @return static
1976
     */
1977 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...
1978
        int $limit,
1979
        string $break = "\n",
1980
        bool $add_final_break = true,
1981
        string $delimiter = null
1982
    ): self {
1983 4
        return static::create(
1984 4
            $this->utf8::wordwrap_per_line(
1985 4
                $this->str,
1986 4
                $limit,
1987 4
                $break,
1988 4
                false,
1989 4
                $add_final_break,
1990 4
                $delimiter
1991
            ),
1992 4
            $this->encoding
1993
        );
1994
    }
1995
1996
    /**
1997
     * Splits on newlines and carriage returns, returning an array of Stringy
1998
     * objects corresponding to the lines in the string.
1999
     *
2000
     * @psalm-mutation-free
2001
     *
2002
     * @return CollectionStringy|static[]
2003
     *                                    <p>An collection of Stringy objects.</p>
2004
     *
2005
     * @psalm-return CollectionStringy<int,static>
2006
     */
2007 51
    public function lines(): CollectionStringy
2008
    {
2009 51
        $array = $this->utf8::str_to_lines($this->str);
2010
        /** @noinspection AlterInForeachInspection */
2011 51
        foreach ($array as $i => &$value) {
2012 51
            $value = static::create($value, $this->encoding);
2013
        }
2014
2015
        /** @noinspection PhpSillyAssignmentInspection */
2016
        /** @var static[] $array */
2017 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...
2018
2019
        /**
2020
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
2021
         */
2022 51
        return CollectionStringy::create($array);
2023
    }
2024
2025
    /**
2026
     * Returns the longest common prefix between the string and $otherStr.
2027
     *
2028
     * @param string $otherStr <p>Second string for comparison.</p>
2029
     *
2030
     * @psalm-mutation-free
2031
     *
2032
     * @return static
2033
     *                <p>Object with its $str being the longest common prefix.</p>
2034
     */
2035 30
    public function longestCommonPrefix(string $otherStr): self
2036
    {
2037 30
        return static::create(
2038 30
            $this->utf8::str_longest_common_prefix(
2039 30
                $this->str,
2040 30
                $otherStr,
2041 30
                $this->encoding
2042
            ),
2043 30
            $this->encoding
2044
        );
2045
    }
2046
2047
    /**
2048
     * Returns the longest common substring between the string and $otherStr.
2049
     * In the case of ties, it returns that which occurs first.
2050
     *
2051
     * @param string $otherStr <p>Second string for comparison.</p>
2052
     *
2053
     * @psalm-mutation-free
2054
     *
2055
     * @return static
2056
     *                <p>Object with its $str being the longest common substring.</p>
2057
     */
2058 30
    public function longestCommonSubstring(string $otherStr): self
2059
    {
2060 30
        return static::create(
2061 30
            $this->utf8::str_longest_common_substring(
2062 30
                $this->str,
2063 30
                $otherStr,
2064 30
                $this->encoding
2065
            ),
2066 30
            $this->encoding
2067
        );
2068
    }
2069
2070
    /**
2071
     * Returns the longest common suffix between the string and $otherStr.
2072
     *
2073
     * @param string $otherStr <p>Second string for comparison.</p>
2074
     *
2075
     * @psalm-mutation-free
2076
     *
2077
     * @return static
2078
     *                <p>Object with its $str being the longest common suffix.</p>
2079
     */
2080 30
    public function longestCommonSuffix(string $otherStr): self
2081
    {
2082 30
        return static::create(
2083 30
            $this->utf8::str_longest_common_suffix(
2084 30
                $this->str,
2085 30
                $otherStr,
2086 30
                $this->encoding
2087
            ),
2088 30
            $this->encoding
2089
        );
2090
    }
2091
2092
    /**
2093
     * Converts the first character of the string to lower case.
2094
     *
2095
     * @psalm-mutation-free
2096
     *
2097
     * @return static
2098
     *                <p>Object with the first character of $str being lower case.</p>
2099
     */
2100 15
    public function lowerCaseFirst(): self
2101
    {
2102 15
        return static::create(
2103 15
            $this->utf8::lcfirst($this->str, $this->encoding),
2104 15
            $this->encoding
2105
        );
2106
    }
2107
2108
    /**
2109
     * Determine if the string matches another string regardless of case.
2110
     * Alias for isEqualsCaseInsensitive()
2111
     *
2112
     * @psalm-mutation-free
2113
     *
2114
     * @param string|Stringy ...$str
2115
     *                               <p>The string to compare against.</p>
2116
     *
2117
     * @psalm-mutation-free
2118
     *
2119
     * @return bool
2120
     */
2121 3
    public function matchCaseInsensitive(...$str): bool
2122
    {
2123 3
        return $this->isEqualsCaseInsensitive(...$str);
2124
    }
2125
2126
    /**
2127
     * Determine if the string matches another string.
2128
     * Alias for isEqualsCaseSensitive()
2129
     *
2130
     * @psalm-mutation-free
2131
     *
2132
     * @param string|Stringy ...$str
2133
     *                               <p>The string to compare against.</p>
2134
     *
2135
     * @psalm-mutation-free
2136
     *
2137
     * @return bool
2138
     */
2139 7
    public function matchCaseSensitive(...$str): bool
2140
    {
2141 7
        return $this->isEqualsCaseSensitive(...$str);
2142
    }
2143
2144
    /**
2145
     * Create a md5 hash from the current string.
2146
     *
2147
     * @psalm-mutation-free
2148
     *
2149
     * @return static
2150
     */
2151 2
    public function md5(): self
2152
    {
2153 2
        return static::create($this->hash('md5'), $this->encoding);
2154
    }
2155
2156
    /**
2157
     * Get every nth character of the string.
2158
     *
2159
     * @param int $step   The number of characters to step
2160
     * @param int $offset The string offset to start at
2161
     *
2162
     * @psalm-mutation-free
2163
     *
2164
     * @return static
2165
     */
2166 4
    public function nth(int $step, int $offset = 0): self
2167
    {
2168 4
        $length = $step - 1;
2169 4
        $substring = $this->substr($offset)->toString();
2170
2171 4
        if ($substring === '') {
2172
            return new static('', $this->encoding);
2173
        }
2174
2175 4
        \preg_match_all(
2176 4
            "/(?:^|(?:.|\p{L}|\w){" . $length . "})(.|\p{L}|\w)/u",
2177 4
            $substring,
2178 4
            $matches
2179
        );
2180
2181 4
        return new static(\implode('', $matches[1] ?? []), $this->encoding);
2182
    }
2183
2184
    /**
2185
     * Returns whether or not a character exists at an index. Offsets may be
2186
     * negative to count from the last character in the string. Implements
2187
     * part of the ArrayAccess interface.
2188
     *
2189
     * @param int $offset <p>The index to check.</p>
2190
     *
2191
     * @psalm-mutation-free
2192
     *
2193
     * @return bool
2194
     *              <p>Whether or not the index exists.</p>
2195
     */
2196 18
    public function offsetExists($offset): bool
2197
    {
2198 18
        return $this->utf8::str_offset_exists(
2199 18
            $this->str,
2200 18
            $offset,
2201 18
            $this->encoding
2202
        );
2203
    }
2204
2205
    /**
2206
     * Returns the character at the given index. Offsets may be negative to
2207
     * count from the last character in the string. Implements part of the
2208
     * ArrayAccess interface, and throws an OutOfBoundsException if the index
2209
     * does not exist.
2210
     *
2211
     * @param int $offset <p>The <strong>index</strong> from which to retrieve the char.</p>
2212
     *
2213
     * @throws \OutOfBoundsException
2214
     *                               <p>If the positive or negative offset does not exist.</p>
2215
     *
2216
     * @return string
2217
     *                <p>The character at the specified index.</p>
2218
     *
2219
     * @psalm-mutation-free
2220
     */
2221 6
    public function offsetGet($offset): string
2222
    {
2223 6
        return $this->utf8::str_offset_get($this->str, $offset, $this->encoding);
2224
    }
2225
2226
    /**
2227
     * Implements part of the ArrayAccess interface, but throws an exception
2228
     * when called. This maintains the immutability of Stringy objects.
2229
     *
2230
     * @param int   $offset <p>The index of the character.</p>
2231
     * @param mixed $value  <p>Value to set.</p>
2232
     *
2233
     * @throws \Exception
2234
     *                    <p>When called.</p>
2235
     *
2236
     * @return void
2237
     */
2238 3
    public function offsetSet($offset, $value)
2239
    {
2240
        // Stringy is immutable, cannot directly set char
2241
        /** @noinspection ThrowRawExceptionInspection */
2242 3
        throw new \Exception('Stringy object is immutable, cannot modify char');
2243
    }
2244
2245
    /**
2246
     * Implements part of the ArrayAccess interface, but throws an exception
2247
     * when called. This maintains the immutability of Stringy objects.
2248
     *
2249
     * @param int $offset <p>The index of the character.</p>
2250
     *
2251
     * @throws \Exception
2252
     *                    <p>When called.</p>
2253
     *
2254
     * @return void
2255
     */
2256 3
    public function offsetUnset($offset)
2257
    {
2258
        // Don't allow directly modifying the string
2259
        /** @noinspection ThrowRawExceptionInspection */
2260 3
        throw new \Exception('Stringy object is immutable, cannot unset char');
2261
    }
2262
2263
    /**
2264
     * Pads the string to a given length with $padStr. If length is less than
2265
     * or equal to the length of the string, no padding takes places. The
2266
     * default string used for padding is a space, and the default type (one of
2267
     * 'left', 'right', 'both') is 'right'. Throws an InvalidArgumentException
2268
     * if $padType isn't one of those 3 values.
2269
     *
2270
     * @param int    $length  <p>Desired string length after padding.</p>
2271
     * @param string $padStr  [optional] <p>String used to pad, defaults to space. Default: ' '</p>
2272
     * @param string $padType [optional] <p>One of 'left', 'right', 'both'. Default: 'right'</p>
2273
     *
2274
     * @throws \InvalidArgumentException
2275
     *                                   <p>If $padType isn't one of 'right', 'left' or 'both'.</p>
2276
     *
2277
     * @return static
2278
     *                <p>Object with a padded $str.</p>
2279
     *
2280
     * @psalm-mutation-free
2281
     */
2282 39
    public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self
2283
    {
2284 39
        return static::create(
2285 39
            $this->utf8::str_pad(
2286 39
                $this->str,
2287 39
                $length,
2288 39
                $padStr,
2289 39
                $padType,
2290 39
                $this->encoding
2291
            )
2292
        );
2293
    }
2294
2295
    /**
2296
     * Returns a new string of a given length such that both sides of the
2297
     * string are padded. Alias for pad() with a $padType of 'both'.
2298
     *
2299
     * @param int    $length <p>Desired string length after padding.</p>
2300
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
2301
     *
2302
     * @psalm-mutation-free
2303
     *
2304
     * @return static
2305
     *                <p>String with padding applied.</p>
2306
     */
2307 33
    public function padBoth(int $length, string $padStr = ' '): self
2308
    {
2309 33
        return static::create(
2310 33
            $this->utf8::str_pad_both(
2311 33
                $this->str,
2312 33
                $length,
2313 33
                $padStr,
2314 33
                $this->encoding
2315
            )
2316
        );
2317
    }
2318
2319
    /**
2320
     * Returns a new string of a given length such that the beginning of the
2321
     * string is padded. Alias for pad() with a $padType of 'left'.
2322
     *
2323
     * @param int    $length <p>Desired string length after padding.</p>
2324
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
2325
     *
2326
     * @psalm-mutation-free
2327
     *
2328
     * @return static
2329
     *                <p>String with left padding.</p>
2330
     */
2331 21
    public function padLeft(int $length, string $padStr = ' '): self
2332
    {
2333 21
        return static::create(
2334 21
            $this->utf8::str_pad_left(
2335 21
                $this->str,
2336 21
                $length,
2337 21
                $padStr,
2338 21
                $this->encoding
2339
            )
2340
        );
2341
    }
2342
2343
    /**
2344
     * Returns a new string of a given length such that the end of the string
2345
     * is padded. Alias for pad() with a $padType of 'right'.
2346
     *
2347
     * @param int    $length <p>Desired string length after padding.</p>
2348
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
2349
     *
2350
     * @psalm-mutation-free
2351
     *
2352
     * @return static
2353
     *                <p>String with right padding.</p>
2354
     */
2355 21
    public function padRight(int $length, string $padStr = ' '): self
2356
    {
2357 21
        return static::create(
2358 21
            $this->utf8::str_pad_right(
2359 21
                $this->str,
2360 21
                $length,
2361 21
                $padStr,
2362 21
                $this->encoding
2363
            )
2364
        );
2365
    }
2366
2367
    /**
2368
     * Returns a new string starting with $prefix.
2369
     *
2370
     * @param string ...$prefix <p>The string to append.</p>
2371
     *
2372
     * @psalm-mutation-free
2373
     *
2374
     * @return static
2375
     *                <p>Object with appended $prefix.</p>
2376
     *
2377
     * @noinspection PhpDocSignatureInspection
2378
     */
2379 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...
2380
    {
2381 7
        if (\count($prefix) <= 1) {
2382
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
2383 6
            $prefix = $prefix[0];
2384
        } else {
2385
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
2386 1
            $prefix = \implode('', $prefix);
2387
        }
2388
2389 7
        return static::create($prefix . $this->str, $this->encoding);
2390
    }
2391
2392
    /**
2393
     * Replaces all occurrences of $pattern in $str by $replacement.
2394
     *
2395
     * @param string $pattern     <p>The regular expression pattern.</p>
2396
     * @param string $replacement <p>The string to replace with.</p>
2397
     * @param string $options     [optional] <p>Matching conditions to be used.</p>
2398
     * @param string $delimiter   [optional] <p>Delimiter the the regex. Default: '/'</p>
2399
     *
2400
     * @psalm-mutation-free
2401
     *
2402
     * @return static
2403
     *                <p>Object with the result2ing $str after the replacements.</p>
2404
     */
2405 29
    public function regexReplace(string $pattern, string $replacement, string $options = '', string $delimiter = '/'): self
2406
    {
2407 29
        return static::create(
2408 29
            $this->utf8::regex_replace(
2409 29
                $this->str,
2410 29
                $pattern,
2411 29
                $replacement,
2412 29
                $options,
2413 29
                $delimiter
2414
            ),
2415 29
            $this->encoding
2416
        );
2417
    }
2418
2419
    /**
2420
     * Remove html via "strip_tags()" from the string.
2421
     *
2422
     * @param string $allowableTags [optional] <p>You can use the optional second parameter to specify tags which should
2423
     *                              not be stripped. Default: null
2424
     *                              </p>
2425
     *
2426
     * @psalm-mutation-free
2427
     *
2428
     * @return static
2429
     */
2430 12
    public function removeHtml(string $allowableTags = ''): self
2431
    {
2432 12
        return static::create(
2433 12
            $this->utf8::remove_html($this->str, $allowableTags),
2434 12
            $this->encoding
2435
        );
2436
    }
2437
2438
    /**
2439
     * Remove all breaks [<br> | \r\n | \r | \n | ...] from the string.
2440
     *
2441
     * @param string $replacement [optional] <p>Default is a empty string.</p>
2442
     *
2443
     * @psalm-mutation-free
2444
     *
2445
     * @return static
2446
     */
2447 12
    public function removeHtmlBreak(string $replacement = ''): self
2448
    {
2449 12
        return static::create(
2450 12
            $this->utf8::remove_html_breaks($this->str, $replacement),
2451 12
            $this->encoding
2452
        );
2453
    }
2454
2455
    /**
2456
     * Returns a new string with the prefix $substring removed, if present.
2457
     *
2458
     * @param string $substring <p>The prefix to remove.</p>
2459
     *
2460
     * @psalm-mutation-free
2461
     *
2462
     * @return static
2463
     *                <p>Object having a $str without the prefix $substring.</p>
2464
     */
2465 36
    public function removeLeft(string $substring): self
2466
    {
2467 36
        return static::create(
2468 36
            $this->utf8::remove_left($this->str, $substring, $this->encoding),
2469 36
            $this->encoding
2470
        );
2471
    }
2472
2473
    /**
2474
     * Returns a new string with the suffix $substring removed, if present.
2475
     *
2476
     * @param string $substring <p>The suffix to remove.</p>
2477
     *
2478
     * @psalm-mutation-free
2479
     *
2480
     * @return static
2481
     *                <p>Object having a $str without the suffix $substring.</p>
2482
     */
2483 36
    public function removeRight(string $substring): self
2484
    {
2485 36
        return static::create(
2486 36
            $this->utf8::remove_right($this->str, $substring, $this->encoding),
2487 36
            $this->encoding
2488
        );
2489
    }
2490
2491
    /**
2492
     * Try to remove all XSS-attacks from the string.
2493
     *
2494
     * @psalm-mutation-free
2495
     *
2496
     * @return static
2497
     */
2498 12
    public function removeXss(): self
2499
    {
2500
        /**
2501
         * @var AntiXSS|null
2502
         *
2503
         * @psalm-suppress ImpureStaticVariable
2504
         */
2505 12
        static $antiXss = null;
2506
2507 12
        if ($antiXss === null) {
2508 1
            $antiXss = new AntiXSS();
2509
        }
2510
2511
        /**
2512
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the anti-xss class
2513
         */
2514 12
        $str = $antiXss->xss_clean($this->str);
2515
2516 12
        return static::create($str, $this->encoding);
2517
    }
2518
2519
    /**
2520
     * Returns a repeated string given a multiplier.
2521
     *
2522
     * @param int $multiplier <p>The number of times to repeat the string.</p>
2523
     *
2524
     * @psalm-mutation-free
2525
     *
2526
     * @return static
2527
     *                <p>Object with a repeated str.</p>
2528
     */
2529 21
    public function repeat(int $multiplier): self
2530
    {
2531 21
        return static::create(
2532 21
            \str_repeat($this->str, $multiplier),
2533 21
            $this->encoding
2534
        );
2535
    }
2536
2537
    /**
2538
     * Replaces all occurrences of $search in $str by $replacement.
2539
     *
2540
     * @param string $search        <p>The needle to search for.</p>
2541
     * @param string $replacement   <p>The string to replace with.</p>
2542
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2543
     *
2544
     * @psalm-mutation-free
2545
     *
2546
     * @return static
2547
     *                <p>Object with the resulting $str after the replacements.</p>
2548
     */
2549 76
    public function replace(string $search, string $replacement, bool $caseSensitive = true): self
2550
    {
2551 76
        if ($search === '' && $replacement === '') {
2552 16
            return static::create($this->str, $this->encoding);
2553
        }
2554
2555 60
        if ($this->str === '' && $search === '') {
2556 2
            return static::create($replacement, $this->encoding);
2557
        }
2558
2559 58
        if ($caseSensitive) {
2560 48
            return static::create(
2561 48
                $this->utf8::str_replace($search, $replacement, $this->str),
2562 48
                $this->encoding
2563
            );
2564
        }
2565
2566 10
        return static::create(
2567 10
            $this->utf8::str_ireplace($search, $replacement, $this->str),
2568 10
            $this->encoding
2569
        );
2570
    }
2571
2572
    /**
2573
     * Replaces all occurrences of $search in $str by $replacement.
2574
     *
2575
     * @param string[]        $search        <p>The elements to search for.</p>
2576
     * @param string|string[] $replacement   <p>The string to replace with.</p>
2577
     * @param bool            $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2578
     *
2579
     * @psalm-mutation-free
2580
     *
2581
     * @return static
2582
     *                <p>Object with the resulting $str after the replacements.</p>
2583
     */
2584 61
    public function replaceAll(array $search, $replacement, bool $caseSensitive = true): self
2585
    {
2586 61
        if ($caseSensitive) {
2587 47
            return static::create(
2588 47
                $this->utf8::str_replace($search, $replacement, $this->str),
2589 47
                $this->encoding
2590
            );
2591
        }
2592
2593 14
        return static::create(
2594 14
            $this->utf8::str_ireplace($search, $replacement, $this->str),
2595 14
            $this->encoding
2596
        );
2597
    }
2598
2599
    /**
2600
     * Replaces all occurrences of $search from the beginning of string with $replacement.
2601
     *
2602
     * @param string $search      <p>The string to search for.</p>
2603
     * @param string $replacement <p>The replacement.</p>
2604
     *
2605
     * @psalm-mutation-free
2606
     *
2607
     * @return static
2608
     *                <p>Object with the resulting $str after the replacements.</p>
2609
     */
2610 32
    public function replaceBeginning(string $search, string $replacement): self
2611
    {
2612 32
        return static::create(
2613 32
            $this->utf8::str_replace_beginning($this->str, $search, $replacement),
2614 32
            $this->encoding
2615
        );
2616
    }
2617
2618
    /**
2619
     * Replaces all occurrences of $search from the ending of string with $replacement.
2620
     *
2621
     * @param string $search      <p>The string to search for.</p>
2622
     * @param string $replacement <p>The replacement.</p>
2623
     *
2624
     * @psalm-mutation-free
2625
     *
2626
     * @return static
2627
     *                <p>Object with the resulting $str after the replacements.</p>
2628
     */
2629 32
    public function replaceEnding(string $search, string $replacement): self
2630
    {
2631 32
        return static::create(
2632 32
            $this->utf8::str_replace_ending($this->str, $search, $replacement),
2633 32
            $this->encoding
2634
        );
2635
    }
2636
2637
    /**
2638
     * Replaces first occurrences of $search from the beginning of string with $replacement.
2639
     *
2640
     * @param string $search      <p>The string to search for.</p>
2641
     * @param string $replacement <p>The replacement.</p>
2642
     *
2643
     * @psalm-mutation-free
2644
     *
2645
     * @return static
2646
     *                <p>Object with the resulting $str after the replacements.</p>
2647
     */
2648 32
    public function replaceFirst(string $search, string $replacement): self
2649
    {
2650 32
        return static::create(
2651 32
            $this->utf8::str_replace_first($search, $replacement, $this->str),
2652 32
            $this->encoding
2653
        );
2654
    }
2655
2656
    /**
2657
     * Replaces last occurrences of $search from the ending of string with $replacement.
2658
     *
2659
     * @param string $search      <p>The string to search for.</p>
2660
     * @param string $replacement <p>The replacement.</p>
2661
     *
2662
     * @psalm-mutation-free
2663
     *
2664
     * @return static
2665
     *                <p>Object with the resulting $str after the replacements.</p>
2666
     */
2667 30
    public function replaceLast(string $search, string $replacement): self
2668
    {
2669 30
        return static::create(
2670 30
            $this->utf8::str_replace_last($search, $replacement, $this->str),
2671 30
            $this->encoding
2672
        );
2673
    }
2674
2675
    /**
2676
     * Returns a reversed string. A multibyte version of strrev().
2677
     *
2678
     * @psalm-mutation-free
2679
     *
2680
     * @return static
2681
     *                <p>Object with a reversed $str.</p>
2682
     */
2683 15
    public function reverse(): self
2684
    {
2685 15
        return static::create($this->utf8::strrev($this->str), $this->encoding);
2686
    }
2687
2688
    /**
2689
     * Truncates the string to a given length, while ensuring that it does not
2690
     * split words. If $substring is provided, and truncating occurs, the
2691
     * string is further truncated so that the substring may be appended without
2692
     * exceeding the desired length.
2693
     *
2694
     * @param int    $length                          <p>Desired length of the truncated string.</p>
2695
     * @param string $substring                       [optional] <p>The substring to append if it can fit. Default: ''</p>
2696
     * @param bool   $ignoreDoNotSplitWordsForOneWord
2697
     *
2698
     * @psalm-mutation-free
2699
     *
2700
     * @return static
2701
     *                <p>Object with the resulting $str after truncating.</p>
2702
     */
2703 68
    public function safeTruncate(
2704
        int $length,
2705
        string $substring = '',
2706
        bool $ignoreDoNotSplitWordsForOneWord = true
2707
    ): self {
2708 68
        return static::create(
2709 68
            $this->utf8::str_truncate_safe(
2710 68
                $this->str,
2711 68
                $length,
2712 68
                $substring,
2713 68
                $this->encoding,
2714 68
                $ignoreDoNotSplitWordsForOneWord
2715
            ),
2716 68
            $this->encoding
2717
        );
2718
    }
2719
2720
    /**
2721
     * Create a sha1 hash from the current string.
2722
     *
2723
     * @psalm-mutation-free
2724
     *
2725
     * @return static
2726
     */
2727 2
    public function sha1(): self
2728
    {
2729 2
        return static::create($this->hash('sha1'), $this->encoding);
2730
    }
2731
2732
    /**
2733
     * Create a sha256 hash from the current string.
2734
     *
2735
     * @psalm-mutation-free
2736
     *
2737
     * @return static
2738
     */
2739 2
    public function sha256(): self
2740
    {
2741 2
        return static::create($this->hash('sha256'), $this->encoding);
2742
    }
2743
2744
    /**
2745
     * Create a sha512 hash from the current string.
2746
     *
2747
     * @psalm-mutation-free
2748
     *
2749
     * @return static
2750
     */
2751 2
    public function sha512(): self
2752
    {
2753 2
        return static::create($this->hash('sha512'), $this->encoding);
2754
    }
2755
2756
    /**
2757
     * Shorten the string after $length, but also after the next word.
2758
     *
2759
     * @param int    $length
2760
     * @param string $strAddOn [optional] <p>Default: '…'</p>
2761
     *
2762
     * @psalm-mutation-free
2763
     *
2764
     * @return static
2765
     */
2766 8
    public function shortenAfterWord(int $length, string $strAddOn = '…'): self
2767
    {
2768 8
        return static::create(
2769 8
            $this->utf8::str_limit_after_word($this->str, $length, $strAddOn),
2770 8
            $this->encoding
2771
        );
2772
    }
2773
2774
    /**
2775
     * A multibyte string shuffle function. It returns a string with its
2776
     * characters in random order.
2777
     *
2778
     * @psalm-mutation-free
2779
     *
2780
     * @return static
2781
     *                <p>Object with a shuffled $str.</p>
2782
     */
2783 9
    public function shuffle(): self
2784
    {
2785 9
        return static::create($this->utf8::str_shuffle($this->str), $this->encoding);
2786
    }
2787
2788
    /**
2789
     * Calculate the similarity between two strings.
2790
     *
2791
     * @param string $str
2792
     *
2793
     * @psalm-mutation-free
2794
     *
2795
     * @return float
2796
     */
2797 2
    public function similarity(string $str): float
2798
    {
2799 2
        \similar_text($this->str, $str, $percent);
2800
2801 2
        return $percent;
2802
    }
2803
2804
    /**
2805
     * Returns the substring beginning at $start, and up to, but not including
2806
     * the index specified by $end. If $end is omitted, the function extracts
2807
     * the remaining string. If $end is negative, it is computed from the end
2808
     * of the string.
2809
     *
2810
     * @param int $start <p>Initial index from which to begin extraction.</p>
2811
     * @param int $end   [optional] <p>Index at which to end extraction. Default: null</p>
2812
     *
2813
     * @psalm-mutation-free
2814
     *
2815
     * @return static
2816
     *                <p>Object with its $str being the extracted substring.</p>
2817
     */
2818 50
    public function slice(int $start, int $end = null): self
2819
    {
2820 50
        return static::create(
2821 50
            $this->utf8::str_slice($this->str, $start, $end, $this->encoding),
2822 50
            $this->encoding
2823
        );
2824
    }
2825
2826
    /**
2827
     * Converts the string into an URL slug. This includes replacing non-ASCII
2828
     * characters with their closest ASCII equivalents, removing remaining
2829
     * non-ASCII and non-alphanumeric characters, and replacing whitespace with
2830
     * $separator. The separator defaults to a single dash, and the string
2831
     * is also converted to lowercase. The language of the source string can
2832
     * also be supplied for language-specific transliteration.
2833
     *
2834
     * @param string                $separator             [optional] <p>The string used to replace whitespace.</p>
2835
     * @param string                $language              [optional] <p>Language of the source string.</p>
2836
     * @param array<string, string> $replacements          [optional] <p>A map of replaceable strings.</p>
2837
     * @param bool                  $replace_extra_symbols [optional]  <p>Add some more replacements e.g. "£" with "
2838
     *                                                     pound ".</p>
2839
     * @param bool                  $use_str_to_lower      [optional] <p>Use "string to lower" for the input.</p>
2840
     * @param bool                  $use_transliterate     [optional]  <p>Use ASCII::to_transliterate() for unknown
2841
     *                                                     chars.</p>
2842
     *
2843
     * @psalm-mutation-free
2844
     *
2845
     * @return static
2846
     *                <p>Object whose $str has been converted to an URL slug.</p>
2847
     *
2848
     * @noinspection PhpTooManyParametersInspection
2849
     */
2850 17
    public function slugify(
2851
        string $separator = '-',
2852
        string $language = 'en',
2853
        array $replacements = [],
2854
        bool $replace_extra_symbols = true,
2855
        bool $use_str_to_lower = true,
2856
        bool $use_transliterate = false
2857
    ): self {
2858 17
        return static::create(
2859 17
            $this->ascii::to_slugify(
2860 17
                $this->str,
2861 17
                $separator,
2862 17
                $language,
2863 17
                $replacements,
2864 17
                $replace_extra_symbols,
2865 17
                $use_str_to_lower,
2866 17
                $use_transliterate
2867
            ),
2868 17
            $this->encoding
2869
        );
2870
    }
2871
2872
    /**
2873
     * Convert a string to e.g.: "snake_case"
2874
     *
2875
     * @psalm-mutation-free
2876
     *
2877
     * @return static
2878
     *                <p>Object with $str in snake_case.</p>
2879
     */
2880 40
    public function snakeize(): self
2881
    {
2882 40
        return static::create(
2883 40
            $this->utf8::str_snakeize($this->str, $this->encoding),
2884 40
            $this->encoding
2885
        );
2886
    }
2887
2888
    /**
2889
     * Wrap the string after the first whitespace character after a given number
2890
     * of characters.
2891
     *
2892
     * @param int    $width Number of characters at which to wrap
2893
     * @param string $break Character used to break the string
2894
     *
2895
     * @psalm-mutation-free
2896
     *
2897
     * @return static
2898
     */
2899 2
    public function softWrap(int $width, string $break = "\n"): self
2900
    {
2901 2
        return $this->lineWrapAfterWord($width, $break, false);
2902
    }
2903
2904
    /**
2905
     * Splits the string with the provided regular expression, returning an
2906
     * array of Stringy objects. An optional integer $limit will truncate the
2907
     * results.
2908
     *
2909
     * @param string $pattern <p>The regex with which to split the string.</p>
2910
     * @param int    $limit   [optional] <p>Maximum number of results to return. Default: -1 === no limit</p>
2911
     *
2912
     * @psalm-mutation-free
2913
     *
2914
     * @return CollectionStringy|static[]
2915
     *                                    <p>An collection of Stringy objects.</p>
2916
     *
2917
     * @psalm-return CollectionStringy<int,static>
2918
     */
2919 51
    public function split(string $pattern, int $limit = null): CollectionStringy
2920
    {
2921 51
        if ($limit === null) {
2922 7
            $limit = -1;
2923
        }
2924
2925 51
        $array = $this->utf8::str_split_pattern($this->str, $pattern, $limit);
2926
        /** @noinspection AlterInForeachInspection */
2927 51
        foreach ($array as $i => &$value) {
2928 45
            $value = static::create($value, $this->encoding);
2929
        }
2930
2931
        /** @noinspection PhpSillyAssignmentInspection */
2932
        /** @var static[] $array */
2933 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...
2934
2935
        /**
2936
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
2937
         */
2938 51
        return CollectionStringy::create($array);
2939
    }
2940
2941
    /**
2942
     * Returns true if the string begins with $substring, false otherwise. By
2943
     * default, the comparison is case-sensitive, but can be made insensitive
2944
     * by setting $caseSensitive to false.
2945
     *
2946
     * @param string $substring     <p>The substring to look for.</p>
2947
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2948
     *
2949
     * @psalm-mutation-free
2950
     *
2951
     * @return bool
2952
     *              <p>Whether or not $str starts with $substring.</p>
2953
     */
2954 99
    public function startsWith(string $substring, bool $caseSensitive = true): bool
2955
    {
2956 99
        if ($caseSensitive) {
2957 53
            return $this->utf8::str_starts_with($this->str, $substring);
2958
        }
2959
2960 46
        return $this->utf8::str_istarts_with($this->str, $substring);
2961
    }
2962
2963
    /**
2964
     * Returns true if the string begins with any of $substrings, false otherwise.
2965
     * By default the comparison is case-sensitive, but can be made insensitive by
2966
     * setting $caseSensitive to false.
2967
     *
2968
     * @param string[] $substrings    <p>Substrings to look for.</p>
2969
     * @param bool     $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2970
     *
2971
     * @psalm-mutation-free
2972
     *
2973
     * @return bool
2974
     *              <p>Whether or not $str starts with $substring.</p>
2975
     */
2976 35
    public function startsWithAny(array $substrings, bool $caseSensitive = true): bool
2977
    {
2978 35
        if ($caseSensitive) {
2979 23
            return $this->utf8::str_starts_with_any($this->str, $substrings);
2980
        }
2981
2982 12
        return $this->utf8::str_istarts_with_any($this->str, $substrings);
2983
    }
2984
2985
    /**
2986
     * Remove one or more strings from the string.
2987
     *
2988
     * @param string|string[] $search One or more strings to be removed
2989
     *
2990
     * @psalm-mutation-free
2991
     *
2992
     * @return static
2993
     */
2994 3
    public function strip($search): self
2995
    {
2996 3
        if (\is_array($search)) {
2997 1
            return $this->replaceAll($search, '');
2998
        }
2999
3000 2
        return $this->replace($search, '');
3001
    }
3002
3003
    /**
3004
     * Strip all whitespace characters. This includes tabs and newline characters,
3005
     * as well as multibyte whitespace such as the thin space and ideographic space.
3006
     *
3007
     * @psalm-mutation-free
3008
     *
3009
     * @return static
3010
     */
3011 36
    public function stripWhitespace(): self
3012
    {
3013 36
        return static::create(
3014 36
            $this->utf8::strip_whitespace($this->str),
3015 36
            $this->encoding
3016
        );
3017
    }
3018
3019
    /**
3020
     * Remove css media-queries.
3021
     *
3022
     * @psalm-mutation-free
3023
     *
3024
     * @return static
3025
     */
3026 2
    public function stripeCssMediaQueries(): self
3027
    {
3028 2
        return static::create(
3029 2
            $this->utf8::css_stripe_media_queries($this->str),
3030 2
            $this->encoding
3031
        );
3032
    }
3033
3034
    /**
3035
     * Remove empty html-tag.
3036
     *
3037
     * e.g.: <tag></tag>
3038
     *
3039
     * @psalm-mutation-free
3040
     *
3041
     * @return static
3042
     */
3043 2
    public function stripeEmptyHtmlTags(): self
3044
    {
3045 2
        return static::create(
3046 2
            $this->utf8::html_stripe_empty_tags($this->str),
3047 2
            $this->encoding
3048
        );
3049
    }
3050
3051
    /**
3052
     * Returns the substring beginning at $start with the specified $length.
3053
     * It differs from the $this->utf8::substr() function in that providing a $length of
3054
     * null will return the rest of the string, rather than an empty string.
3055
     *
3056
     * @param int $start  <p>Position of the first character to use.</p>
3057
     * @param int $length [optional] <p>Maximum number of characters used. Default: null</p>
3058
     *
3059
     * @psalm-mutation-free
3060
     *
3061
     * @return static
3062
     *                <p>Object with its $str being the substring.</p>
3063
     */
3064 31
    public function substr(int $start, int $length = null): self
3065
    {
3066 31
        return static::create(
3067 31
            $this->utf8::substr(
3068 31
                $this->str,
3069 31
                $start,
3070 31
                $length,
3071 31
                $this->encoding
3072
            ),
3073 31
            $this->encoding
3074
        );
3075
    }
3076
3077
    /**
3078
     * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle".
3079
     * If no match is found returns new empty Stringy object.
3080
     *
3081
     * @param string $needle       <p>The string to look for.</p>
3082
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
3083
     *
3084
     * @psalm-mutation-free
3085
     *
3086
     * @return static
3087
     */
3088 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...
3089
    {
3090 4
        return static::create(
3091 4
            $this->utf8::str_substr_first(
3092 4
                $this->str,
3093 4
                $needle,
3094 4
                $beforeNeedle,
3095 4
                $this->encoding
3096
            ),
3097 4
            $this->encoding
3098
        );
3099
    }
3100
3101
    /**
3102
     * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle".
3103
     * If no match is found returns new empty Stringy object.
3104
     *
3105
     * @param string $needle       <p>The string to look for.</p>
3106
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
3107
     *
3108
     * @psalm-mutation-free
3109
     *
3110
     * @return static
3111
     */
3112 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...
3113
    {
3114 4
        return static::create(
3115 4
            $this->utf8::str_isubstr_first(
3116 4
                $this->str,
3117 4
                $needle,
3118 4
                $beforeNeedle,
3119 4
                $this->encoding
3120
            ),
3121 4
            $this->encoding
3122
        );
3123
    }
3124
3125
    /**
3126
     * Surrounds $str with the given substring.
3127
     *
3128
     * @param string $substring <p>The substring to add to both sides.</P>
3129
     *
3130
     * @psalm-mutation-free
3131
     *
3132
     * @return static
3133
     *                <p>Object whose $str had the substring both prepended and appended.</p>
3134
     */
3135 15
    public function surround(string $substring): self
3136
    {
3137 15
        return static::create(
3138 15
            $substring . $this->str . $substring,
3139 15
            $this->encoding
3140
        );
3141
    }
3142
3143
    /**
3144
     * Returns a case swapped version of the string.
3145
     *
3146
     * @psalm-mutation-free
3147
     *
3148
     * @return static
3149
     *                <p>Object whose $str has each character's case swapped.</P>
3150
     */
3151 15
    public function swapCase(): self
3152
    {
3153 15
        return static::create(
3154 15
            $this->utf8::swapCase($this->str, $this->encoding),
3155 15
            $this->encoding
3156
        );
3157
    }
3158
3159
    /**
3160
     * Returns a string with smart quotes, ellipsis characters, and dashes from
3161
     * Windows-1252 (commonly used in Word documents) replaced by their ASCII
3162
     * equivalents.
3163
     *
3164
     * @psalm-mutation-free
3165
     *
3166
     * @return static
3167
     *                <p>Object whose $str has those characters removed.</p>
3168
     */
3169 12
    public function tidy(): self
3170
    {
3171 12
        return static::create(
3172 12
            $this->ascii::normalize_msword($this->str),
3173 12
            $this->encoding
3174
        );
3175
    }
3176
3177
    /**
3178
     * Returns a trimmed string with the first letter of each word capitalized.
3179
     * Also accepts an array, $ignore, allowing you to list words not to be
3180
     * capitalized.
3181
     *
3182
     * @param array|string[]|null $ignore            [optional] <p>An array of words not to capitalize or null.
3183
     *                                               Default: null</p>
3184
     * @param string|null         $word_define_chars [optional] <p>An string of chars that will be used as whitespace
3185
     *                                               separator === words.</p>
3186
     * @param string|null         $language          [optional] <p>Language of the source string.</p>
3187
     *
3188
     * @psalm-mutation-free
3189
     *
3190
     * @return static
3191
     *                <p>Object with a titleized $str.</p>
3192
     */
3193 23
    public function titleize(
3194
        array $ignore = null,
3195
        string $word_define_chars = null,
3196
        string $language = null
3197
    ): self {
3198 23
        return static::create(
3199 23
            $this->utf8::str_titleize(
3200 23
                $this->str,
3201 23
                $ignore,
3202 23
                $this->encoding,
3203 23
                false,
3204 23
                $language,
3205 23
                false,
3206 23
                true,
3207 23
                $word_define_chars
3208
            ),
3209 23
            $this->encoding
3210
        );
3211
    }
3212
3213
    /**
3214
     * Returns a trimmed string in proper title case.
3215
     *
3216
     * Also accepts an array, $ignore, allowing you to list words not to be
3217
     * capitalized.
3218
     *
3219
     * Adapted from John Gruber's script.
3220
     *
3221
     * @see https://gist.github.com/gruber/9f9e8650d68b13ce4d78
3222
     *
3223
     * @param string[] $ignore <p>An array of words not to capitalize.</p>
3224
     *
3225
     * @psalm-mutation-free
3226
     *
3227
     * @return static
3228
     *                <p>Object with a titleized $str</p>
3229
     */
3230 70
    public function titleizeForHumans(array $ignore = []): self
3231
    {
3232 70
        return static::create(
3233 70
            $this->utf8::str_titleize_for_humans(
3234 70
                $this->str,
3235 70
                $ignore,
3236 70
                $this->encoding
3237
            ),
3238 70
            $this->encoding
3239
        );
3240
    }
3241
3242
    /**
3243
     * Returns an ASCII version of the string. A set of non-ASCII characters are
3244
     * replaced with their closest ASCII counterparts, and the rest are removed
3245
     * by default. The language or locale of the source string can be supplied
3246
     * for language-specific transliteration in any of the following formats:
3247
     * en, en_GB, or en-GB. For example, passing "de" results in "äöü" mapping
3248
     * to "aeoeue" rather than "aou" as in other languages.
3249
     *
3250
     * @param string $language          [optional] <p>Language of the source string.</p>
3251
     * @param bool   $removeUnsupported [optional] <p>Whether or not to remove the
3252
     *                                  unsupported characters.</p>
3253
     *
3254
     * @psalm-mutation-free
3255
     *
3256
     * @return static
3257
     *                <p>Object whose $str contains only ASCII characters.</p>
3258
     */
3259 23
    public function toAscii(string $language = 'en', bool $removeUnsupported = true): self
3260
    {
3261 23
        return static::create(
3262 23
            $this->ascii::to_ascii(
3263 23
                $this->str,
3264 23
                $language,
3265 23
                $removeUnsupported
3266
            ),
3267 23
            $this->encoding
3268
        );
3269
    }
3270
3271
    /**
3272
     * Returns a boolean representation of the given logical string value.
3273
     * For example, 'true', '1', 'on' and 'yes' will return true. 'false', '0',
3274
     * 'off', and 'no' will return false. In all instances, case is ignored.
3275
     * For other numeric strings, their sign will determine the return value.
3276
     * In addition, blank strings consisting of only whitespace will return
3277
     * false. For all other strings, the return value is a result of a
3278
     * boolean cast.
3279
     *
3280
     * @psalm-mutation-free
3281
     *
3282
     * @return bool
3283
     *              <p>A boolean value for the string.</p>
3284
     */
3285 45
    public function toBoolean(): bool
3286
    {
3287 45
        return $this->utf8::to_boolean($this->str);
3288
    }
3289
3290
    /**
3291
     * Converts all characters in the string to lowercase.
3292
     *
3293
     * @param bool        $tryToKeepStringLength [optional] <p>true === try to keep the string length: e.g. ẞ -> ß</p>
3294
     * @param string|null $lang                  [optional] <p>Set the language for special cases: az, el, lt, tr</p>
3295
     *
3296
     * @psalm-mutation-free
3297
     *
3298
     * @return static
3299
     *                <p>Object with all characters of $str being lowercase.</p>
3300
     */
3301 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...
3302
    {
3303 17
        return static::create(
3304 17
            $this->utf8::strtolower(
3305 17
                $this->str,
3306 17
                $this->encoding,
3307 17
                false,
3308 17
                $lang,
3309 17
                $tryToKeepStringLength
3310
            ),
3311 17
            $this->encoding
3312
        );
3313
    }
3314
3315
    /**
3316
     * Converts each tab in the string to some number of spaces, as defined by
3317
     * $tabLength. By default, each tab is converted to 4 consecutive spaces.
3318
     *
3319
     * @param int $tabLength [optional] <p>Number of spaces to replace each tab with. Default: 4</p>
3320
     *
3321
     * @psalm-mutation-free
3322
     *
3323
     * @return static
3324
     *                <p>Object whose $str has had tabs switched to spaces.</p>
3325
     */
3326 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...
3327
    {
3328 18
        if ($tabLength === 4) {
3329 9
            $tab = '    ';
3330 9
        } elseif ($tabLength === 2) {
3331 3
            $tab = '  ';
3332
        } else {
3333 6
            $tab = \str_repeat(' ', $tabLength);
3334
        }
3335
3336 18
        return static::create(
3337 18
            \str_replace("\t", $tab, $this->str),
3338 18
            $this->encoding
3339
        );
3340
    }
3341
3342
    /**
3343
     * Return Stringy object as string, but you can also use (string) for automatically casting the object into a
3344
     * string.
3345
     *
3346
     * @psalm-mutation-free
3347
     *
3348
     * @return string
3349
     */
3350 2180
    public function toString(): string
3351
    {
3352 2180
        return (string) $this->str;
3353
    }
3354
3355
    /**
3356
     * Converts each occurrence of some consecutive number of spaces, as
3357
     * defined by $tabLength, to a tab. By default, each 4 consecutive spaces
3358
     * are converted to a tab.
3359
     *
3360
     * @param int $tabLength [optional] <p>Number of spaces to replace with a tab. Default: 4</p>
3361
     *
3362
     * @psalm-mutation-free
3363
     *
3364
     * @return static
3365
     *                <p>Object whose $str has had spaces switched to tabs.</p>
3366
     */
3367 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...
3368
    {
3369 15
        if ($tabLength === 4) {
3370 9
            $tab = '    ';
3371 6
        } elseif ($tabLength === 2) {
3372 3
            $tab = '  ';
3373
        } else {
3374 3
            $tab = \str_repeat(' ', $tabLength);
3375
        }
3376
3377 15
        return static::create(
3378 15
            \str_replace($tab, "\t", $this->str),
3379 15
            $this->encoding
3380
        );
3381
    }
3382
3383
    /**
3384
     * Converts the first character of each word in the string to uppercase
3385
     * and all other chars to lowercase.
3386
     *
3387
     * @psalm-mutation-free
3388
     *
3389
     * @return static
3390
     *                <p>Object with all characters of $str being title-cased.</p>
3391
     */
3392 15
    public function toTitleCase(): self
3393
    {
3394 15
        return static::create(
3395 15
            $this->utf8::titlecase($this->str, $this->encoding),
3396 15
            $this->encoding
3397
        );
3398
    }
3399
3400
    /**
3401
     * Returns an ASCII version of the string. A set of non-ASCII characters are
3402
     * replaced with their closest ASCII counterparts, and the rest are removed
3403
     * unless instructed otherwise.
3404
     *
3405
     * @param bool   $strict  [optional] <p>Use "transliterator_transliterate()" from PHP-Intl | WARNING: bad
3406
     *                        performance | Default: false</p>
3407
     * @param string $unknown [optional] <p>Character use if character unknown. (default is ?)</p>
3408
     *
3409
     * @psalm-mutation-free
3410
     *
3411
     * @return static
3412
     *                <p>Object whose $str contains only ASCII characters.</p>
3413
     */
3414 34
    public function toTransliterate(bool $strict = false, string $unknown = '?'): self
3415
    {
3416 34
        return static::create(
3417 34
            $this->ascii::to_transliterate($this->str, $unknown, $strict),
3418 34
            $this->encoding
3419
        );
3420
    }
3421
3422
    /**
3423
     * Converts all characters in the string to uppercase.
3424
     *
3425
     * @param bool        $tryToKeepStringLength [optional] <p>true === try to keep the string length: e.g. ẞ -> ß</p>
3426
     * @param string|null $lang                  [optional] <p>Set the language for special cases: az, el, lt, tr</p>
3427
     *
3428
     * @psalm-mutation-free
3429
     *
3430
     * @return static
3431
     *                <p>Object with all characters of $str being uppercase.</p>
3432
     */
3433 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...
3434
    {
3435 20
        return static::create(
3436 20
            $this->utf8::strtoupper($this->str, $this->encoding, false, $lang, $tryToKeepStringLength),
3437 20
            $this->encoding
3438
        );
3439
    }
3440
3441
    /**
3442
     * Returns a string with whitespace removed from the start and end of the
3443
     * string. Supports the removal of unicode whitespace. Accepts an optional
3444
     * string of characters to strip instead of the defaults.
3445
     *
3446
     * @param string $chars [optional] <p>String of characters to strip. Default: null</p>
3447
     *
3448
     * @psalm-mutation-free
3449
     *
3450
     * @return static
3451
     *                <p>Object with a trimmed $str.</p>
3452
     */
3453 36
    public function trim(string $chars = null): self
3454
    {
3455 36
        return static::create(
3456 36
            $this->utf8::trim($this->str, $chars),
3457 36
            $this->encoding
3458
        );
3459
    }
3460
3461
    /**
3462
     * Returns a string with whitespace removed from the start of the string.
3463
     * Supports the removal of unicode whitespace. Accepts an optional
3464
     * string of characters to strip instead of the defaults.
3465
     *
3466
     * @param string $chars [optional] <p>Optional string of characters to strip. Default: null</p>
3467
     *
3468
     * @psalm-mutation-free
3469
     *
3470
     * @return static
3471
     *                <p>Object with a trimmed $str.</p>
3472
     */
3473 39
    public function trimLeft(string $chars = null): self
3474
    {
3475 39
        return static::create(
3476 39
            $this->utf8::ltrim($this->str, $chars),
3477 39
            $this->encoding
3478
        );
3479
    }
3480
3481
    /**
3482
     * Returns a string with whitespace removed from the end of the string.
3483
     * Supports the removal of unicode whitespace. Accepts an optional
3484
     * string of characters to strip instead of the defaults.
3485
     *
3486
     * @param string $chars [optional] <p>Optional string of characters to strip. Default: null</p>
3487
     *
3488
     * @psalm-mutation-free
3489
     *
3490
     * @return static
3491
     *                <p>Object with a trimmed $str.</p>
3492
     */
3493 39
    public function trimRight(string $chars = null): self
3494
    {
3495 39
        return static::create(
3496 39
            $this->utf8::rtrim($this->str, $chars),
3497 39
            $this->encoding
3498
        );
3499
    }
3500
3501
    /**
3502
     * Truncates the string to a given length. If $substring is provided, and
3503
     * truncating occurs, the string is further truncated so that the substring
3504
     * may be appended without exceeding the desired length.
3505
     *
3506
     * @param int    $length    <p>Desired length of the truncated string.</p>
3507
     * @param string $substring [optional] <p>The substring to append if it can fit. Default: ''</p>
3508
     *
3509
     * @psalm-mutation-free
3510
     *
3511
     * @return static
3512
     *                <p>Object with the resulting $str after truncating.</p>
3513
     */
3514 66
    public function truncate(int $length, string $substring = ''): self
3515
    {
3516 66
        return static::create(
3517 66
            $this->utf8::str_truncate($this->str, $length, $substring, $this->encoding),
3518 66
            $this->encoding
3519
        );
3520
    }
3521
3522
    /**
3523
     * Returns a lowercase and trimmed string separated by underscores.
3524
     * Underscores are inserted before uppercase characters (with the exception
3525
     * of the first character of the string), and in place of spaces as well as
3526
     * dashes.
3527
     *
3528
     * @psalm-mutation-free
3529
     *
3530
     * @return static
3531
     *                <p>Object with an underscored $str.</p>
3532
     */
3533 48
    public function underscored(): self
3534
    {
3535 48
        return $this->delimit('_');
3536
    }
3537
3538
    /**
3539
     * Returns an UpperCamelCase version of the supplied string. It trims
3540
     * surrounding spaces, capitalizes letters following digits, spaces, dashes
3541
     * and underscores, and removes spaces, dashes, underscores.
3542
     *
3543
     * @psalm-mutation-free
3544
     *
3545
     * @return static
3546
     *                <p>Object with $str in UpperCamelCase.</p>
3547
     */
3548 39
    public function upperCamelize(): self
3549
    {
3550 39
        return static::create(
3551 39
            $this->utf8::str_upper_camelize($this->str, $this->encoding),
3552 39
            $this->encoding
3553
        );
3554
    }
3555
3556
    /**
3557
     * Converts the first character of the supplied string to upper case.
3558
     *
3559
     * @psalm-mutation-free
3560
     *
3561
     * @return static
3562
     *                <p>Object with the first character of $str being upper case.</p>
3563
     */
3564 18
    public function upperCaseFirst(): self
3565
    {
3566 18
        return static::create($this->utf8::ucfirst($this->str, $this->encoding), $this->encoding);
3567
    }
3568
3569
    /**
3570
     * Converts the string into an URL slug. This includes replacing non-ASCII
3571
     * characters with their closest ASCII equivalents, removing remaining
3572
     * non-ASCII and non-alphanumeric characters, and replacing whitespace with
3573
     * $separator. The separator defaults to a single dash, and the string
3574
     * is also converted to lowercase.
3575
     *
3576
     * @param string                $separator    [optional] <p>The string used to replace whitespace. Default: '-'</p>
3577
     * @param string                $language     [optional] <p>The language for the url. Default: 'en'</p>
3578
     * @param array<string, string> $replacements [optional] <p>A map of replaceable strings.</p>
3579
     * @param bool                  $strToLower   [optional] <p>string to lower. Default: true</p>
3580
     *
3581
     * @psalm-mutation-free
3582
     *
3583
     * @return static
3584
     *                <p>Object whose $str has been converted to an URL slug.</p>
3585
     *
3586
     * @psalm-suppress ImpureMethodCall :/
3587
     */
3588 32
    public function urlify(
3589
        string $separator = '-',
3590
        string $language = 'en',
3591
        array $replacements = [],
3592
        bool $strToLower = true
3593
    ): self {
3594
        // init
3595 32
        $str = $this->str;
3596
3597 32
        foreach ($replacements as $from => $to) {
3598 32
            $str = \str_replace($from, $to, $str);
3599
        }
3600
3601 32
        return static::create(
3602 32
            URLify::slug(
3603 32
                $str,
3604 32
                $language,
3605 32
                $separator,
3606 32
                $strToLower
3607
            ),
3608 32
            $this->encoding
3609
        );
3610
    }
3611
3612
    /**
3613
     * Converts the string into an valid UTF-8 string.
3614
     *
3615
     * @psalm-mutation-free
3616
     *
3617
     * @return static
3618
     */
3619 2
    public function utf8ify(): self
3620
    {
3621 2
        return static::create($this->utf8::cleanup($this->str), $this->encoding);
3622
    }
3623
3624
    /**
3625
     * Convert a string into an array of words.
3626
     *
3627
     * @param string   $char_list           <p>Additional chars for the definition of "words".</p>
3628
     * @param bool     $remove_empty_values <p>Remove empty values.</p>
3629
     * @param int|null $remove_short_values <p>The min. string length or null to disable</p>
3630
     *
3631
     * @psalm-mutation-free
3632
     *
3633
     * @return CollectionStringy|static[]
3634
     *
3635
     * @psalm-return CollectionStringy<int,static>
3636
     */
3637 2
    public function words(
3638
        string $char_list = '',
3639
        bool $remove_empty_values = false,
3640
        int $remove_short_values = null
3641
    ): CollectionStringy {
3642
        /**
3643
         * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class
3644
         */
3645 2
        return CollectionStringy::createFromStrings(
3646 2
            $this->utf8::str_to_words(
3647 2
                $this->str,
3648 2
                $char_list,
3649 2
                $remove_empty_values,
3650 2
                $remove_short_values
3651
            )
3652
        );
3653
    }
3654
3655
    /**
3656
     * Surrounds $str with the given substring.
3657
     *
3658
     * @param string $substring <p>The substring to add to both sides.</P>
3659
     *
3660
     * @psalm-mutation-free
3661
     *
3662
     * @return static
3663
     *                <p>Object whose $str had the substring both prepended and appended.</p>
3664
     */
3665 10
    public function wrap(string $substring): self
3666
    {
3667 10
        return $this->surround($substring);
3668
    }
3669
3670
    /**
3671
     * Returns the replacements for the toAscii() method.
3672
     *
3673
     * @noinspection PhpUnused
3674
     *
3675
     * @psalm-mutation-free
3676
     *
3677
     * @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...
3678
     *                       <p>An array of replacements.</p>
3679
     *
3680
     * @deprecated   this is only here for backward-compatibly reasons
3681
     */
3682 1
    protected function charsArray(): array
3683
    {
3684 1
        return $this->ascii::charsArrayWithMultiLanguageValues();
3685
    }
3686
3687
    /**
3688
     * Returns true if $str matches the supplied pattern, false otherwise.
3689
     *
3690
     * @param string $pattern <p>Regex pattern to match against.</p>
3691
     *
3692
     * @psalm-mutation-free
3693
     *
3694
     * @return bool
3695
     *              <p>Whether or not $str matches the pattern.</p>
3696
     */
3697 24
    protected function matchesPattern(string $pattern): bool
3698
    {
3699 24
        return $this->utf8::str_matches_pattern($this->str, $pattern);
3700
    }
3701
}
3702