PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.2.0
Kirki – Freeform Page Builder, Website Builder & Customizer v6.2.0
6.2.0 6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / libraries / framework / helpers.php
kirki / libraries / framework Last commit date
Collections 1 month ago Concerns 2 weeks ago Console 4 days ago Constants 1 month ago Contracts 4 days ago Database 4 days ago Discovery 1 month ago Exceptions 4 days ago Filesystem 4 days ago Http 4 days ago Managers 4 days ago Middlewares 1 month ago Polyfill 1 month ago Routing 4 days ago Supports 4 days ago Validation 4 days ago View 4 days ago Wordpress 4 days ago ApiExceptionHandler.php 1 month ago Application.php 4 days ago Container.php 1 month ago CoreServiceProvider.php 4 days ago DTO.php 1 month ago Facade.php 1 month ago Listener.php 2 weeks ago Resource.php 4 days ago Route.php 4 days ago Sanitizer.php 4 days ago ServiceProvider.php 1 month ago SiteExceptionHandler.php 4 days ago helpers.php 4 days ago
helpers.php
723 lines
1 <?php
2
3 /**
4 * The framework helper functions.
5 *
6 * @package Framework
7 * @subpackage Helpers
8 * @since 1.0.0
9 */
10 namespace Kirki\Framework;
11
12 \defined('ABSPATH') || exit;
13 use Closure;
14 use Faker\Factory;
15 use Faker\Generator;
16 use Kirki\Framework\Application;
17 use Kirki\Framework\Collections\Collection;
18 use Kirki\Framework\Contracts\Support\Arrayable;
19 use Kirki\Framework\Database\Migrations\Migrator;
20 use Kirki\Framework\Http\Request;
21 use Kirki\Framework\Http\RedirectResponse;
22 use Kirki\Framework\Wordpress\User;
23 use Kirki\Framework\Http\Response;
24 use Kirki\Framework\Supports\Arr;
25 use Kirki\Framework\Supports\HigherOrderTapProxy;
26 use Kirki\Framework\Supports\MessagesBag;
27 use Kirki\Framework\Supports\Str;
28 use Kirki\Framework\Supports\Url;
29 use Kirki\Framework\Supports\Utils;
30 use Kirki\Framework\View\TemplateEngine;
31 use Kirki\Framework\View\View;
32 use Kirki\Framework\View\ViewContext;
33 use Symfony\Component\VarDumper\Cloner\VarCloner;
34 use Symfony\Component\VarDumper\Dumper\CliDumper;
35 use Symfony\Component\VarDumper\Dumper\HtmlDumper;
36 use Symfony\Component\VarDumper\VarDumper;
37 use function Kirki\Framework\Polyfill\array_key_first;
38 use function Kirki\Framework\Polyfill\array_key_last;
39 use function Kirki\Framework\Polyfill\is_iterable;
40 if (!\function_exists('Kirki\\Framework\\app')) {
41 /**
42 * Get the container instance.
43 *
44 * @template TClass
45 *
46 * @param string|class-string<TClass>|null $abstract
47 * @param array $parameters
48 *
49 * @return ($abstract is class-string<TClass> ? TClass : ($abstract is null ? Application : mixed))
50 */
51 function app($abstract = null, array $parameters = [])
52 {
53 if (\is_null($abstract)) {
54 return Application::get_instance();
55 }
56 return Application::get_instance()->make($abstract, $parameters);
57 }
58 }
59 if (!\function_exists('Kirki\\Framework\\deep_get')) {
60 /**
61 * Get a value from an array using a dot notation key.
62 *
63 * @param array $target The target array to get the value from.
64 * @param string|array $key The key to get the value from.
65 * @param mixed $default The default value to return if the key is not found.
66 *
67 * @return mixed The value from the array or the default value if the key is not found.
68 *
69 * @since 1.0.0
70 */
71 function deep_get($target, $key, $default = null)
72 {
73 if (\is_null($key)) {
74 return $target;
75 }
76 $key = \is_array($key) ? $key : \explode('.', $key);
77 foreach ($key as $index => $segment) {
78 unset($key[$index]);
79 if (\is_null($segment)) {
80 return $target;
81 }
82 if ($segment === '*') {
83 if ($target instanceof Collection) {
84 $target = $target->all();
85 } elseif (!is_iterable($target)) {
86 return $default;
87 }
88 $result = [];
89 foreach ($target as $item) {
90 $result[] = deep_get($item, $key);
91 }
92 return \in_array('*', $key) ? Arr::collapse($result) : $result;
93 }
94 switch ($segment) {
95 case '\\*':
96 $segment = '*';
97 break;
98 case '\\{first}':
99 $segment = '{first}';
100 break;
101 case '{first}':
102 $segment = array_key_first(Arr::from($target));
103 break;
104 case '\\{last}':
105 $segment = '{last}';
106 break;
107 case '{last}':
108 $segment = array_key_last(Arr::from($target));
109 break;
110 }
111 if (Arr::accessible($target) && Arr::exists($target, $segment)) {
112 $target = $target[$segment];
113 } elseif (\is_object($target) && isset($target->{$segment})) {
114 $target = $target->{$segment};
115 } else {
116 return value($default);
117 }
118 }
119 return $target;
120 }
121 }
122 if (!\function_exists('Kirki\\Framework\\deep_set')) {
123 /**
124 * Set a value in an array using a dot notation key.
125 *
126 * @param array $target The target array to set the value in.
127 * @param string|array $key The key to set the value in.
128 * @param mixed $value The value to set.
129 * @return void
130 */
131 function deep_set(&$target, $key, $value, $overwrite = \true)
132 {
133 $segments = \is_array($key) ? $key : \explode('.', $key);
134 $segment = \array_shift($segments);
135 if ($segment === '*') {
136 if (!Arr::accessible($target)) {
137 $target = [];
138 }
139 if ($segments) {
140 foreach ($target as &$inner) {
141 deep_set($inner, $segments, $value, $overwrite);
142 }
143 unset($inner);
144 } elseif ($overwrite) {
145 foreach ($target as &$inner) {
146 $inner = $value;
147 }
148 }
149 } elseif (Arr::accessible($target)) {
150 if ($segments) {
151 if (!Arr::exists($target, $segment)) {
152 $target[$segment] = [];
153 }
154 deep_set($target[$segment], $segments, $value, $overwrite);
155 } elseif ($overwrite || !Arr::exists($target, $segment)) {
156 $target[$segment] = $value;
157 }
158 } elseif (\is_object($target)) {
159 if ($segments) {
160 if (!isset($target->{$segment})) {
161 $target->{$segment} = [];
162 }
163 deep_set($target->{$segment}, $segments, $value, $overwrite);
164 } elseif ($overwrite || !isset($target->{$segment})) {
165 $target->{$segment} = $value;
166 }
167 } else {
168 $target = [];
169 if ($segments) {
170 deep_set($target[$segment], $segments, $value, $overwrite);
171 } elseif ($overwrite) {
172 $target[$segment] = $value;
173 }
174 }
175 return $target;
176 }
177 }
178 if (!\function_exists('Kirki\\Framework\\config')) {
179 /**
180 * Get the config
181 *
182 * @param string|null $key
183 * @param mixed $default
184 * @return mixed
185 */
186 function config($key = null, $default = null)
187 {
188 static $cache = [];
189 $filename = \strpos($key, '.') ? \substr($key, 0, \strpos($key, '.')) : $key;
190 $key = \strpos($key, '.') ? \substr($key, \strpos($key, '.') + 1) : null;
191 if (!isset($cache[$filename])) {
192 $path = app()->config_path("{$filename}.php");
193 if (\file_exists($path)) {
194 $cache[$filename] = (include $path);
195 } else {
196 $cache[$filename] = null;
197 }
198 }
199 if (\is_null($cache[$filename])) {
200 return value($default);
201 }
202 return deep_get($cache[$filename], $key, $default);
203 }
204 }
205 if (!\function_exists('Kirki\\Framework\\user')) {
206 /**
207 * Get the user instance.
208 *
209 * @return User
210 */
211 function user($user_id = null)
212 {
213 return app()->make(User::class, ['user_id' => $user_id]);
214 }
215 }
216 if (!\function_exists('Kirki\\Framework\\response')) {
217 /**
218 * Get the response instance.
219 *
220 * @return Response
221 */
222 function response()
223 {
224 return app()->make(Response::class)->with_headers(['X-Content-Type-Options' => 'nosniff', 'X-Frame-Options' => 'SAMEORIGIN', 'X-XSS-Protection' => '1; mode=block', 'Referrer-Policy' => 'no-referrer-when-downgrade', 'Cache-Control' => 'public, max-age=60, stale-while-revalidate=30']);
225 }
226 }
227 if (!\function_exists('Kirki\\Framework\\view')) {
228 /**
229 * Create a view instance for the given template.
230 *
231 * @param string $template The template name in dot notation.
232 * @param array $data The data to pass to the template.
233 *
234 * @return View
235 *
236 * @since 1.0.0
237 */
238 function view(string $template, array $data = [])
239 {
240 return new View($template, $data);
241 }
242 }
243 if (!\function_exists('Kirki\\Framework\\view_data')) {
244 /**
245 * Read data from the innermost authorized view context.
246 *
247 * Supports dot notation for nested keys (e.g. `product.name`).
248 *
249 * @param string|null $key Data key (dot notation allowed), or null for the full array.
250 * @param mixed $default Default when missing or unauthorized.
251 *
252 * @return mixed
253 *
254 * @since 2.1.2
255 */
256 function view_data($key = null, $default = null)
257 {
258 return app(ViewContext::class)->get($key, $default);
259 }
260 }
261 if (!\function_exists('Kirki\\Framework\\template_engine')) {
262 /**
263 * Get the template engine instance.
264 *
265 * @return TemplateEngine
266 */
267 function template_engine()
268 {
269 return app(TemplateEngine::class);
270 }
271 }
272 if (!\function_exists('Kirki\\Framework\\include_view')) {
273 /**
274 * Include a nested pure-PHP view partial (Laravel @include equivalent).
275 *
276 * Explicit $data (plus TemplateEngine shared data) is pushed as a child
277 * ViewContext frame. The partial must read values via view_data().
278 *
279 * @param string $view The view name in dot notation.
280 * @param array $data Data for the partial.
281 *
282 * @return void
283 *
284 * @since 2.1.2
285 * @throws \RuntimeException When the view cannot be resolved.
286 */
287 function include_view(string $view, array $data = [])
288 {
289 app(\Kirki\Framework\View\TemplateEngine::class)->include($view, $data, \false);
290 }
291 }
292 if (!\function_exists('Kirki\\Framework\\redirect')) {
293 /**
294 * Create a redirect response.
295 *
296 * @param string $url The redirect target URL.
297 * @param int $status The HTTP status code.
298 *
299 * @return RedirectResponse
300 *
301 * @since 1.0.0
302 */
303 function redirect(string $url, int $status = 302)
304 {
305 return new RedirectResponse($url, $status);
306 }
307 }
308 if (!\function_exists('Kirki\\Framework\\request')) {
309 /**
310 * Get the request instance.
311 *
312 * @param string|null $key
313 * @param mixed $default
314 *
315 * @return ($key is null ? Request : ($key is array ? array : mixed))
316 *
317 * @since 1.0.0
318 */
319 function request($key = null, $default = null)
320 {
321 if (\is_null($key)) {
322 return app('request');
323 }
324 if (\is_array($key)) {
325 return app('request')->only($key);
326 }
327 $value = app('request')->get($key, $default);
328 return \is_null($value) ? value($default) : $value;
329 }
330 }
331 if (!\function_exists('Kirki\\Framework\\with_prefix')) {
332 /**
333 * Get the key with prefix applied.
334 *
335 * @param string $key
336 * @return string
337 */
338 function with_prefix(string $key)
339 {
340 $prefix = app()->prefix();
341 if (Str::starts_with($key, $prefix)) {
342 return $key;
343 }
344 return $prefix . $key;
345 }
346 }
347 if (!\function_exists('Kirki\\Framework\\without_prefix')) {
348 /**
349 * Get the key without prefix applied.
350 *
351 * @param string $key
352 * @return string
353 */
354 function without_prefix(string $key)
355 {
356 $prefix = app()->prefix();
357 if (!Str::starts_with($key, $prefix)) {
358 return $key;
359 }
360 return \substr($key, \strlen($prefix));
361 }
362 }
363 if (!\function_exists('Kirki\\Framework\\redirect')) {
364 /**
365 * Redirect to the given location.
366 *
367 * @param string $location
368 * @return void
369 *
370 * @since 1.0.0
371 */
372 function redirect($location)
373 {
374 Url::redirect($location);
375 }
376 }
377 if (!\function_exists('Kirki\\Framework\\is_valid_json')) {
378 /**
379 * Check if the string is a valid JSON.
380 *
381 * @param string $string
382 * @return bool
383 */
384 function is_valid_json($string)
385 {
386 if (!\is_string($string)) {
387 return \false;
388 }
389 \json_decode($string);
390 return \json_last_error() === \JSON_ERROR_NONE;
391 }
392 }
393 if (!\function_exists('Kirki\\Framework\\clean_path')) {
394 /**
395 * Clean and normalize file paths for consistency.
396 *
397 * @param string $path
398 * @param bool $trailing_slash Add a trailing slash? Default true.
399 * @return string
400 */
401 function clean_path(string $path, bool $trailing_slash = \true)
402 {
403 $path = wp_normalize_path($path);
404 return $trailing_slash ? trailingslashit($path) : untrailingslashit($path);
405 }
406 }
407 if (!\function_exists('Kirki\\Framework\\uuid')) {
408 /**
409 * Generate a UUID.
410 *
411 * @return string
412 */
413 function uuid()
414 {
415 return Utils::uuid();
416 }
417 }
418 if (!\function_exists('Kirki\\Framework\\url')) {
419 /**
420 * Generate a URL.
421 *
422 * @param string $url
423 * @param array $query_vars
424 * @return string
425 */
426 function url($url, $query_vars = [])
427 {
428 return Url::make($url, $query_vars);
429 }
430 }
431 if (!\function_exists('Kirki\\Framework\\is_block_theme')) {
432 /**
433 * Check if the site is using a block template
434 *
435 * This function will return true if the site is using a block template and false otherwise.
436 *
437 * @return bool True if the site is using a block template, false otherwise.
438 */
439 function is_block_theme()
440 {
441 return \function_exists('wp_is_block_theme') && wp_is_block_theme();
442 }
443 }
444 if (!\function_exists('Kirki\\Framework\\migrator')) {
445 /**
446 * Get the migrator instance.
447 *
448 * @return Migrator
449 */
450 function migrator()
451 {
452 return app()->make(Migrator::class);
453 }
454 }
455 if (!\function_exists('Kirki\\Framework\\tap')) {
456 /**
457 * Call the given Closure with the given value.
458 *
459 * @param mixed $value
460 * @param \Closure $callback
461 * @return mixed
462 */
463 function tap($value, $callback = null)
464 {
465 if (\is_null($callback)) {
466 return new HigherOrderTapProxy($value);
467 }
468 $callback($value);
469 return $value;
470 }
471 }
472 if (!\function_exists('Kirki\\Framework\\faker')) {
473 /**
474 * Get the fake instance.
475 *
476 * @return Generator
477 */
478 function faker()
479 {
480 return app()->make(Factory::class);
481 }
482 }
483 if (!\function_exists('Kirki\\Framework\\configure_dumper')) {
484 function configure_dumper()
485 {
486 static $configured = \false;
487 if ($configured) {
488 return;
489 }
490 $configured = \true;
491 $is_cli = \defined('WP_CLI') && \WP_CLI;
492 if ($is_cli) {
493 VarDumper::setHandler(function ($var) {
494 $dumper = new CliDumper();
495 $dumper->dump((new VarCloner())->cloneVar($var));
496 });
497 return;
498 }
499 VarDumper::setHandler(function ($var) {
500 $dumper = new HtmlDumper();
501 $dumper->dump((new VarCloner())->cloneVar($var));
502 });
503 }
504 }
505 if (!\function_exists('Kirki\\Framework\\dump')) {
506 /**
507 * Dump the given arguments.
508 *
509 * @param mixed ...$args
510 *
511 * @return void
512 *
513 * @since 1.0.0
514 */
515 function dump(...$args)
516 {
517 if (!\class_exists(VarDumper::class) || !app()->is_dev_mode()) {
518 return;
519 }
520 configure_dumper();
521 foreach ($args as $arg) {
522 VarDumper::dump($arg);
523 }
524 }
525 }
526 if (!\function_exists('Kirki\\Framework\\dd')) {
527 /**
528 * Dump the given arguments and die.
529 *
530 * @param mixed ...$args
531 *
532 * @return void
533 *
534 * @since 1.0.0
535 */
536 function dd(...$args)
537 {
538 dump(...$args);
539 die(1);
540 }
541 }
542 if (!\function_exists('Kirki\\Framework\\app_path')) {
543 /**
544 * Get the path to the application directory.
545 *
546 * @param string $path
547 * @return string
548 */
549 function app_path($path = '')
550 {
551 return app()->path($path);
552 }
553 }
554 if (!\function_exists('Kirki\\Framework\\config_path')) {
555 /**
556 * Get the path to the config directory.
557 *
558 * @param string $path
559 * @return string
560 */
561 function config_path($path = '')
562 {
563 return app()->config_path($path);
564 }
565 }
566 if (!\function_exists('Kirki\\Framework\\database_path')) {
567 /**
568 * Get the path to the database directory.
569 *
570 * @param string $path
571 * @return string
572 */
573 function database_path($path = '')
574 {
575 return app()->database_path($path);
576 }
577 }
578 if (!\function_exists('Kirki\\Framework\\base_path')) {
579 /**
580 * Get the path to the base directory.
581 *
582 * @param string $path
583 * @return string
584 */
585 function base_path($path = '')
586 {
587 return app()->base_path($path);
588 }
589 }
590 if (!\function_exists('Kirki\\Framework\\resource_path')) {
591 /**
592 * Get the path to the resources directory.
593 *
594 * @param string $path
595 * @return string
596 */
597 function resource_path($path = '')
598 {
599 return app()->resource_path($path);
600 }
601 }
602 if (!\function_exists('Kirki\\Framework\\view_path')) {
603 /**
604 * Get the path to the views directory.
605 *
606 * @param string $path
607 *
608 * @return string
609 *
610 * @since 1.0.0
611 */
612 function view_path($path = '')
613 {
614 return app()->view_path($path);
615 }
616 }
617 if (!\function_exists('Kirki\\Framework\\bootstrap_path')) {
618 /**
619 * Get the path to the bootstrap directory.
620 *
621 * @param string $path
622 * @return string
623 */
624 function bootstrap_path($path = '')
625 {
626 return app()->bootstrap_path($path);
627 }
628 }
629 if (!\function_exists('Kirki\\Framework\\collection')) {
630 /**
631 * Create a collection instance from an array.
632 *
633 * @param array $array
634 * @return Collection
635 */
636 function collection(array $array = [])
637 {
638 return new Collection($array);
639 }
640 }
641 if (!\function_exists('Kirki\\Framework\\resource_url')) {
642 /**
643 * Get the path to the resources directory.
644 *
645 * @param string $path
646 * @return string
647 */
648 function resource_url($path = '')
649 {
650 return app()->base_url(path_join('resources', $path));
651 }
652 }
653 if (!\function_exists('Kirki\\Framework\\json_decoded_data')) {
654 /**
655 * Get the decoded JSON data from a file.
656 *
657 * @param string $file_path
658 * @param bool $associative
659 * @return mixed
660 */
661 function json_decoded_data(string $file_path, bool $associative = \true)
662 {
663 if (!\file_exists($file_path)) {
664 return null;
665 }
666 $content = \file_get_contents($file_path);
667 return \json_decode($content, $associative);
668 }
669 }
670 if (!\function_exists('Kirki\\Framework\\value')) {
671 /**
672 * Get the value of a variable.
673 *
674 * @param mixed $value
675 * @param mixed ...$args
676 * @return mixed
677 */
678 function value($value, ...$args)
679 {
680 return $value instanceof Closure ? $value(...$args) : $value;
681 }
682 }
683 if (!\function_exists('Kirki\\Framework\\is_rest_request')) {
684 /**
685 * Check if the current request is a REST request.
686 *
687 * @return bool
688 */
689 function is_rest_request()
690 {
691 $is_rest = \defined('REST_REQUEST') && REST_REQUEST;
692 if ($is_rest) {
693 return \true;
694 }
695 $rest_route = Sanitizer::apply_rule(\filter_input(\INPUT_GET, 'rest_route', \FILTER_UNSAFE_RAW), Sanitizer::BOOL);
696 if ($rest_route) {
697 return \true;
698 }
699 $request_uri = \filter_input(\INPUT_SERVER, 'REQUEST_URI', \FILTER_SANITIZE_URL);
700 if (empty($request_uri)) {
701 return \false;
702 }
703 $is_rest = \strpos($request_uri, '/' . rest_get_url_prefix() . '/') !== \false;
704 return $is_rest;
705 }
706 }
707 if (!\function_exists('Kirki\\Framework\\message')) {
708 /**
709 * Get a message by key.
710 *
711 * @param string $key the key of the message
712 * @param mixed $args the arguments to pass to the message
713 *
714 * @return string|null
715 *
716 * @since 1.0.0
717 */
718 function message($key, ...$args)
719 {
720 return app()->make(MessagesBag::class)->get($key, ...$args);
721 }
722 }
723