PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.4.5
JetFormBuilder — Dynamic Blocks Form Builder v3.4.5
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 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / includes / classes / tools.php
jetformbuilder / includes / classes Last commit date
arguments 1 year ago arrayable 2 years ago filters 1 year ago http 2 years ago macro-constants 2 years ago post 1 year ago resources 1 year ago theme 2 years ago attributes-trait.php 2 years ago base-attributes-trait.php 2 years ago builder-helper.php 1 year ago compatibility.php 2 years ago date-tools.php 2 years ago gallery.php 2 years ago get-icon-trait.php 2 years ago get-template-trait.php 2 years ago html-attributes-trait.php 2 years ago instance-trait.php 2 years ago regexp-tools.php 2 years ago tools.php 1 year ago
tools.php
668 lines
1 <?php
2
3 namespace Jet_Form_Builder\Classes;
4
5 use Jet_Form_Builder\Plugin;
6
7 // If this file is called directly, abort.
8 if ( ! defined( 'WPINC' ) ) {
9 die;
10 }
11
12 class Tools {
13
14 const EMPTY_DEEP_VALUE = self::class;
15
16 public static function is_editor() {
17 return self::is_block_editor() || self::is_elementor_editor() || self::is_bricks_editor();
18 }
19
20 public static function is_block_editor() {
21 $allowed_actions = array( 'add', 'edit' );
22
23 return (
24 in_array( self::sanitize_get_param( 'context' ), $allowed_actions, true )
25 || in_array( self::sanitize_get_param( 'action' ), $allowed_actions, true )
26 );
27 }
28
29 public static function sanitize_get_param( $param_name ) {
30 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
31 return ! empty( $_GET[ $param_name ] ) ? sanitize_key( $_GET[ $param_name ] ) : '';
32 }
33
34 public static function is_elementor_editor() {
35 if ( ! defined( 'ELEMENTOR_VERSION' ) ) {
36 return false;
37 }
38
39 return ( \Elementor\Plugin::instance()->editor->is_edit_mode() );
40 }
41
42 public static function is_bricks_editor() {
43 if ( ! defined( 'BRICKS_VERSION' ) ) {
44 return false;
45 }
46
47 return ( bricks_is_builder() );
48 }
49
50 /**
51 * Returns all post types list to use in JS components
52 *
53 * @param bool $placeholder
54 *
55 * @param array $args
56 * @param string $operator
57 *
58 * @return array [type] [description]
59 */
60 public static function get_post_types_for_js( $placeholder = false, $args = array(), $operator = 'and' ) {
61
62 $post_types = get_post_types( $args, 'objects', $operator );
63
64 $post_types_list = array();
65
66 if ( $placeholder && is_array( $placeholder ) ) {
67 $placeholder['value'] = isset( $placeholder['value'] ) ? $placeholder['value'] : '';
68 $post_types_list[] = $placeholder;
69 }
70
71 foreach ( $post_types as $post_type ) {
72 if ( Plugin::instance()->post_type->slug() !== $post_type->name ) {
73 $post_types_list[] = array(
74 'value' => $post_type->name,
75 'label' => $post_type->label,
76 );
77 }
78 }
79
80 return self::with_placeholder( $post_types_list );
81 }
82
83 /**
84 * Get post types list for options.
85 *
86 * @return array
87 */
88 public static function get_post_types_for_options(): array {
89 return self::get_post_types_for_js( false, array( 'public' => true ) );
90 }
91
92 private static function get_escape_func( $type ) {
93 switch ( $type ) {
94 case 'template':
95 default:
96 return array( self::class, 'esc_template' );
97 }
98 }
99
100 /**
101 * Sanitize WYSIWYG field
102 *
103 * @param $input
104 *
105 * @return string
106 */
107 public static function sanitize_wysiwyg( $input ): string {
108 $input = wp_kses_post( $input );
109
110 return wp_specialchars_decode( stripslashes( $input ), ENT_COMPAT );
111 }
112
113 /**
114 * Return all taxonomies list to use in JS components
115 *
116 * @param array $args
117 *
118 * @return array
119 */
120 public static function get_taxonomies_for_js( $args = array() ): array {
121 $taxonomies = get_taxonomies( $args, 'objects' );
122
123 return self::with_placeholder( self::prepare_list_for_js( $taxonomies, 'name', 'label' ) );
124 }
125
126 public static function get_taxonomies_for_modify( array $args = array() ): array {
127 $taxonomies = get_taxonomies( $args, 'objects' );
128 $response = array();
129
130 /** @var \WP_Taxonomy $taxonomy */
131 foreach ( $taxonomies as $taxonomy ) {
132 $response[] = array(
133 'label' => $taxonomy->label,
134 'value' => "jet_tax__{$taxonomy->name}",
135 );
136 }
137
138 return self::with_placeholder( $response );
139 }
140
141 public static function get_generators_list_for_js(): array {
142 $generators = Plugin::instance()->form->get_generators_list();
143
144 return self::prepare_list_for_js( $generators );
145 }
146
147 public static function get_allowed_mimes_list_for_js(): array {
148 return array_values( get_allowed_mime_types() );
149 }
150
151 /**
152 * Returns all registeredroles for JS
153 */
154 public static function get_user_roles_for_js( $exclude = array( 'administrator' ) ) {
155
156 $roles = self::get_user_roles( $exclude );
157 $result = array();
158
159 foreach ( $roles as $role => $label ) {
160 $result[] = array(
161 'value' => $role,
162 'label' => $label,
163 );
164 }
165
166 return self::with_placeholder( $result );
167 }
168
169 public static function get_options_pages_for_js() {
170 $pages = array();
171
172 if ( function_exists( 'jet_engine' ) ) {
173 $pages = jet_engine()->options_pages->get_options_pages_for_select();
174 }
175
176 return self::prepare_list_for_js( $pages );
177 }
178
179 /**
180 * Returns pages list
181 *
182 * @return [type] [description]
183 */
184 public static function get_pages_list_for_js() {
185 $pages = get_pages();
186
187 return self::prepare_list_for_js( $pages, 'ID', 'post_title' );
188 }
189
190 /**
191 * Returns pages list
192 *
193 * @param bool $for_elementor
194 *
195 * @param array $args
196 *
197 * @return array [description]
198 */
199 public static function get_forms_list_for_js( $for_elementor = false, $args = array() ) {
200 $posts = get_posts(
201 array_merge(
202 array(
203 'post_status' => 'publish',
204 'posts_per_page' => - 1,
205 'post_type' => jet_form_builder()->post_type->slug(),
206 ),
207 $args
208 )
209 );
210
211 $prepared_list_for_js = self::prepare_list_for_js( $posts, 'ID', 'post_title', $for_elementor );
212
213 if ( true === $for_elementor ) {
214 $manual_form_option = array(
215 'manual_form_id' => __( 'Enter Form ID Manually / Dynamically', 'jet-form-builder' ),
216 );
217
218 $prepared_list_for_js = array_replace( $manual_form_option, $prepared_list_for_js );
219 } else {
220 $manual_form_option[] = array(
221 'value' => -1,
222 'label' => __( 'Enter Form ID Manually / Dynamically', 'jet-form-builder' ),
223 );
224
225 $prepared_list_for_js = array_merge( $manual_form_option, $prepared_list_for_js );
226 }
227
228 return $prepared_list_for_js;
229 }
230
231 /**
232 * Returns all registered user roles
233 *
234 * @param string[] $exclude
235 *
236 * @return array [type] [description]
237 */
238 public static function get_user_roles( $exclude = array( 'administrator' ) ) {
239
240 if ( ! function_exists( 'get_editable_roles' ) ) {
241 return array();
242 } else {
243 $roles = get_editable_roles();
244 $result = array();
245
246 foreach ( $roles as $role => $data ) {
247 if ( ! in_array( $role, $exclude, true ) ) {
248 $result[ $role ] = $data['name'];
249 }
250 }
251
252 return $result;
253 }
254 }
255
256 /**
257 * Prepare passed array for using in JS options
258 *
259 * @param array $array
260 * @param null $value_key
261 * @param null $label_key
262 * @param bool $for_elementor
263 *
264 * Only if $for_elementor === false
265 * @param array $additional_attrs
266 *
267 * @return array [type] [description]
268 */
269 public static function prepare_list_for_js(
270 $collection = array(),
271 $value_key = null,
272 $label_key = null,
273 $for_elementor = false,
274 $additional_attrs = array()
275 ) {
276
277 $result = array();
278
279 if ( ! is_array( $collection ) || empty( $collection ) ) {
280 return $result;
281 }
282
283 foreach ( $collection as $key => $item ) {
284
285 $value = null;
286 $label = null;
287
288 if ( is_scalar( $item ) ) {
289 $value = $key;
290 $label = $item;
291 } else {
292 $value = self::get_property( $item, $value_key );
293 $label = self::get_property( $item, $label_key );
294 }
295
296 if ( $for_elementor ) {
297 $result[ $value ] = $label;
298 } else {
299 $prepared = array(
300 'value' => $value,
301 'label' => $label,
302 );
303 foreach ( $additional_attrs as $attr ) {
304 $prepared[ $attr ] = self::get_property( $item, $attr );
305 }
306
307 $result[] = $prepared;
308 }
309 }
310
311 return $result;
312 }
313
314 /**
315 * @param array $collection
316 * @param string $label
317 *
318 * @return array
319 */
320 public static function with_placeholder( array $collection, string $label = '--' ): array {
321 return array_merge(
322 array(
323 array( 'label' => $label, 'value' => '' ),
324 ),
325 $collection
326 );
327 }
328
329 /**
330 * Check if is valid timestamp
331 *
332 * @param mixed $timestamp
333 *
334 * @return boolean
335 */
336 public static function is_valid_timestamp( $timestamp ): bool {
337 return ( (string) (int) $timestamp === $timestamp || (int) $timestamp === $timestamp )
338 && ( $timestamp <= PHP_INT_MAX )
339 && ( $timestamp >= ~PHP_INT_MAX );
340 }
341
342 public static function array_merge_intersect_key( $source, $arrays ) {
343 foreach ( $source as $index => $path ) {
344 $name = $path['path'] ?? $index;
345
346 $deep_value = self::getDeepValue( $name, $arrays );
347
348 if ( self::EMPTY_DEEP_VALUE === $deep_value ) {
349 unset( $source[ $index ] );
350 } else {
351 $source[ $index ] = $deep_value;
352 }
353 }
354
355 return $source;
356 }
357
358 // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
359 public static function getDeepValue( $key, $source ) {
360 $keys = explode( '/', $key );
361 $last = end( $keys );
362 reset( $keys );
363
364 return self::deep( $keys, current( $keys ), $last, $source );
365 }
366
367 private static function deep( $collection, $key, $last, $source ) {
368
369 if ( isset( $source[ $key ] ) ) {
370 if ( $last !== $key ) {
371 return self::deep( $collection, next( $collection ), $last, $source[ $key ] );
372 }
373
374 return $source[ $key ];
375 }
376
377 return self::EMPTY_DEEP_VALUE;
378 }
379
380 public static function call( $callback, ...$params ) {
381 if ( ! is_callable( $callback ) ) {
382 return;
383 }
384
385 call_user_func( $callback, ...$params );
386 }
387
388 public static function decode_unserializable( $value ) {
389 $data = self::decode_json( $value );
390
391 // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
392 return $data ?: maybe_unserialize( $value );
393 }
394
395 public static function decode_json( $json ) {
396 if ( is_array( $json ) ) {
397 foreach ( $json as $key => $row ) {
398 $json[ $key ] = static::decode_json( $row );
399 }
400
401 return $json;
402 }
403 if ( defined( 'JSON_INVALID_UTF8_IGNORE' ) ) {
404 // phpcs:ignore PHPCompatibility.Constants.NewConstants
405 return json_decode( $json, true, 512, JSON_INVALID_UTF8_IGNORE );
406 }
407
408 return json_decode( $json, true );
409 }
410
411 public static function encode_json( $json ) {
412 return wp_json_encode( $json, JSON_UNESCAPED_UNICODE );
413 }
414
415 public static function sanitize_recursive( $source = null ) {
416 if ( ! is_array( $source ) ) {
417 return self::sanitize( $source );
418 }
419
420 $result = array();
421
422 foreach ( $source as $key => $value ) {
423 $result[ $key ] = self::sanitize_recursive( $value );
424 }
425
426 return $result;
427 }
428
429 public static function maybe_recursive_sanitize( $source = null ) {
430 return self::sanitize_recursive( $source );
431 }
432
433 public static function sanitize( $source ) {
434 if ( self::is_url( $source ) ) {
435 return esc_url_raw( $source );
436 }
437
438 return self::sanitize_text_field( $source );
439 }
440
441 public static function is_url( $url ) {
442 return wp_http_validate_url( $url );
443 }
444
445 public static function sanitize_text_field( $source, $replace_enqueue = true ) {
446 $str = (string) $source;
447
448 $filtered = wp_check_invalid_utf8( $str );
449 $sanitize_callback = apply_filters( 'jet-form-builder/sanitize-string/callback', false );
450
451 if ( $sanitize_callback && is_callable( $sanitize_callback ) ) {
452 $filtered = call_user_func( $sanitize_callback, $filtered );
453 } elseif ( $replace_enqueue && false !== strpos( $filtered, '<' ) ) {
454 $filtered = wp_kses_post( $filtered );
455 }
456
457 return trim( $filtered );
458 }
459
460 /**
461 * @param $type
462 * @param mixed ...$values
463 *
464 * @return mixed
465 */
466 private static function call_escape_func( $type, ...$values ) {
467 return call_user_func( self::get_escape_func( $type ), ...$values );
468 }
469
470 public static function recursive_wp_kses( $source, $allowed_html = 'strip' ) {
471 if ( ! is_array( $source ) ) {
472 return wp_kses( $source, $allowed_html );
473 }
474
475 $result = array();
476 foreach ( $source as $key => $value ) {
477 $result[ $key ] = self::sanitize_recursive( $value );
478 }
479
480 return $result;
481 }
482
483 public static function sanitize_files( $source ) {
484 if ( ! is_array( $source ) ) {
485 return false;
486 }
487
488 $response = array();
489
490 foreach ( $source as $index => $item ) {
491 foreach ( $item as $key => $value ) {
492 switch ( $key ) {
493 case 'error':
494 case 'size':
495 $response[ $index ][ $key ] = absint( $value );
496 break;
497 case 'name':
498 $response[ $index ][ $key ] = sanitize_file_name( $value );
499 break;
500 case 'type':
501 $response[ $index ][ $key ] = sanitize_mime_type( $value );
502 break;
503 case 'tmp_name':
504 $response[ $index ][ $key ] = sanitize_text_field( $value );
505 break;
506 }
507 }
508 }
509
510 return $response;
511 }
512
513 /**
514 * @param $source
515 * @param bool $replace_enqueue
516 *
517 * @return string
518 */
519 private static function esc_template( $source, $replace_enqueue = true ): string {
520 return self::sanitize_text_field( $source, $replace_enqueue );
521 }
522
523 public static function get_jet_engine_version() {
524 return function_exists( 'jet_engine' )
525 ? jet_engine()->get_version()
526 : false;
527 }
528
529 public static function is_readable( string $filename ) {
530 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
531 return strlen( $filename ) <= PHP_MAXPATHLEN && @is_readable( $filename );
532 }
533
534 /**
535 * Returns template path
536 *
537 * @param [type] $path [description]
538 *
539 * @return [type] [description]
540 */
541 public static function get_global_template( $path = '' ) {
542 return JET_FORM_BUILDER_PATH . 'templates/' . $path;
543 }
544
545 public static function get_property( $source, $name, $if_not_exist = '' ) {
546 if ( is_object( $source ) ) {
547 return $source->{$name} ?? $if_not_exist;
548 }
549
550 return $source[ $name ] ?? $if_not_exist;
551 }
552
553 public static function esc_template_string( $source, $replace_enqueue = true ) {
554 return self::call_escape_func( 'template', $source, $replace_enqueue );
555 }
556
557 public static function is_repeater_val( $value ): bool {
558 if ( is_array( $value ) && ! empty( $value ) ) {
559 foreach ( $value as $item ) {
560 return is_array( $item );
561 }
562 }
563
564 return false;
565 }
566
567 public static function set_current_post( $post_id ) {
568 global $post;
569
570 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
571 $post = get_post( absint( $post_id ) );
572 }
573
574 public static function prepare_repeater_value( $value, $fields_map ): array {
575 $prepared_value = array();
576
577 foreach ( $value as $index => $row ) {
578 $prepared_row = array();
579
580 foreach ( $row as $item_key => $item_value ) {
581 $item_key = ! empty( $fields_map[ $item_key ] ) ? self::sanitize_text_field( $fields_map[ $item_key ] ) : $item_key;
582 $prepared_row[ $item_key ] = $item_value;
583 }
584
585 $prepared_value[ 'item-' . $index ] = $prepared_row;
586 }
587
588 return $prepared_value;
589 }
590
591 public static function is_webhook(): bool {
592 return (
593 defined( 'JET_FB_REST_WEBHOOK' ) &&
594 JET_FB_REST_WEBHOOK
595 );
596 }
597
598 public static function esc_attr( $value ) {
599 if ( ! is_scalar( $value ) ) {
600 return esc_attr( self::encode_json( $value ) );
601 }
602
603 return esc_attr( $value );
604 }
605
606 public static function get_suffix(): string {
607 return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
608 }
609
610 /**
611 * Get from function below
612 *
613 * @return string
614 * @see \retrieve_password
615 */
616 public static function get_site_name(): string {
617 if ( is_multisite() ) {
618 return get_network()->site_name;
619 }
620
621 /*
622 * The blogname option is escaped with esc_html on the way into the database
623 * in sanitize_option. We want to reverse this for the plain text arena of emails.
624 */
625
626 return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
627 }
628
629 /**
630 * @param mixed $value
631 */
632 public static function to_string( $value ): string {
633 if ( is_array( $value ) ) {
634 return implode(
635 ',',
636 array_map( array( self::class, 'to_string' ), $value )
637 );
638 }
639
640 if ( is_object( $value ) && ! method_exists( $value, '__toString' ) ) {
641 return '';
642 }
643
644 return (string) $value;
645 }
646
647 public static function is_empty( $value ): bool {
648 return '0' !== $value && 0 !== $value && empty( $value );
649 }
650
651 public static function contains_registered_shortcode( $string ) {
652 global $shortcode_tags;
653
654 foreach ( array_keys( $shortcode_tags ) as $shortcode ) {
655 if ( strpos( $string, "[$shortcode" ) !== false ) {
656 return true;
657 }
658 }
659
660 return false;
661 }
662
663 public static function is_wp_password_hash( $hash ) {
664 return preg_match( '/^\$P\$[A-Za-z0-9\.\/]{31}$/', $hash );
665 }
666
667 }
668