Completed
Push — master ( 4a128e...c419f2 )
by Lars
03:04
created

Stringy::lastSubstringOf()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 6
ccs 3
cts 3
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 voku\helper\AntiXSS;
8
use voku\helper\EmailCheck;
9
use voku\helper\URLify;
10
use voku\helper\UTF8;
11
12
/**
13
 * Class Stringy
14
 *
15
 * @package Stringy
16
 */
17
class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess
18
{
19
  /**
20
   * An instance's string.
21
   *
22
   * @var string
23
   */
24
  protected $str;
25
26
  /**
27
   * The string's encoding, which should be one of the mbstring module's
28
   * supported encodings.
29
   *
30
   * @var string
31
   */
32
  protected $encoding;
33
34
  /**
35
   * Initializes a Stringy object and assigns both str and encoding properties
36
   * the supplied values. $str is cast to a string prior to assignment, and if
37
   * $encoding is not specified, it defaults to mb_internal_encoding(). Throws
38
   * an InvalidArgumentException if the first argument is an array or object
39
   * without a __toString method.
40
   *
41
   * @param mixed  $str      [optional] <p>Value to modify, after being cast to string. Default: ''</p>
42
   * @param string $encoding [optional] <p>The character encoding. Fallback: 'UTF-8'</p>
43
   *
44
   * @throws \InvalidArgumentException <p>if an array or object without a
45
   *         __toString method is passed as the first argument</p>
46
   */
47 1186
  public function __construct($str = '', string $encoding = null)
48
  {
49 1186
    if (\is_array($str)) {
50 1
      throw new \InvalidArgumentException(
51 1
          'Passed value cannot be an array'
52
      );
53
    }
54
55
    if (
56 1185
        \is_object($str)
57
        &&
58 1185
        !\method_exists($str, '__toString')
59
    ) {
60 1
      throw new \InvalidArgumentException(
61 1
          'Passed object must have a __toString method'
62
      );
63
    }
64
65 1184
    $this->str = (string)$str;
66
67 1184
    if ($encoding && $encoding !== 'UTF-8') {
0 ignored issues
show
Bug Best Practice introduced by
The expression $encoding of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
68
      $this->encoding = UTF8::normalize_encoding($encoding);
69
    } else {
70 1184
      $this->encoding = 'UTF-8';
71
    }
72 1184
  }
73
74
  /**
75
   * Returns the value in $str.
76
   *
77
   * @return string <p>The current value of the $str property.</p>
78
   */
79 100
  public function __toString()
80
  {
81 100
    return (string)$this->str;
82
  }
83
84
  /**
85
   * Gets the substring after the first occurrence of a separator.
86
   * If no match is found returns new empty Stringy object.
87
   *
88
   * @param string $separator
89
   *
90
   * @return static
91
   */
92 2
  public function afterFirst(string $separator): self
93
  {
94 2
    return static::create(
95 2
        UTF8::str_substr_after_first_separator(
96 2
            $this->str,
97 2
            $separator,
98 2
            $this->encoding
99
        )
100
    );
101
  }
102
103
  /**
104
   * Gets the substring after the first occurrence of a separator.
105
   * If no match is found returns new empty Stringy object.
106
   *
107
   * @param string $separator
108
   *
109
   * @return static
110
   */
111 1
  public function afterFirstIgnoreCase(string $separator): self
112
  {
113 1
    return static::create(
114 1
        UTF8::str_isubstr_after_first_separator(
115 1
            $this->str,
116 1
            $separator,
117 1
            $this->encoding
118
        )
119
    );
120
  }
121
122
  /**
123
   * Gets the substring after the last occurrence of a separator.
124
   * If no match is found returns new empty Stringy object.
125
   *
126
   * @param string $separator
127
   *
128
   * @return static
129
   */
130 1
  public function afterLast(string $separator): self
131
  {
132 1
    return static::create(
133 1
        UTF8::str_substr_after_last_separator(
134 1
            $this->str,
135 1
            $separator,
136 1
            $this->encoding
137
        )
138
    );
139
  }
140
141
  /**
142
   * Gets the substring after the last occurrence of a separator.
143
   * If no match is found returns new empty Stringy object.
144
   *
145
   * @param string $separator
146
   *
147
   * @return static
148
   */
149 1
  public function afterLastIgnoreCase(string $separator): self
150
  {
151 1
    return static::create(
152 1
        UTF8::str_isubstr_after_last_separator(
153 1
            $this->str,
154 1
            $separator,
155 1
            $this->encoding
156
        )
157
    );
158
  }
159
160
  /**
161
   * Returns a new string with $string appended.
162
   *
163
   * @param string $string <p>The string to append.</p>
164
   *
165
   * @return static <p>Object with appended $string.</p>
166
   */
167 5
  public function append(string $string): self
168
  {
169 5
    return static::create($this->str . $string, $this->encoding);
170
  }
171
172
  /**
173
   * Append an password (limited to chars that are good readable).
174
   *
175
   * @param int $length <p>Length of the random string.</p>
176
   *
177
   * @return static <p>Object with appended password.</p>
178
   */
179 1
  public function appendPassword(int $length): self
180
  {
181 1
    $possibleChars = '2346789bcdfghjkmnpqrtvwxyzBCDFGHJKLMNPQRTVWXYZ!?_#';
182
183 1
    return $this->appendRandomString($length, $possibleChars);
184
  }
185
186
  /**
187
   * Append an random string.
188
   *
189
   * @param int    $length        <p>Length of the random string.</p>
190
   * @param string $possibleChars [optional] <p>Characters string for the random selection.</p>
191
   *
192
   * @return static <p>Object with appended random string.</p>
193
   */
194 2
  public function appendRandomString(int $length, string $possibleChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'): self
195
  {
196 2
    $str = UTF8::get_random_string($length, $possibleChars);
197
198 2
    return $this->append($str);
199
  }
200
201
  /**
202
   * Append an unique identifier.
203
   *
204
   * @param string|int $entropyExtra [optional] <p>Extra entropy via a string or int value.</p>
205
   * @param bool       $md5          [optional] <p>Return the unique identifier as md5-hash? Default: true</p>
206
   *
207
   * @return static <p>Object with appended unique identifier as md5-hash.</p>
208
   */
209 1
  public function appendUniqueIdentifier($entropyExtra = '', bool $md5 = true): self
210
  {
211 1
    $uniqueString = UTF8::get_unique_string($entropyExtra, $md5);
212
213 1
    return $this->append($uniqueString);
214
  }
215
216
  /**
217
   * Returns the character at $index, with indexes starting at 0.
218
   *
219
   * @param int $index <p>Position of the character.</p>
220
   *
221
   * @return static <p>The character at $index.</p>
222
   */
223 8
  public function at(int $index): self
224
  {
225 8
    $chr = UTF8::char_at($this->str, $index);
226
227 8
    return static::create($chr, $this->encoding);
228
  }
229
230
  /**
231
   * Gets the substring before the first occurrence of a separator.
232
   * If no match is found returns new empty Stringy object.
233
   *
234
   * @param string $separator
235
   *
236
   * @return static
237
   */
238 1
  public function beforeFirst(string $separator): self
239
  {
240 1
    return static::create(
241 1
        UTF8::str_substr_before_first_separator(
242 1
            $this->str,
243 1
            $separator,
244 1
            $this->encoding
245
        )
246
    );
247
  }
248
249
  /**
250
   * Gets the substring before the first occurrence of a separator.
251
   * If no match is found returns new empty Stringy object.
252
   *
253
   * @param string $separator
254
   *
255
   * @return static
256
   */
257 1
  public function beforeFirstIgnoreCase(string $separator): self
258
  {
259 1
    return static::create(
260 1
        UTF8::str_isubstr_before_first_separator(
261 1
            $this->str,
262 1
            $separator,
263 1
            $this->encoding
264
        )
265
    );
266
  }
267
268
  /**
269
   * Gets the substring before the last occurrence of a separator.
270
   * If no match is found returns new empty Stringy object.
271
   *
272
   * @param string $separator
273
   *
274
   * @return static
275
   */
276 1
  public function beforeLast(string $separator): self
277
  {
278 1
    return static::create(
279 1
        UTF8::str_substr_before_last_separator(
280 1
            $this->str,
281 1
            $separator,
282 1
            $this->encoding
283
        )
284
    );
285
  }
286
287
  /**
288
   * Gets the substring before the last occurrence of a separator.
289
   * If no match is found returns new empty Stringy object.
290
   *
291
   * @param string $separator
292
   *
293
   * @return static
294
   */
295 1
  public function beforeLastIgnoreCase(string $separator): self
296
  {
297 1
    return static::create(
298 1
        UTF8::str_isubstr_before_last_separator(
299 1
            $this->str,
300 1
            $separator,
301 1
            $this->encoding
302
        )
303
    );
304
  }
305
306
  /**
307
   * Returns the substring between $start and $end, if found, or an empty
308
   * string. An optional offset may be supplied from which to begin the
309
   * search for the start string.
310
   *
311
   * @param string $start  <p>Delimiter marking the start of the substring.</p>
312
   * @param string $end    <p>Delimiter marking the end of the substring.</p>
313
   * @param int    $offset [optional] <p>Index from which to begin the search. Default: 0</p>
314
   *
315
   * @return static <p>Object whose $str is a substring between $start and $end.</p>
316
   */
317 16
  public function between(string $start, string $end, int $offset = 0): self
318
  {
319 16
    $str = UTF8::between(
320 16
        $this->str,
321 16
        $start,
322 16
        $end,
323 16
        $offset,
324 16
        $this->encoding
325
    );
326
327 16
    return static::create($str, $this->encoding);
328
  }
329
330
  /**
331
   * Returns a camelCase version of the string. Trims surrounding spaces,
332
   * capitalizes letters following digits, spaces, dashes and underscores,
333
   * and removes spaces, dashes, as well as underscores.
334
   *
335
   * @return static <p>Object with $str in camelCase.</p>
336
   */
337 19
  public function camelize(): self
338
  {
339 19
    return static::create(
340 19
        UTF8::str_camelize($this->str, $this->encoding),
341 19
        $this->encoding
342
    );
343
  }
344
345
  /**
346
   * Returns the string with the first letter of each word capitalized,
347
   * except for when the word is a name which shouldn't be capitalized.
348
   *
349
   * @return static <p>Object with $str capitalized.</p>
350
   */
351 39
  public function capitalizePersonalName(): self
352
  {
353 39
    return static::create(
354 39
        UTF8::str_capitalize_name($this->str),
355 39
        $this->encoding
356
    );
357
  }
358
359
  /**
360
   * Returns an array consisting of the characters in the string.
361
   *
362
   * @return array <p>An array of string chars.</p>
363
   */
364 4
  public function chars(): array
365
  {
366 4
    return UTF8::chars($this->str);
367
  }
368
369
  /**
370
   * Trims the string and replaces consecutive whitespace characters with a
371
   * single space. This includes tabs and newline characters, as well as
372
   * multibyte whitespace such as the thin space and ideographic space.
373
   *
374
   * @return static <p>Object with a trimmed $str and condensed whitespace.</p>
375
   */
376 13
  public function collapseWhitespace(): self
377
  {
378 13
    $str = UTF8::collapse_whitespace($this->str);
379
380 13
    return static::create($str, $this->encoding);
381
  }
382
383
  /**
384
   * Returns true if the string contains $needle, false otherwise. By default
385
   * the comparison is case-sensitive, but can be made insensitive by setting
386
   * $caseSensitive to false.
387
   *
388
   * @param string $needle        <p>Substring to look for.</p>
389
   * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
390
   *
391
   * @return bool <p>Whether or not $str contains $needle.</p>
392
   */
393 21
  public function contains(string $needle, bool $caseSensitive = true): bool
394
  {
395 21
    return UTF8::str_contains(
396 21
        $this->str,
397 21
        $needle,
398 21
        $caseSensitive,
399 21
        $this->encoding
400
    );
401
  }
402
403
  /**
404
   * Returns true if the string contains all $needles, false otherwise. By
405
   * default the comparison is case-sensitive, but can be made insensitive by
406
   * setting $caseSensitive to false.
407
   *
408
   * @param array $needles       <p>SubStrings to look for.</p>
409
   * @param bool  $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
410
   *
411
   * @return bool <p>Whether or not $str contains $needle.</p>
412
   */
413 44
  public function containsAll(array $needles, bool $caseSensitive = true): bool
414
  {
415 44
    return UTF8::str_contains_all(
416 44
        $this->str,
417 44
        $needles,
418 44
        $caseSensitive,
419 44
        $this->encoding
420
    );
421
  }
422
423
  /**
424
   * Returns true if the string contains any $needles, false otherwise. By
425
   * default the comparison is case-sensitive, but can be made insensitive by
426
   * setting $caseSensitive to false.
427
   *
428
   * @param array $needles       <p>SubStrings to look for.</p>
429
   * @param bool  $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
430
   *
431
   * @return bool <p>Whether or not $str contains $needle.</p>
432
   */
433 43
  public function containsAny(array $needles, bool $caseSensitive = true): bool
434
  {
435 43
    return UTF8::str_contains_any(
436 43
        $this->str,
437 43
        $needles,
438 43
        $caseSensitive,
439 43
        $this->encoding
440
    );
441
  }
442
443
  /**
444
   * Returns the length of the string, implementing the countable interface.
445
   *
446
   * @return int <p>The number of characters in the string, given the encoding.</p>
447
   */
448 1
  public function count(): int
449
  {
450 1
    return $this->length();
451
  }
452
453
  /**
454
   * Returns the number of occurrences of $substring in the given string.
455
   * By default, the comparison is case-sensitive, but can be made insensitive
456
   * by setting $caseSensitive to false.
457
   *
458
   * @param string $substring     <p>The substring to search for.</p>
459
   * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
460
   *
461
   * @return int|false <p>This functions returns an integer or false if there isn't a string.</p>
462
   */
463 15
  public function countSubstr(string $substring, bool $caseSensitive = true)
464
  {
465 15
    return UTF8::substr_count_simple(
466 15
        $this->str,
467 15
        $substring,
468 15
        $caseSensitive,
469 15
        $this->encoding
470
    );
471
  }
472
473
  /**
474
   * Creates a Stringy object and assigns both str and encoding properties
475
   * the supplied values. $str is cast to a string prior to assignment, and if
476
   * $encoding is not specified, it defaults to mb_internal_encoding(). It
477
   * then returns the initialized object. Throws an InvalidArgumentException
478
   * if the first argument is an array or object without a __toString method.
479
   *
480
   * @param mixed  $str      [optional] <p>Value to modify, after being cast to string. Default: ''</p>
481
   * @param string $encoding [optional] <p>The character encoding. Fallback: 'UTF-8'</p>
482
   *
483
   * @return static <p>A Stringy object.</p>
484
   *
485
   * @throws \InvalidArgumentException <p>if an array or object without a
486
   *         __toString method is passed as the first argument</p>
487
   */
488 1176
  public static function create($str = '', string $encoding = null): self
489
  {
490 1176
    if ($encoding && $encoding !== 'UTF-8') {
0 ignored issues
show
Bug Best Practice introduced by
The expression $encoding of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
491
      $encoding = UTF8::normalize_encoding($encoding);
492
    } else {
493 1176
      $encoding = 'UTF-8';
494
    }
495
496 1176
    return new static($str, $encoding);
497
  }
498
499
  /**
500
   * Returns a lowercase and trimmed string separated by dashes. Dashes are
501
   * inserted before uppercase characters (with the exception of the first
502
   * character of the string), and in place of spaces as well as underscores.
503
   *
504
   * @return static <p>Object with a dasherized $str</p>
505
   */
506 19
  public function dasherize(): self
507
  {
508 19
    $str = UTF8::str_dasherize($this->str);
509
510 19
    return static::create($str, $this->encoding);
511
  }
512
513
  /**
514
   * Returns a lowercase and trimmed string separated by the given delimiter.
515
   * Delimiters are inserted before uppercase characters (with the exception
516
   * of the first character of the string), and in place of spaces, dashes,
517
   * and underscores. Alpha delimiters are not converted to lowercase.
518
   *
519
   * @param string $delimiter <p>Sequence used to separate parts of the string.</p>
520
   *
521
   * @return static <p>Object with a delimited $str.</p>
522
   */
523 30
  public function delimit(string $delimiter): self
524
  {
525 30
    $str = UTF8::str_delimit($this->str, $delimiter);
526
527 30
    return static::create($str, $this->encoding);
528
  }
529
530
  /**
531
   * Returns true if the string ends with $substring, false otherwise. By
532
   * default, the comparison is case-sensitive, but can be made insensitive
533
   * by setting $caseSensitive to false.
534
   *
535
   * @param string $substring     <p>The substring to look for.</p>
536
   * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
537
   *
538
   * @return bool <p>Whether or not $str ends with $substring.</p>
539
   */
540 11
  public function endsWith(string $substring, bool $caseSensitive = true): bool
541
  {
542 11
    if ($caseSensitive) {
543 7
      return UTF8::str_ends_with($this->str, $substring);
544
    }
545
546 4
    return UTF8::str_iends_with($this->str, $substring);
547
  }
548
549
  /**
550
   * Returns true if the string ends with any of $substrings, false otherwise.
551
   * By default, the comparison is case-sensitive, but can be made insensitive
552
   * by setting $caseSensitive to false.
553
   *
554
   * @param string[] $substrings    <p>Substrings to look for.</p>
555
   * @param bool     $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
556
   *
557
   * @return bool     <p>Whether or not $str ends with $substring.</p>
558
   */
559 11
  public function endsWithAny(array $substrings, bool $caseSensitive = true): bool
560
  {
561 11
    if ($caseSensitive) {
562 7
      return UTF8::str_ends_with_any($this->str, $substrings);
563
    }
564
565 4
    return UTF8::str_iends_with_any($this->str, $substrings);
566
  }
567
568
  /**
569
   * Ensures that the string begins with $substring. If it doesn't, it's
570
   * prepended.
571
   *
572
   * @param string $substring <p>The substring to add if not present.</p>
573
   *
574
   * @return static <p>Object with its $str prefixed by the $substring.</p>
575
   */
576 10
  public function ensureLeft(string $substring): self
577
  {
578 10
    $str = UTF8::str_ensure_left($this->str, $substring);
579
580 10
    return static::create($str, $this->encoding);
581
  }
582
583
  /**
584
   * Ensures that the string ends with $substring. If it doesn't, it's appended.
585
   *
586
   * @param string $substring <p>The substring to add if not present.</p>
587
   *
588
   * @return static <p>Object with its $str suffixed by the $substring.</p>
589
   */
590 10
  public function ensureRight(string $substring): self
591
  {
592 10
    $str = UTF8::str_ensure_right($this->str, $substring);
593
594 10
    return static::create($str, $this->encoding);
595
  }
596
597
  /**
598
   * Create a escape html version of the string via "UTF8::htmlspecialchars()".
599
   *
600
   * @return static
601
   */
602 6
  public function escape(): self
603
  {
604 6
    $str = UTF8::htmlspecialchars(
605 6
        $this->str,
606 6
        ENT_QUOTES | ENT_SUBSTITUTE,
607 6
        $this->encoding
608
    );
609
610 6
    return static::create($str, $this->encoding);
611
  }
612
613
  /**
614
   * Create an extract from a sentence, so if the search-string was found, it try to centered in the output.
615
   *
616
   * @param string   $search
617
   * @param int|null $length                 [optional] <p>Default: null === text->length / 2</p>
618
   * @param string   $replacerForSkippedText [optional] <p>Default: …</p>
619
   *
620
   * @return static
621
   */
622 1
  public function extractText(string $search = '', int $length = null, string $replacerForSkippedText = '…'): self
623
  {
624 1
    $extract = UTF8::extract_text(
625 1
        $this->str,
626 1
        $search,
627 1
        $length,
628 1
        $replacerForSkippedText,
629 1
        $this->encoding
630
    );
631
632 1
    return static::create($extract, $this->encoding);
633
  }
634
635
  /**
636
   * Returns the first $n characters of the string.
637
   *
638
   * @param int $n <p>Number of characters to retrieve from the start.</p>
639
   *
640
   * @return static <p>Object with its $str being the first $n chars.</p>
641
   */
642 13
  public function first(int $n): self
643
  {
644 13
    $str = UTF8::first_char($this->str, $n);
645
646 13
    return static::create($str, $this->encoding);
647
  }
648
649
  /**
650
   * Returns the encoding used by the Stringy object.
651
   *
652
   * @return string <p>The current value of the $encoding property.</p>
653
   */
654 3
  public function getEncoding(): string
655
  {
656 3
    return $this->encoding;
657
  }
658
659
  /**
660
   * Returns a new ArrayIterator, thus implementing the IteratorAggregate
661
   * interface. The ArrayIterator's constructor is passed an array of chars
662
   * in the multibyte string. This enables the use of foreach with instances
663
   * of Stringy\Stringy.
664
   *
665
   * @return \ArrayIterator <p>An iterator for the characters in the string.</p>
666
   */
667 1
  public function getIterator(): \ArrayIterator
668
  {
669 1
    return new \ArrayIterator($this->chars());
670
  }
671
672
  /**
673
   * Returns true if the string contains a lower case char, false otherwise.
674
   *
675
   * @return bool <p>Whether or not the string contains a lower case character.</p>
676
   */
677 12
  public function hasLowerCase(): bool
678
  {
679 12
    return UTF8::has_lowercase($this->str);
680
  }
681
682
  /**
683
   * Returns true if the string contains an upper case char, false otherwise.
684
   *
685
   * @return bool <p>Whether or not the string contains an upper case character.</p>
686
   */
687 12
  public function hasUpperCase(): bool
688
  {
689 12
    return UTF8::has_uppercase($this->str);
690
  }
691
692
  /**
693
   * Convert all HTML entities to their applicable characters.
694
   *
695
   * @param int $flags       [optional] <p>
696
   *                         A bitmask of one or more of the following flags, which specify how to handle quotes and
697
   *                         which document type to use. The default is ENT_COMPAT.
698
   *                         <table>
699
   *                         Available <i>flags</i> constants
700
   *                         <tr valign="top">
701
   *                         <td>Constant Name</td>
702
   *                         <td>Description</td>
703
   *                         </tr>
704
   *                         <tr valign="top">
705
   *                         <td><b>ENT_COMPAT</b></td>
706
   *                         <td>Will convert double-quotes and leave single-quotes alone.</td>
707
   *                         </tr>
708
   *                         <tr valign="top">
709
   *                         <td><b>ENT_QUOTES</b></td>
710
   *                         <td>Will convert both double and single quotes.</td>
711
   *                         </tr>
712
   *                         <tr valign="top">
713
   *                         <td><b>ENT_NOQUOTES</b></td>
714
   *                         <td>Will leave both double and single quotes unconverted.</td>
715
   *                         </tr>
716
   *                         <tr valign="top">
717
   *                         <td><b>ENT_HTML401</b></td>
718
   *                         <td>
719
   *                         Handle code as HTML 4.01.
720
   *                         </td>
721
   *                         </tr>
722
   *                         <tr valign="top">
723
   *                         <td><b>ENT_XML1</b></td>
724
   *                         <td>
725
   *                         Handle code as XML 1.
726
   *                         </td>
727
   *                         </tr>
728
   *                         <tr valign="top">
729
   *                         <td><b>ENT_XHTML</b></td>
730
   *                         <td>
731
   *                         Handle code as XHTML.
732
   *                         </td>
733
   *                         </tr>
734
   *                         <tr valign="top">
735
   *                         <td><b>ENT_HTML5</b></td>
736
   *                         <td>
737
   *                         Handle code as HTML 5.
738
   *                         </td>
739
   *                         </tr>
740
   *                         </table>
741
   *                         </p>
742
   *
743
   * @return static <p>Object with the resulting $str after being html decoded.</p>
744
   */
745 5 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...
746
  {
747 5
    $str = UTF8::html_entity_decode(
748 5
        $this->str,
749 5
        $flags,
750 5
        $this->encoding
751
    );
752
753 5
    return static::create($str, $this->encoding);
754
  }
755
756
  /**
757
   * Convert all applicable characters to HTML entities.
758
   *
759
   * @param int $flags       [optional] <p>
760
   *                         A bitmask of one or more of the following flags, which specify how to handle quotes and
761
   *                         which document type to use. The default is ENT_COMPAT.
762
   *                         <table>
763
   *                         Available <i>flags</i> constants
764
   *                         <tr valign="top">
765
   *                         <td>Constant Name</td>
766
   *                         <td>Description</td>
767
   *                         </tr>
768
   *                         <tr valign="top">
769
   *                         <td><b>ENT_COMPAT</b></td>
770
   *                         <td>Will convert double-quotes and leave single-quotes alone.</td>
771
   *                         </tr>
772
   *                         <tr valign="top">
773
   *                         <td><b>ENT_QUOTES</b></td>
774
   *                         <td>Will convert both double and single quotes.</td>
775
   *                         </tr>
776
   *                         <tr valign="top">
777
   *                         <td><b>ENT_NOQUOTES</b></td>
778
   *                         <td>Will leave both double and single quotes unconverted.</td>
779
   *                         </tr>
780
   *                         <tr valign="top">
781
   *                         <td><b>ENT_HTML401</b></td>
782
   *                         <td>
783
   *                         Handle code as HTML 4.01.
784
   *                         </td>
785
   *                         </tr>
786
   *                         <tr valign="top">
787
   *                         <td><b>ENT_XML1</b></td>
788
   *                         <td>
789
   *                         Handle code as XML 1.
790
   *                         </td>
791
   *                         </tr>
792
   *                         <tr valign="top">
793
   *                         <td><b>ENT_XHTML</b></td>
794
   *                         <td>
795
   *                         Handle code as XHTML.
796
   *                         </td>
797
   *                         </tr>
798
   *                         <tr valign="top">
799
   *                         <td><b>ENT_HTML5</b></td>
800
   *                         <td>
801
   *                         Handle code as HTML 5.
802
   *                         </td>
803
   *                         </tr>
804
   *                         </table>
805
   *                         </p>
806
   *
807
   * @return static <p>Object with the resulting $str after being html encoded.</p>
808
   */
809 5 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...
810
  {
811 5
    $str = UTF8::htmlentities(
812 5
        $this->str,
813 5
        $flags,
814 5
        $this->encoding
815
    );
816
817 5
    return static::create($str, $this->encoding);
818
  }
819
820
  /**
821
   * Capitalizes the first word of the string, replaces underscores with
822
   * spaces, and strips '_id'.
823
   *
824
   * @return static <p>Object with a humanized $str.</p>
825
   */
826 3
  public function humanize(): self
827
  {
828 3
    $str = UTF8::str_humanize($this->str);
829
830 3
    return static::create($str, $this->encoding);
831
  }
832
833
  /**
834
   * Returns the index of the first occurrence of $needle in the string,
835
   * and false if not found. Accepts an optional offset from which to begin
836
   * the search.
837
   *
838
   * @param string $needle <p>Substring to look for.</p>
839
   * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
840
   *
841
   * @return int|false <p>The occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
842
   */
843 10
  public function indexOf(string $needle, int $offset = 0)
844
  {
845 10
    return UTF8::strpos(
846 10
        $this->str,
847 10
        $needle,
848 10
        $offset,
849 10
        $this->encoding
850
    );
851
  }
852
853
  /**
854
   * Returns the index of the first occurrence of $needle in the string,
855
   * and false if not found. Accepts an optional offset from which to begin
856
   * the search.
857
   *
858
   * @param string $needle <p>Substring to look for.</p>
859
   * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
860
   *
861
   * @return int|false <p>The occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
862
   */
863
  public function indexOfIgnoreCase(string $needle, int $offset = 0)
864
  {
865
    return UTF8::stripos(
866
        $this->str,
867
        $needle,
868
        $offset,
869
        $this->encoding
870
    );
871
  }
872
873
  /**
874
   * Returns the index of the last occurrence of $needle in the string,
875
   * and false if not found. Accepts an optional offset from which to begin
876
   * the search. Offsets may be negative to count from the last character
877
   * in the string.
878
   *
879
   * @param string $needle <p>Substring to look for.</p>
880
   * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
881
   *
882
   * @return int|false <p>The last occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
883
   */
884 10
  public function indexOfLast(string $needle, int $offset = 0)
885
  {
886 10
    return UTF8::strrpos(
887 10
        $this->str,
888 10
        $needle,
889 10
        $offset,
890 10
        $this->encoding
891
    );
892
  }
893
894
  /**
895
   * Returns the index of the last occurrence of $needle in the string,
896
   * and false if not found. Accepts an optional offset from which to begin
897
   * the search. Offsets may be negative to count from the last character
898
   * in the string.
899
   *
900
   * @param string $needle <p>Substring to look for.</p>
901
   * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
902
   *
903
   * @return int|false <p>The last occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
904
   */
905
  public function indexOfLastIgnoreCase(string $needle, int $offset = 0)
906
  {
907
    return UTF8::strripos(
908
        $this->str,
909
        $needle,
910
        $offset,
911
        $this->encoding
912
    );
913
  }
914
915
  /**
916
   * Inserts $substring into the string at the $index provided.
917
   *
918
   * @param string $substring <p>String to be inserted.</p>
919
   * @param int    $index     <p>The index at which to insert the substring.</p>
920
   *
921
   * @return static <p>Object with the resulting $str after the insertion.</p>
922
   */
923 8
  public function insert(string $substring, int $index): self
924
  {
925 8
    $str = UTF8::str_insert(
926 8
        $this->str,
927 8
        $substring,
928 8
        $index,
929 8
        $this->encoding
930
    );
931
932 8
    return static::create($str, $this->encoding);
933
  }
934
935
  /**
936
   * Returns true if the string contains the $pattern, otherwise false.
937
   *
938
   * WARNING: Asterisks ("*") are translated into (".*") zero-or-more regular
939
   * expression wildcards.
940
   *
941
   * @credit Originally from Laravel, thanks Taylor.
942
   *
943
   * @param string $pattern <p>The string or pattern to match against.</p>
944
   *
945
   * @return bool <p>Whether or not we match the provided pattern.</p>
946
   */
947 13
  public function is(string $pattern): bool
948
  {
949 13
    if ($this->toString() === $pattern) {
950 1
      return true;
951
    }
952
953 12
    $quotedPattern = \preg_quote($pattern, '/');
954 12
    $replaceWildCards = \str_replace('\*', '.*', $quotedPattern);
955
956 12
    return $this->matchesPattern('^' . $replaceWildCards . '\z');
957
  }
958
959
  /**
960
   * Returns true if the string contains only alphabetic chars, false otherwise.
961
   *
962
   * @return bool <p>Whether or not $str contains only alphabetic chars.</p>
963
   */
964 10
  public function isAlpha(): bool
965
  {
966 10
    return UTF8::is_alpha($this->str);
967
  }
968
969
  /**
970
   * Returns true if the string contains only alphabetic and numeric chars, false otherwise.
971
   *
972
   * @return bool <p>Whether or not $str contains only alphanumeric chars.</p>
973
   */
974 13
  public function isAlphanumeric(): bool
975
  {
976 13
    return UTF8::is_alphanumeric($this->str);
977
  }
978
979
  /**
980
   * Returns true if the string is base64 encoded, false otherwise.
981
   *
982
   * @return bool <p>Whether or not $str is base64 encoded.</p>
983
   */
984 7
  public function isBase64(): bool
985
  {
986 7
    return UTF8::is_base64($this->str);
987
  }
988
989
  /**
990
   * Returns true if the string contains only whitespace chars, false otherwise.
991
   *
992
   * @return bool <p>Whether or not $str contains only whitespace characters.</p>
993
   */
994 15
  public function isBlank(): bool
995
  {
996 15
    return UTF8::is_blank($this->str);
997
  }
998
999
  /**
1000
   * Returns true if the string contains a valid E-Mail address, false otherwise.
1001
   *
1002
   * @param bool $useExampleDomainCheck   [optional] <p>Default: false</p>
1003
   * @param bool $useTypoInDomainCheck    [optional] <p>Default: false</p>
1004
   * @param bool $useTemporaryDomainCheck [optional] <p>Default: false</p>
1005
   * @param bool $useDnsCheck             [optional] <p>Default: false</p>
1006
   *
1007
   * @return bool <p>Whether or not $str contains a valid E-Mail address.</p>
1008
   */
1009 1
  public function isEmail(bool $useExampleDomainCheck = false, bool $useTypoInDomainCheck = false, bool $useTemporaryDomainCheck = false, bool $useDnsCheck = false): bool
1010
  {
1011 1
    return EmailCheck::isValid($this->str, $useExampleDomainCheck, $useTypoInDomainCheck, $useTemporaryDomainCheck, $useDnsCheck);
1012
  }
1013
1014
  /**
1015
   * Determine whether the string is considered to be empty.
1016
   *
1017
   * A variable is considered empty if it does not exist or if its value equals FALSE.
1018
   * empty() does not generate a warning if the variable does not exist.
1019
   *
1020
   * @return bool <p>Whether or not $str is empty().</p>
1021
   */
1022
  public function isEmpty(): bool
1023
  {
1024
    return UTF8::is_empty($this->str);
1025
  }
1026
1027
  /**
1028
   * Returns true if the string contains only hexadecimal chars, false otherwise.
1029
   *
1030
   * @return bool <p>Whether or not $str contains only hexadecimal chars.</p>
1031
   */
1032 13
  public function isHexadecimal(): bool
1033
  {
1034 13
    return UTF8::is_hexadecimal($this->str);
1035
  }
1036
1037
  /**
1038
   * Returns true if the string contains HTML-Tags, false otherwise.
1039
   *
1040
   * @return bool <p>Whether or not $str contains HTML-Tags.</p>
1041
   */
1042 1
  public function isHtml(): bool
1043
  {
1044 1
    return UTF8::is_html($this->str);
1045
  }
1046
1047
  /**
1048
   * Returns true if the string is JSON, false otherwise. Unlike json_decode
1049
   * in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers,
1050
   * in that an empty string is not considered valid JSON.
1051
   *
1052
   * @return bool <p>Whether or not $str is JSON.</p>
1053
   */
1054 20
  public function isJson(): bool
1055
  {
1056 20
    return UTF8::is_json($this->str);
1057
  }
1058
1059
  /**
1060
   * Returns true if the string contains only lower case chars, false otherwise.
1061
   *
1062
   * @return bool <p>Whether or not $str contains only lower case characters.</p>
1063
   */
1064 8
  public function isLowerCase(): bool
1065
  {
1066 8
    return UTF8::is_lowercase($this->str);
1067
  }
1068
1069
  /**
1070
   * Returns true if the string is serialized, false otherwise.
1071
   *
1072
   * @return bool <p>Whether or not $str is serialized.</p>
1073
   */
1074 7
  public function isSerialized(): bool
1075
  {
1076 7
    return UTF8::is_serialized($this->str);
1077
  }
1078
1079
  /**
1080
   * Returns true if the string contains only lower case chars, false
1081
   * otherwise.
1082
   *
1083
   * @return bool <p>Whether or not $str contains only lower case characters.</p>
1084
   */
1085 8
  public function isUpperCase(): bool
1086
  {
1087 8
    return UTF8::is_uppercase($this->str);
1088
  }
1089
1090
  /**
1091
   * Returns the last $n characters of the string.
1092
   *
1093
   * @param int $n <p>Number of characters to retrieve from the end.</p>
1094
   *
1095
   * @return static <p>Object with its $str being the last $n chars.</p>
1096
   */
1097 12
  public function last(int $n): self
1098
  {
1099 12
    $str = UTF8::str_last_char(
1100 12
        $this->str,
1101 12
        $n,
1102 12
        $this->encoding
1103
    );
1104
1105 12
    return static::create($str, $this->encoding);
1106
  }
1107
1108
  /**
1109
   * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle".
1110
   * If no match is found returns new empty Stringy object.
1111
   *
1112
   * @param string $needle       <p>The string to look for.</p>
1113
   * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1114
   *
1115
   * @return static
1116
   */
1117 2
  public function lastSubstringOf(string $needle, bool $beforeNeedle = false): self
1118
  {
1119 2
    $str = UTF8::str_substr_last($this->str, $needle, $beforeNeedle, $this->encoding);
1120
1121 2
    return static::create($str, $this->encoding);
1122
  }
1123
1124
  /**
1125
   * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle".
1126
   * If no match is found returns new empty Stringy object.
1127
   *
1128
   * @param string $needle       <p>The string to look for.</p>
1129
   * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1130
   *
1131
   * @return static
1132
   */
1133 1
  public function lastSubstringOfIgnoreCase(string $needle, bool $beforeNeedle = false): self
1134
  {
1135 1
    $str = UTF8::str_isubstr_last($this->str, $needle, $beforeNeedle, $this->encoding);
1136
1137 1
    return static::create($str, $this->encoding);
1138
  }
1139
1140
  /**
1141
   * Returns the length of the string.
1142
   *
1143
   * @return int <p>The number of characters in $str given the encoding.</p>
1144
   */
1145 6
  public function length(): int
1146
  {
1147 6
    return UTF8::strlen($this->str, $this->encoding);
1148
  }
1149
1150
  /**
1151
   * Line-Wrap the string after $limit, but also after the next word.
1152
   *
1153
   * @param int $limit
1154
   *
1155
   * @return static
1156
   */
1157 1
  public function lineWrapAfterWord(int $limit): self
1158
  {
1159 1
    $str = UTF8::wordwrap_per_line($this->str, $limit);
1160
1161 1
    return static::create($str, $this->encoding);
1162
  }
1163
1164
  /**
1165
   * Splits on newlines and carriage returns, returning an array of Stringy
1166
   * objects corresponding to the lines in the string.
1167
   *
1168
   * @return static[] <p>An array of Stringy objects.</p>
1169
   */
1170 17
  public function lines(): array
1171
  {
1172 17
    $array = UTF8::str_to_lines($this->str);
1173
1174 17
    foreach ($array as $i => &$value) {
1175 17
      $value = static::create($value, $this->encoding);
1176
    }
1177
1178 17
    return $array;
1179
  }
1180
1181
  /**
1182
   * Returns the longest common prefix between the string and $otherStr.
1183
   *
1184
   * @param string $otherStr <p>Second string for comparison.</p>
1185
   *
1186
   * @return static <p>Object with its $str being the longest common prefix.</p>
1187
   */
1188 10
  public function longestCommonPrefix(string $otherStr): self
1189
  {
1190 10
    $str = UTF8::str_longest_common_prefix(
1191 10
        $this->str,
1192 10
        $otherStr,
1193 10
        $this->encoding
1194
    );
1195
1196 10
    return static::create($str, $this->encoding);
1197
  }
1198
1199
  /**
1200
   * Returns the longest common substring between the string and $otherStr.
1201
   * In the case of ties, it returns that which occurs first.
1202
   *
1203
   * @param string $otherStr <p>Second string for comparison.</p>
1204
   *
1205
   * @return static <p>Object with its $str being the longest common substring.</p>
1206
   */
1207 10
  public function longestCommonSubstring(string $otherStr): self
1208
  {
1209 10
    $longestCommonSubstring = UTF8::str_longest_common_substring(
1210 10
        $this->str,
1211 10
        $otherStr,
1212 10
        $this->encoding
1213
    );
1214
1215 10
    return static::create($longestCommonSubstring, $this->encoding);
1216
  }
1217
1218
  /**
1219
   * Returns the longest common suffix between the string and $otherStr.
1220
   *
1221
   * @param string $otherStr <p>Second string for comparison.</p>
1222
   *
1223
   * @return static <p>Object with its $str being the longest common suffix.</p>
1224
   */
1225 10
  public function longestCommonSuffix(string $otherStr): self
1226
  {
1227 10
    $longestCommonSuffix = UTF8::str_longest_common_suffix(
1228 10
        $this->str,
1229 10
        $otherStr,
1230 10
        $this->encoding
1231
    );
1232
1233 10
    return static::create($longestCommonSuffix, $this->encoding);
1234
  }
1235
1236
  /**
1237
   * Converts the first character of the string to lower case.
1238
   *
1239
   * @return static <p>Object with the first character of $str being lower case.</p>
1240
   */
1241 5
  public function lowerCaseFirst(): self
1242
  {
1243 5
    $str = UTF8::lcfirst($this->str, $this->encoding);
1244
1245 5
    return static::create($str, $this->encoding);
1246
  }
1247
1248
  /**
1249
   * Returns true if $str matches the supplied pattern, false otherwise.
1250
   *
1251
   * @param string $pattern <p>Regex pattern to match against.</p>
1252
   *
1253
   * @return bool <p>Whether or not $str matches the pattern.</p>
1254
   */
1255 12
  protected function matchesPattern(string $pattern): bool
1256
  {
1257 12
    return UTF8::str_matches_pattern($this->str, $pattern);
1258
  }
1259
1260
  /**
1261
   * Returns whether or not a character exists at an index. Offsets may be
1262
   * negative to count from the last character in the string. Implements
1263
   * part of the ArrayAccess interface.
1264
   *
1265
   * @param int $offset <p>The index to check.</p>
1266
   *
1267
   * @return boolean <p>Whether or not the index exists.</p>
1268
   */
1269 6
  public function offsetExists($offset): bool
1270
  {
1271 6
    return UTF8::str_offset_exists(
1272 6
        $this->str,
1273 6
        $offset,
1274 6
        $this->encoding
1275
    );
1276
  }
1277
1278
  /**
1279
   * Returns the character at the given index. Offsets may be negative to
1280
   * count from the last character in the string. Implements part of the
1281
   * ArrayAccess interface, and throws an OutOfBoundsException if the index
1282
   * does not exist.
1283
   *
1284
   * @param int $offset <p>The <strong>index</strong> from which to retrieve the char.</p>
1285
   *
1286
   * @return string <p>The character at the specified index.</p>
1287
   *
1288
   * @throws \OutOfBoundsException <p>If the positive or negative offset does not exist.</p>
1289
   */
1290 2
  public function offsetGet($offset): string
1291
  {
1292 2
    return UTF8::str_offset_get($this->str, $offset, $this->encoding);
1293
  }
1294
1295
  /**
1296
   * Implements part of the ArrayAccess interface, but throws an exception
1297
   * when called. This maintains the immutability of Stringy objects.
1298
   *
1299
   * @param int   $offset <p>The index of the character.</p>
1300
   * @param mixed $value  <p>Value to set.</p>
1301
   *
1302
   * @throws \Exception <p>When called.</p>
1303
   */
1304 1
  public function offsetSet($offset, $value)
1305
  {
1306
    // Stringy is immutable, cannot directly set char
1307
    /** @noinspection ThrowRawExceptionInspection */
1308 1
    throw new \Exception('Stringy object is immutable, cannot modify char');
1309
  }
1310
1311
  /**
1312
   * Implements part of the ArrayAccess interface, but throws an exception
1313
   * when called. This maintains the immutability of Stringy objects.
1314
   *
1315
   * @param int $offset <p>The index of the character.</p>
1316
   *
1317
   * @throws \Exception <p>When called.</p>
1318
   */
1319 1
  public function offsetUnset($offset)
1320
  {
1321
    // Don't allow directly modifying the string
1322
    /** @noinspection ThrowRawExceptionInspection */
1323 1
    throw new \Exception('Stringy object is immutable, cannot unset char');
1324
  }
1325
1326
  /**
1327
   * Pads the string to a given length with $padStr. If length is less than
1328
   * or equal to the length of the string, no padding takes places. The
1329
   * default string used for padding is a space, and the default type (one of
1330
   * 'left', 'right', 'both') is 'right'. Throws an InvalidArgumentException
1331
   * if $padType isn't one of those 3 values.
1332
   *
1333
   * @param int    $length  <p>Desired string length after padding.</p>
1334
   * @param string $padStr  [optional] <p>String used to pad, defaults to space. Default: ' '</p>
1335
   * @param string $padType [optional] <p>One of 'left', 'right', 'both'. Default: 'right'</p>
1336
   *
1337
   * @return static <p>Object with a padded $str.</p>
1338
   *
1339
   * @throws \InvalidArgumentException <p>If $padType isn't one of 'right', 'left' or 'both'.</p>
1340
   */
1341 13
  public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self
1342
  {
1343 13
    return static::create(
1344 13
        UTF8::str_pad(
1345 13
            $this->str,
1346 13
            $length,
1347 13
            $padStr,
1348 13
            $padType,
1349 13
            $this->encoding
1350
        )
1351
    );
1352
  }
1353
1354
  /**
1355
   * Returns a new string of a given length such that both sides of the
1356
   * string are padded. Alias for pad() with a $padType of 'both'.
1357
   *
1358
   * @param int    $length <p>Desired string length after padding.</p>
1359
   * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
1360
   *
1361
   * @return static <p>String with padding applied.</p>
1362
   */
1363 11
  public function padBoth(int $length, string $padStr = ' '): self
1364
  {
1365 11
    return static::create(
1366 11
        UTF8::str_pad_both(
1367 11
            $this->str,
1368 11
            $length,
1369 11
            $padStr,
1370 11
            $this->encoding
1371
        )
1372
    );
1373
  }
1374
1375
  /**
1376
   * Returns a new string of a given length such that the beginning of the
1377
   * string is padded. Alias for pad() with a $padType of 'left'.
1378
   *
1379
   * @param int    $length <p>Desired string length after padding.</p>
1380
   * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
1381
   *
1382
   * @return static <p>String with left padding.</p>
1383
   */
1384 7
  public function padLeft(int $length, string $padStr = ' '): self
1385
  {
1386 7
    return static::create(
1387 7
        UTF8::str_pad_left(
1388 7
            $this->str,
1389 7
            $length,
1390 7
            $padStr,
1391 7
            $this->encoding
1392
        )
1393
    );
1394
  }
1395
1396
  /**
1397
   * Returns a new string of a given length such that the end of the string
1398
   * is padded. Alias for pad() with a $padType of 'right'.
1399
   *
1400
   * @param int    $length <p>Desired string length after padding.</p>
1401
   * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
1402
   *
1403
   * @return static <p>String with right padding.</p>
1404
   */
1405 7
  public function padRight(int $length, string $padStr = ' '): self
1406
  {
1407 7
    return static::create(
1408 7
        UTF8::str_pad_right(
1409 7
            $this->str,
1410 7
            $length,
1411 7
            $padStr,
1412 7
            $this->encoding
1413
        )
1414
    );
1415
  }
1416
1417
  /**
1418
   * Returns a new string starting with $string.
1419
   *
1420
   * @param string $string <p>The string to append.</p>
1421
   *
1422
   * @return static <p>Object with appended $string.</p>
1423
   */
1424 2
  public function prepend(string $string): self
1425
  {
1426 2
    return static::create($string . $this->str, $this->encoding);
1427
  }
1428
1429
  /**
1430
   * Replaces all occurrences of $pattern in $str by $replacement.
1431
   *
1432
   * @param string $pattern     <p>The regular expression pattern.</p>
1433
   * @param string $replacement <p>The string to replace with.</p>
1434
   * @param string $options     [optional] <p>Matching conditions to be used.</p>
1435
   * @param string $delimiter   [optional] <p>Delimiter the the regex. Default: '/'</p>
1436
   *
1437
   * @return static <p>Object with the result2ing $str after the replacements.</p>
1438
   */
1439 10
  public function regexReplace(string $pattern, string $replacement, string $options = '', string $delimiter = '/'): self
1440
  {
1441 10
    $str = UTF8::regex_replace(
1442 10
        $this->str,
1443 10
        $pattern,
1444 10
        $replacement,
1445 10
        $options,
1446 10
        $delimiter
1447
    );
1448
1449 10
    return static::create($str, $this->encoding);
1450
  }
1451
1452
  /**
1453
   * Remove html via "strip_tags()" from the string.
1454
   *
1455
   * @param string $allowableTags [optional] <p>You can use the optional second parameter to specify tags which should
1456
   *                              not be stripped. Default: null
1457
   *                              </p>
1458
   *
1459
   * @return static
1460
   */
1461 6
  public function removeHtml(string $allowableTags = null): self
1462
  {
1463 6
    $str = UTF8::remove_html($this->str, $allowableTags);
1464
1465 6
    return static::create($str, $this->encoding);
1466
  }
1467
1468
  /**
1469
   * Remove all breaks [<br> | \r\n | \r | \n | ...] from the string.
1470
   *
1471
   * @param string $replacement [optional] <p>Default is a empty string.</p>
1472
   *
1473
   * @return static
1474
   */
1475 6
  public function removeHtmlBreak(string $replacement = ''): self
1476
  {
1477 6
    $str = UTF8::remove_html_breaks($this->str, $replacement);
1478
1479 6
    return static::create($str, $this->encoding);
1480
  }
1481
1482
  /**
1483
   * Returns a new string with the prefix $substring removed, if present.
1484
   *
1485
   * @param string $substring <p>The prefix to remove.</p>
1486
   *
1487
   * @return static <p>Object having a $str without the prefix $substring.</p>
1488
   */
1489 12
  public function removeLeft(string $substring): self
1490
  {
1491 12
    $str = UTF8::remove_left($this->str, $substring, $this->encoding);
1492
1493 12
    return static::create($str, $this->encoding);
1494
  }
1495
1496
  /**
1497
   * Returns a new string with the suffix $substring removed, if present.
1498
   *
1499
   * @param string $substring <p>The suffix to remove.</p>
1500
   *
1501
   * @return static <p>Object having a $str without the suffix $substring.</p>
1502
   */
1503 12
  public function removeRight(string $substring): self
1504
  {
1505 12
    $str = UTF8::remove_right($this->str, $substring, $this->encoding);
1506
1507 12
    return static::create($str, $this->encoding);
1508
1509
  }
1510
1511
  /**
1512
   * Try to remove all XSS-attacks from the string.
1513
   *
1514
   * @return static
1515
   */
1516 6
  public function removeXss(): self
1517
  {
1518 6
    static $antiXss = null;
1519
1520 6
    if ($antiXss === null) {
1521 1
      $antiXss = new AntiXSS();
1522
    }
1523
1524 6
    $str = $antiXss->xss_clean($this->str);
1525
1526 6
    return static::create($str, $this->encoding);
1527
  }
1528
1529
  /**
1530
   * Returns a repeated string given a multiplier.
1531
   *
1532
   * @param int $multiplier <p>The number of times to repeat the string.</p>
1533
   *
1534
   * @return static <p>Object with a repeated str.</p>
1535
   */
1536 7
  public function repeat(int $multiplier): self
1537
  {
1538 7
    $repeated = UTF8::str_repeat($this->str, $multiplier);
1539
1540 7
    return static::create($repeated, $this->encoding);
1541
  }
1542
1543
  /**
1544
   * Replaces all occurrences of $search in $str by $replacement.
1545
   *
1546
   * @param string $search        <p>The needle to search for.</p>
1547
   * @param string $replacement   <p>The string to replace with.</p>
1548
   * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
1549
   *
1550
   * @return static <p>Object with the resulting $str after the replacements.</p>
1551
   */
1552 29 View Code Duplication
  public function replace(string $search, string $replacement, bool $caseSensitive = true): 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...
1553
  {
1554 29
    if ($caseSensitive) {
1555 22
      $return = UTF8::str_replace($search, $replacement, $this->str);
1556
    } else {
1557 7
      $return = UTF8::str_ireplace($search, $replacement, $this->str);
1558
    }
1559
1560 29
    return static::create($return, $this->encoding);
1561
  }
1562
1563
  /**
1564
   * Replaces all occurrences of $search in $str by $replacement.
1565
   *
1566
   * @param array        $search        <p>The elements to search for.</p>
1567
   * @param string|array $replacement   <p>The string to replace with.</p>
1568
   * @param bool         $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
1569
   *
1570
   * @return static <p>Object with the resulting $str after the replacements.</p>
1571
   */
1572 30 View Code Duplication
  public function replaceAll(array $search, $replacement, bool $caseSensitive = true): 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...
1573
  {
1574 30
    if ($caseSensitive) {
1575 23
      $return = UTF8::str_replace($search, $replacement, $this->str);
1576
    } else {
1577 7
      $return = UTF8::str_ireplace($search, $replacement, $this->str);
1578
    }
1579
1580 30
    return static::create($return, $this->encoding);
1581
  }
1582
1583
  /**
1584
   * Replaces first occurrences of $search from the beginning of string with $replacement.
1585
   *
1586
   * @param string $search      <p>The string to search for.</p>
1587
   * @param string $replacement <p>The replacement.</p>
1588
   *
1589
   * @return static <p>Object with the resulting $str after the replacements.</p>
1590
   */
1591 16
  public function replaceFirst(string $search, string $replacement): self
1592
  {
1593 16
    $str = UTF8::str_replace_first($search, $replacement, $this->str);
1594
1595 16
    return static::create($str, $this->encoding);
1596
  }
1597
1598
  /**
1599
   * Replaces last occurrences of $search from the ending of string with $replacement.
1600
   *
1601
   * @param string $search      <p>The string to search for.</p>
1602
   * @param string $replacement <p>The replacement.</p>
1603
   *
1604
   * @return static <p>Object with the resulting $str after the replacements.</p>
1605
   */
1606 15
  public function replaceLast(string $search, string $replacement): self
1607
  {
1608 15
    $str = UTF8::str_replace_last($search, $replacement, $this->str);
1609
1610 15
    return static::create($str, $this->encoding);
1611
  }
1612
1613
  /**
1614
   * Replaces all occurrences of $search from the beginning of string with $replacement.
1615
   *
1616
   * @param string $search      <p>The string to search for.</p>
1617
   * @param string $replacement <p>The replacement.</p>
1618
   *
1619
   * @return static <p>Object with the resulting $str after the replacements.</p>
1620
   */
1621 16
  public function replaceBeginning(string $search, string $replacement): self
1622
  {
1623 16
    $str = UTF8::str_replace_beginning($this->str, $search, $replacement);
1624
1625 16
    return static::create($str, $this->encoding);
1626
  }
1627
1628
  /**
1629
   * Replaces all occurrences of $search from the ending of string with $replacement.
1630
   *
1631
   * @param string $search      <p>The string to search for.</p>
1632
   * @param string $replacement <p>The replacement.</p>
1633
   *
1634
   * @return static <p>Object with the resulting $str after the replacements.</p>
1635
   */
1636 16
  public function replaceEnding(string $search, string $replacement): self
1637
  {
1638 16
    $str = UTF8::str_replace_ending($this->str, $search, $replacement);
1639
1640 16
    return static::create($str, $this->encoding);
1641
  }
1642
1643
  /**
1644
   * Returns a reversed string. A multibyte version of strrev().
1645
   *
1646
   * @return static <p>Object with a reversed $str.</p>
1647
   */
1648 5
  public function reverse(): self
1649
  {
1650 5
    $reversed = UTF8::strrev($this->str);
1651
1652 5
    return static::create($reversed, $this->encoding);
1653
  }
1654
1655
  /**
1656
   * Truncates the string to a given length, while ensuring that it does not
1657
   * split words. If $substring is provided, and truncating occurs, the
1658
   * string is further truncated so that the substring may be appended without
1659
   * exceeding the desired length.
1660
   *
1661
   * @param int    $length    <p>Desired length of the truncated string.</p>
1662
   * @param string $substring [optional] <p>The substring to append if it can fit. Default: ''</p>
1663
   *
1664
   * @return static <p>Object with the resulting $str after truncating.</p>
1665
   */
1666 23
  public function safeTruncate(int $length, string $substring = ''): self
1667
  {
1668 23
    $str = UTF8::str_truncate_safe($this->str, $length, $substring, $this->encoding);
1669
1670 23
    return static::create($str, $this->encoding);
1671
  }
1672
1673
  /**
1674
   * Shorten the string after $length, but also after the next word.
1675
   *
1676
   * @param int    $length
1677
   * @param string $strAddOn [optional] <p>Default: '…'</p>
1678
   *
1679
   * @return static
1680
   */
1681 4
  public function shortenAfterWord(int $length, string $strAddOn = '…'): self
1682
  {
1683 4
    $string = UTF8::str_limit_after_word($this->str, $length, $strAddOn);
1684
1685 4
    return static::create($string, $this->encoding);
1686
  }
1687
1688
  /**
1689
   * A multibyte string shuffle function. It returns a string with its
1690
   * characters in random order.
1691
   *
1692
   * @return static <p>Object with a shuffled $str.</p>
1693
   */
1694 3
  public function shuffle(): self
1695
  {
1696 3
    $shuffledStr = UTF8::str_shuffle($this->str);
1697
1698 3
    return static::create($shuffledStr, $this->encoding);
1699
  }
1700
1701
  /**
1702
   * Returns the substring beginning at $start, and up to, but not including
1703
   * the index specified by $end. If $end is omitted, the function extracts
1704
   * the remaining string. If $end is negative, it is computed from the end
1705
   * of the string.
1706
   *
1707
   * @param int $start <p>Initial index from which to begin extraction.</p>
1708
   * @param int $end   [optional] <p>Index at which to end extraction. Default: null</p>
1709
   *
1710
   * @return static <p>Object with its $str being the extracted substring.</p>
1711
   */
1712 18
  public function slice(int $start, int $end = null): self
1713
  {
1714 18
    $str = UTF8::str_slice($this->str, $start, $end, $this->encoding);
1715
1716 18
    return static::create($str, $this->encoding);
1717
  }
1718
1719
  /**
1720
   * Converts the string into an URL slug. This includes replacing non-ASCII
1721
   * characters with their closest ASCII equivalents, removing remaining
1722
   * non-ASCII and non-alphanumeric characters, and replacing whitespace with
1723
   * $replacement. The replacement defaults to a single dash, and the string
1724
   * is also converted to lowercase.
1725
   *
1726
   * @param string $replacement [optional] <p>The string used to replace whitespace. Default: '-'</p>
1727
   * @param string $language    [optional] <p>The language for the url. Default: 'de'</p>
1728
   * @param bool   $strToLower  [optional] <p>string to lower. Default: true</p>
1729
   *
1730
   * @return static <p>Object whose $str has been converted to an URL slug.</p>
1731
   */
1732 15
  public function slugify(string $replacement = '-', string $language = 'de', bool $strToLower = true): self
1733
  {
1734 15
    $slug = URLify::slug($this->str, $language, $replacement, $strToLower);
1735
1736 15
    return static::create($slug, $this->encoding);
1737
  }
1738
1739
  /**
1740
   * Convert a string to e.g.: "snake_case"
1741
   *
1742
   * @return static <p>Object with $str in snake_case.</p>
1743
   */
1744 20
  public function snakeize(): self
1745
  {
1746 20
    $str = UTF8::str_snakeize($this->str, $this->encoding);
1747
1748 20
    return static::create($str, $this->encoding);
1749
  }
1750
1751
  /**
1752
   * Splits the string with the provided regular expression, returning an
1753
   * array of Stringy objects. An optional integer $limit will truncate the
1754
   * results.
1755
   *
1756
   * @param string $pattern <p>The regex with which to split the string.</p>
1757
   * @param int    $limit   [optional] <p>Maximum number of results to return. Default: -1 === no limit</p>
1758
   *
1759
   * @return static[] <p>An array of Stringy objects.</p>
1760
   */
1761 16
  public function split(string $pattern, int $limit = -1): array
1762
  {
1763 16
    $array = UTF8::str_split_pattern($this->str, $pattern, $limit);
1764
1765 16
    foreach ($array as $i => &$value) {
1766 14
      $value = static::create($value, $this->encoding);
1767
    }
1768
1769 16
    return $array;
1770
  }
1771
1772
  /**
1773
   * Returns true if the string begins with $substring, false otherwise. By
1774
   * default, the comparison is case-sensitive, but can be made insensitive
1775
   * by setting $caseSensitive to false.
1776
   *
1777
   * @param string $substring     <p>The substring to look for.</p>
1778
   * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
1779
   *
1780
   * @return bool <p>Whether or not $str starts with $substring.</p>
1781
   */
1782 11
  public function startsWith(string $substring, bool $caseSensitive = true): bool
1783
  {
1784 11
    if ($caseSensitive) {
1785 7
      return UTF8::str_starts_with($this->str, $substring);
1786
    }
1787
1788 4
    return UTF8::str_istarts_with($this->str, $substring);
1789
  }
1790
1791
  /**
1792
   * Returns true if the string begins with any of $substrings, false otherwise.
1793
   * By default the comparison is case-sensitive, but can be made insensitive by
1794
   * setting $caseSensitive to false.
1795
   *
1796
   * @param array $substrings    <p>Substrings to look for.</p>
1797
   * @param bool  $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
1798
   *
1799
   * @return bool  <p>Whether or not $str starts with $substring.</p>
1800
   */
1801 12
  public function startsWithAny(array $substrings, bool $caseSensitive = true): bool
1802
  {
1803 12
    if ($caseSensitive) {
1804 8
      return UTF8::str_starts_with_any($this->str, $substrings);
1805
    }
1806
1807 4
    return UTF8::str_istarts_with_any($this->str, $substrings);
1808
  }
1809
1810
  /**
1811
   * Strip all whitespace characters. This includes tabs and newline characters,
1812
   * as well as multibyte whitespace such as the thin space and ideographic space.
1813
   *
1814
   * @return static
1815
   */
1816 12
  public function stripWhitespace(): self
1817
  {
1818 12
    $str = UTF8::strip_whitespace($this->str);
1819
1820 12
    return static::create($str, $this->encoding);
1821
  }
1822
1823
  /**
1824
   * Remove css media-queries.
1825
   *
1826
   * @return static
1827
   */
1828 1
  public function stripeCssMediaQueries(): self
1829
  {
1830 1
    $str = UTF8::css_stripe_media_queries($this->str);
1831
1832 1
    return static::create($str, $this->encoding);
1833
  }
1834
1835
  /**
1836
   * Remove empty html-tag.
1837
   *
1838
   * e.g.: <tag></tag>
1839
   *
1840
   * @return static
1841
   */
1842 1
  public function stripeEmptyHtmlTags(): self
1843
  {
1844 1
    $str = UTF8::html_stripe_empty_tags($this->str);
1845
1846 1
    return static::create($str, $this->encoding);
1847
  }
1848
1849
  /**
1850
   * Returns the substring beginning at $start with the specified $length.
1851
   * It differs from the UTF8::substr() function in that providing a $length of
1852
   * null will return the rest of the string, rather than an empty string.
1853
   *
1854
   * @param int $start  <p>Position of the first character to use.</p>
1855
   * @param int $length [optional] <p>Maximum number of characters used. Default: null</p>
1856
   *
1857
   * @return static <p>Object with its $str being the substring.</p>
1858
   */
1859 9
  public function substr(int $start, int $length = null): self
1860
  {
1861 9
    $str = UTF8::substr(
1862 9
        $this->str,
1863 9
        $start,
1864 9
        $length,
1865 9
        $this->encoding
1866
    );
1867
1868 9
    return static::create($str, $this->encoding);
1869
  }
1870
1871
  /**
1872
   * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle".
1873
   * If no match is found returns new empty Stringy object.
1874
   *
1875
   * @param string $needle       <p>The string to look for.</p>
1876
   * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1877
   *
1878
   * @return static
1879
   */
1880 2
  public function substringOf(string $needle, bool $beforeNeedle = false): self
1881
  {
1882 2
    $str = UTF8::str_substr_first($this->str, $needle, $beforeNeedle, $this->encoding);
1883
1884 2
    return static::create($str, $this->encoding);
1885
  }
1886
1887
  /**
1888
   * Gets the substring after (or before via "$beforeNeedle") the first 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
   * @return static
1895
   */
1896 2
  public function substringOfIgnoreCase(string $needle, bool $beforeNeedle = false): self
1897
  {
1898 2
    $str = UTF8::str_isubstr_first($this->str, $needle, $beforeNeedle, $this->encoding);
1899
1900 2
    return static::create($str, $this->encoding);
1901
  }
1902
1903
  /**
1904
   * Surrounds $str with the given substring.
1905
   *
1906
   * @param string $substring <p>The substring to add to both sides.</P>
1907
   *
1908
   * @return static <p>Object whose $str had the substring both prepended and appended.</p>
1909
   */
1910 5
  public function surround(string $substring): self
1911
  {
1912 5
    $str = UTF8::str_surround($this->str, $substring);
1913
1914 5
    return static::create($str, $this->encoding);
1915
  }
1916
1917
  /**
1918
   * Returns a case swapped version of the string.
1919
   *
1920
   * @return static <p>Object whose $str has each character's case swapped.</P>
1921
   */
1922 5
  public function swapCase(): self
1923
  {
1924 5
    $str = UTF8::swapCase($this->str, $this->encoding);
1925
1926 5
    return static::create($str, $this->encoding);
1927
  }
1928
1929
  /**
1930
   * Returns a string with smart quotes, ellipsis characters, and dashes from
1931
   * Windows-1252 (commonly used in Word documents) replaced by their ASCII
1932
   * equivalents.
1933
   *
1934
   * @return static <p>Object whose $str has those characters removed.</p>
1935
   */
1936 4
  public function tidy(): self
1937
  {
1938 4
    $str = UTF8::normalize_msword($this->str);
1939
1940 4
    return static::create($str, $this->encoding);
1941
  }
1942
1943
  /**
1944
   * Returns a trimmed string with the first letter of each word capitalized.
1945
   * Also accepts an array, $ignore, allowing you to list words not to be
1946
   * capitalized.
1947
   *
1948
   * @param array|null $ignore [optional] <p>An array of words not to capitalize or null. Default: null</p>
1949
   *
1950
   * @return static <p>Object with a titleized $str.</p>
1951
   */
1952 5
  public function titleize(array $ignore = null): self
1953
  {
1954 5
    $str = UTF8::str_titleize($this->str, $ignore, $this->encoding);
1955
1956 5
    return static::create($str, $this->encoding);
1957
  }
1958
1959
  /**
1960
   * Returns a trimmed string in proper title case.
1961
   *
1962
   * Also accepts an array, $ignore, allowing you to list words not to be
1963
   * capitalized.
1964
   *
1965
   * Adapted from John Gruber's script.
1966
   *
1967
   * @see https://gist.github.com/gruber/9f9e8650d68b13ce4d78
1968
   *
1969
   * @param array $ignore <p>An array of words not to capitalize.</p>
1970
   *
1971
   * @return static <p>Object with a titleized $str</p>
1972
   */
1973 35
  public function titleizeForHumans(array $ignore = []): self
1974
  {
1975 35
    $str = UTF8::str_titleize_for_humans($this->str, $ignore, $this->encoding);
1976
1977 35
    return static::create($str, $this->encoding);
1978
  }
1979
1980
  /**
1981
   * Returns an ASCII version of the string. A set of non-ASCII characters are
1982
   * replaced with their closest ASCII counterparts, and the rest are removed
1983
   * unless instructed otherwise.
1984
   *
1985
   * @param bool $strict [optional] <p>Use "transliterator_transliterate()" from PHP-Intl | WARNING: bad performance |
1986
   *                     Default: false</p>
1987
   *
1988
   * @return static <p>Object whose $str contains only ASCII characters.</p>
1989
   */
1990 16
  public function toAscii(bool $strict = false): self
1991
  {
1992 16
    $str = UTF8::to_ascii($this->str, '?', $strict);
1993
1994 16
    return static::create($str, $this->encoding);
1995
  }
1996
1997
  /**
1998
   * Returns a boolean representation of the given logical string value.
1999
   * For example, 'true', '1', 'on' and 'yes' will return true. 'false', '0',
2000
   * 'off', and 'no' will return false. In all instances, case is ignored.
2001
   * For other numeric strings, their sign will determine the return value.
2002
   * In addition, blank strings consisting of only whitespace will return
2003
   * false. For all other strings, the return value is a result of a
2004
   * boolean cast.
2005
   *
2006
   * @return bool <p>A boolean value for the string.</p>
2007
   */
2008 15
  public function toBoolean(): bool
2009
  {
2010 15
    return UTF8::to_boolean($this->str);
2011
  }
2012
2013
  /**
2014
   * Converts all characters in the string to lowercase.
2015
   *
2016
   * @return static <p>Object with all characters of $str being lowercase.</p>
2017
   */
2018 7
  public function toLowerCase(): self
2019
  {
2020 7
    $str = UTF8::strtolower($this->str, $this->encoding);
2021
2022 7
    return static::create($str, $this->encoding);
2023
  }
2024
2025
  /**
2026
   * Converts each tab in the string to some number of spaces, as defined by
2027
   * $tabLength. By default, each tab is converted to 4 consecutive spaces.
2028
   *
2029
   * @param int $tabLength [optional] <p>Number of spaces to replace each tab with. Default: 4</p>
2030
   *
2031
   * @return static <p>Object whose $str has had tabs switched to spaces.</p>
2032
   */
2033 6
  public function toSpaces(int $tabLength = 4): self
2034
  {
2035 6
    $str = UTF8::tabs_to_spaces($this->str, $tabLength);
2036
2037 6
    return static::create($str, $this->encoding);
2038
  }
2039
2040
  /**
2041
   * Return Stringy object as string, but you can also use (string) for automatically casting the object into a string.
2042
   *
2043
   * @return string
2044
   */
2045 1071
  public function toString(): string
2046
  {
2047 1071
    return (string)$this->str;
2048
  }
2049
2050
  /**
2051
   * Converts each occurrence of some consecutive number of spaces, as
2052
   * defined by $tabLength, to a tab. By default, each 4 consecutive spaces
2053
   * are converted to a tab.
2054
   *
2055
   * @param int $tabLength [optional] <p>Number of spaces to replace with a tab. Default: 4</p>
2056
   *
2057
   * @return static <p>Object whose $str has had spaces switched to tabs.</p>
2058
   */
2059 5
  public function toTabs(int $tabLength = 4): self
2060
  {
2061 5
    $str = UTF8::spaces_to_tabs($this->str, $tabLength);
2062
2063 5
    return static::create($str, $this->encoding);
2064
  }
2065
2066
  /**
2067
   * Converts the first character of each word in the string to uppercase
2068
   * and all other chars to lowercase.
2069
   *
2070
   * @return static <p>Object with all characters of $str being title-cased.</p>
2071
   */
2072 5
  public function toTitleCase(): self
2073
  {
2074 5
    $str = UTF8::titlecase($this->str, $this->encoding);
2075
2076 5
    return static::create($str, $this->encoding);
2077
  }
2078
2079
  /**
2080
   * Converts all characters in the string to uppercase.
2081
   *
2082
   * @return static <p>Object with all characters of $str being uppercase.</p>
2083
   */
2084 5
  public function toUpperCase(): self
2085
  {
2086 5
    $str = UTF8::strtoupper($this->str, $this->encoding);
2087
2088 5
    return static::create($str, $this->encoding);
2089
  }
2090
2091
  /**
2092
   * Returns a string with whitespace removed from the start and end of the
2093
   * string. Supports the removal of unicode whitespace. Accepts an optional
2094
   * string of characters to strip instead of the defaults.
2095
   *
2096
   * @param string $chars [optional] <p>String of characters to strip. Default: null</p>
2097
   *
2098
   * @return static <p>Object with a trimmed $str.</p>
2099
   */
2100 12
  public function trim(string $chars = null): self
2101
  {
2102 12
    $str = UTF8::trim($this->str, $chars);
2103
2104 12
    return static::create($str, $this->encoding);
2105
  }
2106
2107
  /**
2108
   * Returns a string with whitespace removed from the start of the string.
2109
   * Supports the removal of unicode whitespace. Accepts an optional
2110
   * string of characters to strip instead of the defaults.
2111
   *
2112
   * @param string $chars [optional] <p>Optional string of characters to strip. Default: null</p>
2113
   *
2114
   * @return static <p>Object with a trimmed $str.</p>
2115
   */
2116 13
  public function trimLeft(string $chars = null): self
2117
  {
2118 13
    $str = UTF8::ltrim($this->str, $chars);
2119
2120 13
    return static::create($str, $this->encoding);
2121
  }
2122
2123
  /**
2124
   * Returns a string with whitespace removed from the end of the string.
2125
   * Supports the removal of unicode whitespace. Accepts an optional
2126
   * string of characters to strip instead of the defaults.
2127
   *
2128
   * @param string $chars [optional] <p>Optional string of characters to strip. Default: null</p>
2129
   *
2130
   * @return static <p>Object with a trimmed $str.</p>
2131
   */
2132 13
  public function trimRight(string $chars = null): self
2133
  {
2134 13
    $str = UTF8::rtrim($this->str, $chars);
2135
2136 13
    return static::create($str, $this->encoding);
2137
  }
2138
2139
  /**
2140
   * Truncates the string to a given length. If $substring is provided, and
2141
   * truncating occurs, the string is further truncated so that the substring
2142
   * may be appended without exceeding the desired length.
2143
   *
2144
   * @param int    $length    <p>Desired length of the truncated string.</p>
2145
   * @param string $substring [optional] <p>The substring to append if it can fit. Default: ''</p>
2146
   *
2147
   * @return static <p>Object with the resulting $str after truncating.</p>
2148
   */
2149 22
  public function truncate(int $length, string $substring = ''): self
2150
  {
2151 22
    $str = UTF8::str_truncate($this->str, $length, $substring, $this->encoding);
2152
2153 22
    return static::create($str, $this->encoding);
2154
  }
2155
2156
  /**
2157
   * Returns a lowercase and trimmed string separated by underscores.
2158
   * Underscores are inserted before uppercase characters (with the exception
2159
   * of the first character of the string), and in place of spaces as well as
2160
   * dashes.
2161
   *
2162
   * @return static <p>Object with an underscored $str.</p>
2163
   */
2164 16
  public function underscored(): self
2165
  {
2166 16
    return $this->delimit('_');
2167
  }
2168
2169
  /**
2170
   * Returns an UpperCamelCase version of the supplied string. It trims
2171
   * surrounding spaces, capitalizes letters following digits, spaces, dashes
2172
   * and underscores, and removes spaces, dashes, underscores.
2173
   *
2174
   * @return static  <p>Object with $str in UpperCamelCase.</p>
2175
   */
2176 13
  public function upperCamelize(): self
2177
  {
2178 13
    $str = UTF8::str_upper_camelize($this->str, $this->encoding);
2179
2180 13
    return static::create($str, $this->encoding);
2181
  }
2182
2183
  /**
2184
   * Converts the first character of the supplied string to upper case.
2185
   *
2186
   * @return static <p>Object with the first character of $str being upper case.</p>
2187
   */
2188 6
  public function upperCaseFirst(): self
2189
  {
2190 6
    $str = UTF8::ucfirst($this->str, $this->encoding);
2191
2192 6
    return static::create($str, $this->encoding);
2193
  }
2194
2195
  /**
2196
   * Converts the string into an valid UTF-8 string.
2197
   *
2198
   * @return static
2199
   */
2200 1
  public function utf8ify(): self
2201
  {
2202 1
    $str = UTF8::cleanup($this->str);
2203
2204 1
    return static::create($str, $this->encoding);
2205
  }
2206
}
2207