helpers.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  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 subclasses 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_merge([$class => $class], class_parents($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. http_response_code(500);
  502. foreach ($args as $x) {
  503. (new Dumper)->dump($x);
  504. }
  505. die(1);
  506. }
  507. }
  508. if (! function_exists('e')) {
  509. /**
  510. * Escape HTML special characters in a string.
  511. *
  512. * @param \Illuminate\Contracts\Support\Htmlable|string $value
  513. * @param bool $doubleEncode
  514. * @return string
  515. */
  516. function e($value, $doubleEncode = false)
  517. {
  518. if ($value instanceof Htmlable) {
  519. return $value->toHtml();
  520. }
  521. return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', $doubleEncode);
  522. }
  523. }
  524. if (! function_exists('ends_with')) {
  525. /**
  526. * Determine if a given string ends with a given substring.
  527. *
  528. * @param string $haystack
  529. * @param string|array $needles
  530. * @return bool
  531. */
  532. function ends_with($haystack, $needles)
  533. {
  534. return Str::endsWith($haystack, $needles);
  535. }
  536. }
  537. if (! function_exists('env')) {
  538. /**
  539. * Gets the value of an environment variable.
  540. *
  541. * @param string $key
  542. * @param mixed $default
  543. * @return mixed
  544. */
  545. function env($key, $default = null)
  546. {
  547. $value = getenv($key);
  548. if ($value === false) {
  549. return value($default);
  550. }
  551. switch (strtolower($value)) {
  552. case 'true':
  553. case '(true)':
  554. return true;
  555. case 'false':
  556. case '(false)':
  557. return false;
  558. case 'empty':
  559. case '(empty)':
  560. return '';
  561. case 'null':
  562. case '(null)':
  563. return;
  564. }
  565. if (strlen($value) > 1 && Str::startsWith($value, '"') && Str::endsWith($value, '"')) {
  566. return substr($value, 1, -1);
  567. }
  568. return $value;
  569. }
  570. }
  571. if (! function_exists('filled')) {
  572. /**
  573. * Determine if a value is "filled".
  574. *
  575. * @param mixed $value
  576. * @return bool
  577. */
  578. function filled($value)
  579. {
  580. return ! blank($value);
  581. }
  582. }
  583. if (! function_exists('head')) {
  584. /**
  585. * Get the first element of an array. Useful for method chaining.
  586. *
  587. * @param array $array
  588. * @return mixed
  589. */
  590. function head($array)
  591. {
  592. return reset($array);
  593. }
  594. }
  595. if (! function_exists('kebab_case')) {
  596. /**
  597. * Convert a string to kebab case.
  598. *
  599. * @param string $value
  600. * @return string
  601. */
  602. function kebab_case($value)
  603. {
  604. return Str::kebab($value);
  605. }
  606. }
  607. if (! function_exists('last')) {
  608. /**
  609. * Get the last element from an array.
  610. *
  611. * @param array $array
  612. * @return mixed
  613. */
  614. function last($array)
  615. {
  616. return end($array);
  617. }
  618. }
  619. if (! function_exists('object_get')) {
  620. /**
  621. * Get an item from an object using "dot" notation.
  622. *
  623. * @param object $object
  624. * @param string $key
  625. * @param mixed $default
  626. * @return mixed
  627. */
  628. function object_get($object, $key, $default = null)
  629. {
  630. if (is_null($key) || trim($key) == '') {
  631. return $object;
  632. }
  633. foreach (explode('.', $key) as $segment) {
  634. if (! is_object($object) || ! isset($object->{$segment})) {
  635. return value($default);
  636. }
  637. $object = $object->{$segment};
  638. }
  639. return $object;
  640. }
  641. }
  642. if (! function_exists('optional')) {
  643. /**
  644. * Provide access to optional objects.
  645. *
  646. * @param mixed $value
  647. * @return mixed
  648. */
  649. function optional($value = null)
  650. {
  651. return new Optional($value);
  652. }
  653. }
  654. if (! function_exists('preg_replace_array')) {
  655. /**
  656. * Replace a given pattern with each value in the array in sequentially.
  657. *
  658. * @param string $pattern
  659. * @param array $replacements
  660. * @param string $subject
  661. * @return string
  662. */
  663. function preg_replace_array($pattern, array $replacements, $subject)
  664. {
  665. return preg_replace_callback($pattern, function () use (&$replacements) {
  666. foreach ($replacements as $key => $value) {
  667. return array_shift($replacements);
  668. }
  669. }, $subject);
  670. }
  671. }
  672. if (! function_exists('retry')) {
  673. /**
  674. * Retry an operation a given number of times.
  675. *
  676. * @param int $times
  677. * @param callable $callback
  678. * @param int $sleep
  679. * @return mixed
  680. *
  681. * @throws \Exception
  682. */
  683. function retry($times, callable $callback, $sleep = 0)
  684. {
  685. $times--;
  686. beginning:
  687. try {
  688. return $callback();
  689. } catch (Exception $e) {
  690. if (! $times) {
  691. throw $e;
  692. }
  693. $times--;
  694. if ($sleep) {
  695. usleep($sleep * 1000);
  696. }
  697. goto beginning;
  698. }
  699. }
  700. }
  701. if (! function_exists('snake_case')) {
  702. /**
  703. * Convert a string to snake case.
  704. *
  705. * @param string $value
  706. * @param string $delimiter
  707. * @return string
  708. */
  709. function snake_case($value, $delimiter = '_')
  710. {
  711. return Str::snake($value, $delimiter);
  712. }
  713. }
  714. if (! function_exists('starts_with')) {
  715. /**
  716. * Determine if a given string starts with a given substring.
  717. *
  718. * @param string $haystack
  719. * @param string|array $needles
  720. * @return bool
  721. */
  722. function starts_with($haystack, $needles)
  723. {
  724. return Str::startsWith($haystack, $needles);
  725. }
  726. }
  727. if (! function_exists('str_after')) {
  728. /**
  729. * Return the remainder of a string after a given value.
  730. *
  731. * @param string $subject
  732. * @param string $search
  733. * @return string
  734. */
  735. function str_after($subject, $search)
  736. {
  737. return Str::after($subject, $search);
  738. }
  739. }
  740. if (! function_exists('str_before')) {
  741. /**
  742. * Get the portion of a string before a given value.
  743. *
  744. * @param string $subject
  745. * @param string $search
  746. * @return string
  747. */
  748. function str_before($subject, $search)
  749. {
  750. return Str::before($subject, $search);
  751. }
  752. }
  753. if (! function_exists('str_contains')) {
  754. /**
  755. * Determine if a given string contains a given substring.
  756. *
  757. * @param string $haystack
  758. * @param string|array $needles
  759. * @return bool
  760. */
  761. function str_contains($haystack, $needles)
  762. {
  763. return Str::contains($haystack, $needles);
  764. }
  765. }
  766. if (! function_exists('str_finish')) {
  767. /**
  768. * Cap a string with a single instance of a given value.
  769. *
  770. * @param string $value
  771. * @param string $cap
  772. * @return string
  773. */
  774. function str_finish($value, $cap)
  775. {
  776. return Str::finish($value, $cap);
  777. }
  778. }
  779. if (! function_exists('str_is')) {
  780. /**
  781. * Determine if a given string matches a given pattern.
  782. *
  783. * @param string|array $pattern
  784. * @param string $value
  785. * @return bool
  786. */
  787. function str_is($pattern, $value)
  788. {
  789. return Str::is($pattern, $value);
  790. }
  791. }
  792. if (! function_exists('str_limit')) {
  793. /**
  794. * Limit the number of characters in a string.
  795. *
  796. * @param string $value
  797. * @param int $limit
  798. * @param string $end
  799. * @return string
  800. */
  801. function str_limit($value, $limit = 100, $end = '...')
  802. {
  803. return Str::limit($value, $limit, $end);
  804. }
  805. }
  806. if (! function_exists('str_plural')) {
  807. /**
  808. * Get the plural form of an English word.
  809. *
  810. * @param string $value
  811. * @param int $count
  812. * @return string
  813. */
  814. function str_plural($value, $count = 2)
  815. {
  816. return Str::plural($value, $count);
  817. }
  818. }
  819. if (! function_exists('str_random')) {
  820. /**
  821. * Generate a more truly "random" alpha-numeric string.
  822. *
  823. * @param int $length
  824. * @return string
  825. *
  826. * @throws \RuntimeException
  827. */
  828. function str_random($length = 16)
  829. {
  830. return Str::random($length);
  831. }
  832. }
  833. if (! function_exists('str_replace_array')) {
  834. /**
  835. * Replace a given value in the string sequentially with an array.
  836. *
  837. * @param string $search
  838. * @param array $replace
  839. * @param string $subject
  840. * @return string
  841. */
  842. function str_replace_array($search, array $replace, $subject)
  843. {
  844. return Str::replaceArray($search, $replace, $subject);
  845. }
  846. }
  847. if (! function_exists('str_replace_first')) {
  848. /**
  849. * Replace the first occurrence of a given value in the string.
  850. *
  851. * @param string $search
  852. * @param string $replace
  853. * @param string $subject
  854. * @return string
  855. */
  856. function str_replace_first($search, $replace, $subject)
  857. {
  858. return Str::replaceFirst($search, $replace, $subject);
  859. }
  860. }
  861. if (! function_exists('str_replace_last')) {
  862. /**
  863. * Replace the last occurrence of a given value in the string.
  864. *
  865. * @param string $search
  866. * @param string $replace
  867. * @param string $subject
  868. * @return string
  869. */
  870. function str_replace_last($search, $replace, $subject)
  871. {
  872. return Str::replaceLast($search, $replace, $subject);
  873. }
  874. }
  875. if (! function_exists('str_singular')) {
  876. /**
  877. * Get the singular form of an English word.
  878. *
  879. * @param string $value
  880. * @return string
  881. */
  882. function str_singular($value)
  883. {
  884. return Str::singular($value);
  885. }
  886. }
  887. if (! function_exists('str_slug')) {
  888. /**
  889. * Generate a URL friendly "slug" from a given string.
  890. *
  891. * @param string $title
  892. * @param string $separator
  893. * @param string $language
  894. * @return string
  895. */
  896. function str_slug($title, $separator = '-', $language = 'en')
  897. {
  898. return Str::slug($title, $separator, $language);
  899. }
  900. }
  901. if (! function_exists('str_start')) {
  902. /**
  903. * Begin a string with a single instance of a given value.
  904. *
  905. * @param string $value
  906. * @param string $prefix
  907. * @return string
  908. */
  909. function str_start($value, $prefix)
  910. {
  911. return Str::start($value, $prefix);
  912. }
  913. }
  914. if (! function_exists('studly_case')) {
  915. /**
  916. * Convert a value to studly caps case.
  917. *
  918. * @param string $value
  919. * @return string
  920. */
  921. function studly_case($value)
  922. {
  923. return Str::studly($value);
  924. }
  925. }
  926. if (! function_exists('tap')) {
  927. /**
  928. * Call the given Closure with the given value then return the value.
  929. *
  930. * @param mixed $value
  931. * @param callable|null $callback
  932. * @return mixed
  933. */
  934. function tap($value, $callback = null)
  935. {
  936. if (is_null($callback)) {
  937. return new HigherOrderTapProxy($value);
  938. }
  939. $callback($value);
  940. return $value;
  941. }
  942. }
  943. if (! function_exists('throw_if')) {
  944. /**
  945. * Throw the given exception if the given condition is true.
  946. *
  947. * @param mixed $condition
  948. * @param \Throwable|string $exception
  949. * @param array ...$parameters
  950. * @return mixed
  951. * @throws \Throwable
  952. */
  953. function throw_if($condition, $exception, ...$parameters)
  954. {
  955. if ($condition) {
  956. throw (is_string($exception) ? new $exception(...$parameters) : $exception);
  957. }
  958. return $condition;
  959. }
  960. }
  961. if (! function_exists('throw_unless')) {
  962. /**
  963. * Throw the given exception unless the given condition is true.
  964. *
  965. * @param mixed $condition
  966. * @param \Throwable|string $exception
  967. * @param array ...$parameters
  968. * @return mixed
  969. * @throws \Throwable
  970. */
  971. function throw_unless($condition, $exception, ...$parameters)
  972. {
  973. if (! $condition) {
  974. throw (is_string($exception) ? new $exception(...$parameters) : $exception);
  975. }
  976. return $condition;
  977. }
  978. }
  979. if (! function_exists('title_case')) {
  980. /**
  981. * Convert a value to title case.
  982. *
  983. * @param string $value
  984. * @return string
  985. */
  986. function title_case($value)
  987. {
  988. return Str::title($value);
  989. }
  990. }
  991. if (! function_exists('trait_uses_recursive')) {
  992. /**
  993. * Returns all traits used by a trait and its traits.
  994. *
  995. * @param string $trait
  996. * @return array
  997. */
  998. function trait_uses_recursive($trait)
  999. {
  1000. $traits = class_uses($trait);
  1001. foreach ($traits as $trait) {
  1002. $traits += trait_uses_recursive($trait);
  1003. }
  1004. return $traits;
  1005. }
  1006. }
  1007. if (! function_exists('transform')) {
  1008. /**
  1009. * Transform the given value if it is present.
  1010. *
  1011. * @param mixed $value
  1012. * @param callable $callback
  1013. * @param mixed $default
  1014. * @return mixed|null
  1015. */
  1016. function transform($value, callable $callback, $default = null)
  1017. {
  1018. if (filled($value)) {
  1019. return $callback($value);
  1020. }
  1021. if (is_callable($default)) {
  1022. return $default($value);
  1023. }
  1024. return $default;
  1025. }
  1026. }
  1027. if (! function_exists('value')) {
  1028. /**
  1029. * Return the default value of the given value.
  1030. *
  1031. * @param mixed $value
  1032. * @return mixed
  1033. */
  1034. function value($value)
  1035. {
  1036. return $value instanceof Closure ? $value() : $value;
  1037. }
  1038. }
  1039. if (! function_exists('windows_os')) {
  1040. /**
  1041. * Determine whether the current environment is Windows based.
  1042. *
  1043. * @return bool
  1044. */
  1045. function windows_os()
  1046. {
  1047. return strtolower(substr(PHP_OS, 0, 3)) === 'win';
  1048. }
  1049. }
  1050. if (! function_exists('with')) {
  1051. /**
  1052. * Return the given value, optionally passed through the given callback.
  1053. *
  1054. * @param mixed $value
  1055. * @param callable|null $callback
  1056. * @return mixed
  1057. */
  1058. function with($value, callable $callback = null)
  1059. {
  1060. return is_null($callback) ? $value : $callback($value);
  1061. }
  1062. }