helpers.php 27KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  1. <?php
  2. use Illuminate\Support\Arr;
  3. use Illuminate\Support\Str;
  4. use Illuminate\Support\Optional;
  5. use Illuminate\Support\Collection;
  6. use Illuminate\Support\Debug\Dumper;
  7. use Illuminate\Contracts\Support\Htmlable;
  8. use Illuminate\Support\HigherOrderTapProxy;
  9. if (! function_exists('append_config')) {
  10. /**
  11. * Assign high numeric IDs to a config item to force appending.
  12. *
  13. * @param array $array
  14. * @return array
  15. */
  16. function append_config(array $array)
  17. {
  18. $start = 9999;
  19. foreach ($array as $key => $value) {
  20. if (is_numeric($key)) {
  21. $start++;
  22. $array[$start] = Arr::pull($array, $key);
  23. }
  24. }
  25. return $array;
  26. }
  27. }
  28. if (! function_exists('array_add')) {
  29. /**
  30. * Add an element to an array using "dot" notation if it doesn't exist.
  31. *
  32. * @param array $array
  33. * @param string $key
  34. * @param mixed $value
  35. * @return array
  36. */
  37. function array_add($array, $key, $value)
  38. {
  39. return Arr::add($array, $key, $value);
  40. }
  41. }
  42. if (! function_exists('array_collapse')) {
  43. /**
  44. * Collapse an array of arrays into a single array.
  45. *
  46. * @param array $array
  47. * @return array
  48. */
  49. function array_collapse($array)
  50. {
  51. return Arr::collapse($array);
  52. }
  53. }
  54. if (! function_exists('array_divide')) {
  55. /**
  56. * Divide an array into two arrays. One with keys and the other with values.
  57. *
  58. * @param array $array
  59. * @return array
  60. */
  61. function array_divide($array)
  62. {
  63. return Arr::divide($array);
  64. }
  65. }
  66. if (! function_exists('array_dot')) {
  67. /**
  68. * Flatten a multi-dimensional associative array with dots.
  69. *
  70. * @param array $array
  71. * @param string $prepend
  72. * @return array
  73. */
  74. function array_dot($array, $prepend = '')
  75. {
  76. return Arr::dot($array, $prepend);
  77. }
  78. }
  79. if (! function_exists('array_except')) {
  80. /**
  81. * Get all of the given array except for a specified array of keys.
  82. *
  83. * @param array $array
  84. * @param array|string $keys
  85. * @return array
  86. */
  87. function array_except($array, $keys)
  88. {
  89. return Arr::except($array, $keys);
  90. }
  91. }
  92. if (! function_exists('array_first')) {
  93. /**
  94. * Return the first element in an array passing a given truth test.
  95. *
  96. * @param array $array
  97. * @param callable|null $callback
  98. * @param mixed $default
  99. * @return mixed
  100. */
  101. function array_first($array, callable $callback = null, $default = null)
  102. {
  103. return Arr::first($array, $callback, $default);
  104. }
  105. }
  106. if (! function_exists('array_flatten')) {
  107. /**
  108. * Flatten a multi-dimensional array into a single level.
  109. *
  110. * @param array $array
  111. * @param int $depth
  112. * @return array
  113. */
  114. function array_flatten($array, $depth = INF)
  115. {
  116. return Arr::flatten($array, $depth);
  117. }
  118. }
  119. if (! function_exists('array_forget')) {
  120. /**
  121. * Remove one or many array items from a given array using "dot" notation.
  122. *
  123. * @param array $array
  124. * @param array|string $keys
  125. * @return void
  126. */
  127. function array_forget(&$array, $keys)
  128. {
  129. return Arr::forget($array, $keys);
  130. }
  131. }
  132. if (! function_exists('array_get')) {
  133. /**
  134. * Get an item from an array using "dot" notation.
  135. *
  136. * @param \ArrayAccess|array $array
  137. * @param string $key
  138. * @param mixed $default
  139. * @return mixed
  140. */
  141. function array_get($array, $key, $default = null)
  142. {
  143. return Arr::get($array, $key, $default);
  144. }
  145. }
  146. if (! function_exists('array_has')) {
  147. /**
  148. * Check if an item or items exist in an array using "dot" notation.
  149. *
  150. * @param \ArrayAccess|array $array
  151. * @param string|array $keys
  152. * @return bool
  153. */
  154. function array_has($array, $keys)
  155. {
  156. return Arr::has($array, $keys);
  157. }
  158. }
  159. if (! function_exists('array_last')) {
  160. /**
  161. * Return the last element in an array passing a given truth test.
  162. *
  163. * @param array $array
  164. * @param callable|null $callback
  165. * @param mixed $default
  166. * @return mixed
  167. */
  168. function array_last($array, callable $callback = null, $default = null)
  169. {
  170. return Arr::last($array, $callback, $default);
  171. }
  172. }
  173. if (! function_exists('array_only')) {
  174. /**
  175. * Get a subset of the items from the given array.
  176. *
  177. * @param array $array
  178. * @param array|string $keys
  179. * @return array
  180. */
  181. function array_only($array, $keys)
  182. {
  183. return Arr::only($array, $keys);
  184. }
  185. }
  186. if (! function_exists('array_pluck')) {
  187. /**
  188. * Pluck an array of values from an array.
  189. *
  190. * @param array $array
  191. * @param string|array $value
  192. * @param string|array|null $key
  193. * @return array
  194. */
  195. function array_pluck($array, $value, $key = null)
  196. {
  197. return Arr::pluck($array, $value, $key);
  198. }
  199. }
  200. if (! function_exists('array_prepend')) {
  201. /**
  202. * Push an item onto the beginning of an array.
  203. *
  204. * @param array $array
  205. * @param mixed $value
  206. * @param mixed $key
  207. * @return array
  208. */
  209. function array_prepend($array, $value, $key = null)
  210. {
  211. return Arr::prepend($array, $value, $key);
  212. }
  213. }
  214. if (! function_exists('array_pull')) {
  215. /**
  216. * Get a value from the array, and remove it.
  217. *
  218. * @param array $array
  219. * @param string $key
  220. * @param mixed $default
  221. * @return mixed
  222. */
  223. function array_pull(&$array, $key, $default = null)
  224. {
  225. return Arr::pull($array, $key, $default);
  226. }
  227. }
  228. if (! function_exists('array_random')) {
  229. /**
  230. * Get a random value from an array.
  231. *
  232. * @param array $array
  233. * @param int|null $num
  234. * @return mixed
  235. */
  236. function array_random($array, $num = null)
  237. {
  238. return Arr::random($array, $num);
  239. }
  240. }
  241. if (! function_exists('array_set')) {
  242. /**
  243. * Set an array item to a given value using "dot" notation.
  244. *
  245. * If no key is given to the method, the entire array will be replaced.
  246. *
  247. * @param array $array
  248. * @param string $key
  249. * @param mixed $value
  250. * @return array
  251. */
  252. function array_set(&$array, $key, $value)
  253. {
  254. return Arr::set($array, $key, $value);
  255. }
  256. }
  257. if (! function_exists('array_sort')) {
  258. /**
  259. * Sort the array by the given callback or attribute name.
  260. *
  261. * @param array $array
  262. * @param callable|string|null $callback
  263. * @return array
  264. */
  265. function array_sort($array, $callback = null)
  266. {
  267. return Arr::sort($array, $callback);
  268. }
  269. }
  270. if (! function_exists('array_sort_recursive')) {
  271. /**
  272. * Recursively sort an array by keys and values.
  273. *
  274. * @param array $array
  275. * @return array
  276. */
  277. function array_sort_recursive($array)
  278. {
  279. return Arr::sortRecursive($array);
  280. }
  281. }
  282. if (! function_exists('array_where')) {
  283. /**
  284. * Filter the array using the given callback.
  285. *
  286. * @param array $array
  287. * @param callable $callback
  288. * @return array
  289. */
  290. function array_where($array, callable $callback)
  291. {
  292. return Arr::where($array, $callback);
  293. }
  294. }
  295. if (! function_exists('array_wrap')) {
  296. /**
  297. * If the given value is not an array, wrap it in one.
  298. *
  299. * @param mixed $value
  300. * @return array
  301. */
  302. function array_wrap($value)
  303. {
  304. return Arr::wrap($value);
  305. }
  306. }
  307. if (! function_exists('blank')) {
  308. /**
  309. * Determine if the given value is "blank".
  310. *
  311. * @param mixed $value
  312. * @return bool
  313. */
  314. function blank($value)
  315. {
  316. if (is_null($value)) {
  317. return true;
  318. }
  319. if (is_string($value)) {
  320. return trim($value) === '';
  321. }
  322. if (is_numeric($value) || is_bool($value)) {
  323. return false;
  324. }
  325. if ($value instanceof Countable) {
  326. return count($value) === 0;
  327. }
  328. return empty($value);
  329. }
  330. }
  331. if (! function_exists('camel_case')) {
  332. /**
  333. * Convert a value to camel case.
  334. *
  335. * @param string $value
  336. * @return string
  337. */
  338. function camel_case($value)
  339. {
  340. return Str::camel($value);
  341. }
  342. }
  343. if (! function_exists('class_basename')) {
  344. /**
  345. * Get the class "basename" of the given object / class.
  346. *
  347. * @param string|object $class
  348. * @return string
  349. */
  350. function class_basename($class)
  351. {
  352. $class = is_object($class) ? get_class($class) : $class;
  353. return basename(str_replace('\\', '/', $class));
  354. }
  355. }
  356. if (! function_exists('class_uses_recursive')) {
  357. /**
  358. * Returns all traits used by a class, its parent classes and trait of their traits.
  359. *
  360. * @param object|string $class
  361. * @return array
  362. */
  363. function class_uses_recursive($class)
  364. {
  365. if (is_object($class)) {
  366. $class = get_class($class);
  367. }
  368. $results = [];
  369. foreach (array_reverse(class_parents($class)) + [$class => $class] as $class) {
  370. $results += trait_uses_recursive($class);
  371. }
  372. return array_unique($results);
  373. }
  374. }
  375. if (! function_exists('collect')) {
  376. /**
  377. * Create a collection from the given value.
  378. *
  379. * @param mixed $value
  380. * @return \Illuminate\Support\Collection
  381. */
  382. function collect($value = null)
  383. {
  384. return new Collection($value);
  385. }
  386. }
  387. if (! function_exists('data_fill')) {
  388. /**
  389. * Fill in data where it's missing.
  390. *
  391. * @param mixed $target
  392. * @param string|array $key
  393. * @param mixed $value
  394. * @return mixed
  395. */
  396. function data_fill(&$target, $key, $value)
  397. {
  398. return data_set($target, $key, $value, false);
  399. }
  400. }
  401. if (! function_exists('data_get')) {
  402. /**
  403. * Get an item from an array or object using "dot" notation.
  404. *
  405. * @param mixed $target
  406. * @param string|array $key
  407. * @param mixed $default
  408. * @return mixed
  409. */
  410. function data_get($target, $key, $default = null)
  411. {
  412. if (is_null($key)) {
  413. return $target;
  414. }
  415. $key = is_array($key) ? $key : explode('.', $key);
  416. while (! is_null($segment = array_shift($key))) {
  417. if ($segment === '*') {
  418. if ($target instanceof Collection) {
  419. $target = $target->all();
  420. } elseif (! is_array($target)) {
  421. return value($default);
  422. }
  423. $result = Arr::pluck($target, $key);
  424. return in_array('*', $key) ? Arr::collapse($result) : $result;
  425. }
  426. if (Arr::accessible($target) && Arr::exists($target, $segment)) {
  427. $target = $target[$segment];
  428. } elseif (is_object($target) && isset($target->{$segment})) {
  429. $target = $target->{$segment};
  430. } else {
  431. return value($default);
  432. }
  433. }
  434. return $target;
  435. }
  436. }
  437. if (! function_exists('data_set')) {
  438. /**
  439. * Set an item on an array or object using dot notation.
  440. *
  441. * @param mixed $target
  442. * @param string|array $key
  443. * @param mixed $value
  444. * @param bool $overwrite
  445. * @return mixed
  446. */
  447. function data_set(&$target, $key, $value, $overwrite = true)
  448. {
  449. $segments = is_array($key) ? $key : explode('.', $key);
  450. if (($segment = array_shift($segments)) === '*') {
  451. if (! Arr::accessible($target)) {
  452. $target = [];
  453. }
  454. if ($segments) {
  455. foreach ($target as &$inner) {
  456. data_set($inner, $segments, $value, $overwrite);
  457. }
  458. } elseif ($overwrite) {
  459. foreach ($target as &$inner) {
  460. $inner = $value;
  461. }
  462. }
  463. } elseif (Arr::accessible($target)) {
  464. if ($segments) {
  465. if (! Arr::exists($target, $segment)) {
  466. $target[$segment] = [];
  467. }
  468. data_set($target[$segment], $segments, $value, $overwrite);
  469. } elseif ($overwrite || ! Arr::exists($target, $segment)) {
  470. $target[$segment] = $value;
  471. }
  472. } elseif (is_object($target)) {
  473. if ($segments) {
  474. if (! isset($target->{$segment})) {
  475. $target->{$segment} = [];
  476. }
  477. data_set($target->{$segment}, $segments, $value, $overwrite);
  478. } elseif ($overwrite || ! isset($target->{$segment})) {
  479. $target->{$segment} = $value;
  480. }
  481. } else {
  482. $target = [];
  483. if ($segments) {
  484. data_set($target[$segment], $segments, $value, $overwrite);
  485. } elseif ($overwrite) {
  486. $target[$segment] = $value;
  487. }
  488. }
  489. return $target;
  490. }
  491. }
  492. if (! function_exists('dd')) {
  493. /**
  494. * Dump the passed variables and end the script.
  495. *
  496. * @param mixed $args
  497. * @return void
  498. */
  499. function dd(...$args)
  500. {
  501. foreach ($args as $x) {
  502. (new Dumper)->dump($x);
  503. }
  504. die(1);
  505. }
  506. }
  507. if (! function_exists('e')) {
  508. /**
  509. * Escape HTML special characters in a string.
  510. *
  511. * @param \Illuminate\Contracts\Support\Htmlable|string $value
  512. * @param bool $doubleEncode
  513. * @return string
  514. */
  515. function e($value, $doubleEncode = true)
  516. {
  517. if ($value instanceof Htmlable) {
  518. return $value->toHtml();
  519. }
  520. return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', $doubleEncode);
  521. }
  522. }
  523. if (! function_exists('ends_with')) {
  524. /**
  525. * Determine if a given string ends with a given substring.
  526. *
  527. * @param string $haystack
  528. * @param string|array $needles
  529. * @return bool
  530. */
  531. function ends_with($haystack, $needles)
  532. {
  533. return Str::endsWith($haystack, $needles);
  534. }
  535. }
  536. if (! function_exists('env')) {
  537. /**
  538. * Gets the value of an environment variable.
  539. *
  540. * @param string $key
  541. * @param mixed $default
  542. * @return mixed
  543. */
  544. function env($key, $default = null)
  545. {
  546. $value = getenv($key);
  547. if ($value === false) {
  548. return value($default);
  549. }
  550. switch (strtolower($value)) {
  551. case 'true':
  552. case '(true)':
  553. return true;
  554. case 'false':
  555. case '(false)':
  556. return false;
  557. case 'empty':
  558. case '(empty)':
  559. return '';
  560. case 'null':
  561. case '(null)':
  562. return;
  563. }
  564. if (($valueLength = strlen($value)) > 1 && $value[0] === '"' && $value[$valueLength - 1] === '"') {
  565. return substr($value, 1, -1);
  566. }
  567. return $value;
  568. }
  569. }
  570. if (! function_exists('filled')) {
  571. /**
  572. * Determine if a value is "filled".
  573. *
  574. * @param mixed $value
  575. * @return bool
  576. */
  577. function filled($value)
  578. {
  579. return ! blank($value);
  580. }
  581. }
  582. if (! function_exists('head')) {
  583. /**
  584. * Get the first element of an array. Useful for method chaining.
  585. *
  586. * @param array $array
  587. * @return mixed
  588. */
  589. function head($array)
  590. {
  591. return reset($array);
  592. }
  593. }
  594. if (! function_exists('kebab_case')) {
  595. /**
  596. * Convert a string to kebab case.
  597. *
  598. * @param string $value
  599. * @return string
  600. */
  601. function kebab_case($value)
  602. {
  603. return Str::kebab($value);
  604. }
  605. }
  606. if (! function_exists('last')) {
  607. /**
  608. * Get the last element from an array.
  609. *
  610. * @param array $array
  611. * @return mixed
  612. */
  613. function last($array)
  614. {
  615. return end($array);
  616. }
  617. }
  618. if (! function_exists('object_get')) {
  619. /**
  620. * Get an item from an object using "dot" notation.
  621. *
  622. * @param object $object
  623. * @param string $key
  624. * @param mixed $default
  625. * @return mixed
  626. */
  627. function object_get($object, $key, $default = null)
  628. {
  629. if (is_null($key) || trim($key) == '') {
  630. return $object;
  631. }
  632. foreach (explode('.', $key) as $segment) {
  633. if (! is_object($object) || ! isset($object->{$segment})) {
  634. return value($default);
  635. }
  636. $object = $object->{$segment};
  637. }
  638. return $object;
  639. }
  640. }
  641. if (! function_exists('optional')) {
  642. /**
  643. * Provide access to optional objects.
  644. *
  645. * @param mixed $value
  646. * @param callable|null $callback
  647. * @return mixed
  648. */
  649. function optional($value = null, callable $callback = null)
  650. {
  651. if (is_null($callback)) {
  652. return new Optional($value);
  653. } elseif (! is_null($value)) {
  654. return $callback($value);
  655. }
  656. }
  657. }
  658. if (! function_exists('preg_replace_array')) {
  659. /**
  660. * Replace a given pattern with each value in the array in sequentially.
  661. *
  662. * @param string $pattern
  663. * @param array $replacements
  664. * @param string $subject
  665. * @return string
  666. */
  667. function preg_replace_array($pattern, array $replacements, $subject)
  668. {
  669. return preg_replace_callback($pattern, function () use (&$replacements) {
  670. foreach ($replacements as $key => $value) {
  671. return array_shift($replacements);
  672. }
  673. }, $subject);
  674. }
  675. }
  676. if (! function_exists('retry')) {
  677. /**
  678. * Retry an operation a given number of times.
  679. *
  680. * @param int $times
  681. * @param callable $callback
  682. * @param int $sleep
  683. * @return mixed
  684. *
  685. * @throws \Exception
  686. */
  687. function retry($times, callable $callback, $sleep = 0)
  688. {
  689. $times--;
  690. beginning:
  691. try {
  692. return $callback();
  693. } catch (Exception $e) {
  694. if (! $times) {
  695. throw $e;
  696. }
  697. $times--;
  698. if ($sleep) {
  699. usleep($sleep * 1000);
  700. }
  701. goto beginning;
  702. }
  703. }
  704. }
  705. if (! function_exists('snake_case')) {
  706. /**
  707. * Convert a string to snake case.
  708. *
  709. * @param string $value
  710. * @param string $delimiter
  711. * @return string
  712. */
  713. function snake_case($value, $delimiter = '_')
  714. {
  715. return Str::snake($value, $delimiter);
  716. }
  717. }
  718. if (! function_exists('starts_with')) {
  719. /**
  720. * Determine if a given string starts with a given substring.
  721. *
  722. * @param string $haystack
  723. * @param string|array $needles
  724. * @return bool
  725. */
  726. function starts_with($haystack, $needles)
  727. {
  728. return Str::startsWith($haystack, $needles);
  729. }
  730. }
  731. if (! function_exists('str_after')) {
  732. /**
  733. * Return the remainder of a string after a given value.
  734. *
  735. * @param string $subject
  736. * @param string $search
  737. * @return string
  738. */
  739. function str_after($subject, $search)
  740. {
  741. return Str::after($subject, $search);
  742. }
  743. }
  744. if (! function_exists('str_before')) {
  745. /**
  746. * Get the portion of a string before a given value.
  747. *
  748. * @param string $subject
  749. * @param string $search
  750. * @return string
  751. */
  752. function str_before($subject, $search)
  753. {
  754. return Str::before($subject, $search);
  755. }
  756. }
  757. if (! function_exists('str_contains')) {
  758. /**
  759. * Determine if a given string contains a given substring.
  760. *
  761. * @param string $haystack
  762. * @param string|array $needles
  763. * @return bool
  764. */
  765. function str_contains($haystack, $needles)
  766. {
  767. return Str::contains($haystack, $needles);
  768. }
  769. }
  770. if (! function_exists('str_finish')) {
  771. /**
  772. * Cap a string with a single instance of a given value.
  773. *
  774. * @param string $value
  775. * @param string $cap
  776. * @return string
  777. */
  778. function str_finish($value, $cap)
  779. {
  780. return Str::finish($value, $cap);
  781. }
  782. }
  783. if (! function_exists('str_is')) {
  784. /**
  785. * Determine if a given string matches a given pattern.
  786. *
  787. * @param string|array $pattern
  788. * @param string $value
  789. * @return bool
  790. */
  791. function str_is($pattern, $value)
  792. {
  793. return Str::is($pattern, $value);
  794. }
  795. }
  796. if (! function_exists('str_limit')) {
  797. /**
  798. * Limit the number of characters in a string.
  799. *
  800. * @param string $value
  801. * @param int $limit
  802. * @param string $end
  803. * @return string
  804. */
  805. function str_limit($value, $limit = 100, $end = '...')
  806. {
  807. return Str::limit($value, $limit, $end);
  808. }
  809. }
  810. if (! function_exists('str_plural')) {
  811. /**
  812. * Get the plural form of an English word.
  813. *
  814. * @param string $value
  815. * @param int $count
  816. * @return string
  817. */
  818. function str_plural($value, $count = 2)
  819. {
  820. return Str::plural($value, $count);
  821. }
  822. }
  823. if (! function_exists('str_random')) {
  824. /**
  825. * Generate a more truly "random" alpha-numeric string.
  826. *
  827. * @param int $length
  828. * @return string
  829. *
  830. * @throws \RuntimeException
  831. */
  832. function str_random($length = 16)
  833. {
  834. return Str::random($length);
  835. }
  836. }
  837. if (! function_exists('str_replace_array')) {
  838. /**
  839. * Replace a given value in the string sequentially with an array.
  840. *
  841. * @param string $search
  842. * @param array $replace
  843. * @param string $subject
  844. * @return string
  845. */
  846. function str_replace_array($search, array $replace, $subject)
  847. {
  848. return Str::replaceArray($search, $replace, $subject);
  849. }
  850. }
  851. if (! function_exists('str_replace_first')) {
  852. /**
  853. * Replace the first occurrence of a given value in the string.
  854. *
  855. * @param string $search
  856. * @param string $replace
  857. * @param string $subject
  858. * @return string
  859. */
  860. function str_replace_first($search, $replace, $subject)
  861. {
  862. return Str::replaceFirst($search, $replace, $subject);
  863. }
  864. }
  865. if (! function_exists('str_replace_last')) {
  866. /**
  867. * Replace the last occurrence of a given value in the string.
  868. *
  869. * @param string $search
  870. * @param string $replace
  871. * @param string $subject
  872. * @return string
  873. */
  874. function str_replace_last($search, $replace, $subject)
  875. {
  876. return Str::replaceLast($search, $replace, $subject);
  877. }
  878. }
  879. if (! function_exists('str_singular')) {
  880. /**
  881. * Get the singular form of an English word.
  882. *
  883. * @param string $value
  884. * @return string
  885. */
  886. function str_singular($value)
  887. {
  888. return Str::singular($value);
  889. }
  890. }
  891. if (! function_exists('str_slug')) {
  892. /**
  893. * Generate a URL friendly "slug" from a given string.
  894. *
  895. * @param string $title
  896. * @param string $separator
  897. * @param string $language
  898. * @return string
  899. */
  900. function str_slug($title, $separator = '-', $language = 'en')
  901. {
  902. return Str::slug($title, $separator, $language);
  903. }
  904. }
  905. if (! function_exists('str_start')) {
  906. /**
  907. * Begin a string with a single instance of a given value.
  908. *
  909. * @param string $value
  910. * @param string $prefix
  911. * @return string
  912. */
  913. function str_start($value, $prefix)
  914. {
  915. return Str::start($value, $prefix);
  916. }
  917. }
  918. if (! function_exists('studly_case')) {
  919. /**
  920. * Convert a value to studly caps case.
  921. *
  922. * @param string $value
  923. * @return string
  924. */
  925. function studly_case($value)
  926. {
  927. return Str::studly($value);
  928. }
  929. }
  930. if (! function_exists('tap')) {
  931. /**
  932. * Call the given Closure with the given value then return the value.
  933. *
  934. * @param mixed $value
  935. * @param callable|null $callback
  936. * @return mixed
  937. */
  938. function tap($value, $callback = null)
  939. {
  940. if (is_null($callback)) {
  941. return new HigherOrderTapProxy($value);
  942. }
  943. $callback($value);
  944. return $value;
  945. }
  946. }
  947. if (! function_exists('throw_if')) {
  948. /**
  949. * Throw the given exception if the given condition is true.
  950. *
  951. * @param mixed $condition
  952. * @param \Throwable|string $exception
  953. * @param array ...$parameters
  954. * @return mixed
  955. * @throws \Throwable
  956. */
  957. function throw_if($condition, $exception, ...$parameters)
  958. {
  959. if ($condition) {
  960. throw (is_string($exception) ? new $exception(...$parameters) : $exception);
  961. }
  962. return $condition;
  963. }
  964. }
  965. if (! function_exists('throw_unless')) {
  966. /**
  967. * Throw the given exception unless the given condition is true.
  968. *
  969. * @param mixed $condition
  970. * @param \Throwable|string $exception
  971. * @param array ...$parameters
  972. * @return mixed
  973. * @throws \Throwable
  974. */
  975. function throw_unless($condition, $exception, ...$parameters)
  976. {
  977. if (! $condition) {
  978. throw (is_string($exception) ? new $exception(...$parameters) : $exception);
  979. }
  980. return $condition;
  981. }
  982. }
  983. if (! function_exists('title_case')) {
  984. /**
  985. * Convert a value to title case.
  986. *
  987. * @param string $value
  988. * @return string
  989. */
  990. function title_case($value)
  991. {
  992. return Str::title($value);
  993. }
  994. }
  995. if (! function_exists('trait_uses_recursive')) {
  996. /**
  997. * Returns all traits used by a trait and its traits.
  998. *
  999. * @param string $trait
  1000. * @return array
  1001. */
  1002. function trait_uses_recursive($trait)
  1003. {
  1004. $traits = class_uses($trait);
  1005. foreach ($traits as $trait) {
  1006. $traits += trait_uses_recursive($trait);
  1007. }
  1008. return $traits;
  1009. }
  1010. }
  1011. if (! function_exists('transform')) {
  1012. /**
  1013. * Transform the given value if it is present.
  1014. *
  1015. * @param mixed $value
  1016. * @param callable $callback
  1017. * @param mixed $default
  1018. * @return mixed|null
  1019. */
  1020. function transform($value, callable $callback, $default = null)
  1021. {
  1022. if (filled($value)) {
  1023. return $callback($value);
  1024. }
  1025. if (is_callable($default)) {
  1026. return $default($value);
  1027. }
  1028. return $default;
  1029. }
  1030. }
  1031. if (! function_exists('value')) {
  1032. /**
  1033. * Return the default value of the given value.
  1034. *
  1035. * @param mixed $value
  1036. * @return mixed
  1037. */
  1038. function value($value)
  1039. {
  1040. return $value instanceof Closure ? $value() : $value;
  1041. }
  1042. }
  1043. if (! function_exists('windows_os')) {
  1044. /**
  1045. * Determine whether the current environment is Windows based.
  1046. *
  1047. * @return bool
  1048. */
  1049. function windows_os()
  1050. {
  1051. return strtolower(substr(PHP_OS, 0, 3)) === 'win';
  1052. }
  1053. }
  1054. if (! function_exists('with')) {
  1055. /**
  1056. * Return the given value, optionally passed through the given callback.
  1057. *
  1058. * @param mixed $value
  1059. * @param callable|null $callback
  1060. * @return mixed
  1061. */
  1062. function with($value, callable $callback = null)
  1063. {
  1064. return is_null($callback) ? $value : $callback($value);
  1065. }
  1066. }