1 <?php
2
3 namespace Docolight\Support;
4
5 use RuntimeException;
6 use Docolight\Support\Traits\Macroable;
7
8 9 10 11 12
13 class Str
14 {
15 use Macroable;
16
17 18 19 20 21
22 protected static $snakeCache = [];
23
24 25 26 27 28
29 protected static $camelCache = [];
30
31 32 33 34 35
36 protected static $studlyCache = [];
37
38 39 40 41 42 43 44
45 public static function camel($value)
46 {
47 if (isset(static::$camelCache[$value])) {
48 return static::$camelCache[$value];
49 }
50
51 return static::$camelCache[$value] = lcfirst(static::studly($value));
52 }
53
54 55 56 57 58 59 60 61
62 public static function contains($haystack, $needles)
63 {
64 foreach ((array) $needles as $needle) {
65 if ($needle != '' and strpos($haystack, $needle) !== false) {
66 return true;
67 }
68 }
69
70 return false;
71 }
72
73 74 75 76 77 78 79 80
81 public static function endsWith($haystack, $needles)
82 {
83 foreach ((array) $needles as $needle) {
84 if ((string) $needle === substr($haystack, -strlen($needle))) {
85 return true;
86 }
87 }
88
89 return false;
90 }
91
92 93 94 95 96 97 98 99
100 public static function finish($value, $cap)
101 {
102 $quoted = preg_quote($cap, '/');
103
104 return preg_replace('/(?:'.$quoted.')+$/', '', $value).$cap;
105 }
106
107 108 109 110 111 112 113 114
115 public static function is($pattern, $value)
116 {
117 if ($pattern == $value) {
118 return true;
119 }
120
121 $pattern = preg_quote($pattern, '#');
122
123
124
125
126 $pattern = str_replace('\*', '.*', $pattern).'\z';
127
128 return (bool) preg_match('#^'.$pattern.'#', $value);
129 }
130
131 132 133 134 135 136 137
138 public static function length($value)
139 {
140 return mb_strlen($value);
141 }
142
143 144 145 146 147 148 149 150 151
152 public static function limit($value, $limit = 100, $end = '...')
153 {
154 if (mb_strwidth($value, 'UTF-8') <= $limit) {
155 return $value;
156 }
157
158 return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')).$end;
159 }
160
161 162 163 164 165 166 167
168 public static function lower($value)
169 {
170 return mb_strtolower($value);
171 }
172
173 174 175 176 177 178 179 180 181
182 public static function words($value, $words = 100, $end = '...')
183 {
184 preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/u', $value, $matches);
185
186 if (!isset($matches[0]) || strlen($value) === strlen($matches[0])) {
187 return $value;
188 }
189
190 return rtrim($matches[0]).$end;
191 }
192
193 194 195 196 197 198 199 200
201 public static function parseCallback($callback, $default)
202 {
203 return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default];
204 }
205
206 207 208 209 210 211 212 213 214
215 public static function random($length = 16)
216 {
217 $string = '';
218
219 while (($len = strlen($string)) < $length) {
220 $size = $length - $len;
221
222 $bytes = static::randomBytes($size);
223
224 $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
225 }
226
227 return $string;
228 }
229
230 231 232 233 234 235 236 237 238
239 public static function randomBytes($length = 16)
240 {
241 if (function_exists('random_bytes')) {
242 $bytes = random_bytes($length);
243 } elseif (function_exists('openssl_random_pseudo_bytes')) {
244 $bytes = openssl_random_pseudo_bytes($length, $strong);
245 if ($bytes === false || $strong === false) {
246 throw new RuntimeException('Unable to generate random string.');
247 }
248 } else {
249 throw new RuntimeException('OpenSSL extension is required for PHP 5 users.');
250 }
251
252 return $bytes;
253 }
254
255 256 257 258 259 260 261 262 263
264 public static function quickRandom($length = 16)
265 {
266 $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
267
268 return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
269 }
270
271 272 273 274 275 276 277 278 279 280 281 282
283 public static function equals($knownString, $userInput)
284 {
285 if (!is_string($knownString)) {
286 $knownString = (string) $knownString;
287 }
288
289 if (!is_string($userInput)) {
290 $userInput = (string) $userInput;
291 }
292
293 if (function_exists('hash_equals')) {
294 return hash_equals($knownString, $userInput);
295 }
296
297 $knownLength = mb_strlen($knownString);
298
299 if (mb_strlen($userInput) !== $knownLength) {
300 return false;
301 }
302
303 $result = 0;
304
305 for ($i = 0; $i < $knownLength; ++$i) {
306 $result |= (ord($knownString[$i]) ^ ord($userInput[$i]));
307 }
308
309 return 0 === $result;
310 }
311
312 313 314 315 316 317 318
319 public static function upper($value)
320 {
321 return mb_strtoupper($value);
322 }
323
324 325 326 327 328 329 330
331 public static function title($value)
332 {
333 return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
334 }
335
336 337 338 339 340 341 342 343
344 public static function slug($title, $separator = '-')
345 {
346 $title = static::ascii($title);
347
348
349 $flip = $separator == '-' ? '_' : '-';
350
351 $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);
352
353
354 $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', mb_strtolower($title));
355
356
357 $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
358
359 return trim($title, $separator);
360 }
361
362 363 364 365 366 367 368 369
370 public static function snake($value, $delimiter = '_')
371 {
372 $key = $value.$delimiter;
373
374 if (isset(static::$snakeCache[$key])) {
375 return static::$snakeCache[$key];
376 }
377
378 if (!ctype_lower($value)) {
379 $value = strtolower(preg_replace('/(.)(?=[A-Z])/', '$1'.$delimiter, $value));
380 }
381
382 return static::$snakeCache[$key] = $value;
383 }
384
385 386 387 388 389 390 391 392
393 public static function startsWith($haystack, $needles)
394 {
395 foreach ((array) $needles as $needle) {
396 if ($needle != '' and strpos($haystack, $needle) === 0) {
397 return true;
398 }
399 }
400
401 return false;
402 }
403
404 405 406 407 408 409 410
411 public static function studly($value)
412 {
413 $key = $value;
414
415 if (isset(static::$studlyCache[$key])) {
416 return static::$studlyCache[$key];
417 }
418
419 $value = ucwords(str_replace(['-', '_'], ' ', $value));
420
421 return static::$studlyCache[$key] = str_replace(' ', '', $value);
422 }
423
424 425 426 427 428 429 430 431
432 public static function first($string, $separator)
433 {
434 return trim(head(explode($separator, $string)));
435 }
436
437 438 439 440 441 442 443 444
445 public static function last($string, $separator)
446 {
447 return trim(last(explode($separator, $string)));
448 }
449 }
450