<?php namespace Illuminate\Support; use RuntimeException; use Stringy\StaticStringy; use Illuminate\Support\Traits\Macroable; class Str { use Macroable; /** * The cache of snake-cased words. * * @var array */ protected static $snakeCache = []; /** * The cache of camel-cased words. * * @var array */ protected static $camelCache = []; /** * The cache of studly-cased words. * * @var array */ protected static $studlyCache = []; /** * Transliterate a UTF-8 value to ASCII. * * @param string $value * @return string */ public static function ascii($value) { return StaticStringy::toAscii($value); } /** * Convert a value to camel case. * * @param string $value * @return string */ public static function camel($value) { if (isset(static::$camelCache[$value])) { return static::$camelCache[$value]; } return static::$camelCache[$value] = lcfirst(static::studly($value)); } /** * Determine if a given string contains a given substring. * * @param string $haystack * @param string|array $needles * @return bool */ public static function contains($haystack, $needles) { foreach ((array) $needles as $needle) { if ($needle != '' && strpos($haystack, $needle) !== false) return true; } return false; } /** * Determine if a given string ends with a given substring. * * @param string $haystack * @param string|array $needles * @return bool */ public static function endsWith($haystack, $needles) { foreach ((array) $needles as $needle) { if ((string) $needle === substr($haystack, -strlen($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.')+$/', '', $value).$cap; } /** * Determine if a given string matches a given pattern. * * @param string $pattern * @param string $value * @return bool */ public static function is($pattern, $value) { 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).'\z'; return (bool) preg_match('#^'.$pattern.'#', $value); } /** * Return the length of the given string. * * @param string $value * @return int */ public static function length($value) { return mb_strlen($value); } /** * 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_strlen($value) <= $limit) return $value; return rtrim(mb_substr($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); } /** * Limit the number of words in a string. * * @param string $value * @param int $words * @param string $end * @return string */ public static function words($value, $words = 100, $end = '...') { preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/u', $value, $matches); if ( ! isset($matches[0]) || strlen($value) === strlen($matches[0])) return $value; return rtrim($matches[0]).$end; } /** * Parse a Class@method style callback into class and method. * * @param string $callback * @param string $default * @return array */ public static function parseCallback($callback, $default) { return static::contains($callback, '@') ? explode('@', $callback, 2) : array($callback, $default); } /** * Get the plural form of an English word. * * @param string $value * @param int $count * @return string */ public static function plural($value, $count = 2) { return Pluralizer::plural($value, $count); } /** * Generate a more truly "random" alpha-numeric string. * * @param int $length * @return string * * @throws \RuntimeException */ public static function random($length = 16) { if ( ! function_exists('openssl_random_pseudo_bytes')) { throw new RuntimeException('OpenSSL extension is required.'); } $bytes = openssl_random_pseudo_bytes($length * 2); if ($bytes === false) { throw new RuntimeException('Unable to generate random string.'); } return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $length); } /** * Generate a "random" alpha-numeric string. * * Should not be considered sufficient for cryptography, etc. * * @param int $length * @return string */ public static function quickRandom($length = 16) { $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; return substr(str_shuffle(str_repeat($pool, $length)), 0, $length); } /** * Convert the given string to upper-case. * * @param string $value * @return string */ public static function upper($value) { return mb_strtoupper($value); } /** * Convert the given string to title case. * * @param string $value * @return string */ public static function title($value) { return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8'); } /** * Get the singular form of an English word. * * @param string $value * @return string */ public static function singular($value) { return Pluralizer::singular($value); } /** * Generate a URL friendly "slug" from a given string. * * @param string $title * @param string $separator * @return string */ public static function slug($title, $separator = '-') { $title = static::ascii($title); // Convert all dashes/underscores into separator $flip = $separator == '-' ? '_' : '-'; $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $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. * * @param string $value * @param string $delimiter * @return string */ public static function snake($value, $delimiter = '_') { $key = $value.$delimiter; if (isset(static::$snakeCache[$key])) { return static::$snakeCache[$key]; } if ( ! ctype_lower($value)) { $value = strtolower(preg_replace('/(.)(?=[A-Z])/', '$1'.$delimiter, $value)); } return static::$snakeCache[$key] = $value; } /** * Determine if a given string starts with a given substring. * * @param string $haystack * @param string|array $needles * @return bool */ public static function startsWith($haystack, $needles) { foreach ((array) $needles as $needle) { if ($needle != '' && strpos($haystack, $needle) === 0) return true; } return false; } /** * Convert a value to studly caps case. * * @param string $value * @return string */ public static function studly($value) { $key = $value; if (isset(static::$studlyCache[$key])) { return static::$studlyCache[$key]; } $value = ucwords(str_replace(array('-', '_'), ' ', $value)); return static::$studlyCache[$key] = str_replace(' ', '', $value); } }