.gitattributes000064400000000054151360551150007440 0ustar00/tests export-ignore /.github export-ignore LICENSE000064400000002110151360551150005545 0ustar00The MIT License (MIT) Copyright (c) Taylor Otwell Copyright (c) Hyperf Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. composer.json000064400000002620151360551150007270 0ustar00{ "name": "hyperf/stringable", "description": "Hyperf Stringable package which come from illuminate/support", "license": "MIT", "keywords": [ "php", "swoole", "hyperf", "stringable" ], "homepage": "https://hyperf.io", "support": { "docs": "https://hyperf.wiki", "issues": "https://github.com/hyperf/hyperf/issues", "pull-request": "https://github.com/hyperf/hyperf/pulls", "source": "https://github.com/hyperf/hyperf" }, "require": { "php": ">=8.1", "ext-mbstring": "*", "hyperf/collection": "~3.1.0", "hyperf/conditionable": "~3.1.0", "hyperf/macroable": "~3.1.0", "hyperf/tappable": "~3.1.0" }, "suggest": { "ramsey/uuid": "Required to use uuid and orderedUuid methods.(^4.7|^5.0)", "symfony/uid": "Required to use ulid method.(^5.0|^6.0)", "doctrine/inflector": "Required to use plural and singular methods.(^2.0|^3.0)" }, "autoload": { "psr-4": { "Hyperf\\Stringable\\": "src/" }, "files": [ "src/Functions.php" ] }, "autoload-dev": { "psr-4": { "HyperfTest\\Stringable\\": "tests/" } }, "config": { "sort-packages": true }, "extra": { "branch-alias": { "dev-master": "3.0-dev" } } } src/Functions.php000064400000001437151360551150010023 0ustar00pluralize($value); return static::matchCase($plural, $value); } /** * Get the singular form of an English word. * * @param string $value * @return string */ public static function singular($value) { $singular = static::getInflector()->singularize($value); return static::matchCase($singular, $value); } public static function setInflector(?Inflector $inflector): void { static::$inflector = $inflector; } /** * Get the inflector instance. */ public static function getInflector(): Inflector { if (is_null(static::$inflector)) { static::$inflector = new Inflector( new CachedWordInflector(new RulesetInflector( English\Rules::getSingularRuleset() )), new CachedWordInflector(new RulesetInflector( English\Rules::getPluralRuleset() )) ); } return static::$inflector; } /** * Determine if the given value is uncountable. * * @param string $value * @return bool */ protected static function uncountable($value) { return in_array(strtolower($value), static::$uncountable); } /** * Attempt to match the case on two strings. * * @param string $value * @param string $comparison * @return string */ protected static function matchCase($value, $comparison) { $functions = ['mb_strtolower', 'mb_strtoupper', 'ucfirst', 'ucwords']; foreach ($functions as $function) { if (call_user_func($function, $comparison) === $comparison) { return call_user_func($function, $value); } } return $value; } } src/Str.php000064400000141421151360551150006621 0ustar00 $val) { $value = str_replace($val, (string) $key, $value); } return preg_replace('/[^\x20-\x7E]/u', '', $value); } /** * Get the portion of a string before a given value. * * @param string $subject * @param string $search * @return string */ public static function before($subject, $search) { return $search === '' ? $subject : explode($search, $subject)[0]; } /** * Get the portion of a string before the last occurrence of a given value. * * @param string $subject * @param string $search * @return string */ public static function beforeLast($subject, $search) { if ($search === '') { return $subject; } $pos = mb_strrpos($subject, $search); if ($pos === false) { return $subject; } return static::substr($subject, 0, $pos); } /** * Get the portion of a string between two given values. * * @param string $subject * @param string $from * @param string $to * @return string */ public static function between($subject, $from, $to) { if ($from === '' || $to === '') { return $subject; } return static::beforeLast(static::after($subject, $from), $to); } /** * Convert a value to camel case. * * @param string $value * @return string */ public static function camel($value) { return lcfirst(static::studly($value)); } /** * Get the character at the specified index. * * @param string $subject * @param int $index * @return null|string */ public static function charAt($subject, $index) { $length = mb_strlen($subject); if ($index < 0 ? $index < -$length : $index > $length - 1) { return null; } return mb_substr($subject, $index, 1); } /** * Determine if a given string contains a given substring. * * @param array|string $needles */ public static function contains(string $haystack, mixed $needles, bool $ignoreCase = false): bool { if ($ignoreCase) { return static::containsIgnoreCase($haystack, $needles); } foreach ((array) $needles as $needle) { $needle = (string) $needle; if ($needle !== '' && str_contains($haystack, $needle)) { return true; } } return false; } /** * Determine if a given string contains a given substring regardless of case sensitivity. * * @param array|string $needles */ public static function containsIgnoreCase(string $haystack, $needles): bool { foreach ((array) $needles as $needle) { $needle = (string) $needle; if ($needle !== '' && stripos($haystack, $needle) !== false) { return true; } } return false; } /** * Determine if a given string contains all array values. * * @param string[] $needles * @return bool */ public static function containsAll(string $haystack, array $needles, bool $ignoreCase = false) { foreach ($needles as $needle) { if (! static::contains($haystack, $needle, $ignoreCase)) { return false; } } return true; } /** * Determine if a given string ends with a given substring. * * @param array|string $needles * @return bool */ public static function endsWith(string $haystack, $needles) { foreach ((array) $needles as $needle) { $needle = (string) $needle; if ($needle !== '' && str_ends_with($haystack, $needle)) { return true; } } return false; } /** * Cap a string with a single instance of a given value. * * @param string $value * @param string $cap * @return string */ public static function finish($value, $cap) { $quoted = preg_quote($cap, '/'); return preg_replace('/(?:' . $quoted . ')+$/u', '', $value) . $cap; } /** * Determine if a given string matches a given pattern. * * @param array|string $pattern * @param string $value * @return bool */ public static function is($pattern, $value) { $patterns = Arr::wrap($pattern); if (empty($patterns)) { return false; } foreach ($patterns as $pattern) { // If the given value is an exact match we can of course return true right // from the beginning. Otherwise, we will translate asterisks and do an // actual pattern match against the two strings to see if they match. if ($pattern == $value) { return true; } $pattern = preg_quote($pattern, '#'); // Asterisks are translated into zero-or-more regular expression wildcards // to make it convenient to check if the strings starts with the given // pattern such as "library/*", making any string check convenient. $pattern = str_replace('\*', '.*', $pattern); if (preg_match('#^' . $pattern . '\z#u', $value) === 1) { return true; } } return false; } /** * Convert a string to kebab case. * * @param string $value * @return string */ public static function kebab($value) { return static::snake($value, '-'); } /** * Return the length of the given string. * * @param string $value * @param string $encoding * @return int */ public static function length($value, $encoding = null) { return mb_strlen($value, $encoding); } /** * Limit the number of characters in a string. * * @param string $value * @param int $limit * @param string $end * @return string */ public static function limit($value, $limit = 100, $end = '...') { if (mb_strwidth($value, 'UTF-8') <= $limit) { return $value; } return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')) . $end; } /** * Convert the given string to lower-case. * * @param string $value * @return string */ public static function lower($value) { return mb_strtolower($value, 'UTF-8'); } /** * Limit the number of words in a string. */ public static function words(string $value, int $words = 100, string $end = '...'): string { preg_match('/^\s*+(?:\S++\s*+){1,' . $words . '}/u', $value, $matches); if (! isset($matches[0]) || static::length($value) === static::length($matches[0])) { return $value; } return rtrim($matches[0]) . $end; } /** * Get the string matching the given pattern. * * @param string $pattern * @param string $subject * @return string */ public static function match($pattern, $subject) { preg_match($pattern, $subject, $matches); if (! $matches) { return ''; } return $matches[1] ?? $matches[0]; } /** * Determine if a given string matches a given pattern. * * @param iterable|string $patterns * @param string $value * @return bool */ public static function isMatch($patterns, $value) { $value = (string) $value; if (! is_iterable($patterns)) { $patterns = [$patterns]; } foreach ($patterns as $pattern) { $pattern = (string) $pattern; if (preg_match($pattern, $value) === 1) { return true; } } return false; } /** * Get the string matching the given pattern. * * @param string $pattern * @param string $subject * @return Collection */ public static function matchAll($pattern, $subject) { preg_match_all($pattern, $subject, $matches); if (empty($matches[0])) { return collect(); } return collect($matches[1] ?? $matches[0]); } /** * Pad both sides of a string with another. * * @param string $value * @param int $length * @param string $pad * @return string */ public static function padBoth($value, $length, $pad = ' ') { return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_BOTH); } /** * Pad the left side of a string with another. * * @param string $value * @param int $length * @param string $pad * @return string */ public static function padLeft($value, $length, $pad = ' ') { return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_LEFT); } /** * Pad the right side of a string with another. * * @param string $value * @param int $length * @param string $pad * @return string */ public static function padRight($value, $length, $pad = ' ') { return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_RIGHT); } /** * Parse a Class@method style callback into class and method. * * @param null|string $default */ public static function parseCallback(string $callback, $default = null): array { return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default]; } /** * Pluralize the last word of an English, studly caps case string. */ public static function pluralStudly(string $value, int $count = 2): string { $parts = preg_split('/(.)(?=[A-Z])/u', $value, -1, PREG_SPLIT_DELIM_CAPTURE); $lastWord = array_pop($parts); return implode('', $parts) . self::plural($lastWord, $count); } /** * Get the plural form of an English word. */ public static function plural(string $value, int $count = 2): string { return Pluralizer::plural($value, $count); } /** * Generate a more truly "random" alpha-numeric string. */ public static function random(int $length = 16): string { $string = ''; while (($len = strlen($string)) < $length) { $size = $length - $len; $bytes = random_bytes($size); $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size); } return $string; } /** * Repeat the given string. * * @return string */ public static function repeat(string $string, int $times) { return str_repeat($string, $times); } /** * Replace a given value in the string sequentially with an array. */ public static function replaceArray(string $search, array $replace, string $subject): string { foreach ($replace as $value) { $subject = static::replaceFirst($search, (string) $value, $subject); } return $subject; } /** * Replace the given value in the given string. * * @param string|string[] $search * @param string|string[] $replace * @param string|string[] $subject * @return string */ public static function replace($search, $replace, $subject) { return str_replace($search, $replace, $subject); } /** * Replace the first occurrence of a given value in the string. */ public static function replaceFirst(string $search, string $replace, string $subject): string { if ($search == '') { return $subject; } $position = strpos($subject, $search); if ($position !== false) { return substr_replace($subject, $replace, $position, strlen($search)); } return $subject; } /** * Replace the last occurrence of a given value in the string. */ public static function replaceLast(string $search, string $replace, string $subject): string { $position = strrpos($subject, $search); if ($position !== false) { return substr_replace($subject, $replace, $position, strlen($search)); } return $subject; } /** * Remove any occurrence of the given string in the subject. * * @param array|string $search * @param string $subject * @param bool $caseSensitive * @return string */ public static function remove($search, $subject, $caseSensitive = true) { return $caseSensitive ? str_replace($search, '', $subject) : str_ireplace($search, '', $subject); } /** * Begin a string with a single instance of a given value. */ public static function start(string $value, string $prefix): string { $quoted = preg_quote($prefix, '/'); return $prefix . preg_replace('/^(?:' . $quoted . ')+/u', '', $value); } /** * Strip HTML and PHP tags from the given string. * * @param null|string|string[] $allowedTags */ public static function stripTags(string $value, $allowedTags = null): string { return strip_tags($value, $allowedTags); } /** * Convert the given string to upper-case. */ public static function upper(string $value): string { return mb_strtoupper($value, 'UTF-8'); } /** * Convert the given string to title case. */ public static function title(string $value): string { return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8'); } /** * Get the singular form of an English word. */ public static function singular(string $value): string { return Pluralizer::singular($value); } /** * Generate a URL friendly "slug" from a given string. * @param mixed $dictionary */ public static function slug(string $title, string $separator = '-', ?string $language = 'en', $dictionary = ['@' => 'at']): string { $title = $language ? static::ascii($title, $language) : $title; // Convert all dashes/underscores into separator $flip = $separator === '-' ? '_' : '-'; $title = preg_replace('![' . preg_quote($flip) . ']+!u', $separator, $title); // Replace dictionary words foreach ($dictionary as $key => $value) { $dictionary[$key] = $separator . $value . $separator; } $title = str_replace(array_keys($dictionary), array_values($dictionary), $title); // Remove all characters that are not the separator, letters, numbers, or whitespace. $title = preg_replace('![^' . preg_quote($separator) . '\pL\pN\s]+!u', '', mb_strtolower($title)); // Replace all separator characters and whitespace by a single separator $title = preg_replace('![' . preg_quote($separator) . '\s]+!u', $separator, $title); return trim($title, $separator); } /** * Convert a string to snake case. */ public static function snake(string $value, string $delimiter = '_'): string { if (! ctype_lower($value)) { $value = preg_replace('/\s+/u', '', ucwords($value)); $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1' . $delimiter, $value)); } return $value; } /** * Determine if a given string starts with a given substring. * * @param array|string $needles */ public static function startsWith(string $haystack, $needles): bool { foreach ((array) $needles as $needle) { $needle = (string) $needle; if ($needle !== '' && str_starts_with($haystack, $needle)) { return true; } } return false; } /** * Convert a value to studly caps case. */ public static function studly(string $value, string $gap = ''): string { $value = ucwords(str_replace(['-', '_'], ' ', $value)); return str_replace(' ', $gap, $value); } /** * Returns the portion of string specified by the start and length parameters. * * @param string $string * @param int $start * @param null|int $length * @return string */ public static function substr($string, $start, $length = null) { return mb_substr($string, $start, $length, 'UTF-8'); } /** * Returns the number of substring occurrences. * * @param string $haystack * @param string $needle * @param int $offset * @param null|int $length * @return int */ public static function substrCount($haystack, $needle, $offset = 0, $length = null) { if (! is_null($length)) { return substr_count($haystack, $needle, $offset, $length); } return substr_count($haystack, $needle, $offset); } /** * Make a string's first character uppercase. */ public static function ucfirst(string $string): string { return static::upper(static::substr($string, 0, 1)) . static::substr($string, 1); } /** * Replaces the first or the last ones chars from a string by a given char. * * @param int $offset if is negative it starts from the end * @param string $replacement default is * */ public static function mask(string $string, int $offset = 0, int $length = 0, string $replacement = '*') { if ($length < 0) { throw new InvalidArgumentException('The length must equal or greater than zero.'); } $stringLength = mb_strlen($string); $absOffset = abs($offset); if ($absOffset >= $stringLength) { return $string; } $hiddenLength = $length ?: $stringLength - $absOffset; if ($offset >= 0) { return mb_substr($string, 0, $offset) . str_repeat($replacement, $hiddenLength) . mb_substr($string, $offset + $hiddenLength); } return mb_substr($string, 0, max($stringLength - $hiddenLength - $absOffset, 0)) . str_repeat($replacement, $hiddenLength) . mb_substr($string, $offset); } /** * Determine if a given value is a valid ULID. * * @param mixed $value */ public static function isUlid($value): bool { if (! is_string($value)) { return false; } if (strlen($value) !== 26) { return false; } if (strspn($value, '0123456789ABCDEFGHJKMNPQRSTVWXYZabcdefghjkmnpqrstvwxyz') !== 26) { return false; } return $value[0] <= '7'; } public static function ulid(?DateTimeInterface $time = null): Ulid { if (! class_exists(Ulid::class)) { throw new RuntimeException('The "symfony/uid" package is required to use the "ulid" method. Please run "composer require symfony/uid".'); } return new Ulid(Ulid::generate($time)); } public static function isUrl($value, array $protocols = []): bool { if (! is_string($value)) { return false; } $protocolList = empty($protocols) ? 'aaa|aaas|about|acap|acct|acd|acr|adiumxtra|adt|afp|afs|aim|amss|android|appdata|apt|ark|attachment|aw|barion|beshare|bitcoin|bitcoincash|blob|bolo|browserext|calculator|callto|cap|cast|casts|chrome|chrome-extension|cid|coap|coap\+tcp|coap\+ws|coaps|coaps\+tcp|coaps\+ws|com-eventbrite-attendee|content|conti|crid|cvs|dab|data|dav|diaspora|dict|did|dis|dlna-playcontainer|dlna-playsingle|dns|dntp|dpp|drm|drop|dtn|dvb|ed2k|elsi|example|facetime|fax|feed|feedready|file|filesystem|finger|first-run-pen-experience|fish|fm|ftp|fuchsia-pkg|geo|gg|git|gizmoproject|go|gopher|graph|gtalk|h323|ham|hcap|hcp|http|https|hxxp|hxxps|hydrazone|iax|icap|icon|im|imap|info|iotdisco|ipn|ipp|ipps|irc|irc6|ircs|iris|iris\.beep|iris\.lwz|iris\.xpc|iris\.xpcs|isostore|itms|jabber|jar|jms|keyparc|lastfm|ldap|ldaps|leaptofrogans|lorawan|lvlt|magnet|mailserver|mailto|maps|market|message|mid|mms|modem|mongodb|moz|ms-access|ms-browser-extension|ms-calculator|ms-drive-to|ms-enrollment|ms-excel|ms-eyecontrolspeech|ms-gamebarservices|ms-gamingoverlay|ms-getoffice|ms-help|ms-infopath|ms-inputapp|ms-lockscreencomponent-config|ms-media-stream-id|ms-mixedrealitycapture|ms-mobileplans|ms-officeapp|ms-people|ms-project|ms-powerpoint|ms-publisher|ms-restoretabcompanion|ms-screenclip|ms-screensketch|ms-search|ms-search-repair|ms-secondary-screen-controller|ms-secondary-screen-setup|ms-settings|ms-settings-airplanemode|ms-settings-bluetooth|ms-settings-camera|ms-settings-cellular|ms-settings-cloudstorage|ms-settings-connectabledevices|ms-settings-displays-topology|ms-settings-emailandaccounts|ms-settings-language|ms-settings-location|ms-settings-lock|ms-settings-nfctransactions|ms-settings-notifications|ms-settings-power|ms-settings-privacy|ms-settings-proximity|ms-settings-screenrotation|ms-settings-wifi|ms-settings-workplace|ms-spd|ms-sttoverlay|ms-transit-to|ms-useractivityset|ms-virtualtouchpad|ms-visio|ms-walk-to|ms-whiteboard|ms-whiteboard-cmd|ms-word|msnim|msrp|msrps|mss|mtqp|mumble|mupdate|mvn|news|nfs|ni|nih|nntp|notes|ocf|oid|onenote|onenote-cmd|opaquelocktoken|openpgp4fpr|pack|palm|paparazzi|payto|pkcs11|platform|pop|pres|prospero|proxy|pwid|psyc|pttp|qb|query|redis|rediss|reload|res|resource|rmi|rsync|rtmfp|rtmp|rtsp|rtsps|rtspu|s3|secondlife|service|session|sftp|sgn|shttp|sieve|simpleledger|sip|sips|skype|smb|sms|smtp|snews|snmp|soap\.beep|soap\.beeps|soldat|spiffe|spotify|ssh|steam|stun|stuns|submit|svn|tag|teamspeak|tel|teliaeid|telnet|tftp|tg|things|thismessage|tip|tn3270|tool|ts3server|turn|turns|tv|udp|unreal|urn|ut2004|v-event|vemmi|ventrilo|videotex|vnc|view-source|wais|webcal|wpid|ws|wss|wtai|wyciwyg|xcon|xcon-userid|xfire|xmlrpc\.beep|xmlrpc\.beeps|xmpp|xri|ymsgr|z39\.50|z39\.50r|z39\.50s' : implode('|', $protocols); /* * This pattern is derived from Symfony\Component\Validator\Constraints\UrlValidator (5.0.7). * * (c) Fabien Potencier http://symfony.com */ $pattern = '~^ (DEFAULT_PROTOCOLS):// # protocol (((?:[\_\.\pL\pN-]|%[0-9A-Fa-f]{2})+:)?((?:[\_\.\pL\pN-]|%[0-9A-Fa-f]{2})+)@)? # basic auth ( ([\pL\pN\pS\-\_\.])+(\.?([\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name | # or \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address | # or \[ (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::)))) \] # an IPv6 address ) (:[0-9]+)? # a port (optional) (?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})* )* # a path (?:\? (?:[\pL\pN\-._\~!$&\'\[\]()*+,;=:@/?]|%[0-9A-Fa-f]{2})* )? # a query (optional) (?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%[0-9A-Fa-f]{2})* )? # a fragment (optional) $~ixu'; return preg_match(str_replace('DEFAULT_PROTOCOLS', $protocolList, $pattern), $value) > 0; } /** * Determine if a given value is a valid UUID. * * @param mixed $value */ public static function isUuid($value): bool { if (! is_string($value)) { return false; } return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', $value) > 0; } public static function uuid(): UuidInterface { if (! class_exists(Uuid::class)) { throw new RuntimeException('The "ramsey/uuid" package is required to use the "uuid" method. Please run "composer require ramsey/uuid".'); } return Uuid::uuid4(); } public static function orderedUuid(?DateTimeInterface $time = null): UuidInterface { if (! class_exists(Uuid::class)) { throw new RuntimeException('The "ramsey/uuid" package is required to use the "orderedUuid" method. Please run "composer require ramsey/uuid".'); } return Uuid::uuid7($time); } public static function betweenFirst($subject, $from, $to) { if ($from === '' || $to === '') { return $subject; } return Str::before(Str::after($subject, $from), $to); } public static function classNamespace($value): string { if ($pos = strrpos($value, '\\')) { return substr($value, 0, $pos); } return ''; } public static function convertCase(string $string, int $mode = MB_CASE_FOLD, ?string $encoding = 'UTF-8'): string { return mb_convert_case($string, $mode, $encoding); } public static function excerpt($text, $phrase = '', $options = []) { $radius = $options['radius'] ?? 100; $omission = $options['omission'] ?? '...'; preg_match('/^(.*?)(' . preg_quote((string) $phrase) . ')(.*)$/iu', (string) $text, $matches); if (empty($matches)) { return null; } $startStr = ltrim($matches[1]); $start = Str::of(mb_substr($matches[1], max(mb_strlen($startStr, 'UTF-8') - $radius, 0), $radius, 'UTF-8'))->ltrim(); $start = $start->unless( (fn ($startWithRadius) => $startWithRadius->exactly($startStr))($start), fn ($startWithRadius) => $startWithRadius->prepend($omission), ); $endStr = rtrim($matches[3]); $end = Str::of(mb_substr($endStr, 0, $radius, 'UTF-8'))->rtrim(); $end = $end->unless( (fn ($endWithRadius) => $endWithRadius->exactly($endStr))($end), fn ($endWithRadius) => $endWithRadius->append($omission), ); return $start->append($matches[2], $end)->__toString(); } public static function isJson($value): bool { if (! is_string($value)) { return false; } if (function_exists('json_validate')) { return json_validate($value, 512); } try { json_decode($value, true, 512, JSON_THROW_ON_ERROR); } catch (JsonException $e) { return false; } return true; } public static function lcfirst($string): string { return Str::lower(Str::substr($string, 0, 1)) . Str::substr($string, 1); } public static function password($length = 32, $letters = true, $numbers = true, $symbols = true, $spaces = false) { return (new Collection()) ->when($letters, fn ($c) => $c->merge([ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ])) ->when($numbers, fn ($c) => $c->merge([ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ])) ->when($symbols, fn ($c) => $c->merge([ '~', '!', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '.', ',', '<', '>', '?', '/', '\\', '{', '}', '[', ']', '|', ':', ';', ])) ->when($spaces, fn ($c) => $c->merge([' '])) ->pipe(fn ($c) => Collection::times($length, fn () => $c[random_int(0, $c->count() - 1)])) ->implode(''); } public static function replaceStart($search, $replace, $subject) { $search = (string) $search; if ($search === '') { return $subject; } if (static::startsWith($subject, $search)) { return static::replaceFirst($search, $replace, $subject); } return $subject; } public static function replaceEnd($search, $replace, $subject) { $search = (string) $search; if ($search === '') { return $subject; } if (static::endsWith($subject, $search)) { return static::replaceLast($search, $replace, $subject); } return $subject; } public static function reverse($value): string { return implode(array_reverse(mb_str_split($value))); } public static function squish($value): array|string|null { return preg_replace('~(\s|\x{3164}|\x{1160})+~u', ' ', preg_replace('~^[\s\x{FEFF}]+|[\s\x{FEFF}]+$~u', '', $value)); } public static function substrReplace($string, $replace, $offset = 0, $length = null): array|string { if ($length === null) { $length = strlen($string); } return substr_replace($string, $replace, $offset, $length); } public static function swap(array $map, $subject): array|string { return str_replace(array_keys($map), array_values($map), $subject); } public static function ucsplit($string): array|bool { return preg_split('/(?=\p{Lu})/u', $string, -1, PREG_SPLIT_NO_EMPTY); } public static function wordCount($string): array|int { return str_word_count($string); } public static function wrap($value, $before, $after = null): string { return $before . $value . ($after ??= $before); } public static function wordWrap($string, $characters = 75, $break = "\n", $cutLongWords = false): string { return wordwrap($string, $characters, $break, $cutLongWords); } /** * Returns the replacements for the ascii method. * Note: Adapted from Stringy\Stringy. * * @see https://github.com/danielstjules/Stringy/blob/3.1.0/LICENSE.txt */ protected static function charsArray(): array { static $charsArray; if (isset($charsArray)) { return $charsArray; } return $charsArray = [ '0' => ['°', '₀', '۰', '0'], '1' => ['¹', '₁', '۱', '1'], '2' => ['²', '₂', '۲', '2'], '3' => ['³', '₃', '۳', '3'], '4' => ['⁴', '₄', '۴', '٤', '4'], '5' => ['⁵', '₅', '۵', '٥', '5'], '6' => ['⁶', '₆', '۶', '٦', '6'], '7' => ['⁷', '₇', '۷', '7'], '8' => ['⁸', '₈', '۸', '8'], '9' => ['⁹', '₉', '۹', '9'], 'a' => [ 'à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ', 'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ā', 'ą', 'å', 'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ', 'ἇ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ', 'ά', 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ', 'အ', 'ာ', 'ါ', 'ǻ', 'ǎ', 'ª', 'ა', 'अ', 'ا', 'a', 'ä', ], 'b' => ['б', 'β', 'ب', 'ဗ', 'ბ', 'b'], 'c' => ['ç', 'ć', 'č', 'ĉ', 'ċ', 'c'], 'd' => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', 'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ', 'd'], 'e' => [ 'é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ', 'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ', 'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э', 'є', 'ə', 'ဧ', 'ေ', 'ဲ', 'ე', 'ए', 'إ', 'ئ', 'e', ], 'f' => ['ф', 'φ', 'ف', 'ƒ', 'ფ', 'f'], 'g' => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', 'گ', 'g'], 'h' => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ', 'h'], 'i' => [ 'í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į', 'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ', 'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'і', 'ї', 'и', 'ဣ', 'ိ', 'ီ', 'ည်', 'ǐ', 'ი', 'इ', 'ی', 'i', ], 'j' => ['ĵ', 'ј', 'Ј', 'ჯ', 'ج', 'j'], 'k' => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك', 'က', 'კ', 'ქ', 'ک', 'k'], 'l' => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل', 'လ', 'ლ', 'l'], 'm' => ['м', 'μ', 'م', 'မ', 'მ', 'm'], 'n' => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န', 'ნ', 'n'], 'o' => [ 'ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ', 'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő', 'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό', 'о', 'و', 'θ', 'ို', 'ǒ', 'ǿ', 'º', 'ო', 'ओ', 'o', 'ö', ], 'p' => ['п', 'π', 'ပ', 'პ', 'پ', 'p'], 'q' => ['ყ', 'q'], 'r' => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', 'რ', 'r'], 's' => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ', 'ſ', 'ს', 's'], 't' => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ', 'თ', 'ტ', 't'], 'u' => [ 'ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ', 'ự', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у', 'ဉ', 'ု', 'ူ', 'ǔ', 'ǖ', 'ǘ', 'ǚ', 'ǜ', 'უ', 'उ', 'u', 'ў', 'ü', ], 'v' => ['в', 'ვ', 'ϐ', 'v'], 'w' => ['ŵ', 'ω', 'ώ', 'ဝ', 'ွ', 'w'], 'x' => ['χ', 'ξ', 'x'], 'y' => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', 'ϋ', 'ύ', 'ΰ', 'ي', 'ယ', 'y'], 'z' => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ', 'z'], 'aa' => ['ع', 'आ', 'آ'], 'ae' => ['æ', 'ǽ'], 'ai' => ['ऐ'], 'ch' => ['ч', 'ჩ', 'ჭ', 'چ'], 'dj' => ['ђ', 'đ'], 'dz' => ['џ', 'ძ'], 'ei' => ['ऍ'], 'gh' => ['غ', 'ღ'], 'ii' => ['ई'], 'ij' => ['ij'], 'kh' => ['х', 'خ', 'ხ'], 'lj' => ['љ'], 'nj' => ['њ'], 'oe' => ['ö', 'œ', 'ؤ'], 'oi' => ['ऑ'], 'oii' => ['ऒ'], 'ps' => ['ψ'], 'sh' => ['ш', 'შ', 'ش'], 'shch' => ['щ'], 'ss' => ['ß'], 'sx' => ['ŝ'], 'th' => ['þ', 'ϑ', 'ث', 'ذ', 'ظ'], 'ts' => ['ц', 'ც', 'წ'], 'ue' => ['ü'], 'uu' => ['ऊ'], 'ya' => ['я'], 'yu' => ['ю'], 'zh' => ['ж', 'ჟ', 'ژ'], '(c)' => ['©'], 'A' => [ 'Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ', 'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Å', 'Ā', 'Ą', 'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ', 'Ἇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ', 'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 'А', 'Ǻ', 'Ǎ', 'A', 'Ä', ], 'B' => ['Б', 'Β', 'ब', 'B'], 'C' => ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ', 'C'], 'D' => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ', 'D'], 'E' => [ 'É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ', 'Ệ', 'Ë', 'Ē', 'Ę', 'Ě', 'Ĕ', 'Ė', 'Ε', 'Έ', 'Ἐ', 'Ἑ', 'Ἒ', 'Ἓ', 'Ἔ', 'Ἕ', 'Έ', 'Ὲ', 'Е', 'Ё', 'Э', 'Є', 'Ə', 'E', ], 'F' => ['Ф', 'Φ', 'F'], 'G' => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ', 'G'], 'H' => ['Η', 'Ή', 'Ħ', 'H'], 'I' => [ 'Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į', 'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ', 'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї', 'Ǐ', 'ϒ', 'I', ], 'J' => ['J'], 'K' => ['К', 'Κ', 'K'], 'L' => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल', 'L'], 'M' => ['М', 'Μ', 'M'], 'N' => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν', 'N'], 'O' => [ 'Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ', 'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ø', 'Ō', 'Ő', 'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ', 'Ὸ', 'Ό', 'О', 'Θ', 'Ө', 'Ǒ', 'Ǿ', 'O', 'Ö', ], 'P' => ['П', 'Π', 'P'], 'Q' => ['Q'], 'R' => ['Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ', 'R'], 'S' => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ', 'S'], 'T' => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ', 'T'], 'U' => [ 'Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ', 'Ự', 'Û', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У', 'Ǔ', 'Ǖ', 'Ǘ', 'Ǚ', 'Ǜ', 'U', 'Ў', 'Ü', ], 'V' => ['В', 'V'], 'W' => ['Ω', 'Ώ', 'Ŵ', 'W'], 'X' => ['Χ', 'Ξ', 'X'], 'Y' => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', 'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ', 'Y'], 'Z' => ['Ź', 'Ž', 'Ż', 'З', 'Ζ', 'Z'], 'AE' => ['Æ', 'Ǽ'], 'Ch' => ['Ч'], 'Dj' => ['Ђ'], 'Dz' => ['Џ'], 'Gx' => ['Ĝ'], 'Hx' => ['Ĥ'], 'Ij' => ['IJ'], 'Jx' => ['Ĵ'], 'Kh' => ['Х'], 'Lj' => ['Љ'], 'Nj' => ['Њ'], 'Oe' => ['Œ'], 'Ps' => ['Ψ'], 'Sh' => ['Ш'], 'Shch' => ['Щ'], 'Ss' => ['ẞ'], 'Th' => ['Þ'], 'Ts' => ['Ц'], 'Ya' => ['Я'], 'Yu' => ['Ю'], 'Zh' => ['Ж'], ' ' => [ "\xC2\xA0", "\xE2\x80\x80", "\xE2\x80\x81", "\xE2\x80\x82", "\xE2\x80\x83", "\xE2\x80\x84", "\xE2\x80\x85", "\xE2\x80\x86", "\xE2\x80\x87", "\xE2\x80\x88", "\xE2\x80\x89", "\xE2\x80\x8A", "\xE2\x80\xAF", "\xE2\x81\x9F", "\xE3\x80\x80", "\xEF\xBE\xA0", ], ]; } /** * Returns the language specific replacements for the ascii method. * Note: Adapted from Stringy\Stringy. * * @see https://github.com/danielstjules/Stringy/blob/3.1.0/LICENSE.txt * @return null|array */ protected static function languageSpecificCharsArray(string $language) { static $languageSpecific; if (! isset($languageSpecific)) { $languageSpecific = [ 'bg' => [ ['х', 'Х', 'щ', 'Щ', 'ъ', 'Ъ', 'ь', 'Ь'], ['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y'], ], 'de' => [ ['ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü'], ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'], ], ]; } return $languageSpecific[$language] ?? null; } } src/StrCache.php000064400000002621151360551150007543 0ustar00value = (string) $value; } /** * Proxy dynamic properties onto methods. * * @param string $key * @return mixed */ public function __get($key) { return $this->{$key}(); } /** * Get the raw string value. * * @return string */ public function __toString() { return $this->value; } /** * Return the remainder of a string after the first occurrence of a given value. * * @param string $search * @return static */ public function after($search) { return new static(Str::after($this->value, $search)); } /** * Return the remainder of a string after the last occurrence of a given value. * * @param string $search * @return static */ public function afterLast($search) { return new static(Str::afterLast($this->value, $search)); } /** * Append the given values to the string. * * @param string $values * @return static */ public function append(...$values) { return new static($this->value . implode('', $values)); } /** * Transliterate a UTF-8 value to ASCII. * * @param string $language * @return static */ public function ascii($language = 'en') { return new static(Str::ascii($this->value, $language)); } /** * Get the trailing name component of the path. * * @param string $suffix * @return static */ public function basename($suffix = '') { return new static(basename($this->value, $suffix)); } /** * Get the character at the specified index. * * @param int $index * @return false|string */ public function charAt($index) { return Str::charAt($this->value, $index); } /** * Get the basename of the class path. * * @return static */ public function classBasename() { return new static(class_basename($this->value)); } /** * Get the portion of a string before the first occurrence of a given value. * * @param string $search * @return static */ public function before($search) { return new static(Str::before($this->value, $search)); } /** * Get the portion of a string before the last occurrence of a given value. * * @param string $search * @return static */ public function beforeLast($search) { return new static(Str::beforeLast($this->value, $search)); } /** * Get the portion of a string between two given values. * * @param string $from * @param string $to * @return static */ public function between($from, $to) { return new static(Str::between($this->value, $from, $to)); } /** * Convert a value to camel case. * * @return static */ public function camel() { return new static(Str::camel($this->value)); } /** * Determine if a given string contains a given substring. * * @param string|string[] $needles * @return bool */ public function contains($needles) { return Str::contains($this->value, $needles); } /** * Determine if a given string contains all array values. * * @return bool */ public function containsAll(array $needles) { return Str::containsAll($this->value, $needles); } /** * Get the parent directory's path. * * @param int $levels * @return static */ public function dirname($levels = 1) { return new static(dirname($this->value, $levels)); } /** * Determine if a given string ends with a given substring. * * @param string|string[] $needles * @return bool */ public function endsWith($needles) { return Str::endsWith($this->value, $needles); } /** * Determine if the string is an exact match with the given value. * * @param string|\Stringable $value * @return bool */ public function exactly($value) { if ($value instanceof \Stringable) { $value = $value->__toString(); } return $this->value === $value; } /** * Explode the string into an array. * * @param string $delimiter * @param int $limit * @return Collection */ public function explode($delimiter, $limit = PHP_INT_MAX) { return collect(explode($delimiter, $this->value, $limit)); } /** * Split a string using a regular expression or by length. * * @param int|string $pattern * @param int $limit * @param int $flags * @return Collection */ public function split($pattern, $limit = -1, $flags = 0) { if (filter_var($pattern, FILTER_VALIDATE_INT) !== false) { return collect(mb_str_split($this->value, $pattern)); } $segments = preg_split($pattern, $this->value, $limit, $flags); return ! empty($segments) ? collect($segments) : collect(); } /** * Cap a string with a single instance of a given value. * * @param string $cap * @return static */ public function finish($cap) { return new static(Str::finish($this->value, $cap)); } /** * Determine if a given string matches a given pattern. * * @param string|string[] $pattern * @return bool */ public function is($pattern) { return Str::is($pattern, $this->value); } /** * Determine if the given string is empty. * * @return bool */ public function isEmpty() { return $this->value === ''; } /** * Determine if the given string is not empty. * * @return bool */ public function isNotEmpty() { return ! $this->isEmpty(); } public function isUlid(): bool { return Str::isUlid($this->value); } public function isUrl(): bool { return Str::isUrl($this->value); } public function isUuid(): bool { return Str::isUuid($this->value); } /** * Convert a string to kebab case. * * @return static */ public function kebab() { return new static(Str::kebab($this->value)); } /** * Return the length of the given string. * * @param string $encoding * @return int */ public function length($encoding = null) { return Str::length($this->value, $encoding); } /** * Limit the number of characters in a string. * * @param int $limit * @param string $end * @return static */ public function limit($limit = 100, $end = '...') { return new static(Str::limit($this->value, $limit, $end)); } /** * Convert the given string to lower-case. * * @return static */ public function lower() { return new static(Str::lower($this->value)); } /** * Get the string matching the given pattern. * * @param string $pattern * @return static */ public function match($pattern) { preg_match($pattern, $this->value, $matches); if (! $matches) { return new static(); } return new static($matches[1] ?? $matches[0]); } /** * Determine if a given string matches a given pattern. * * @param iterable|string $pattern * @return bool */ public function isMatch($pattern) { return Str::isMatch($pattern, $this->value); } /** * Get the string matching the given pattern. * * @param string $pattern * @return Collection */ public function matchAll($pattern) { preg_match_all($pattern, $this->value, $matches); if (empty($matches[0])) { return collect(); } return collect($matches[1] ?? $matches[0]); } /** * Determine if the string matches the given pattern. * * @param string $pattern * @return bool */ public function test($pattern) { return $this->match($pattern)->isNotEmpty(); } /** * Pad both sides of the string with another. * * @param int $length * @param string $pad * @return static */ public function padBoth($length, $pad = ' ') { return new static(Str::padBoth($this->value, $length, $pad)); } /** * Pad the left side of the string with another. * * @param int $length * @param string $pad * @return static */ public function padLeft($length, $pad = ' ') { return new static(Str::padLeft($this->value, $length, $pad)); } /** * Pad the right side of the string with another. * * @param int $length * @param string $pad * @return static */ public function padRight($length, $pad = ' ') { return new static(Str::padRight($this->value, $length, $pad)); } /** * Parse a Class@method style callback into class and method. * * @param null|string $default * @return array */ public function parseCallback($default = null) { return Str::parseCallback($this->value, $default); } /** * Call the given callback and return a new string. * * @return static */ public function pipe(callable $callback) { return new static(call_user_func($callback, $this)); } /** * Get the plural form of an English word. * * @param int $count * @return static */ public function plural($count = 2) { return new static(Str::plural($this->value, $count)); } /** * Pluralize the last word of an English, studly caps case string. * * @param int $count * @return static */ public function pluralStudly($count = 2) { return new static(Str::pluralStudly($this->value, $count)); } /** * Prepend the given values to the string. * * @param string $values * @return static */ public function prepend(...$values) { return new static(implode('', $values) . $this->value); } /** * Remove any occurrence of the given string in the subject. * * @param string|string[] $search * @param bool $caseSensitive * @return static */ public function remove($search, $caseSensitive = true) { return new static(Str::remove($search, $this->value, $caseSensitive)); } /** * Repeat the string. * * @return static */ public function repeat(int $times) { return new static(Str::repeat($this->value, $times)); } /** * Replace the given value in the given string. * * @param string|string[] $search * @param string|string[] $replace * @return static */ public function replace($search, $replace) { return new static(Str::replace($search, $replace, $this->value)); } /** * Replace a given value in the string sequentially with an array. * * @param string $search * @return static */ public function replaceArray($search, array $replace) { return new static(Str::replaceArray($search, $replace, $this->value)); } /** * Replace the first occurrence of a given value in the string. * * @param string $search * @param string $replace * @return static */ public function replaceFirst($search, $replace) { return new static(Str::replaceFirst($search, $replace, $this->value)); } /** * Replace the last occurrence of a given value in the string. * * @param string $search * @param string $replace * @return static */ public function replaceLast($search, $replace) { return new static(Str::replaceLast($search, $replace, $this->value)); } /** * Replace the patterns matching the given regular expression. * * @param string $pattern * @param Closure|string $replace * @param int $limit * @return static */ public function replaceMatches($pattern, $replace, $limit = -1) { if ($replace instanceof Closure) { return new static(preg_replace_callback($pattern, $replace, $this->value, $limit)); } return new static(preg_replace($pattern, $replace, $this->value, $limit)); } /** * Begin a string with a single instance of a given value. * * @param string $prefix * @return static */ public function start($prefix) { return new static(Str::start($this->value, $prefix)); } /** * Strip HTML and PHP tags from the given string. * * @param null|string|string[] $allowedTags * @return static */ public function stripTags($allowedTags = null) { return new static(strip_tags($this->value, $allowedTags)); } /** * Convert the given string to upper-case. * * @return static */ public function upper() { return new static(Str::upper($this->value)); } /** * Convert the given string to title case. * * @return static */ public function title() { return new static(Str::title($this->value)); } /** * Get the singular form of an English word. * * @return static */ public function singular() { return new static(Str::singular($this->value)); } /** * Generate a URL friendly "slug" from a given string. * * @param string $separator * @param null|string $language * @return static */ public function slug($separator = '-', $language = 'en') { return new static(Str::slug($this->value, $separator, $language)); } /** * Convert a string to snake case. * * @param string $delimiter * @return static */ public function snake($delimiter = '_') { return new static(Str::snake($this->value, $delimiter)); } /** * Determine if a given string starts with a given substring. * * @param string|string[] $needles * @return bool */ public function startsWith($needles) { return Str::startsWith($this->value, $needles); } /** * Convert a value to studly caps case. * * @return static */ public function studly() { return new static(Str::studly($this->value)); } /** * Returns the portion of the string specified by the start and length parameters. * * @param int $start * @param null|int $length * @return static */ public function substr($start, $length = null) { return new static(Str::substr($this->value, $start, $length)); } /** * Returns the number of substring occurrences. * * @param string $needle * @param null|int $offset * @param null|int $length * @return int */ public function substrCount($needle, $offset = null, $length = null) { return Str::substrCount($this->value, $needle, $offset ?? 0, $length); } /** * Trim the string of the given characters. * * @param string $characters * @return static */ public function trim($characters = null) { return new static(trim(...array_merge([$this->value], func_get_args()))); } /** * Left trim the string of the given characters. * * @param string $characters * @return static */ public function ltrim($characters = null) { return new static(ltrim(...array_merge([$this->value], func_get_args()))); } /** * Right trim the string of the given characters. * * @param string $characters * @return static */ public function rtrim($characters = null) { return new static(rtrim(...array_merge([$this->value], func_get_args()))); } /** * Make a string's first character uppercase. * * @return static */ public function ucfirst() { return new static(Str::ucfirst($this->value)); } /** * Replaces the first or the last ones chars from a string by a given char. * * @param int $offset if is negative it starts from the end * @param string $replacement default is * * @return static */ public function mask(int $offset = 0, int $length = 0, string $replacement = '*') { return new static(Str::mask($this->value, $offset, $length, $replacement)); } /** * Execute the given callback if the string is empty. * * @param callable $callback * @param null|callable $default * @return static */ public function whenEmpty($callback, $default = null) { return $this->when($this->isEmpty(), $callback, $default); } /** * Execute the given callback if the string is not empty. * * @param callable $callback * @param null|callable $default * @return static */ public function whenNotEmpty($callback, $default = null) { return $this->when($this->isNotEmpty(), $callback, $default); } /** * Limit the number of words in a string. * * @param int $words * @param string $end * @return static */ public function words($words = 100, $end = '...') { return new static(Str::words($this->value, $words, $end)); } /** * Get the number of words a string contains. * * @return int */ public function wordCount() { return str_word_count($this->value); } /** * Convert the object to a string when JSON encoded. */ public function jsonSerialize(): mixed { return $this->__toString(); } /** * Determine if the given offset exists. */ public function offsetExists(mixed $offset): bool { return isset($this->value[$offset]); } /** * Get the value at the given offset. */ public function offsetGet(mixed $offset): string { return $this->value[$offset]; } /** * Set the value at the given offset. */ public function offsetSet(mixed $offset, mixed $value): void { $this->value[$offset] = $value; } /** * Unset the value at the given offset. */ public function offsetUnset(mixed $offset): void { unset($this->value[$offset]); } public function betweenFirst($from, $to): static { return new static(Str::betweenFirst($this->value, $from, $to)); } public function classNamespace(): static { return new static(Str::classNamespace($this->value)); } public function convertCase($mode = MB_CASE_FOLD, $encoding = 'UTF-8'): static { return new static(Str::convertCase($this->value, $mode, $encoding)); } public function excerpt($phrase = '', $options = []): ?string { return Str::excerpt($this->value, $phrase, $options); } public function isJson(): bool { return Str::isJson($this->value); } public function lcfirst(): static { return new static(Str::lcfirst($this->value)); } public function newLine($count = 1): static { return $this->append(str_repeat(PHP_EOL, $count)); } public function replaceStart($search, $replace): static { return new static(Str::replaceStart($search, $replace, $this->value)); } public function replaceEnd($search, $replace): static { return new static(Str::replaceEnd($search, $replace, $this->value)); } public function reverse(): static { return new static(Str::reverse($this->value)); } public function scan($format): Collection { return collect(sscanf($this->value, $format)); } public function squish(): static { return new static(Str::squish($this->value)); } public function substrReplace($replace, $offset = 0, $length = null): static { return new static(Str::substrReplace($this->value, $replace, $offset, $length)); } public function swap(array $map) { return new static(strtr($this->value, $map)); } public function toString(): string { return $this->value; } public function ucsplit(): Collection { return collect(Str::ucsplit($this->value)); } public function value(): string { return $this->toString(); } public function whenContains($needles, $callback, $default = null) { return $this->when($this->contains($needles), $callback, $default); } public function whenContainsAll(array $needles, $callback, $default = null) { return $this->when($this->containsAll($needles), $callback, $default); } public function whenEndsWith($needles, $callback, $default = null) { return $this->when($this->endsWith($needles), $callback, $default); } public function whenExactly($needles, $callback, $default = null) { return $this->when($this->exactly($needles), $callback, $default); } public function whenIs($pattern, $callback, $default = null) { return $this->when($this->is($pattern), $callback, $default); } public function whenIsUlid($callback, $default = null) { return $this->when($this->isUlid(), $callback, $default); } public function whenIsUuid($callback, $default = null) { return $this->when($this->isUuid(), $callback, $default); } public function whenNotExactly($needles, $callback, $default = null) { return $this->when(! $this->exactly($needles), $callback, $default); } public function whenStartsWith($needles, $callback, $default = null) { return $this->when($this->startsWith($needles), $callback, $default); } public function whenTest($pattern, $callback, $default = null) { return $this->when($this->test($pattern), $callback, $default); } public function wrap($before, $after = null) { return new static(Str::wrap($this->value, $before, $after)); } /** * Wrap a string to a given number of characters. * * @param mixed $characters * @param mixed $break * @param mixed $cutLongWords */ public function wordWrap($characters = 75, $break = "\n", $cutLongWords = false): static { return new static(Str::wordWrap($this->value, $characters, $break, $cutLongWords)); } }