PluginProbe
JetFormBuilder — Dynamic Blocks Form Builder / 1.2.0
JetFormBuilder — Dynamic Blocks Form Builder v1.2.0
3.6.5.2 3.6.5.1 3.6.5 3.6.4.2 3.6.4.1 3.6.4 3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 All 130 releases
← All changes | includes/classes/tools.php +381 -849 trunk1.2.0 View file →
@@ -1,849 +1,381 @@
1 -<?php
2 -
3 -namespace Jet_Form_Builder\Classes;
4 -
5 -use Jet_Form_Builder\Plugin;
6 -use Jet_Form_Builder\Generators\Registry as GeneratorRegistry;
7 -
8 -// If this file is called directly, abort.
9 -if ( ! defined( 'WPINC' ) ) {
10 - die;
11 -}
12 -
13 -class Tools {
14 -
15 - const EMPTY_DEEP_VALUE = self::class;
16 -
17 - public static function is_editor() {
18 - return self::is_block_editor() || self::is_elementor_editor() || self::is_bricks_editor();
19 - }
20 -
21 - public static function is_block_editor() {
22 - $allowed_actions = array( 'add', 'edit' );
23 -
24 - return (
25 - in_array( self::sanitize_get_param( 'context' ), $allowed_actions, true )
26 - || in_array( self::sanitize_get_param( 'action' ), $allowed_actions, true )
27 - );
28 - }
29 -
30 - public static function sanitize_get_param( $param_name ) {
31 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended
32 - return ! empty( $_GET[ $param_name ] ) ? sanitize_key( $_GET[ $param_name ] ) : '';
33 - }
34 -
35 - public static function is_elementor_editor() {
36 - if ( ! defined( 'ELEMENTOR_VERSION' ) ) {
37 - return false;
38 - }
39 -
40 - return ( \Elementor\Plugin::instance()->editor->is_edit_mode() );
41 - }
42 -
43 - public static function is_bricks_editor() {
44 - if ( ! defined( 'BRICKS_VERSION' ) ) {
45 - return false;
46 - }
47 -
48 - return ( bricks_is_builder() );
49 - }
50 -
51 - /**
52 - * Returns all post types list to use in JS components
53 - *
54 - * @param bool $placeholder
55 - *
56 - * @param array $args
57 - * @param string $operator
58 - *
59 - * @return array [type] [description]
60 - */
61 - public static function get_post_types_for_js( $placeholder = false, $args = array(), $operator = 'and' ) {
62 -
63 - $post_types = get_post_types( $args, 'objects', $operator );
64 -
65 - $post_types_list = array();
66 -
67 - if ( $placeholder && is_array( $placeholder ) ) {
68 - $placeholder['value'] = isset( $placeholder['value'] ) ? $placeholder['value'] : '';
69 - $post_types_list[] = $placeholder;
70 - }
71 -
72 - foreach ( $post_types as $post_type ) {
73 - if ( Plugin::instance()->post_type->slug() !== $post_type->name ) {
74 - $post_types_list[] = array(
75 - 'value' => $post_type->name,
76 - 'label' => $post_type->label,
77 - );
78 - }
79 - }
80 -
81 - return self::with_placeholder( $post_types_list );
82 - }
83 -
84 - /**
85 - * Get post types list for options.
86 - *
87 - * @return array
88 - */
89 - public static function get_post_types_for_options(): array {
90 - return self::get_post_types_for_js( false, array( 'public' => true ) );
91 - }
92 -
93 - private static function get_escape_func( $type ) {
94 - switch ( $type ) {
95 - case 'template':
96 - default:
97 - return array( self::class, 'esc_template' );
98 - }
99 - }
100 -
101 - /**
102 - * Sanitize WYSIWYG field
103 - *
104 - * @param $input
105 - *
106 - * @return string
107 - */
108 - public static function sanitize_wysiwyg( $input ): string {
109 - $input = wp_specialchars_decode( stripslashes( $input ), ENT_COMPAT );
110 -
111 - return wp_kses_post( $input );
112 - }
113 -
114 - /**
115 - * Return all taxonomies list to use in JS components
116 - *
117 - * @param array $args
118 - *
119 - * @return array
120 - */
121 - public static function get_taxonomies_for_js( $args = array() ): array {
122 - $taxonomies = get_taxonomies( $args, 'objects' );
123 -
124 - return self::with_placeholder( self::prepare_list_for_js( $taxonomies, 'name', 'label' ) );
125 - }
126 -
127 - public static function get_taxonomies_for_modify( array $args = array() ): array {
128 - $taxonomies = get_taxonomies( $args, 'objects' );
129 - $response = array();
130 -
131 - /** @var \WP_Taxonomy $taxonomy */
132 - foreach ( $taxonomies as $taxonomy ) {
133 - $response[] = array(
134 - 'label' => $taxonomy->label,
135 - 'value' => "jet_tax__{$taxonomy->name}",
136 - );
137 - }
138 -
139 - return self::with_placeholder( $response );
140 - }
141 -
142 - public static function get_generators_list_for_js(): array {
143 - $generators = Plugin::instance()->form->get_generators_list();
144 -
145 - return self::prepare_list_for_js( $generators );
146 - }
147 -
148 - /**
149 - * Get generator schemas for JS localization.
150 - *
151 - * @return array
152 - */
153 - public static function get_generator_schemas_for_js(): array {
154 - if ( ! class_exists( GeneratorRegistry::class ) ) {
155 - return array();
156 - }
157 -
158 - try {
159 - $registry = GeneratorRegistry::instance();
160 - return $registry->get_schemas_for_js();
161 - } catch ( \Exception $e ) {
162 - return array();
163 - }
164 - }
165 -
166 - public static function get_allowed_mimes_list_for_js(): array {
167 - return array_values( get_allowed_mime_types() );
168 - }
169 -
170 - /**
171 - * Returns all registeredroles for JS
172 - */
173 - public static function get_user_roles_for_js( $exclude = array( 'administrator' ) ) {
174 -
175 - $roles = self::get_user_roles( $exclude );
176 - $result = array();
177 -
178 - foreach ( $roles as $role => $label ) {
179 - $result[] = array(
180 - 'value' => $role,
181 - 'label' => $label,
182 - );
183 - }
184 -
185 - return self::with_placeholder( $result );
186 - }
187 -
188 - public static function get_options_pages_for_js() {
189 - $pages = array();
190 -
191 - if ( function_exists( 'jet_engine' ) ) {
192 - $pages = jet_engine()->options_pages->get_options_pages_for_select();
193 - }
194 -
195 - return self::prepare_list_for_js( $pages );
196 - }
197 -
198 - /**
199 - * Returns pages list
200 - *
201 - * @return [type] [description]
202 - */
203 - public static function get_pages_list_for_js() {
204 - $pages = get_pages();
205 -
206 - return self::prepare_list_for_js( $pages, 'ID', 'post_title' );
207 - }
208 -
209 - /**
210 - * Returns pages list
211 - *
212 - * @param bool $for_elementor
213 - *
214 - * @param array $args
215 - *
216 - * @return array [description]
217 - */
218 - public static function get_forms_list_for_js( $for_elementor = false, $args = array() ) {
219 - $posts = get_posts(
220 - array_merge(
221 - array(
222 - 'post_status' => 'publish',
223 - 'posts_per_page' => - 1,
224 - 'post_type' => jet_form_builder()->post_type->slug(),
225 - ),
226 - $args
227 - )
228 - );
229 -
230 - $prepared_list_for_js = self::prepare_list_for_js( $posts, 'ID', 'post_title', $for_elementor );
231 -
232 - if ( true === $for_elementor ) {
233 - $manual_form_option = array(
234 - 'manual_form_id' => __( 'Enter Form ID Manually / Dynamically', 'jet-form-builder' ),
235 - );
236 -
237 - $prepared_list_for_js = array_replace( $manual_form_option, $prepared_list_for_js );
238 - } else {
239 - $manual_form_option[] = array(
240 - 'value' => -1,
241 - 'label' => __( 'Enter Form ID Manually / Dynamically', 'jet-form-builder' ),
242 - );
243 -
244 - $prepared_list_for_js = array_merge( $manual_form_option, $prepared_list_for_js );
245 - }
246 -
247 - return $prepared_list_for_js;
248 - }
249 -
250 - /**
251 - * Returns all registered user roles
252 - *
253 - * @param string[] $exclude
254 - *
255 - * @return array [type] [description]
256 - */
257 - public static function get_user_roles( $exclude = array( 'administrator' ) ) {
258 -
259 - if ( ! function_exists( 'get_editable_roles' ) ) {
260 - return array();
261 - } else {
262 - $roles = get_editable_roles();
263 - $result = array();
264 -
265 - foreach ( $roles as $role => $data ) {
266 - if ( ! in_array( $role, $exclude, true ) ) {
267 - $result[ $role ] = $data['name'];
268 - }
269 - }
270 -
271 - return $result;
272 - }
273 - }
274 -
275 - /**
276 - * Returns editable roles and ensures the core helper is loaded.
277 - *
278 - * @return array
279 - */
280 - public static function get_editable_roles_safe(): array {
281 - if ( ! function_exists( 'get_editable_roles' ) ) {
282 - require_once ABSPATH . 'wp-admin/includes/user.php';
283 - }
284 -
285 - if ( ! function_exists( 'get_editable_roles' ) ) {
286 - return array();
287 - }
288 -
289 - return get_editable_roles();
290 - }
291 -
292 - /**
293 - * Returns all registered roles without filtering by the current user's capabilities.
294 - *
295 - * @return array
296 - */
297 - public static function get_registered_roles_safe(): array {
298 - $wp_roles = wp_roles();
299 -
300 - if ( ! is_a( $wp_roles, \WP_Roles::class ) ) {
301 - return array();
302 - }
303 -
304 - return $wp_roles->roles ?? array();
305 - }
306 -
307 - /**
308 - * Returns auto-detected low-privilege roles that can be used as
309 - * a starting point for self-service role transitions.
310 - *
311 - * @return string[]
312 - */
313 - public static function get_default_self_promotable_roles(): array {
314 - $editable_roles = self::get_registered_roles_safe();
315 -
316 - if ( empty( $editable_roles ) ) {
317 - return array();
318 - }
319 -
320 - $roles = array();
321 -
322 - foreach ( array_keys( $editable_roles ) as $role ) {
323 - if ( self::is_safe_self_promotable_role( $role ) ) {
324 - $roles[] = $role;
325 - }
326 - }
327 -
328 - return array_values( array_unique( $roles ) );
329 - }
330 -
331 - public static function is_safe_self_promotable_role( string $role ): bool {
332 - if ( 'administrator' === $role ) {
333 - return false;
334 - }
335 -
336 - $wp_roles = wp_roles();
337 -
338 - if ( ! isset( $wp_roles->roles[ $role ] ) ) {
339 - return false;
340 - }
341 -
342 - $caps = array_filter( $wp_roles->roles[ $role ]['capabilities'] ?? array() );
343 -
344 - $dangerous_caps = array(
345 - 'activate_plugins',
346 - 'create_users',
347 - 'delete_users',
348 - 'edit_users',
349 - 'list_users',
350 - 'promote_users',
351 - 'remove_users',
352 - 'manage_options',
353 - 'edit_theme_options',
354 - 'switch_themes',
355 - 'install_plugins',
356 - 'update_plugins',
357 - 'delete_plugins',
358 - 'install_themes',
359 - 'update_themes',
360 - 'delete_themes',
361 - 'unfiltered_html',
362 - 'edit_others_posts',
363 - 'delete_others_posts',
364 - 'publish_posts',
365 - 'manage_categories',
366 - );
367 -
368 - foreach ( $dangerous_caps as $cap ) {
369 - if ( ! empty( $caps[ $cap ] ) ) {
370 - return false;
371 - }
372 - }
373 -
374 - return true;
375 - }
376 -
377 - /**
378 - * Prepare passed array for using in JS options
379 - *
380 - * @param array $array
381 - * @param null $value_key
382 - * @param null $label_key
383 - * @param bool $for_elementor
384 - *
385 - * Only if $for_elementor === false
386 - * @param array $additional_attrs
387 - *
388 - * @return array [type] [description]
389 - */
390 - public static function prepare_list_for_js(
391 - $collection = array(),
392 - $value_key = null,
393 - $label_key = null,
394 - $for_elementor = false,
395 - $additional_attrs = array()
396 - ) {
397 -
398 - $result = array();
399 -
400 - if ( ! is_array( $collection ) || empty( $collection ) ) {
401 - return $result;
402 - }
403 -
404 - foreach ( $collection as $key => $item ) {
405 -
406 - $value = null;
407 - $label = null;
408 -
409 - if ( is_scalar( $item ) ) {
410 - $value = $key;
411 - $label = $item;
412 - } else {
413 - $value = self::get_property( $item, $value_key );
414 - $label = self::get_property( $item, $label_key );
415 - }
416 -
417 - if ( $for_elementor ) {
418 - $result[ $value ] = $label;
419 - } else {
420 - $prepared = array(
421 - 'value' => $value,
422 - 'label' => $label,
423 - );
424 - foreach ( $additional_attrs as $attr ) {
425 - $prepared[ $attr ] = self::get_property( $item, $attr );
426 - }
427 -
428 - $result[] = $prepared;
429 - }
430 - }
431 -
432 - return $result;
433 - }
434 -
435 - /**
436 - * @param array $collection
437 - * @param string $label
438 - *
439 - * @return array
440 - */
441 - public static function with_placeholder( array $collection, string $label = '--' ): array {
442 - return array_merge(
443 - array(
444 - array( 'label' => $label, 'value' => '' ),
445 - ),
446 - $collection
447 - );
448 - }
449 -
450 - /**
451 - * Check if is valid timestamp
452 - *
453 - * @param mixed $timestamp
454 - *
455 - * @return boolean
456 - */
457 - public static function is_valid_timestamp( $timestamp ): bool {
458 - return ( (string) (int) $timestamp === $timestamp || (int) $timestamp === $timestamp )
459 - && ( $timestamp <= PHP_INT_MAX )
460 - && ( $timestamp >= ~PHP_INT_MAX );
461 - }
462 -
463 - public static function array_merge_intersect_key( $source, $arrays ) {
464 - foreach ( $source as $index => $path ) {
465 - $name = $path['path'] ?? $index;
466 -
467 - $deep_value = self::getDeepValue( $name, $arrays );
468 -
469 - if ( self::EMPTY_DEEP_VALUE === $deep_value ) {
470 - unset( $source[ $index ] );
471 - } else {
472 - $source[ $index ] = $deep_value;
473 - }
474 - }
475 -
476 - return $source;
477 - }
478 -
479 - // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
480 - public static function getDeepValue( $key, $source ) {
481 - $keys = explode( '/', $key );
482 - $last = end( $keys );
483 - reset( $keys );
484 -
485 - return self::deep( $keys, current( $keys ), $last, $source );
486 - }
487 -
488 - private static function deep( $collection, $key, $last, $source ) {
489 -
490 - if ( isset( $source[ $key ] ) ) {
491 - if ( $last !== $key ) {
492 - return self::deep( $collection, next( $collection ), $last, $source[ $key ] );
493 - }
494 -
495 - return $source[ $key ];
496 - }
497 -
498 - return self::EMPTY_DEEP_VALUE;
499 - }
500 -
501 - public static function call( $callback, ...$params ) {
502 - if ( ! is_callable( $callback ) ) {
503 - return;
504 - }
505 -
506 - call_user_func( $callback, ...$params );
507 - }
508 -
509 - public static function decode_unserializable( $value ) {
510 - $data = self::decode_json( $value );
511 -
512 - // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
513 - return $data ?: maybe_unserialize( $value );
514 - }
515 -
516 - public static function decode_json( $json ) {
517 - if ( is_array( $json ) ) {
518 - foreach ( $json as $key => $row ) {
519 - $json[ $key ] = static::decode_json( $row );
520 - }
521 -
522 - return $json;
523 - }
524 - if ( defined( 'JSON_INVALID_UTF8_IGNORE' ) ) {
525 - // phpcs:ignore PHPCompatibility.Constants.NewConstants
526 - return json_decode( $json, true, 512, JSON_INVALID_UTF8_IGNORE );
527 - }
528 -
529 - return json_decode( $json, true );
530 - }
531 -
532 - public static function encode_json( $json ) {
533 - return wp_json_encode( $json, JSON_UNESCAPED_UNICODE );
534 - }
535 -
536 - public static function sanitize_recursive( $source = null ) {
537 - if ( ! is_array( $source ) ) {
538 - return self::sanitize( $source );
539 - }
540 -
541 - $result = array();
542 -
543 - foreach ( $source as $key => $value ) {
544 - $result[ $key ] = self::sanitize_recursive( $value );
545 - }
546 -
547 - return $result;
548 - }
549 -
550 - public static function maybe_recursive_sanitize( $source = null ) {
551 - return self::sanitize_recursive( $source );
552 - }
553 -
554 - public static function sanitize( $source ) {
555 - if ( self::is_url( $source ) ) {
556 - return esc_url_raw( $source );
557 - }
558 -
559 - return self::sanitize_text_field( $source );
560 - }
561 -
562 - public static function is_url( $url ) {
563 - return wp_http_validate_url( $url );
564 - }
565 -
566 - public static function sanitize_text_field( $source, $replace_enqueue = true ) {
567 - $str = (string) $source;
568 -
569 - $filtered = wp_check_invalid_utf8( $str );
570 - $sanitize_callback = apply_filters( 'jet-form-builder/sanitize-string/callback', false );
571 -
572 - if ( $sanitize_callback && is_callable( $sanitize_callback ) ) {
573 - $filtered = call_user_func( $sanitize_callback, $filtered );
574 - } elseif ( $replace_enqueue && false !== strpos( $filtered, '<' ) ) {
575 - $filtered = wp_kses_post( $filtered );
576 - }
577 -
578 - return trim( $filtered );
579 - }
580 -
581 - /**
582 - * @param $type
583 - * @param mixed ...$values
584 - *
585 - * @return mixed
586 - */
587 - private static function call_escape_func( $type, ...$values ) {
588 - return call_user_func( self::get_escape_func( $type ), ...$values );
589 - }
590 -
591 - public static function recursive_wp_kses( $source, $allowed_html = 'strip' ) {
592 - if ( ! is_array( $source ) ) {
593 - return wp_kses( $source, $allowed_html );
594 - }
595 -
596 - $result = array();
597 - foreach ( $source as $key => $value ) {
598 - $result[ $key ] = self::sanitize_recursive( $value );
599 - }
600 -
601 - return $result;
602 - }
603 -
604 - public static function sanitize_files( $source ) {
605 - if ( ! is_array( $source ) ) {
606 - return false;
607 - }
608 -
609 - $response = array();
610 -
611 - foreach ( $source as $index => $item ) {
612 - foreach ( $item as $key => $value ) {
613 - switch ( $key ) {
614 - case 'error':
615 - case 'size':
616 - $response[ $index ][ $key ] = absint( $value );
617 - break;
618 - case 'name':
619 - $response[ $index ][ $key ] = sanitize_file_name( $value );
620 - break;
621 - case 'type':
622 - $response[ $index ][ $key ] = sanitize_mime_type( $value );
623 - break;
624 - case 'tmp_name':
625 - $response[ $index ][ $key ] = sanitize_text_field( $value );
626 - break;
627 - }
628 - }
629 - }
630 -
631 - return $response;
632 - }
633 -
634 - /**
635 - * @param $source
636 - * @param bool $replace_enqueue
637 - *
638 - * @return string
639 - */
640 - private static function esc_template( $source, $replace_enqueue = true ): string {
641 - return self::sanitize_text_field( $source, $replace_enqueue );
642 - }
643 -
644 - public static function get_jet_engine_version() {
645 - return function_exists( 'jet_engine' )
646 - ? jet_engine()->get_version()
647 - : false;
648 - }
649 -
650 - public static function is_readable( string $filename ) {
651 - // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
652 - return strlen( $filename ) <= PHP_MAXPATHLEN && @is_readable( $filename );
653 - }
654 -
655 - /**
656 - * Returns template path
657 - *
658 - * @param [type] $path [description]
659 - *
660 - * @return [type] [description]
661 - */
662 - public static function get_global_template( $path = '' ) {
663 - return JET_FORM_BUILDER_PATH . 'templates/' . $path;
664 - }
665 -
666 - public static function get_property( $source, $name, $if_not_exist = '' ) {
667 - if ( is_object( $source ) ) {
668 - return $source->{$name} ?? $if_not_exist;
669 - }
670 -
671 - return $source[ $name ] ?? $if_not_exist;
672 - }
673 -
674 - public static function esc_template_string( $source, $replace_enqueue = true ) {
675 - return self::call_escape_func( 'template', $source, $replace_enqueue );
676 - }
677 -
678 - public static function is_repeater_val( $value ): bool {
679 - if ( is_array( $value ) && ! empty( $value ) ) {
680 - foreach ( $value as $item ) {
681 - return is_array( $item );
682 - }
683 - }
684 -
685 - return false;
686 - }
687 -
688 - public static function set_current_post( $post_id ) {
689 - global $post;
690 -
691 - // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
692 - $post = get_post( absint( $post_id ) );
693 - }
694 -
695 - public static function prepare_repeater_value( $value, $fields_map ): array {
696 - $prepared_value = array();
697 -
698 - foreach ( $value as $index => $row ) {
699 - $prepared_row = array();
700 -
701 - foreach ( $row as $item_key => $item_value ) {
702 - $item_key = ! empty( $fields_map[ $item_key ] ) ? self::sanitize_text_field( $fields_map[ $item_key ] ) : $item_key;
703 - $prepared_row[ $item_key ] = $item_value;
704 - }
705 -
706 - $prepared_value[ 'item-' . $index ] = $prepared_row;
707 - }
708 -
709 - return $prepared_value;
710 - }
711 -
712 - public static function is_webhook(): bool {
713 - return (
714 - defined( 'JET_FB_REST_WEBHOOK' ) &&
715 - JET_FB_REST_WEBHOOK
716 - );
717 - }
718 -
719 - public static function esc_attr( $value ) {
720 - if ( ! is_scalar( $value ) ) {
721 - return esc_attr( self::encode_json( $value ) );
722 - }
723 -
724 - return esc_attr( $value );
725 - }
726 -
727 - public static function get_suffix(): string {
728 - return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
729 - }
730 -
731 - /**
732 - * Get from function below
733 - *
734 - * @return string
735 - * @see \retrieve_password
736 - */
737 - public static function get_site_name(): string {
738 - if ( is_multisite() ) {
739 - return get_network()->site_name;
740 - }
741 -
742 - /*
743 - * The blogname option is escaped with esc_html on the way into the database
744 - * in sanitize_option. We want to reverse this for the plain text arena of emails.
745 - */
746 -
747 - return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
748 - }
749 -
750 - /**
751 - * @param mixed $value
752 - */
753 - public static function to_string( $value ): string {
754 - if ( is_array( $value ) ) {
755 - return implode(
756 - ',',
757 - array_map( array( self::class, 'to_string' ), $value )
758 - );
759 - }
760 -
761 - if ( is_object( $value ) && ! method_exists( $value, '__toString' ) ) {
762 - return '';
763 - }
764 -
765 - return (string) $value;
766 - }
767 -
768 - public static function is_empty( $value ): bool {
769 - return '0' !== $value && 0 !== $value && empty( $value );
770 - }
771 -
772 - public static function contains_registered_shortcode( $string ) {
773 - global $shortcode_tags;
774 -
775 - foreach ( array_keys( $shortcode_tags ) as $shortcode ) {
776 - if ( strpos( $string, "[$shortcode" ) !== false ) {
777 - return true;
778 - }
779 - }
780 -
781 - return false;
782 - }
783 -
784 - /**
785 - * Check if string is a WordPress password hash
786 - * Supports all WordPress hash formats:
787 - * - Old Portable Hash: $P$...
788 - * - Bcrypt: $2a$, $2y$...
789 - *
790 - * @param string $hash Password hash to check
791 - * @return bool
792 - */
793 - public static function is_wp_password_hash( $hash ) {
794 - if ( ! is_string( $hash ) || empty( $hash ) ) {
795 - return false;
796 - }
797 -
798 - // Old Portable Hash format: $P$[A-Za-z0-9./]{31}
799 - if ( preg_match( '/^\$P\$[A-Za-z0-9\.\/]{31}$/', $hash ) ) {
800 - return true;
801 - }
802 -
803 - // Bcrypt format: $2a$, $2x$, $2y$ followed by cost and hash
804 - if ( preg_match( '/^\$2[axy]\$\d{2}\$[A-Za-z0-9\.\/]{53}$/', $hash ) ) {
805 - return true;
806 - }
807 -
808 - return false;
809 - }
810 -
811 - public static function get_array_of_user_roles( $settings ) {
812 - if ( is_string( $settings ) ) {
813 - return '' === $settings ? array() : array( $settings );
814 - }
815 -
816 - if ( ! is_array( $settings ) ) {
817 - return array();
818 - }
819 -
820 - return $settings;
821 - }
822 -
823 - public static function get_main_user_role_by_priority( $roles ): string {
824 - if ( is_string( $roles ) ) {
825 - $roles = array( $roles );
826 - }
827 - $wp_roles_priority = array(
828 - 'editor' => 4,
829 - 'author' => 3,
830 - 'contributor' => 2,
831 - 'subscriber' => 1,
832 - );
833 -
834 - $wp_roles = array_intersect( $roles, array_keys( $wp_roles_priority ) );
835 - $custom_roles = array_diff( $roles, array_keys( $wp_roles_priority ) );
836 -
837 - usort(
838 - $wp_roles,
839 - function ( $a, $b ) use ( $wp_roles_priority ) {
840 - return ( $wp_roles_priority[ $b ] ?? 0 ) <=> ( $wp_roles_priority[ $a ] ?? 0 );
841 - }
842 - );
843 -
844 - return $wp_roles[0] ?? $custom_roles[0] ?? '';
845 - }
846 -
847 -
848 -
849 -}
1 +<?php
2 +
3 +namespace Jet_Form_Builder\Classes;
4 +
5 +// If this file is called directly, abort.
6 +use Jet_Form_Builder\Plugin;
7 +
8 +if ( ! defined( 'WPINC' ) ) {
9 + die;
10 +}
11 +
12 +
13 +class Tools {
14 +
15 + const EMPTY_DEEP_VALUE = self::class;
16 +
17 + public static function is_editor() {
18 + return self::is_block_editor() || self::is_elementor_editor();
19 + }
20 +
21 + public static function is_block_editor() {
22 + $action = ! empty( $_GET['context'] ) ? $_GET['context'] : '';
23 +
24 + if ( isset( $_GET['action'] ) ) {
25 + $action = $action ? $action : $_GET['action'];
26 + }
27 +
28 + return in_array( $action, array( 'add', 'edit' ) );
29 + }
30 +
31 + public static function is_elementor_editor() {
32 + if ( ! defined( 'ELEMENTOR_VERSION' ) ) {
33 + return false;
34 + }
35 + return ( \Elementor\Plugin::instance()->editor->is_edit_mode() );
36 + }
37 +
38 + /**
39 + * Returns all post types list to use in JS components
40 + *
41 + * @param bool $placeholder
42 + *
43 + * @param array $args
44 + * @param string $operator
45 + *
46 + * @return array [type] [description]
47 + */
48 + public static function get_post_types_for_js( $placeholder = false, $args = array(), $operator = 'and' ) {
49 +
50 + $post_types = get_post_types( $args, 'objects', $operator );
51 +
52 + $post_types_list = array();
53 +
54 + if ( $placeholder && is_array( $placeholder ) ) {
55 + $placeholder['value'] = isset( $placeholder['value'] ) ? $placeholder['value'] : '';
56 + $post_types_list[] = $placeholder;
57 + }
58 +
59 + foreach ( $post_types as $post_type ) {
60 + if ( $post_type->name !== Plugin::instance()->post_type->slug() ) {
61 + $post_types_list[] = array(
62 + 'value' => $post_type->name,
63 + 'label' => $post_type->label,
64 + );
65 + }
66 + }
67 +
68 + return self::with_placeholder( $post_types_list );
69 + }
70 +
71 + /**
72 + * Get post types list for options.
73 + *
74 + * @return array
75 + */
76 + public static function get_post_types_for_options() {
77 + return self::get_post_types_for_js( false, array( 'public' => true ) );
78 + }
79 +
80 + /**
81 + * Sanitize WYSIWYG field
82 + *
83 + * @param $input
84 + *
85 + * @return string
86 + */
87 + public static function sanitize_wysiwyg( $input ) {
88 + $input = wpautop( $input );
89 +
90 + return wp_kses_post( $input );
91 + }
92 +
93 + /**
94 + * Return all taxonomies list to use in JS components
95 + *
96 + * @return [type] [description]
97 + */
98 + public static function get_taxonomies_for_js() {
99 + $taxonomies = get_taxonomies( array(), 'objects' );
100 +
101 + return self::with_placeholder( self::prepare_list_for_js( $taxonomies, 'name', 'label' ) );
102 + }
103 +
104 + public static function get_generators_list_for_js() {
105 + $generators = Plugin::instance()->form->get_generators_list();
106 +
107 + return self::prepare_list_for_js( $generators );
108 + }
109 +
110 + public static function get_allowed_mimes_list_for_js() {
111 + $mimes = get_allowed_mime_types();
112 +
113 + $mimes_list = array();
114 + foreach ( $mimes as $mime ) {
115 + $mimes_list[] = array(
116 + 'label' => $mime,
117 + 'value' => $mime
118 + );
119 + }
120 +
121 + return $mimes_list;
122 + }
123 +
124 + /**
125 + * Returns all registeredroles for JS
126 + */
127 + public static function get_user_roles_for_js() {
128 +
129 + $roles = self::get_user_roles();
130 + $result = array();
131 +
132 + foreach ( $roles as $role => $label ) {
133 + $result[] = array(
134 + 'value' => $role,
135 + 'label' => $label,
136 + );
137 + }
138 +
139 + return self::with_placeholder( $result );
140 + }
141 +
142 + public static function get_options_pages_for_js() {
143 + $pages = array();
144 +
145 + if ( function_exists( 'jet_engine' ) ) {
146 + $pages = jet_engine()->options_pages->get_options_pages_for_select();
147 + }
148 +
149 + return self::prepare_list_for_js( $pages );
150 + }
151 +
152 + /**
153 + * Returns pages list
154 + * @return [type] [description]
155 + */
156 + public static function get_pages_list_for_js() {
157 + $pages = get_pages();
158 +
159 + return self::prepare_list_for_js( $pages, 'ID', 'post_title' );
160 + }
161 +
162 + /**
163 + * Returns pages list
164 + *
165 + * @param bool $for_elementor
166 + *
167 + * @return array [description]
168 + */
169 + public static function get_forms_list_for_js( $for_elementor = false ) {
170 + $posts = get_posts( array(
171 + 'post_status' => 'publish',
172 + 'posts_per_page' => - 1,
173 + 'post_type' => jet_form_builder()->post_type->slug(),
174 + ) );
175 +
176 + return self::prepare_list_for_js( $posts, 'ID', 'post_title', $for_elementor );
177 + }
178 +
179 + public static function get_form_settings_options( $for_elementor = false ) {
180 + $submit_type = array(
181 + 'reload' => 'Page Reload',
182 + 'ajax' => 'AJAX',
183 + );
184 + $fields_layout = array(
185 + 'column' => 'Column',
186 + 'row' => 'Row'
187 + );
188 +
189 + if ( ! $for_elementor ) {
190 + $submit_type = self::prepare_list_for_js( $submit_type );
191 + $fields_layout = self::prepare_list_for_js( $fields_layout );
192 + }
193 +
194 + return array(
195 + 'submit_type' => $submit_type,
196 + 'fields_layout' => $fields_layout
197 + );
198 + }
199 +
200 + /**
201 + * Returns all registered user roles
202 + *
203 + * @param string[] $exclude
204 + *
205 + * @return array [type] [description]
206 + */
207 + public static function get_user_roles( $exclude = array( 'administrator' ) ) {
208 +
209 + if ( ! function_exists( 'get_editable_roles' ) ) {
210 + return array();
211 + } else {
212 + $roles = get_editable_roles();
213 + $result = array();
214 +
215 + foreach ( $roles as $role => $data ) {
216 + if ( ! in_array( $role, $exclude ) ) {
217 + $result[ $role ] = $data['name'];
218 + }
219 + }
220 + return $result;
221 + }
222 + }
223 +
224 + /**
225 + * Prepare passed array for using in JS options
226 + *
227 + * @return [type] [description]
228 + */
229 + public static function prepare_list_for_js( $array = array(), $value_key = null, $label_key = null, $for_elementor = false ) {
230 +
231 + $result = array();
232 +
233 + if ( ! is_array( $array ) || empty( $array ) ) {
234 + return $result;
235 + }
236 +
237 + foreach ( $array as $key => $item ) {
238 +
239 + $value = null;
240 + $label = null;
241 +
242 + if ( is_object( $item ) ) {
243 + $value = $item->$value_key;
244 + $label = $item->$label_key;
245 + } elseif ( is_array( $item ) ) {
246 + $value = $item[ $value_key ];
247 + $label = $item[ $label_key ];
248 + } else {
249 + $value = $key;
250 + $label = $item;
251 + }
252 +
253 + if ( $for_elementor ) {
254 + $result[ $value ] = $label;
255 + } else {
256 + $result[] = array(
257 + 'value' => $value,
258 + 'label' => $label,
259 + );
260 + }
261 + }
262 +
263 + return $result;
264 +
265 + }
266 +
267 + public static function with_placeholder( $array, $label = '--' ) {
268 + return array_merge(
269 + array(
270 + array( 'label' => $label, 'value' => '' ),
271 + ),
272 + $array
273 + );
274 + }
275 +
276 + /**
277 + * Check if is valid timestamp
278 + *
279 + * @param mixed $timestamp
280 + *
281 + * @return boolean
282 + */
283 + public static function is_valid_timestamp( $timestamp ) {
284 + return ( ( string ) ( int ) $timestamp === $timestamp || ( int ) $timestamp === $timestamp )
285 + && ( $timestamp <= PHP_INT_MAX )
286 + && ( $timestamp >= ~PHP_INT_MAX );
287 + }
288 +
289 + public static function array_merge_intersect_key( $source, $arrays ) {
290 + foreach ( $source as $index => $path ) {
291 + $name = isset( $path['path'] ) ? $path['path'] : $index;
292 +
293 + $deep_value = self::getDeepValue( $name, $arrays );
294 +
295 + if ( self::EMPTY_DEEP_VALUE === $deep_value ) {
296 + unset( $source[ $index ] );
297 + } else {
298 + $source[ $index ] = $deep_value;
299 + }
300 + }
301 +
302 + return $source;
303 + }
304 +
305 + public static function getDeepValue( $key, $source ) {
306 + $keys = explode( '/', $key );
307 + $last = end( $keys );
308 + reset( $keys );
309 +
310 + return self::deep( $keys, current( $keys ), $last, $source );
311 + }
312 +
313 + private static function deep( $array, $key, $last, $source ) {
314 +
315 + if ( isset( $source[ $key ] ) ) {
316 + if ( $last !== $key ) {
317 + return self::deep( $array, next( $array ), $last, $source[ $key ] );
318 + }
319 +
320 + return $source[ $key ];
321 + }
322 +
323 + return self::EMPTY_DEEP_VALUE;
324 + }
325 +
326 + public static function run_callbacks( $callbacks = array(), ...$params ) {
327 + if ( ! $callbacks ) {
328 + return;
329 + }
330 +
331 + foreach ( $callbacks as $callback ) {
332 + if ( ! is_callable( $callback ) ) {
333 + continue;
334 + }
335 + call_user_func( $callback, ...$params );
336 + }
337 + }
338 +
339 + public static function decode_unserializable( $value ) {
340 + $data = json_decode( $value, true );
341 +
342 + return $data ? $data : maybe_unserialize( $value );
343 + }
344 +
345 + public static function maybe_recursive_sanitize( $source = null ) {
346 + if ( ! is_array( $source ) ) {
347 + return esc_attr( $source );
348 + }
349 +
350 + $result = array();
351 + foreach ( $source as $key => $value ) {
352 + $result[ $key ] = self::maybe_recursive_sanitize( $value );
353 + }
354 +
355 + return $result;
356 + }
357 +
358 + public static function sanitize_files( $source ) {
359 + if ( ! is_array( $source ) ) {
360 + return false;
361 + }
362 +
363 + $response = array();
364 +
365 + foreach ( $source as $index => $item ) {
366 + foreach ( $item as $key => $value ) {
367 + switch ( $key ) {
368 + case 'error':
369 + case 'size':
370 + $response[ $index ][ $key ] = absint( $value );
371 + break;
372 + default:
373 + $response[ $index ][ $key ] = esc_attr( $value );
374 + }
375 + }
376 + }
377 +
378 + return $response;
379 + }
380 +
381 +}