PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.3.4.2
JetFormBuilder — Dynamic Blocks Form Builder v3.3.4.2
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 2 years ago arrayable 2 years ago filters 2 years ago http 2 years ago macro-constants 2 years ago post 2 years ago resources 2 years ago theme 2 years ago attributes-trait.php 2 years ago base-attributes-trait.php 2 years ago builder-helper.php 2 years 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 2 years ago
tools.php
635 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 return self::prepare_list_for_js( $posts, 'ID', 'post_title', $for_elementor );
212 }
213
214 /**
215 * Returns all registered user roles
216 *
217 * @param string[] $exclude
218 *
219 * @return array [type] [description]
220 */
221 public static function get_user_roles( $exclude = array( 'administrator' ) ) {
222
223 if ( ! function_exists( 'get_editable_roles' ) ) {
224 return array();
225 } else {
226 $roles = get_editable_roles();
227 $result = array();
228
229 foreach ( $roles as $role => $data ) {
230 if ( ! in_array( $role, $exclude, true ) ) {
231 $result[ $role ] = $data['name'];
232 }
233 }
234
235 return $result;
236 }
237 }
238
239 /**
240 * Prepare passed array for using in JS options
241 *
242 * @param array $array
243 * @param null $value_key
244 * @param null $label_key
245 * @param bool $for_elementor
246 *
247 * Only if $for_elementor === false
248 * @param array $additional_attrs
249 *
250 * @return array [type] [description]
251 */
252 public static function prepare_list_for_js(
253 $collection = array(),
254 $value_key = null,
255 $label_key = null,
256 $for_elementor = false,
257 $additional_attrs = array()
258 ) {
259
260 $result = array();
261
262 if ( ! is_array( $collection ) || empty( $collection ) ) {
263 return $result;
264 }
265
266 foreach ( $collection as $key => $item ) {
267
268 $value = null;
269 $label = null;
270
271 if ( is_scalar( $item ) ) {
272 $value = $key;
273 $label = $item;
274 } else {
275 $value = self::get_property( $item, $value_key );
276 $label = self::get_property( $item, $label_key );
277 }
278
279 if ( $for_elementor ) {
280 $result[ $value ] = $label;
281 } else {
282 $prepared = array(
283 'value' => $value,
284 'label' => $label,
285 );
286 foreach ( $additional_attrs as $attr ) {
287 $prepared[ $attr ] = self::get_property( $item, $attr );
288 }
289
290 $result[] = $prepared;
291 }
292 }
293
294 return $result;
295 }
296
297 /**
298 * @param array $collection
299 * @param string $label
300 *
301 * @return array
302 */
303 public static function with_placeholder( array $collection, string $label = '--' ): array {
304 return array_merge(
305 array(
306 array( 'label' => $label, 'value' => '' ),
307 ),
308 $collection
309 );
310 }
311
312 /**
313 * Check if is valid timestamp
314 *
315 * @param mixed $timestamp
316 *
317 * @return boolean
318 */
319 public static function is_valid_timestamp( $timestamp ): bool {
320 return ( (string) (int) $timestamp === $timestamp || (int) $timestamp === $timestamp )
321 && ( $timestamp <= PHP_INT_MAX )
322 && ( $timestamp >= ~PHP_INT_MAX );
323 }
324
325 public static function array_merge_intersect_key( $source, $arrays ) {
326 foreach ( $source as $index => $path ) {
327 $name = $path['path'] ?? $index;
328
329 $deep_value = self::getDeepValue( $name, $arrays );
330
331 if ( self::EMPTY_DEEP_VALUE === $deep_value ) {
332 unset( $source[ $index ] );
333 } else {
334 $source[ $index ] = $deep_value;
335 }
336 }
337
338 return $source;
339 }
340
341 // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
342 public static function getDeepValue( $key, $source ) {
343 $keys = explode( '/', $key );
344 $last = end( $keys );
345 reset( $keys );
346
347 return self::deep( $keys, current( $keys ), $last, $source );
348 }
349
350 private static function deep( $collection, $key, $last, $source ) {
351
352 if ( isset( $source[ $key ] ) ) {
353 if ( $last !== $key ) {
354 return self::deep( $collection, next( $collection ), $last, $source[ $key ] );
355 }
356
357 return $source[ $key ];
358 }
359
360 return self::EMPTY_DEEP_VALUE;
361 }
362
363 public static function call( $callback, ...$params ) {
364 if ( ! is_callable( $callback ) ) {
365 return;
366 }
367
368 call_user_func( $callback, ...$params );
369 }
370
371 public static function decode_unserializable( $value ) {
372 $data = self::decode_json( $value );
373
374 // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
375 return $data ?: maybe_unserialize( $value );
376 }
377
378 public static function decode_json( $json ) {
379 if ( is_array( $json ) ) {
380 foreach ( $json as $key => $row ) {
381 $json[ $key ] = static::decode_json( $row );
382 }
383
384 return $json;
385 }
386 if ( defined( 'JSON_INVALID_UTF8_IGNORE' ) ) {
387 // phpcs:ignore PHPCompatibility.Constants.NewConstants
388 return json_decode( $json, true, 512, JSON_INVALID_UTF8_IGNORE );
389 }
390
391 return json_decode( $json, true );
392 }
393
394 public static function encode_json( $json ) {
395 return wp_json_encode( $json, JSON_UNESCAPED_UNICODE );
396 }
397
398 public static function sanitize_recursive( $source = null ) {
399 if ( ! is_array( $source ) ) {
400 return self::sanitize( $source );
401 }
402
403 $result = array();
404
405 foreach ( $source as $key => $value ) {
406 $result[ $key ] = self::sanitize_recursive( $value );
407 }
408
409 return $result;
410 }
411
412 public static function maybe_recursive_sanitize( $source = null ) {
413 return self::sanitize_recursive( $source );
414 }
415
416 public static function sanitize( $source ) {
417 if ( self::is_url( $source ) ) {
418 return esc_url_raw( $source );
419 }
420
421 return self::sanitize_text_field( $source );
422 }
423
424 public static function is_url( $url ) {
425 return wp_http_validate_url( $url );
426 }
427
428 public static function sanitize_text_field( $source, $replace_enqueue = true ) {
429 $str = (string) $source;
430
431 $filtered = wp_check_invalid_utf8( $str );
432 $sanitize_callback = apply_filters( 'jet-form-builder/sanitize-string/callback', false );
433
434 if ( $sanitize_callback && is_callable( $sanitize_callback ) ) {
435 $filtered = call_user_func( $sanitize_callback, $filtered );
436 } elseif ( $replace_enqueue && false !== strpos( $filtered, '<' ) ) {
437 $filtered = wp_kses_post( $filtered );
438 }
439
440 return trim( $filtered );
441 }
442
443 /**
444 * @param $type
445 * @param mixed ...$values
446 *
447 * @return mixed
448 */
449 private static function call_escape_func( $type, ...$values ) {
450 return call_user_func( self::get_escape_func( $type ), ...$values );
451 }
452
453 public static function recursive_wp_kses( $source, $allowed_html = 'strip' ) {
454 if ( ! is_array( $source ) ) {
455 return wp_kses( $source, $allowed_html );
456 }
457
458 $result = array();
459 foreach ( $source as $key => $value ) {
460 $result[ $key ] = self::sanitize_recursive( $value );
461 }
462
463 return $result;
464 }
465
466 public static function sanitize_files( $source ) {
467 if ( ! is_array( $source ) ) {
468 return false;
469 }
470
471 $response = array();
472
473 foreach ( $source as $index => $item ) {
474 foreach ( $item as $key => $value ) {
475 switch ( $key ) {
476 case 'error':
477 case 'size':
478 $response[ $index ][ $key ] = absint( $value );
479 break;
480 case 'name':
481 $response[ $index ][ $key ] = sanitize_file_name( $value );
482 break;
483 case 'type':
484 $response[ $index ][ $key ] = sanitize_mime_type( $value );
485 break;
486 case 'tmp_name':
487 $response[ $index ][ $key ] = sanitize_text_field( $value );
488 break;
489 }
490 }
491 }
492
493 return $response;
494 }
495
496 /**
497 * @param $source
498 * @param bool $replace_enqueue
499 *
500 * @return string
501 */
502 private static function esc_template( $source, $replace_enqueue = true ): string {
503 return self::sanitize_text_field( $source, $replace_enqueue );
504 }
505
506 public static function get_jet_engine_version() {
507 return function_exists( 'jet_engine' )
508 ? jet_engine()->get_version()
509 : false;
510 }
511
512 public static function is_readable( string $filename ) {
513 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
514 return strlen( $filename ) <= PHP_MAXPATHLEN && @is_readable( $filename );
515 }
516
517 /**
518 * Returns template path
519 *
520 * @param [type] $path [description]
521 *
522 * @return [type] [description]
523 */
524 public static function get_global_template( $path = '' ) {
525 return JET_FORM_BUILDER_PATH . 'templates/' . $path;
526 }
527
528 public static function get_property( $source, $name, $if_not_exist = '' ) {
529 if ( is_object( $source ) ) {
530 return $source->{$name} ?? $if_not_exist;
531 }
532
533 return $source[ $name ] ?? $if_not_exist;
534 }
535
536 public static function esc_template_string( $source, $replace_enqueue = true ) {
537 return self::call_escape_func( 'template', $source, $replace_enqueue );
538 }
539
540 public static function is_repeater_val( $value ): bool {
541 if ( is_array( $value ) && ! empty( $value ) ) {
542 foreach ( $value as $item ) {
543 return is_array( $item );
544 }
545 }
546
547 return false;
548 }
549
550 public static function set_current_post( $post_id ) {
551 global $post;
552
553 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
554 $post = get_post( absint( $post_id ) );
555 }
556
557 public static function prepare_repeater_value( $value, $fields_map ): array {
558 $prepared_value = array();
559
560 foreach ( $value as $index => $row ) {
561 $prepared_row = array();
562
563 foreach ( $row as $item_key => $item_value ) {
564 $item_key = ! empty( $fields_map[ $item_key ] ) ? self::sanitize_text_field( $fields_map[ $item_key ] ) : $item_key;
565 $prepared_row[ $item_key ] = $item_value;
566 }
567
568 $prepared_value[ 'item-' . $index ] = $prepared_row;
569 }
570
571 return $prepared_value;
572 }
573
574 public static function is_webhook(): bool {
575 return (
576 defined( 'JET_FB_REST_WEBHOOK' ) &&
577 JET_FB_REST_WEBHOOK
578 );
579 }
580
581 public static function esc_attr( $value ) {
582 if ( ! is_scalar( $value ) ) {
583 return esc_attr( self::encode_json( $value ) );
584 }
585
586 return esc_attr( $value );
587 }
588
589 public static function get_suffix(): string {
590 return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
591 }
592
593 /**
594 * Get from function below
595 *
596 * @return string
597 * @see \retrieve_password
598 */
599 public static function get_site_name(): string {
600 if ( is_multisite() ) {
601 return get_network()->site_name;
602 }
603
604 /*
605 * The blogname option is escaped with esc_html on the way into the database
606 * in sanitize_option. We want to reverse this for the plain text arena of emails.
607 */
608
609 return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
610 }
611
612 /**
613 * @param mixed $value
614 */
615 public static function to_string( $value ): string {
616 if ( is_array( $value ) ) {
617 return implode(
618 ',',
619 array_map( array( self::class, 'to_string' ), $value )
620 );
621 }
622
623 if ( is_object( $value ) && ! method_exists( $value, '__toString' ) ) {
624 return '';
625 }
626
627 return (string) $value;
628 }
629
630 public static function is_empty( $value ): bool {
631 return '0' !== $value && 0 !== $value && empty( $value );
632 }
633
634 }
635