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