ts3phpframework
Loading...
Searching...
No Matches
StringHelper.php
Go to the documentation of this file.
1<?php
2
3namespace PlanetTeamSpeak\TeamSpeak3Framework\Helper;
4
5use ArrayAccess;
6use Countable;
7use Iterator;
8use JsonSerializable;
9use PlanetTeamSpeak\TeamSpeak3Framework\Exception\HelperException;
10use PlanetTeamSpeak\TeamSpeak3Framework\TeamSpeak3;
11
18class StringHelper implements ArrayAccess, Iterator, Countable, JsonSerializable
19{
25 protected string $string;
26
31 protected int $position = 0;
32
38 public function __construct(string $string)
39 {
40 $this->string = $string;
41 }
42
49 public static function factory(string $string): StringHelper
50 {
51 return new self($string);
52 }
53
62 public function replace(array|string $search, array|string $replace, bool $caseSensitivity = true): static
63 {
64 if ($caseSensitivity) {
65 $this->string = str_replace($search, $replace, $this->string);
66 } else {
67 $this->string = str_ireplace($search, $replace, $this->string);
68 }
69
70 return $this;
71 }
72
80 public function arg(array $args, string $char = "%"): static
81 {
82 $args = array_reverse($args, true);
83
84 foreach ($args as $key => $val) {
85 $args[$char . $key] = $val;
86 unset($args[$key]);
87 }
88
89 $this->string = strtr($this->string, $args);
90
91 return $this;
92 }
93
100 public function startsWith(string $pattern): bool
101 {
102 return str_starts_with($this->string, $pattern);
103 }
104
111 public function endsWith(string $pattern): bool
112 {
113 return str_ends_with($this->string, $pattern);
114 }
115
122 public function findFirst(string $needle): int
123 {
124 return strpos($this->string, $needle);
125 }
126
133 public function findLast(string $needle): int
134 {
135 return strrpos($this->string, $needle);
136 }
137
143 public function toLower(): StringHelper
144 {
145 return new self(strtolower($this->string));
146 }
147
153 public function toUpper(): StringHelper
154 {
155 return new self(strtoupper($this->string));
156 }
157
165 public function contains(string $pattern, bool $regexp = false): bool
166 {
167 if (empty($pattern)) {
168 return true;
169 }
170
171 if ($regexp) {
172 return boolval(preg_match(sprintf("/%s/i", $pattern), $this->string));
173 } else {
174 return stristr($this->string, $pattern) !== false;
175 }
176 }
177
185 public function substr(int $start, int $length = null): StringHelper
186 {
187 $string = ($length !== null) ? substr($this->string, $start, $length) : substr($this->string, $start);
188
189 return new self($string);
190 }
191
199 public function split(string $separator, int $limit = 0): array
200 {
201 $parts = explode($separator, $this->string, ($limit) ?: $this->count());
202
203 foreach ($parts as $key => $val) {
204 $parts[$key] = new self($val);
205 }
206
207 return $parts;
208 }
209
216 public function append(string $part): static
217 {
218 $this->string = $this->string . $part;
219
220 return $this;
221 }
222
229 public function prepend(string $part): static
230 {
231 $this->string = $part . $this->string;
232
233 return $this;
234 }
235
244 public function section(string $separator, int $first = 0, int $last = 0): ?StringHelper
245 {
246 $sections = explode($separator, $this->string);
247
248 $total = count($sections);
249
250 if ($first > $total) {
251 return null;
252 }
253 if ($first > $last) {
254 $last = $first;
255 }
256
257 for ($i = 0; $i < $total; $i++) {
258 if ($i < $first || $i > $last) {
259 unset($sections[$i]);
260 }
261 }
262
263 $string = implode($separator, $sections);
264
265 return new self($string);
266 }
267
275 public function resize(int $size, string $char = "\0"): static
276 {
277 $chars = ($size - $this->count());
278
279 if ($chars < 0) {
280 $this->string = substr($this->string, 0, $chars);
281 } elseif ($chars > 0) {
282 $this->string = str_pad($this->string, $size, $char);
283 }
284
285 return $this;
286 }
287
293 public function trim(): static
294 {
295 $this->string = trim($this->string);
296
297 return $this;
298 }
299
305 public function escape(): static
306 {
307 foreach (TeamSpeak3::getEscapePatterns() as $search => $replace) {
308 $this->string = str_replace($search, $replace, $this->string);
309 }
310
311 return $this;
312 }
313
319 public function unescape(): static
320 {
321 $this->string = strtr($this->string, array_flip(TeamSpeak3::getEscapePatterns()));
322
323 return $this;
324 }
325
331 public function filterAlnum(): static
332 {
333 $this->string = preg_replace("/[^[:alnum:]]/", "", $this->string);
334
335 return $this;
336 }
337
343 public function filterAlpha(): static
344 {
345 $this->string = preg_replace("/[^[:alpha:]]/", "", $this->string);
346
347 return $this;
348 }
349
355 public function filterDigits(): static
356 {
357 $this->string = preg_replace("/[^[:digit:]]/", "", $this->string);
358
359 return $this;
360 }
361
367 public function isInt(): bool
368 {
369 return is_numeric($this->string) &&
370 !$this->contains(".") &&
371 !$this->contains("x") &&
372 !$this->contains("e") &&
373 !$this->contains("+") &&
374 !$this->contains("-");
375 }
376
382 public function toInt(): int
383 {
384 if ($this->string == pow(2, 63) || $this->string == pow(2, 64) || $this->string > pow(2, 31)) {
385 return -1;
386 }
387
388 return intval($this->string);
389 }
390
396 public function toCrc32(): int
397 {
398 return crc32($this->string);
399 }
400
406 public function toMd5(): string
407 {
408 return md5($this->string);
409 }
410
416 public function toSha1(): string
417 {
418 return sha1($this->string);
419 }
420
427 public function isUtf8(): bool
428 {
429 $pattern = [];
430
431 $pattern[] = "[\xC2-\xDF][\x80-\xBF]"; // non-overlong 2-byte
432 $pattern[] = "\xE0[\xA0-\xBF][\x80-\xBF]"; // excluding overlongs
433 $pattern[] = "[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}"; // straight 3-byte
434 $pattern[] = "\xED[\x80-\x9F][\x80-\xBF]"; // excluding surrogates
435 $pattern[] = "\xF0[\x90-\xBF][\x80-\xBF]{2}"; // planes 1-3
436 $pattern[] = "[\xF1-\xF3][\x80-\xBF]{3}"; // planes 4-15
437 $pattern[] = "\xF4[\x80-\x8F][\x80-\xBF]{2}"; // plane 16
438
439 return (bool)preg_match("%(?:" . implode("|", $pattern) . ")+%xs", $this->string);
440 }
441
447 public function toUtf8(): static
448 {
449 if (!$this->isUtf8()) {
450 $this->string = mb_convert_encoding($this->string, 'UTF-8', mb_list_encodings());
451 }
452
453 return $this;
454 }
455
461 public function toBase64(): string
462 {
463 return base64_encode($this->string);
464 }
465
472 public static function fromBase64(string $base64): StringHelper
473 {
474 return new self(base64_decode($base64));
475 }
476
482 public function toHex(): string
483 {
484 $hex = "";
485
486 foreach ($this as $char) {
487 $hex .= $char->toHex();
488 }
489
490 return $hex;
491 }
492
500 public static function fromHex(string $hex): StringHelper
501 {
502 $string = "";
503
504 if (strlen($hex) % 2 == 1) {
505 throw new HelperException("given parameter '" . $hex . "' is not a valid hexadecimal number");
506 }
507
508 foreach (str_split($hex, 2) as $chunk) {
509 $string .= chr(hexdec($chunk));
510 }
511
512 return new self($string);
513 }
514
520 public function transliterate(): StringHelper
521 {
522 $utf8_accents = [
523 "à" => "a",
524 "ô" => "o",
525 "ď" => "d",
526 "ḟ" => "f",
527 "ë" => "e",
528 "š" => "s",
529 "ơ" => "o",
530 "ß" => "ss",
531 "ă" => "a",
532 "ř" => "r",
533 "ț" => "t",
534 "ň" => "n",
535 "ā" => "a",
536 "ķ" => "k",
537 "ŝ" => "s",
538 "ỳ" => "y",
539 "ņ" => "n",
540 "ĺ" => "l",
541 "ħ" => "h",
542 "ṗ" => "p",
543 "ó" => "o",
544 "ú" => "u",
545 "ě" => "e",
546 "é" => "e",
547 "ç" => "c",
548 "ẁ" => "w",
549 "ċ" => "c",
550 "õ" => "o",
551 "ṡ" => "s",
552 "ø" => "o",
553 "ģ" => "g",
554 "ŧ" => "t",
555 "ș" => "s",
556 "ė" => "e",
557 "ĉ" => "c",
558 "ś" => "s",
559 "î" => "i",
560 "ű" => "u",
561 "ć" => "c",
562 "ę" => "e",
563 "ŵ" => "w",
564 "ṫ" => "t",
565 "ū" => "u",
566 "č" => "c",
567 "ö" => "oe",
568 "è" => "e",
569 "ŷ" => "y",
570 "ą" => "a",
571 "ł" => "l",
572 "ų" => "u",
573 "ů" => "u",
574 "ş" => "s",
575 "ğ" => "g",
576 "ļ" => "l",
577 "ƒ" => "f",
578 "ž" => "z",
579 "ẃ" => "w",
580 "ḃ" => "b",
581 "å" => "a",
582 "ì" => "i",
583 "ï" => "i",
584 "ḋ" => "d",
585 "ť" => "t",
586 "ŗ" => "r",
587 "ä" => "ae",
588 "í" => "i",
589 "ŕ" => "r",
590 "ê" => "e",
591 "ü" => "ue",
592 "ò" => "o",
593 "ē" => "e",
594 "ñ" => "n",
595 "ń" => "n",
596 "ĥ" => "h",
597 "ĝ" => "g",
598 "đ" => "d",
599 "ĵ" => "j",
600 "ÿ" => "y",
601 "ũ" => "u",
602 "ŭ" => "u",
603 "ư" => "u",
604 "ţ" => "t",
605 "ý" => "y",
606 "ő" => "o",
607 "â" => "a",
608 "ľ" => "l",
609 "ẅ" => "w",
610 "ż" => "z",
611 "ī" => "i",
612 "ã" => "a",
613 "ġ" => "g",
614 "ṁ" => "m",
615 "ō" => "o",
616 "ĩ" => "i",
617 "ù" => "u",
618 "į" => "i",
619 "ź" => "z",
620 "á" => "a",
621 "û" => "u",
622 "þ" => "th",
623 "ð" => "dh",
624 "æ" => "ae",
625 "µ" => "u",
626 "ĕ" => "e",
627 "œ" => "oe",
628 "À" => "A",
629 "Ô" => "O",
630 "Ď" => "D",
631 "Ḟ" => "F",
632 "Ë" => "E",
633 "Š" => "S",
634 "Ơ" => "O",
635 "Ă" => "A",
636 "Ř" => "R",
637 "Ț" => "T",
638 "Ň" => "N",
639 "Ā" => "A",
640 "Ķ" => "K",
641 "Ŝ" => "S",
642 "Ỳ" => "Y",
643 "Ņ" => "N",
644 "Ĺ" => "L",
645 "Ħ" => "H",
646 "Ṗ" => "P",
647 "Ó" => "O",
648 "Ú" => "U",
649 "Ě" => "E",
650 "É" => "E",
651 "Ç" => "C",
652 "Ẁ" => "W",
653 "Ċ" => "C",
654 "Õ" => "O",
655 "Ṡ" => "S",
656 "Ø" => "O",
657 "Ģ" => "G",
658 "Ŧ" => "T",
659 "Ș" => "S",
660 "Ė" => "E",
661 "Ĉ" => "C",
662 "Ś" => "S",
663 "Î" => "I",
664 "Ű" => "U",
665 "Ć" => "C",
666 "Ę" => "E",
667 "Ŵ" => "W",
668 "Ṫ" => "T",
669 "Ū" => "U",
670 "Č" => "C",
671 "Ö" => "Oe",
672 "È" => "E",
673 "Ŷ" => "Y",
674 "Ą" => "A",
675 "Ł" => "L",
676 "Ų" => "U",
677 "Ů" => "U",
678 "Ş" => "S",
679 "Ğ" => "G",
680 "Ļ" => "L",
681 "Ƒ" => "F",
682 "Ž" => "Z",
683 "Ẃ" => "W",
684 "Ḃ" => "B",
685 "Å" => "A",
686 "Ì" => "I",
687 "Ï" => "I",
688 "Ḋ" => "D",
689 "Ť" => "T",
690 "Ŗ" => "R",
691 "Ä" => "Ae",
692 "Í" => "I",
693 "Ŕ" => "R",
694 "Ê" => "E",
695 "Ü" => "Ue",
696 "Ò" => "O",
697 "Ē" => "E",
698 "Ñ" => "N",
699 "Ń" => "N",
700 "Ĥ" => "H",
701 "Ĝ" => "G",
702 "Đ" => "D",
703 "Ĵ" => "J",
704 "Ÿ" => "Y",
705 "Ũ" => "U",
706 "Ŭ" => "U",
707 "Ư" => "U",
708 "Ţ" => "T",
709 "Ý" => "Y",
710 "Ő" => "O",
711 "Â" => "A",
712 "Ľ" => "L",
713 "Ẅ" => "W",
714 "Ż" => "Z",
715 "Ī" => "I",
716 "Ã" => "A",
717 "Ġ" => "G",
718 "Ṁ" => "M",
719 "Ō" => "O",
720 "Ĩ" => "I",
721 "Ù" => "U",
722 "Į" => "I",
723 "Ź" => "Z",
724 "Á" => "A",
725 "Û" => "U",
726 "Þ" => "Th",
727 "Ð" => "Dh",
728 "Æ" => "Ae",
729 "Ĕ" => "E",
730 "Œ" => "Oe",
731 ];
732
733 return new self($this->toUtf8()->replace(array_keys($utf8_accents), array_values($utf8_accents)));
734 }
735
743 public function uriSafe(string $spacer = "-"): StringHelper
744 {
745 $this->string = str_replace($spacer, " ", $this->string);
746 $this->string = $this->transliterate();
747 $this->string = preg_replace("/(\s|[^A-Za-z0-9\-])+/", $spacer, trim(strtolower($this->string)));
748 $this->string = trim($this->string, $spacer);
749
750 return new self($this->string);
751 }
752
758 public function spaceToPercent(): string
759 {
760 return str_replace(" ", "%20", $this->string);
761 }
762
768 public function toString(): string
769 {
770 return $this->string;
771 }
772
781 public function __call(string $function, array $args)
782 {
783 if (!function_exists($function)) {
784 throw new HelperException("cannot call undefined function '" . $function . "' on this object");
785 }
786
787 if (count($args)) {
788 if (($key = array_search($this, $args, true)) !== false) {
789 $args[$key] = $this->string;
790 } else {
791 throw new HelperException("cannot call undefined function '" . $function . "' without the " . __CLASS__ . " object parameter");
792 }
793
794 $return = call_user_func_array($function, $args);
795 } else {
796 $return = call_user_func($function, $this->string);
797 }
798
799 if (is_string($return)) {
800 $this->string = $return;
801 } else {
802 return $return;
803 }
804
805 return $this;
806 }
807
813 public function __toString()
814 {
815 return $this->string;
816 }
817
823 public function jsonSerialize(): string
824 {
825 return $this->toUtf8()->string;
826 }
827
831 public function count(): int
832 {
833 return strlen($this->string);
834 }
835
839 public function rewind(): void
840 {
841 $this->position = 0;
842 }
843
847 public function valid(): bool
848 {
849 return $this->position < $this->count();
850 }
851
855 public function key(): int
856 {
857 return $this->position;
858 }
859
864 public function current(): Char
865 {
866 return new Char($this->string[$this->position]);
867 }
868
872 public function next(): void
873 {
874 $this->position++;
875 }
876
880 public function offsetExists($offset): bool
881 {
882 return $offset < strlen($this->string);
883 }
884
889 public function offsetGet($offset): ?Char
890 {
891 return ($this->offsetExists($offset)) ? new Char($this->string[$offset]) : null;
892 }
893
897 public function offsetSet($offset, $value): void
898 {
899 if (!$this->offsetExists($offset)) {
900 return;
901 }
902
903 $this->string[$offset] = strval($value);
904 }
905
909 public function offsetUnset($offset): void
910 {
911 if (!$this->offsetExists($offset)) {
912 return;
913 }
914
915 $this->string = substr_replace($this->string, "", $offset, 1);
916 }
917}
Enhanced exception class for PlanetTeamSpeak\TeamSpeak3Framework\Helper* objects.
Helper class for char handling.
Definition Char.php:14
section(string $separator, int $first=0, int $last=0)
replace(array|string $search, array|string $replace, bool $caseSensitivity=true)
contains(string $pattern, bool $regexp=false)