PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.1.8
JetFormBuilder — Dynamic Blocks Form Builder v3.1.8
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 macros-parser.php 2 years ago regexp-tools.php 2 years ago tools.php 2 years ago
tools.php
627 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();
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 /**
43 * Returns all post types list to use in JS components
44 *
45 * @param bool $placeholder
46 *
47 * @param array $args
48 * @param string $operator
49 *
50 * @return array [type] [description]
51 */
52 public static function get_post_types_for_js( $placeholder = false, $args = array(), $operator = 'and' ) {
53
54 $post_types = get_post_types( $args, 'objects', $operator );
55
56 $post_types_list = array();
57
58 if ( $placeholder && is_array( $placeholder ) ) {
59 $placeholder['value'] = isset( $placeholder['value'] ) ? $placeholder['value'] : '';
60 $post_types_list[] = $placeholder;
61 }
62
63 foreach ( $post_types as $post_type ) {
64 if ( Plugin::instance()->post_type->slug() !== $post_type->name ) {
65 $post_types_list[] = array(
66 'value' => $post_type->name,
67 'label' => $post_type->label,
68 );
69 }
70 }
71
72 return self::with_placeholder( $post_types_list );
73 }
74
75 /**
76 * Get post types list for options.
77 *
78 * @return array
79 */
80 public static function get_post_types_for_options(): array {
81 return self::get_post_types_for_js( false, array( 'public' => true ) );
82 }
83
84 private static function get_escape_func( $type ) {
85 switch ( $type ) {
86 case 'template':
87 default:
88 return array( self::class, 'esc_template' );
89 }
90 }
91
92 /**
93 * Sanitize WYSIWYG field
94 *
95 * @param $input
96 *
97 * @return string
98 */
99 public static function sanitize_wysiwyg( $input ): string {
100 $input = wp_kses_post( $input );
101
102 return wp_specialchars_decode( stripslashes( $input ), ENT_COMPAT );
103 }
104
105 /**
106 * Return all taxonomies list to use in JS components
107 *
108 * @param array $args
109 *
110 * @return array
111 */
112 public static function get_taxonomies_for_js( $args = array() ): array {
113 $taxonomies = get_taxonomies( $args, 'objects' );
114
115 return self::with_placeholder( self::prepare_list_for_js( $taxonomies, 'name', 'label' ) );
116 }
117
118 public static function get_taxonomies_for_modify( array $args = array() ): array {
119 $taxonomies = get_taxonomies( $args, 'objects' );
120 $response = array();
121
122 /** @var \WP_Taxonomy $taxonomy */
123 foreach ( $taxonomies as $taxonomy ) {
124 $response[] = array(
125 'label' => $taxonomy->label,
126 'value' => "jet_tax__{$taxonomy->name}",
127 );
128 }
129
130 return self::with_placeholder( $response );
131 }
132
133 public static function get_generators_list_for_js(): array {
134 $generators = Plugin::instance()->form->get_generators_list();
135
136 return self::prepare_list_for_js( $generators );
137 }
138
139 public static function get_allowed_mimes_list_for_js(): array {
140 return array_values( get_allowed_mime_types() );
141 }
142
143 /**
144 * Returns all registeredroles for JS
145 */
146 public static function get_user_roles_for_js( $exclude = array( 'administrator' ) ) {
147
148 $roles = self::get_user_roles( $exclude );
149 $result = array();
150
151 foreach ( $roles as $role => $label ) {
152 $result[] = array(
153 'value' => $role,
154 'label' => $label,
155 );
156 }
157
158 return self::with_placeholder( $result );
159 }
160
161 public static function get_options_pages_for_js() {
162 $pages = array();
163
164 if ( function_exists( 'jet_engine' ) ) {
165 $pages = jet_engine()->options_pages->get_options_pages_for_select();
166 }
167
168 return self::prepare_list_for_js( $pages );
169 }
170
171 /**
172 * Returns pages list
173 *
174 * @return [type] [description]
175 */
176 public static function get_pages_list_for_js() {
177 $pages = get_pages();
178
179 return self::prepare_list_for_js( $pages, 'ID', 'post_title' );
180 }
181
182 /**
183 * Returns pages list
184 *
185 * @param bool $for_elementor
186 *
187 * @param array $args
188 *
189 * @return array [description]
190 */
191 public static function get_forms_list_for_js( $for_elementor = false, $args = array() ) {
192 $posts = get_posts(
193 array_merge(
194 array(
195 'post_status' => 'publish',
196 'posts_per_page' => - 1,
197 'post_type' => jet_form_builder()->post_type->slug(),
198 ),
199 $args
200 )
201 );
202
203 return self::prepare_list_for_js( $posts, 'ID', 'post_title', $for_elementor );
204 }
205
206 /**
207 * Returns all registered user roles
208 *
209 * @param string[] $exclude
210 *
211 * @return array [type] [description]
212 */
213 public static function get_user_roles( $exclude = array( 'administrator' ) ) {
214
215 if ( ! function_exists( 'get_editable_roles' ) ) {
216 return array();
217 } else {
218 $roles = get_editable_roles();
219 $result = array();
220
221 foreach ( $roles as $role => $data ) {
222 if ( ! in_array( $role, $exclude, true ) ) {
223 $result[ $role ] = $data['name'];
224 }
225 }
226
227 return $result;
228 }
229 }
230
231 /**
232 * Prepare passed array for using in JS options
233 *
234 * @param array $array
235 * @param null $value_key
236 * @param null $label_key
237 * @param bool $for_elementor
238 *
239 * Only if $for_elementor === false
240 * @param array $additional_attrs
241 *
242 * @return array [type] [description]
243 */
244 public static function prepare_list_for_js(
245 $collection = array(),
246 $value_key = null,
247 $label_key = null,
248 $for_elementor = false,
249 $additional_attrs = array()
250 ) {
251
252 $result = array();
253
254 if ( ! is_array( $collection ) || empty( $collection ) ) {
255 return $result;
256 }
257
258 foreach ( $collection as $key => $item ) {
259
260 $value = null;
261 $label = null;
262
263 if ( is_scalar( $item ) ) {
264 $value = $key;
265 $label = $item;
266 } else {
267 $value = self::get_property( $item, $value_key );
268 $label = self::get_property( $item, $label_key );
269 }
270
271 if ( $for_elementor ) {
272 $result[ $value ] = $label;
273 } else {
274 $prepared = array(
275 'value' => $value,
276 'label' => $label,
277 );
278 foreach ( $additional_attrs as $attr ) {
279 $prepared[ $attr ] = self::get_property( $item, $attr );
280 }
281
282 $result[] = $prepared;
283 }
284 }
285
286 return $result;
287 }
288
289 /**
290 * @param array $collection
291 * @param string $label
292 *
293 * @return array
294 */
295 public static function with_placeholder( array $collection, string $label = '--' ): array {
296 return array_merge(
297 array(
298 array( 'label' => $label, 'value' => '' ),
299 ),
300 $collection
301 );
302 }
303
304 /**
305 * Check if is valid timestamp
306 *
307 * @param mixed $timestamp
308 *
309 * @return boolean
310 */
311 public static function is_valid_timestamp( $timestamp ): bool {
312 return ( (string) (int) $timestamp === $timestamp || (int) $timestamp === $timestamp )
313 && ( $timestamp <= PHP_INT_MAX )
314 && ( $timestamp >= ~PHP_INT_MAX );
315 }
316
317 public static function array_merge_intersect_key( $source, $arrays ) {
318 foreach ( $source as $index => $path ) {
319 $name = $path['path'] ?? $index;
320
321 $deep_value = self::getDeepValue( $name, $arrays );
322
323 if ( self::EMPTY_DEEP_VALUE === $deep_value ) {
324 unset( $source[ $index ] );
325 } else {
326 $source[ $index ] = $deep_value;
327 }
328 }
329
330 return $source;
331 }
332
333 // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
334 public static function getDeepValue( $key, $source ) {
335 $keys = explode( '/', $key );
336 $last = end( $keys );
337 reset( $keys );
338
339 return self::deep( $keys, current( $keys ), $last, $source );
340 }
341
342 private static function deep( $collection, $key, $last, $source ) {
343
344 if ( isset( $source[ $key ] ) ) {
345 if ( $last !== $key ) {
346 return self::deep( $collection, next( $collection ), $last, $source[ $key ] );
347 }
348
349 return $source[ $key ];
350 }
351
352 return self::EMPTY_DEEP_VALUE;
353 }
354
355 public static function call( $callback, ...$params ) {
356 if ( ! is_callable( $callback ) ) {
357 return;
358 }
359
360 call_user_func( $callback, ...$params );
361 }
362
363 public static function decode_unserializable( $value ) {
364 $data = self::decode_json( $value );
365
366 // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
367 return $data ?: maybe_unserialize( $value );
368 }
369
370 public static function decode_json( $json ) {
371 if ( is_array( $json ) ) {
372 foreach ( $json as $key => $row ) {
373 $json[ $key ] = static::decode_json( $row );
374 }
375
376 return $json;
377 }
378 if ( defined( 'JSON_INVALID_UTF8_IGNORE' ) ) {
379 // phpcs:ignore PHPCompatibility.Constants.NewConstants
380 return json_decode( $json, true, 512, JSON_INVALID_UTF8_IGNORE );
381 }
382
383 return json_decode( $json, true );
384 }
385
386 public static function encode_json( $json ) {
387 return wp_json_encode( $json, JSON_UNESCAPED_UNICODE );
388 }
389
390 public static function sanitize_recursive( $source = null ) {
391 if ( ! is_array( $source ) ) {
392 return self::sanitize( $source );
393 }
394
395 $result = array();
396
397 foreach ( $source as $key => $value ) {
398 $result[ $key ] = self::sanitize_recursive( $value );
399 }
400
401 return $result;
402 }
403
404 public static function maybe_recursive_sanitize( $source = null ) {
405 return self::sanitize_recursive( $source );
406 }
407
408 public static function sanitize( $source ) {
409 if ( self::is_url( $source ) ) {
410 return esc_url_raw( $source );
411 }
412
413 return self::sanitize_text_field( $source );
414 }
415
416 public static function is_url( $url ) {
417 return wp_http_validate_url( $url );
418 }
419
420 public static function sanitize_text_field( $source, $replace_enqueue = true ) {
421 $str = (string) $source;
422
423 $filtered = wp_check_invalid_utf8( $str );
424 $sanitize_callback = apply_filters( 'jet-form-builder/sanitize-string/callback', false );
425
426 if ( $sanitize_callback && is_callable( $sanitize_callback ) ) {
427 $filtered = call_user_func( $sanitize_callback, $filtered );
428 } elseif ( $replace_enqueue && false !== strpos( $filtered, '<' ) ) {
429 $filtered = wp_kses_post( $filtered );
430 }
431
432 return trim( $filtered );
433 }
434
435 /**
436 * @param $type
437 * @param mixed ...$values
438 *
439 * @return mixed
440 */
441 private static function call_escape_func( $type, ...$values ) {
442 return call_user_func( self::get_escape_func( $type ), ...$values );
443 }
444
445 public static function recursive_wp_kses( $source, $allowed_html = 'strip' ) {
446 if ( ! is_array( $source ) ) {
447 return wp_kses( $source, $allowed_html );
448 }
449
450 $result = array();
451 foreach ( $source as $key => $value ) {
452 $result[ $key ] = self::sanitize_recursive( $value );
453 }
454
455 return $result;
456 }
457
458 public static function sanitize_files( $source ) {
459 if ( ! is_array( $source ) ) {
460 return false;
461 }
462
463 $response = array();
464
465 foreach ( $source as $index => $item ) {
466 foreach ( $item as $key => $value ) {
467 switch ( $key ) {
468 case 'error':
469 case 'size':
470 $response[ $index ][ $key ] = absint( $value );
471 break;
472 case 'name':
473 $response[ $index ][ $key ] = sanitize_file_name( $value );
474 break;
475 case 'type':
476 $response[ $index ][ $key ] = sanitize_mime_type( $value );
477 break;
478 case 'tmp_name':
479 $response[ $index ][ $key ] = sanitize_text_field( $value );
480 break;
481 }
482 }
483 }
484
485 return $response;
486 }
487
488 /**
489 * @param $source
490 * @param bool $replace_enqueue
491 *
492 * @return string
493 */
494 private static function esc_template( $source, $replace_enqueue = true ): string {
495 return self::sanitize_text_field( $source, $replace_enqueue );
496 }
497
498 public static function get_jet_engine_version() {
499 return function_exists( 'jet_engine' )
500 ? jet_engine()->get_version()
501 : false;
502 }
503
504 public static function is_readable( string $filename ) {
505 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
506 return strlen( $filename ) <= PHP_MAXPATHLEN && @is_readable( $filename );
507 }
508
509 /**
510 * Returns template path
511 *
512 * @param [type] $path [description]
513 *
514 * @return [type] [description]
515 */
516 public static function get_global_template( $path = '' ) {
517 return JET_FORM_BUILDER_PATH . 'templates/' . $path;
518 }
519
520 public static function get_property( $source, $name, $if_not_exist = '' ) {
521 if ( is_object( $source ) ) {
522 return $source->{$name} ?? $if_not_exist;
523 }
524
525 return $source[ $name ] ?? $if_not_exist;
526 }
527
528 public static function esc_template_string( $source, $replace_enqueue = true ) {
529 return self::call_escape_func( 'template', $source, $replace_enqueue );
530 }
531
532 public static function is_repeater_val( $value ): bool {
533 if ( is_array( $value ) && ! empty( $value ) ) {
534 foreach ( $value as $item ) {
535 return is_array( $item );
536 }
537 }
538
539 return false;
540 }
541
542 public static function set_current_post( $post_id ) {
543 global $post;
544
545 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
546 $post = get_post( absint( $post_id ) );
547 }
548
549 public static function prepare_repeater_value( $value, $fields_map ): array {
550 $prepared_value = array();
551
552 foreach ( $value as $index => $row ) {
553 $prepared_row = array();
554
555 foreach ( $row as $item_key => $item_value ) {
556 $item_key = ! empty( $fields_map[ $item_key ] ) ? self::sanitize_text_field( $fields_map[ $item_key ] ) : $item_key;
557 $prepared_row[ $item_key ] = $item_value;
558 }
559
560 $prepared_value[ 'item-' . $index ] = $prepared_row;
561 }
562
563 return $prepared_value;
564 }
565
566 public static function is_webhook(): bool {
567 return (
568 defined( 'JET_FB_REST_WEBHOOK' ) &&
569 JET_FB_REST_WEBHOOK
570 );
571 }
572
573 public static function esc_attr( $value ) {
574 if ( ! is_scalar( $value ) && $value ) {
575 return esc_attr( self::encode_json( $value ) );
576 }
577
578 return esc_attr( $value );
579 }
580
581 public static function get_suffix(): string {
582 return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
583 }
584
585 /**
586 * Get from function below
587 *
588 * @return string
589 * @see \retrieve_password
590 */
591 public static function get_site_name(): string {
592 if ( is_multisite() ) {
593 return get_network()->site_name;
594 }
595
596 /*
597 * The blogname option is escaped with esc_html on the way into the database
598 * in sanitize_option. We want to reverse this for the plain text arena of emails.
599 */
600
601 return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
602 }
603
604 /**
605 * @param mixed $value
606 */
607 public static function to_string( $value ): string {
608 if ( is_array( $value ) ) {
609 return implode(
610 ',',
611 array_map( array( self::class, 'to_string' ), $value )
612 );
613 }
614
615 if ( is_object( $value ) && ! method_exists( $value, '__toString' ) ) {
616 return '';
617 }
618
619 return (string) $value;
620 }
621
622 public static function is_empty( $value ): bool {
623 return '0' !== $value && 0 !== $value && empty( $value );
624 }
625
626 }
627