Passed
Push — master ( a932b5...900153 )
by Brian
10:03 queued 04:59
created

WP_Super_Duper::get_fusion_params()   D

Complexity

Conditions 18
Paths 2

Size

Total Lines 69
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
eloc 38
nc 2
nop 0
dl 0
loc 69
rs 4.8666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
if ( ! class_exists( 'WP_Super_Duper' ) ) {
7
8
	define( 'SUPER_DUPER_VER', '1.1.25' );
9
10
	/**
11
	 * A Class to be able to create a Widget, Shortcode or Block to be able to output content for WordPress.
12
	 *
13
	 * Should not be called direct but extended instead.
14
	 *
15
	 * Class WP_Super_Duper
16
	 * @since 1.0.16 change log moved to file change-log.txt - CHANGED
17
	 * @ver 1.1.1
18
	 */
19
	class WP_Super_Duper extends WP_Widget {
20
21
		public $version = SUPER_DUPER_VER;
22
		public $font_awesome_icon_version = "5.11.2";
23
		public $block_code;
24
		public $options;
25
		public $base_id;
26
		public $settings_hash;
27
		public $arguments = array();
28
		public $instance = array();
29
		private $class_name;
30
31
		/**
32
		 * The relative url to the current folder.
33
		 *
34
		 * @var string
35
		 */
36
		public $url = '';
37
38
		/**
39
		 * Take the array options and use them to build.
40
		 */
41
		public function __construct( $options ) {
42
			global $sd_widgets;
43
44
			$sd_widgets[ $options['base_id'] ] = array(
45
				'name'       => $options['name'],
46
				'class_name' => $options['class_name'],
47
				'output_types' => !empty($options['output_types']) ? $options['output_types'] : array()
48
			);
49
			$this->base_id                     = $options['base_id'];
50
			// lets filter the options before we do anything
51
			$options       = apply_filters( "wp_super_duper_options", $options );
52
			$options       = apply_filters( "wp_super_duper_options_{$this->base_id}", $options );
53
			$options       = $this->add_name_from_key( $options );
54
			$this->options = $options;
55
56
			$this->base_id   = $options['base_id'];
57
			$this->arguments = isset( $options['arguments'] ) ? $options['arguments'] : array();
58
59
            // nested blocks can't work as a widget
60
            if(!empty($this->options['nested-block'])){
61
                if(empty($this->options['output_types'])){
62
                    $this->options['output_types'] = array('shortcode','block');
63
                }elseif (($key = array_search('widget', $this->options['output_types'])) !== false) {
64
                    unset($this->options['output_types'][$key]);
65
                }
66
            }
67
68
			// init parent
69
			if(empty($this->options['output_types']) || in_array('widget',$this->options['output_types'])){
70
                parent::__construct( $options['base_id'], $options['name'], $options['widget_ops'] );
71
			}
72
73
74
			if ( isset( $options['class_name'] ) ) {
75
				// register widget
76
				$this->class_name = $options['class_name'];
77
78
				// register shortcode, this needs to be done even for blocks and widgets
79
                $this->register_shortcode();
80
81
82
				// Fusion Builder (avada) support
83
				if ( function_exists( 'fusion_builder_map' ) ) {
84
					add_action( 'init', array( $this, 'register_fusion_element' ) );
85
				}
86
87
				// register block
88
				if(empty($this->options['output_types']) || in_array('block',$this->options['output_types'])){
89
				    add_action( 'admin_enqueue_scripts', array( $this, 'register_block' ) );
90
                }
91
			}
92
93
			// add the CSS and JS we need ONCE
94
			global $sd_widget_scripts;
95
96
			if ( ! $sd_widget_scripts ) {
97
				wp_add_inline_script( 'admin-widgets', $this->widget_js() );
98
				wp_add_inline_script( 'customize-controls', $this->widget_js() );
99
				wp_add_inline_style( 'widgets', $this->widget_css() );
100
101
				// maybe add elementor editor styles
102
				add_action( 'elementor/editor/after_enqueue_styles', array( $this, 'elementor_editor_styles' ) );
103
104
				$sd_widget_scripts = true;
105
106
				// add shortcode insert button once
107
				add_action( 'media_buttons', array( $this, 'shortcode_insert_button' ) );
108
				// generatepress theme sections compatibility
109
				if ( function_exists( 'generate_sections_sections_metabox' ) ) {
110
					add_action( 'generate_sections_metabox', array( $this, 'shortcode_insert_button_script' ) );
111
				}
112
				/* Load script on Divi theme builder page */
113
				if ( function_exists( 'et_builder_is_tb_admin_screen' ) && et_builder_is_tb_admin_screen() ) {
114
					add_thickbox();
115
					add_action( 'admin_footer', array( $this, 'shortcode_insert_button_script' ) );
116
				}
117
118
				if ( $this->is_preview() ) {
119
					add_action( 'wp_footer', array( $this, 'shortcode_insert_button_script' ) );
120
					// this makes the insert button work for elementor
121
					add_action( 'elementor/editor/after_enqueue_scripts', array(
122
						$this,
123
						'shortcode_insert_button_script'
124
					) ); // for elementor
125
				}
126
				// this makes the insert button work for cornerstone
127
				add_action( 'wp_print_footer_scripts', array( __CLASS__, 'maybe_cornerstone_builder' ) );
128
129
				add_action( 'wp_ajax_super_duper_get_widget_settings', array( __CLASS__, 'get_widget_settings' ) );
130
				add_action( 'wp_ajax_super_duper_get_picker', array( __CLASS__, 'get_picker' ) );
131
132
				// add generator text to head
133
				add_action( 'admin_head', array( $this, 'generator' ) );
134
				add_action( 'wp_head', array( $this, 'generator' ) );
135
			}
136
137
			do_action( 'wp_super_duper_widget_init', $options, $this );
138
		}
139
140
        /**
141
         * The register widget function
142
         * @return void
143
         */
144
		public function _register() {
145
            if(empty($this->options['output_types']) || in_array('widget',$this->options['output_types'])){
146
                parent::_register();
147
			}
148
		}
149
150
		/**
151
		 * Add our widget CSS to elementor editor.
152
		 */
153
		public function elementor_editor_styles() {
154
			wp_add_inline_style( 'elementor-editor', $this->widget_css( false ) );
155
		}
156
157
		public function register_fusion_element() {
158
159
			$options = $this->options;
160
161
			if ( $this->base_id ) {
162
163
				$params = $this->get_fusion_params();
164
165
				$args = array(
166
					'name'            => $options['name'],
167
					'shortcode'       => $this->base_id,
168
					'icon'            => $options['block-icon'] ? $options['block-icon'] : 'far fa-square',
169
					'allow_generator' => true,
170
				);
171
172
				if ( ! empty( $params ) ) {
173
					$args['params'] = $params;
174
				}
175
176
				fusion_builder_map( $args );
0 ignored issues
show
Bug introduced by
The function fusion_builder_map was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

176
				/** @scrutinizer ignore-call */ 
177
    fusion_builder_map( $args );
Loading history...
177
			}
178
179
		}
180
181
		public function get_fusion_params() {
182
			$params    = array();
183
			$arguments = $this->get_arguments();
184
185
			if ( ! empty( $arguments ) ) {
186
				foreach ( $arguments as $key => $val ) {
187
					$param = array();
188
					// type
189
					$param['type'] = str_replace(
190
						array(
191
							"text",
192
							"number",
193
							"email",
194
							"color",
195
							"checkbox"
196
						),
197
						array(
198
							"textfield",
199
							"textfield",
200
							"textfield",
201
							"colorpicker",
202
							"select",
203
204
						),
205
						$val['type'] );
206
207
					// multiselect
208
					if ( $val['type'] == 'multiselect' || ( ( $param['type'] == 'select' || $val['type'] == 'select' ) && ! empty( $val['multiple'] ) ) ) {
209
						$param['type']     = 'multiple_select';
210
						$param['multiple'] = true;
211
					}
212
213
					// heading
214
					$param['heading'] = isset( $val['title'] ) ? $val['title'] : '';
215
216
					// description
217
					$param['description'] = isset( $val['desc'] ) ? $val['desc'] : '';
218
219
					// param_name
220
					$param['param_name'] = $key;
221
222
					// Default
223
					$param['default'] = isset( $val['default'] ) ? $val['default'] : '';
224
225
					// Group
226
					if ( isset( $val['group'] ) ) {
227
						$param['group'] = $val['group'];
228
					}
229
230
					// value
231
					if ( $val['type'] == 'checkbox' ) {
232
						if ( isset( $val['default'] ) && $val['default'] == '0' ) {
233
							unset( $param['default'] );
234
						}
235
						$param['value'] = array( '0' => __( "No" ), '1' => __( "Yes" ) );
236
					} elseif ( $param['type'] == 'select' || $param['type'] == 'multiple_select' ) {
237
						$param['value'] = isset( $val['options'] ) ? $val['options'] : array();
238
					} else {
239
						$param['value'] = isset( $val['default'] ) ? $val['default'] : '';
240
					}
241
242
					// setup the param
243
					$params[] = $param;
244
245
				}
246
			}
247
248
249
			return $params;
250
		}
251
252
		/**
253
		 * Maybe insert the shortcode inserter button in the footer if we are in the cornerstone builder
254
		 */
255
		public static function maybe_cornerstone_builder() {
256
			if ( did_action( 'cornerstone_before_boot_app' ) ) {
257
				self::shortcode_insert_button_script();
258
			}
259
		}
260
261
		/**
262
		 * A function to ge the shortcode builder picker html.
263
		 *
264
		 * @param string $editor_id
265
		 *
266
		 * @return string
267
		 */
268
		public static function get_picker( $editor_id = '' ) {
269
270
			ob_start();
271
			if ( isset( $_POST['editor_id'] ) ) {
272
				$editor_id = esc_attr( $_POST['editor_id'] );
273
			} elseif ( isset( $_REQUEST['et_fb'] ) ) {
274
				$editor_id = 'main_content_content_vb_tiny_mce';
275
			}
276
277
			global $sd_widgets;
278
279
//			print_r($sd_widgets);exit;
280
			?>
281
282
			<div class="sd-shortcode-left-wrap">
283
				<?php
284
				ksort( $sd_widgets );
285
				//				print_r($sd_widgets);exit;
286
				if ( ! empty( $sd_widgets ) ) {
287
					echo '<select class="widefat" onchange="sd_get_shortcode_options(this);">';
288
					echo "<option>" . __( 'Select shortcode' ) . "</option>";
289
					foreach ( $sd_widgets as $shortcode => $class ) {
290
						if(!empty($class['output_types']) && !in_array('shortcode', $class['output_types'])){ continue; }
291
						echo "<option value='" . esc_attr( $shortcode ) . "'>" . esc_attr( $shortcode ) . " (" . esc_attr( $class['name'] ) . ")</option>";
292
					}
293
					echo "</select>";
294
295
				}
296
				?>
297
				<div class="sd-shortcode-settings"></div>
298
299
			</div>
300
301
			<div class="sd-shortcode-right-wrap">
302
				<textarea id='sd-shortcode-output' disabled></textarea>
303
				<div id='sd-shortcode-output-actions'>
304
					<?php if ( $editor_id != '' ) { ?>
305
						<button class="button sd-insert-shortcode-button"
306
						        onclick="sd_insert_shortcode(<?php if ( ! empty( $editor_id ) ) {
307
							        echo "'" . $editor_id . "'";
308
						        } ?>)"><?php _e( 'Insert shortcode' ); ?></button>
309
					<?php } ?>
310
					<button class="button"
311
					        onclick="sd_copy_to_clipboard()"><?php _e( 'Copy shortcode' ); ?></button>
312
				</div>
313
			</div>
314
			<?php
315
316
			$html = ob_get_clean();
317
318
			if ( wp_doing_ajax() ) {
319
				echo $html;
320
				$should_die = true;
321
322
				// some builder get the editor via ajax so we should not die on those occasions
323
				$dont_die = array(
324
					'parent_tag',// WP Bakery
325
					'avia_request' // enfold
326
				);
327
328
				foreach ( $dont_die as $request ) {
329
					if ( isset( $_REQUEST[ $request ] ) ) {
330
						$should_die = false;
331
					}
332
				}
333
334
				if ( $should_die ) {
335
					wp_die();
336
				}
337
338
			} else {
339
				return $html;
340
			}
341
342
			return '';
343
344
		}
345
346
		/**
347
		 * Output the version in the header.
348
		 */
349
		public function generator() {
350
			$file = str_replace( array( "/", "\\" ), "/", realpath( __FILE__ ) );
351
			$plugins_dir = str_replace( array( "/", "\\" ), "/", realpath( WP_PLUGIN_DIR ) );
352
353
			// Find source plugin/theme of SD
354
			$source = array();
355
			if ( strpos( $file, $plugins_dir ) !== false ) {
356
				$source = explode( "/", plugin_basename( $file ) );
357
			} else if ( function_exists( 'get_theme_root' ) ) {
358
				$themes_dir = str_replace( array( "/", "\\" ), "/", realpath( get_theme_root() ) );
359
360
				if ( strpos( $file, $themes_dir ) !== false ) {
361
					$source = explode( "/", ltrim( str_replace( $themes_dir, "", $file ), "/" ) );
362
				}
363
			}
364
365
			echo '<meta name="generator" content="WP Super Duper v' . $this->version . '"' . ( ! empty( $source[0] ) ? ' data-sd-source="' . esc_attr( $source[0] ) . '"' : '' ) . ' />';
366
		}
367
368
		/**
369
		 * Get widget settings.
370
		 *
371
		 * @since 1.0.0
372
		 */
373
		public static function get_widget_settings() {
374
			global $sd_widgets;
375
376
			$shortcode = isset( $_REQUEST['shortcode'] ) && $_REQUEST['shortcode'] ? sanitize_title_with_dashes( $_REQUEST['shortcode'] ) : '';
377
			if ( ! $shortcode ) {
378
				wp_die();
379
			}
380
			$widget_args = isset( $sd_widgets[ $shortcode ] ) ? $sd_widgets[ $shortcode ] : '';
381
			if ( ! $widget_args ) {
382
				wp_die();
383
			}
384
			$class_name = isset( $widget_args['class_name'] ) && $widget_args['class_name'] ? $widget_args['class_name'] : '';
385
			if ( ! $class_name ) {
386
				wp_die();
387
			}
388
389
			// invoke an instance method
390
			$widget = new $class_name;
391
392
			ob_start();
393
			$widget->form( array() );
394
			$form = ob_get_clean();
395
			echo "<form id='$shortcode'>" . $form . "<div class=\"widget-control-save\"></div></form>";
396
			echo "<style>" . $widget->widget_css() . "</style>";
397
			echo "<script>" . $widget->widget_js() . "</script>";
398
			?>
399
			<?php
400
			wp_die();
401
		}
402
403
		/**
404
		 * Insert shortcode builder button to classic editor (not inside Gutenberg, not needed).
405
		 *
406
		 * @param string $editor_id Optional. Shortcode editor id. Default null.
407
		 * @param string $insert_shortcode_function Optional. Insert shortcode function. Default null.
408
		 *
409
		 *@since 1.0.0
410
		 *
411
		 */
412
		public static function shortcode_insert_button( $editor_id = '', $insert_shortcode_function = '' ) {
413
			global $sd_widgets, $shortcode_insert_button_once;
414
			if ( $shortcode_insert_button_once ) {
415
				return;
416
			}
417
			add_thickbox();
418
419
420
			/**
421
			 * Cornerstone makes us play dirty tricks :/
422
			 * All media_buttons are removed via JS unless they are two specific id's so we wrap our content in this ID so it is not removed.
423
			 */
424
			if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) {
425
				echo '<span id="insert-media-button">';
426
			}
427
428
			echo self::shortcode_button( 'this', 'true' );
429
430
			// see opening note
431
			if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) {
432
				echo '</span>'; // end #insert-media-button
433
			}
434
435
			// Add separate script for generatepress theme sections
436
			if ( function_exists( 'generate_sections_sections_metabox' ) && did_action( 'generate_sections_metabox' ) ) {
437
			} else {
438
				self::shortcode_insert_button_script( $editor_id, $insert_shortcode_function );
439
			}
440
441
			$shortcode_insert_button_once = true;
442
		}
443
444
		/**
445
		 * Gets the shortcode insert button html.
446
		 *
447
		 * @param string $id
448
		 * @param string $search_for_id
449
		 *
450
		 * @return mixed
451
		 */
452
		public static function shortcode_button( $id = '', $search_for_id = '' ) {
453
			ob_start();
454
			?>
455
			<span class="sd-lable-shortcode-inserter">
456
				<a onclick="sd_ajax_get_picker(<?php echo $id;
457
				if ( $search_for_id ) {
458
					echo "," . $search_for_id;
459
				} ?>);" href="#TB_inline?width=100%&height=550&inlineId=super-duper-content-ajaxed"
460
				   class="thickbox button super-duper-content-open" title="Add Shortcode">
461
					<span style="vertical-align: middle;line-height: 18px;font-size: 20px;"
462
					      class="dashicons dashicons-screenoptions"></span>
463
				</a>
464
				<div id="super-duper-content-ajaxed" style="display:none;">
465
					<span>Loading</span>
466
				</div>
467
			</span>
468
469
			<?php
470
			$html = ob_get_clean();
471
472
			// remove line breaks so we can use it in js
473
			return preg_replace( "/\r|\n/", "", trim( $html ) );
474
		}
475
476
		/**
477
		 * Makes SD work with the siteOrigin page builder.
478
		 *
479
		 * @return mixed
480
		 *@since 1.0.6
481
		 */
482
		public static function siteorigin_js() {
483
			ob_start();
484
			?>
485
			<script>
486
				/**
487
				 * Check a form to see what items should be shown or hidden.
488
				 */
489
				function sd_so_show_hide(form) {
490
					jQuery(form).find(".sd-argument").each(function () {
491
492
						var $element_require = jQuery(this).data('element_require');
493
494
						if ($element_require) {
495
496
							$element_require = $element_require.replace("&#039;", "'"); // replace single quotes
497
							$element_require = $element_require.replace("&quot;", '"'); // replace double quotes
498
499
							if (eval($element_require)) {
500
								jQuery(this).removeClass('sd-require-hide');
501
							} else {
502
								jQuery(this).addClass('sd-require-hide');
503
							}
504
						}
505
					});
506
				}
507
508
				/**
509
				 * Toggle advanced settings visibility.
510
				 */
511
				function sd_so_toggle_advanced($this) {
512
					var form = jQuery($this).parents('form,.form,.so-content');
513
					form.find('.sd-advanced-setting').toggleClass('sd-adv-show');
514
					return false;// prevent form submit
515
				}
516
517
				/**
518
				 * Initialise a individual widget.
519
				 */
520
				function sd_so_init_widget($this, $selector) {
521
					if (!$selector) {
522
						$selector = 'form';
523
					}
524
					// only run once.
525
					if (jQuery($this).data('sd-widget-enabled')) {
526
						return;
527
					} else {
528
						jQuery($this).data('sd-widget-enabled', true);
529
					}
530
531
					var $button = '<button title="<?php _e( 'Advanced Settings' );?>" class="button button-primary right sd-advanced-button" onclick="sd_so_toggle_advanced(this);return false;"><i class="fas fa-sliders-h" aria-hidden="true"></i></button>';
532
					var form = jQuery($this).parents('' + $selector + '');
533
534
					if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) {
535
						jQuery(form).append($button);
536
					}
537
538
					// show hide on form change
539
					jQuery(form).on("change", function () {
540
						sd_so_show_hide(form);
541
					});
542
543
					// show hide on load
544
					sd_so_show_hide(form);
545
				}
546
547
				jQuery(function () {
548
					jQuery(document).on('open_dialog', function (w, e) {
549
						setTimeout(function () {
550
							if (jQuery('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced').length) {
551
								if (jQuery('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced').val() == '1') {
552
									sd_so_init_widget('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced', 'div');
553
								}
554
							}
555
						}, 200);
556
					});
557
				});
558
			</script>
559
			<?php
560
			$output = ob_get_clean();
561
562
			/*
563
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
564
			 */
565
566
			return str_replace( array(
567
				'<script>',
568
				'</script>'
569
			), '', $output );
570
		}
571
572
		/**
573
		 * Output the JS and CSS for the shortcode insert button.
574
		 *
575
		 * @param string $editor_id
576
		 * @param string $insert_shortcode_function
577
		 *
578
		 *@since 1.0.6
579
		 *
580
		 */
581
		public static function shortcode_insert_button_script( $editor_id = '', $insert_shortcode_function = '' ) {
582
			?>
583
			<style>
584
				.sd-shortcode-left-wrap {
585
					float: left;
586
					width: 60%;
587
				}
588
589
				.sd-shortcode-left-wrap .gd-help-tip {
590
					float: none;
591
				}
592
593
				.sd-shortcode-left-wrap .widefat {
594
					border-spacing: 0;
595
					width: 100%;
596
					clear: both;
597
					margin: 0;
598
					border: 1px solid #ddd;
599
					box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
600
					background-color: #fff;
601
					color: #32373c;
602
					outline: 0;
603
					transition: 50ms border-color ease-in-out;
604
					padding: 3px 5px;
605
				}
606
607
				.sd-shortcode-left-wrap input[type=checkbox].widefat {
608
					border: 1px solid #b4b9be;
609
					background: #fff;
610
					color: #555;
611
					clear: none;
612
					cursor: pointer;
613
					display: inline-block;
614
					line-height: 0;
615
					height: 16px;
616
					margin: -4px 4px 0 0;
617
					margin-top: 0;
618
					outline: 0;
619
					padding: 0 !important;
620
					text-align: center;
621
					vertical-align: middle;
622
					width: 16px;
623
					min-width: 16px;
624
					-webkit-appearance: none;
625
					box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
626
					transition: .05s border-color ease-in-out;
627
				}
628
629
				.sd-shortcode-left-wrap input[type=checkbox]:checked:before {
630
					content: "\f147";
631
					margin: -3px 0 0 -4px;
632
					color: #1e8cbe;
633
					float: left;
634
					display: inline-block;
635
					vertical-align: middle;
636
					width: 16px;
637
					font: normal 21px/1 dashicons;
638
					speak: none;
639
					-webkit-font-smoothing: antialiased;
640
					-moz-osx-font-smoothing: grayscale;
641
				}
642
643
				#sd-shortcode-output-actions button,
644
				.sd-advanced-button {
645
					color: #555;
646
					border-color: #ccc;
647
					background: #f7f7f7;
648
					box-shadow: 0 1px 0 #ccc;
649
					vertical-align: top;
650
					display: inline-block;
651
					text-decoration: none;
652
					font-size: 13px;
653
					line-height: 26px;
654
					height: 28px;
655
					margin: 0;
656
					padding: 0 10px 1px;
657
					cursor: pointer;
658
					border-width: 1px;
659
					border-style: solid;
660
					-webkit-appearance: none;
661
					border-radius: 3px;
662
					white-space: nowrap;
663
					box-sizing: border-box;
664
				}
665
666
				button.sd-advanced-button {
667
					background: #0073aa;
668
					border-color: #006799;
669
					box-shadow: inset 0 2px 0 #006799;
670
					vertical-align: top;
671
					color: #fff;
672
					text-decoration: none;
673
					text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;
674
					float: right;
675
					margin-right: 3px !important;
676
					font-size: 20px !important;
677
				}
678
679
				.sd-shortcode-right-wrap {
680
					float: right;
681
					width: 35%;
682
				}
683
684
				#sd-shortcode-output {
685
					background: rgba(255, 255, 255, .5);
686
					border-color: rgba(222, 222, 222, .75);
687
					box-shadow: inset 0 1px 2px rgba(0, 0, 0, .04);
688
					color: rgba(51, 51, 51, .5);
689
					overflow: auto;
690
					padding: 2px 6px;
691
					line-height: 1.4;
692
					resize: vertical;
693
				}
694
695
				#sd-shortcode-output {
696
					height: 250px;
697
					width: 100%;
698
				}
699
700
				<?php if ( function_exists( 'generate_sections_sections_metabox' ) ) { ?>
701
				.generate-sections-modal #custom-media-buttons > .sd-lable-shortcode-inserter {
702
					display: inline;
703
				}
704
				<?php } ?>
705
				<?php if ( function_exists( 'et_builder_is_tb_admin_screen' ) && et_builder_is_tb_admin_screen() ) { ?>
706
				body.divi_page_et_theme_builder div#TB_window.gd-tb-window{z-index:9999999}
707
				<?php } ?>
708
			</style>
709
			<?php
710
			if ( class_exists( 'SiteOrigin_Panels' ) ) {
711
				echo "<script>" . self::siteorigin_js() . "</script>";
712
			}
713
			?>
714
			<script>
715
				<?php
716
				if(! empty( $insert_shortcode_function )){
717
					echo $insert_shortcode_function;
718
				}else{
719
720
				/**
721
				 * Function for super duper insert shortcode.
722
				 *
723
				 * @since 1.0.0
724
				 */
725
				?>
726
				function sd_insert_shortcode($editor_id) {
727
					$shortcode = jQuery('#TB_ajaxContent #sd-shortcode-output').val();
728
					if ($shortcode) {
729
						if (!$editor_id) {
730
							<?php
731
							if ( isset( $_REQUEST['et_fb'] ) ) {
732
								echo '$editor_id = "#main_content_content_vb_tiny_mce";';
733
							} elseif ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) {
734
								echo '$editor_id = "#elementor-controls .wp-editor-container textarea";';
735
							} else {
736
								echo '$editor_id = "#wp-content-editor-container textarea";';
737
							}
738
							?>
739
						} else {
740
							$editor_id = '#' + $editor_id;
741
						}
742
						tmceActive = jQuery($editor_id).attr("aria-hidden") == "true" ? true : false;
743
						/* GeneratePress */
744
						if (jQuery('#generate-sections-modal-dialog ' + $editor_id).length) {
745
							$editor_id = '#generate-sections-modal-dialog ' + $editor_id;
746
							tmceActive = jQuery($editor_id).closest('.wp-editor-wrap').hasClass('tmce-active') ? true : false;
747
						}
748
						if (typeof tinyMCE !== 'undefined' && tinyMCE.activeEditor && tmceActive) {
749
							tinyMCE.execCommand('mceInsertContent', false, $shortcode);
750
						} else {
751
							var $txt = jQuery($editor_id);
752
							var caretPos = $txt[0].selectionStart;
753
							var textAreaTxt = $txt.val();
754
							var txtToAdd = $shortcode;
755
							var textareaValue = textAreaTxt.substring(0, caretPos) + txtToAdd + textAreaTxt.substring(caretPos);
756
							$txt.focus().val(textareaValue).change().keydown().blur().keyup().keypress().trigger('input').trigger('change');
757
758
							// set Divi react input value
759
							var input = document.getElementById("main_content_content_vb_tiny_mce");
760
							if (input) {
761
								sd_setNativeValue(input, textareaValue);
762
							}
763
764
						}
765
						tb_remove();
766
					}
767
				}
768
769
				/*
770
				 Set the value of elements controlled via react.
771
				 */
772
				function sd_setNativeValue(element, value) {
773
					let lastValue = element.value;
774
					element.value = value;
775
					let event = new Event("input", {target: element, bubbles: true});
776
					// React 15
777
					event.simulated = true;
778
					// React 16
779
					let tracker = element._valueTracker;
780
					if (tracker) {
781
						tracker.setValue(lastValue);
782
					}
783
					element.dispatchEvent(event);
784
				}
785
				<?php }?>
786
787
				/*
788
				 Copies the shortcode to the clipboard.
789
				 */
790
				function sd_copy_to_clipboard() {
791
					/* Get the text field */
792
					var copyText = document.querySelector("#TB_ajaxContent #sd-shortcode-output");
793
					//un-disable the field
794
					copyText.disabled = false;
795
					/* Select the text field */
796
					copyText.select();
797
					/* Copy the text inside the text field */
798
					document.execCommand("Copy");
799
					//re-disable the field
800
					copyText.disabled = true;
801
					/* Alert the copied text */
802
					alert("Copied the text: " + copyText.value);
803
				}
804
805
				/*
806
				 Gets the shortcode options.
807
				 */
808
				function sd_get_shortcode_options($this) {
809
					$short_code = jQuery($this).val();
810
					if ($short_code) {
811
						var data = {
812
							'action': 'super_duper_get_widget_settings',
813
							'shortcode': $short_code,
814
							'attributes': 123,
815
							'post_id': 321,
816
							'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>'
817
						};
818
819
						if (typeof ajaxurl === 'undefined') {
820
							var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' );?>";
821
						}
822
823
						jQuery.post(ajaxurl, data, function (response) {
824
							jQuery('#TB_ajaxContent .sd-shortcode-settings').html(response);
825
826
							jQuery('#' + $short_code).on('change', 'select', function () {
827
								sd_build_shortcode($short_code);
828
							}); // take care of select tags
829
830
							jQuery('#' + $short_code).on('change keypress keyup', 'input,textarea', function () {
831
								sd_build_shortcode($short_code);
832
							});
833
834
							sd_build_shortcode($short_code);
835
836
							// resize the window to fit
837
							setTimeout(function () {
838
								jQuery('#TB_ajaxContent').css('width', 'auto').css('height', '75vh');
839
							}, 200);
840
841
							return response;
842
						});
843
					}
844
				}
845
846
				/*
847
				 Builds and inserts the shortcode into the viewer.
848
				 */
849
				function sd_build_shortcode($id) {
850
					var multiSelects = {};
851
					var multiSelectsRemove = [];
852
853
					$output = "[" + $id;
854
855
					$form_data = jQuery("#" + $id).serializeArray();
856
857
					// run checks for multiselects
858
					jQuery.each($form_data, function (index, element) {
859
						if (element && element.value) {
860
							$field_name = element.name.substr(element.name.indexOf("][") + 2);
861
							$field_name = $field_name.replace("]", "");
862
							// check if its a multiple
863
							if ($field_name.includes("[]")) {
864
								multiSelectsRemove[multiSelectsRemove.length] = index;
865
								$field_name = $field_name.replace("[]", "");
866
								if ($field_name in multiSelects) {
867
									multiSelects[$field_name] = multiSelects[$field_name] + "," + element.value;
868
								} else {
869
									multiSelects[$field_name] = element.value;
870
								}
871
							}
872
						}
873
					});
874
875
					// fix multiselects if any are found
876
					if (multiSelectsRemove.length) {
877
878
						// remove all multiselects
879
						multiSelectsRemove.reverse();
880
						multiSelectsRemove.forEach(function (index) {
881
							$form_data.splice(index, 1);
882
						});
883
884
						$ms_arr = [];
885
						// add multiselets back
886
						jQuery.each(multiSelects, function (index, value) {
887
							$ms_arr[$ms_arr.length] = {"name": "[][" + index + "]", "value": value};
888
						});
889
						$form_data = $form_data.concat($ms_arr);
890
					}
891
892
					if ($form_data) {
893
						$content = '';
894
						$form_data.forEach(function (element) {
895
							if (element.value) {
896
								$field_name = element.name.substr(element.name.indexOf("][") + 2);
897
								$field_name = $field_name.replace("]", "");
898
								if ($field_name == 'html') {
899
									$content = element.value;
900
								} else {
901
									$output = $output + " " + $field_name + '="' + element.value + '"';
902
								}
903
							}
904
						});
905
					}
906
					$output = $output + "]";
907
908
					// check for content field
909
					if ($content) {
910
						$output = $output + $content + "[/" + $id + "]";
911
					}
912
913
					jQuery('#TB_ajaxContent #sd-shortcode-output').html($output);
914
				}
915
916
				/*
917
				 Delay the init of the textareas for 1 second.
918
				 */
919
				(function () {
920
					setTimeout(function () {
921
						sd_init_textareas();
922
					}, 1000);
923
				})();
924
925
				/*
926
				 Init the textareas to be able to show the shortcode builder button.
927
				 */
928
				function sd_init_textareas() {
929
					// General textareas
930
					jQuery(document).on('focus', 'textarea', function () {
931
						if (jQuery(this).hasClass('wp-editor-area')) {
932
							// insert the shortcode button to the textarea lable if not there already
933
							if (!jQuery(this).parent().find('.sd-lable-shortcode-inserter').length) {
934
								jQuery(this).parent().find('.quicktags-toolbar').append(sd_shortcode_button(jQuery(this).attr('id')));
935
							}
936
						} else {
937
							// insert the shortcode button to the textarea lable if not there already
938
							if (!jQuery("label[for='" + jQuery(this).attr('id') + "']").find('.sd-lable-shortcode-inserter').length) {
939
								jQuery("label[for='" + jQuery(this).attr('id') + "']").append(sd_shortcode_button(jQuery(this).attr('id')));
940
							}
941
						}
942
					});
943
944
					// The below tries to add the shortcode builder button to the builders own raw/shortcode sections.
945
946
					// DIVI
947
					jQuery(document).on('focusin', '.et-fb-codemirror', function () {
948
						// insert the shortcode button to the textarea lable if not there already
949
						if (!jQuery(this).closest('.et-fb-form__group').find('.sd-lable-shortcode-inserter').length) {
950
							jQuery(this).closest('.et-fb-form__group').find('.et-fb-form__label-text').append(sd_shortcode_button());
951
						}
952
					});
953
954
					// Beaver
955
					jQuery(document).on('focusin', '.fl-code-field', function () {
956
						// insert the shortcode button to the textarea lable if not there already
957
						if (!jQuery(this).closest('.fl-field-control-wrapper').find('.sd-lable-shortcode-inserter').length) {
958
							jQuery(this).closest('.fl-field-control-wrapper').prepend(sd_shortcode_button());
959
						}
960
					});
961
962
					// Fushion builder (avada)
963
					jQuery(document).on('focusin', '.CodeMirror.cm-s-default', function () {
964
						// insert the shortcode button to the textarea lable if not there already
965
						if (!jQuery(this).parent().find('.sd-lable-shortcode-inserter').length) {
966
							jQuery(sd_shortcode_button()).insertBefore(this);
967
						}
968
					});
969
970
					// Avia builder (enfold)
971
					jQuery(document).on('focusin', '#aviaTBcontent', function () {
972
						// insert the shortcode button to the textarea lable if not there already
973
						if (!jQuery(this).parent().parent().find('.avia-name-description ').find('.sd-lable-shortcode-inserter').length) {
974
							jQuery(this).parent().parent().find('.avia-name-description strong').append(sd_shortcode_button(jQuery(this).attr('id')));
975
						}
976
					});
977
978
					// Cornerstone textareas
979
					jQuery(document).on('focusin', '.cs-control.cs-control-textarea', function () {
980
						// insert the shortcode button to the textarea lable if not there already
981
						if (!jQuery(this).find('.cs-control-header label').find('.sd-lable-shortcode-inserter').length) {
982
							jQuery(this).find('.cs-control-header label').append(sd_shortcode_button());
983
						}
984
					});
985
986
					// Cornerstone main bar
987
					setTimeout(function () {
988
						// insert the shortcode button to the textarea lable if not there already
989
						if (!jQuery('.cs-bar-btns').find('.sd-lable-shortcode-inserter').length) {
990
							jQuery('<li style="text-align: center;padding: 5px;list-style: none;">' + sd_shortcode_button() + '</li>').insertBefore('.cs-action-toggle-custom-css');
991
						}
992
					}, 2000);
993
994
995
					// WP Bakery, code editor does not render shortcodes.
996
//					jQuery(document).on('focusin', '.wpb-textarea_raw_html', function () {
997
//						// insert the shortcode button to the textarea lable if not there already
998
//						if(!jQuery(this).parent().parent().find('.wpb_element_label').find('.sd-lable-shortcode-inserter').length){
999
//							jQuery(this).parent().parent().find('.wpb_element_label').append(sd_shortcode_button());
1000
//						}
1001
//					});
1002
				}
1003
1004
				/**
1005
				 * Gets the html for the picker via ajax and updates it on the fly.
1006
				 *
1007
				 * @param $id
1008
				 * @param $search
1009
				 */
1010
				function sd_ajax_get_picker($id, $search) {
1011
					if ($search) {
1012
						$this = $id;
1013
						$id = jQuery($this).closest('.wp-editor-wrap').find('.wp-editor-container textarea').attr('id');
1014
					}
1015
1016
					var data = {
1017
						'action': 'super_duper_get_picker',
1018
						'editor_id': $id,
1019
						'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_picker' );?>'
1020
					};
1021
1022
					if (!ajaxurl) {
1023
						var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' ); ?>";
1024
					}
1025
1026
					jQuery.post(ajaxurl, data, function (response) {
1027
						jQuery('#TB_ajaxContent').closest('#TB_window').addClass('gd-tb-window');
1028
						jQuery('#TB_ajaxContent').html(response);
1029
						//return response;
1030
					}).then(function (env) {
1031
						jQuery('body').on('thickbox:removed', function () {
1032
							jQuery('#super-duper-content-ajaxed').html('');
1033
						});
1034
					});
1035
				}
1036
1037
				/**
1038
				 * Get the html for the shortcode inserter button depending on if a textarea id is available.
1039
				 *
1040
				 * @param $id string The textarea id.
1041
				 * @returns {string}
1042
				 */
1043
				function sd_shortcode_button($id) {
1044
					if ($id) {
1045
						return '<?php echo self::shortcode_button( "\\''+\$id+'\\'" );?>';
1046
					} else {
1047
						return '<?php echo self::shortcode_button();?>';
1048
					}
1049
				}
1050
			</script>
1051
			<?php
1052
		}
1053
1054
		/**
1055
		 * Gets some CSS for the widgets screen.
1056
		 *
1057
		 * @param bool $advanced If we should include advanced CSS.
1058
		 *
1059
		 * @return mixed
1060
		 */
1061
		public function widget_css( $advanced = true ) {
1062
			ob_start();
1063
			?>
1064
			<style>
1065
				<?php if( $advanced ){ ?>
1066
				.sd-advanced-setting {
1067
					display: none;
1068
				}
1069
1070
				.sd-advanced-setting.sd-adv-show {
1071
					display: block;
1072
				}
1073
1074
				.sd-argument.sd-require-hide,
1075
				.sd-advanced-setting.sd-require-hide {
1076
					display: none;
1077
				}
1078
1079
				button.sd-advanced-button {
1080
					margin-right: 3px !important;
1081
					font-size: 20px !important;
1082
				}
1083
1084
				<?php } ?>
1085
1086
				button.sd-toggle-group-button {
1087
					background-color: #f3f3f3;
1088
					color: #23282d;
1089
					cursor: pointer;
1090
					padding: 10px;
1091
					width: 100%;
1092
					border: none;
1093
					text-align: left;
1094
					outline: none;
1095
					font-size: 13px;
1096
					font-weight: bold;
1097
					margin-bottom: 1px;
1098
				}
1099
			</style>
1100
			<?php
1101
			$output = ob_get_clean();
1102
1103
			/*
1104
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
1105
			 */
1106
1107
			return str_replace( array(
1108
				'<style>',
1109
				'</style>'
1110
			), '', $output );
1111
		}
1112
1113
		/**
1114
		 * Gets some JS for the widgets screen.
1115
		 *
1116
		 * @return mixed
1117
		 */
1118
		public function widget_js() {
1119
			ob_start();
1120
			?>
1121
			<script>
1122
1123
				/**
1124
				 * Toggle advanced settings visibility.
1125
				 */
1126
				function sd_toggle_advanced($this) {
1127
					var form = jQuery($this).parents('form,.form');
1128
					form.find('.sd-advanced-setting').toggleClass('sd-adv-show');
1129
					return false;// prevent form submit
1130
				}
1131
1132
				/**
1133
				 * Check a form to see what items should be shown or hidden.
1134
				 */
1135
				function sd_show_hide(form) {
1136
					jQuery(form).find(".sd-argument").each(function () {
1137
1138
						var $element_require = jQuery(this).data('element_require');
1139
1140
						if ($element_require) {
1141
1142
							$element_require = $element_require.replace("&#039;", "'"); // replace single quotes
1143
							$element_require = $element_require.replace("&quot;", '"'); // replace double quotes
1144
1145
							if (eval($element_require)) {
1146
								jQuery(this).removeClass('sd-require-hide');
1147
							} else {
1148
								jQuery(this).addClass('sd-require-hide');
1149
							}
1150
						}
1151
					});
1152
				}
1153
1154
				/**
1155
				 * Initialise widgets from the widgets screen.
1156
				 */
1157
				function sd_init_widgets($selector) {
1158
					jQuery(".sd-show-advanced").each(function (index) {
1159
						sd_init_widget(this, $selector);
1160
					});
1161
				}
1162
1163
				/**
1164
				 * Initialise a individual widget.
1165
				 */
1166
				function sd_init_widget($this, $selector, $form) {
1167
					if (!$selector) {
1168
						$selector = 'form';
1169
					}
1170
					// Only run once.
1171
					if (jQuery($this).data('sd-widget-enabled')) {
1172
						return;
1173
					} else {
1174
						jQuery($this).data('sd-widget-enabled', true);
1175
					}
1176
1177
					var $button = '<button title="<?php _e( 'Advanced Settings' );?>" style="line-height: 28px;" class="button button-primary right sd-advanced-button" onclick="sd_toggle_advanced(this);return false;"><span class="dashicons dashicons-admin-settings" style="width: 28px;font-size: 28px;"></span></button>';
1178
					var form = $form ? $form : jQuery($this).parents('' + $selector + '');
1179
1180
					if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) {
1181
						console.log('add advanced button');
1182
						if (jQuery(form).find('.widget-control-save').length > 0) {
1183
							jQuery(form).find('.widget-control-save').after($button);
1184
						} else {
1185
							jQuery(form).find('.sd-show-advanced').after($button);
1186
						}
1187
					} else {
1188
						console.log('no advanced button, ' + jQuery($this).val() + ', ' + jQuery(form).find('.sd-advanced-button').length);
1189
					}
1190
1191
					/* Show hide on form change */
1192
					jQuery(form).on("change", function() {
1193
						sd_show_hide(form);
1194
					});
1195
1196
					/* Show hide on load */
1197
					sd_show_hide(form);
1198
				}
1199
1200
				/**
1201
				 * Init a customizer widget.
1202
				 */
1203
				function sd_init_customizer_widget(section) {
1204
					if (section.expanded) {
1205
						section.expanded.bind(function (isExpanding) {
1206
							if (isExpanding) {
1207
								// is it a SD widget?
1208
								if (jQuery(section.container).find('.sd-show-advanced').length) {
1209
									// init the widget
1210
									sd_init_widget(jQuery(section.container).find('.sd-show-advanced'), ".form");
1211
								}
1212
							}
1213
						});
1214
					}
1215
				}
1216
1217
				/**
1218
				 * If on widgets screen.
1219
				 */
1220
				jQuery(function () {
1221
					// if not in customizer.
1222
					if (!wp.customize) {
1223
						sd_init_widgets("form");
1224
					}
1225
1226
					/* Init on widget added */
1227
					jQuery(document).on('widget-added', function (e, widget) {
1228
						/* Is it a SD widget? */
1229
						if (jQuery(widget).find('.sd-show-advanced').length) {
1230
							var widgetId = jQuery(widget).find('[name="widget-id"]').length ? ': ' + jQuery(widget).find('[name="widget-id"]').val() : '';
1231
							console.log('widget added' + widgetId);
1232
							/* Init the widget */
1233
							sd_init_widget(jQuery(widget).find('.sd-show-advanced'), "form", jQuery(widget).find('.sd-show-advanced').closest('form'));
1234
						}
1235
					});
1236
1237
					/* Init on widget updated */
1238
					jQuery(document).on('widget-updated', function (e, widget) {
1239
						/* Is it a SD widget? */
1240
						if (jQuery(widget).find('.sd-show-advanced').length) {
1241
							var widgetId = jQuery(widget).find('[name="widget-id"]').length ? ': ' + jQuery(widget).find('[name="widget-id"]').val() : '';
1242
							console.log('widget updated' + widgetId);
1243
							/* Init the widget */
1244
							sd_init_widget(jQuery(widget).find('.sd-show-advanced'), "form", jQuery(widget).find('.sd-show-advanced').closest('form'));
1245
						}
1246
					});
1247
				});
1248
1249
				/**
1250
				 * We need to run this before jQuery is ready
1251
				 */
1252
				if (wp.customize) {
1253
					wp.customize.bind('ready', function () {
1254
1255
						// init widgets on load
1256
						wp.customize.control.each(function (section) {
1257
							sd_init_customizer_widget(section);
1258
						});
1259
1260
						// init widgets on add
1261
						wp.customize.control.bind('add', function (section) {
1262
							sd_init_customizer_widget(section);
1263
						});
1264
1265
					});
1266
1267
				}
1268
				<?php do_action( 'wp_super_duper_widget_js', $this ); ?>
1269
			</script>
1270
			<?php
1271
			$output = ob_get_clean();
1272
1273
			/*
1274
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
1275
			 */
1276
1277
			return str_replace( array(
1278
				'<script>',
1279
				'</script>'
1280
			), '', $output );
1281
		}
1282
1283
1284
		/**
1285
		 * Set the name from the argument key.
1286
		 *
1287
		 * @param $options
1288
		 *
1289
		 * @return mixed
1290
		 */
1291
		private function add_name_from_key( $options, $arguments = false ) {
1292
			if ( ! empty( $options['arguments'] ) ) {
1293
				foreach ( $options['arguments'] as $key => $val ) {
1294
					$options['arguments'][ $key ]['name'] = $key;
1295
				}
1296
			} elseif ( $arguments && is_array( $options ) && ! empty( $options ) ) {
1297
				foreach ( $options as $key => $val ) {
1298
					$options[ $key ]['name'] = $key;
1299
				}
1300
			}
1301
1302
			return $options;
1303
		}
1304
1305
		/**
1306
		 * Register the parent shortcode.
1307
		 *
1308
		 * @since 1.0.0
1309
		 */
1310
		public function register_shortcode() {
1311
			add_shortcode( $this->base_id, array( $this, 'shortcode_output' ) );
1312
			add_action( 'wp_ajax_super_duper_output_shortcode', array( $this, 'render_shortcode' ) );
1313
		}
1314
1315
		/**
1316
		 * Render the shortcode via ajax so we can return it to Gutenberg.
1317
		 *
1318
		 * @since 1.0.0
1319
		 */
1320
		public function render_shortcode() {
1321
			check_ajax_referer( 'super_duper_output_shortcode', '_ajax_nonce', true );
1322
			if ( ! current_user_can( 'manage_options' ) ) {
1323
				wp_die();
1324
			}
1325
1326
			// we might need the $post value here so lets set it.
1327
			if ( isset( $_POST['post_id'] ) && $_POST['post_id'] ) {
1328
				$post_obj = get_post( absint( $_POST['post_id'] ) );
1329
				if ( ! empty( $post_obj ) && empty( $post ) ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $post seems to never exist and therefore empty should always be true.
Loading history...
1330
					global $post;
1331
					$post = $post_obj;
1332
				}
1333
			}
1334
1335
			if ( isset( $_POST['shortcode'] ) && $_POST['shortcode'] ) {
1336
				$is_preview = $this->is_preview();
1337
				$shortcode_name   = sanitize_title_with_dashes( $_POST['shortcode'] );
1338
				$attributes_array = isset( $_POST['attributes'] ) && $_POST['attributes'] ? $_POST['attributes'] : array();
1339
				$attributes       = '';
1340
				if ( ! empty( $attributes_array ) ) {
1341
					foreach ( $attributes_array as $key => $value ) {
1342
						if ( is_array( $value ) ) {
1343
							$value = implode( ",", $value );
1344
						}
1345
1346
						if ( ! empty( $value ) ) {
1347
							$value = wp_unslash( $value );
1348
1349
							// Encode [ and ].
1350
							if ( $is_preview ) {
1351
								$value = $this->encode_shortcodes( $value );
1352
							}
1353
						}
1354
						$attributes .= " " . sanitize_title_with_dashes( $key ) . "='" . esc_attr( $value ) . "' ";
1355
					}
1356
				}
1357
1358
				$shortcode = "[" . $shortcode_name . " " . $attributes . "]";
1359
1360
				$content = do_shortcode( $shortcode );
1361
1362
				// Decode [ and ].
1363
				if ( ! empty( $content ) && $is_preview ) {
1364
					$content = $this->decode_shortcodes( $content );
1365
				}
1366
1367
				echo $content;
0 ignored issues
show
Security Cross-Site Scripting introduced by
$content can contain request data and is used in output context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and Data is passed through sanitize_title_with_dashes(), and sanitize_title_with_dashes($_POST['shortcode']) is assigned to $shortcode_name in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1337
  1. Read from $_POST, and Data is passed through sanitize_title_with_dashes(), and sanitize_title_with_dashes($_POST['shortcode']) is assigned to $shortcode_name
    in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1337
  2. '[' . $shortcode_name . ' ' . $attributes . ']' is assigned to $shortcode
    in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1358
  3. Data is passed through do_shortcode(), and do_shortcode($shortcode) is assigned to $content
    in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1360
  2. Path: Read from $_POST, and IssetNode && $_POST['attributes'] ? $_POST['attributes'] : array() is assigned to $attributes_array in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1338
  1. Read from $_POST, and IssetNode && $_POST['attributes'] ? $_POST['attributes'] : array() is assigned to $attributes_array
    in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1338
  2. $attributes_array is assigned to $key
    in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1341
  3. Data is passed through sanitize_title_with_dashes(), and ' ' . sanitize_title_with_dashes($key) . '='' . esc_attr($value) . '' ' is assigned to $attributes
    in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1354
  4. '[' . $shortcode_name . ' ' . $attributes . ']' is assigned to $shortcode
    in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1358
  5. Data is passed through do_shortcode(), and do_shortcode($shortcode) is assigned to $content
    in vendor/ayecode/wp-super-duper/wp-super-duper.php on line 1360

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
1368
			}
1369
			wp_die();
1370
		}
1371
1372
		/**
1373
		 * Output the shortcode.
1374
		 *
1375
		 * @param array $args
1376
		 * @param string $content
1377
		 *
1378
		 * @return string
1379
		 */
1380
		public function shortcode_output( $args = array(), $content = '' ) {
1381
			$_instance = $args;
1382
1383
			$args = $this->argument_values( $args );
1384
1385
			// add extra argument so we know its a output to gutenberg
1386
			//$args
1387
			$args = $this->string_to_bool( $args );
1388
1389
			// if we have a enclosed shortcode we add it to the special `html` argument
1390
			if ( ! empty( $content ) ) {
1391
				$args['html'] = $content;
1392
			}
1393
1394
			if ( ! $this->is_preview() ) {
1395
				/**
1396
				 * Filters the settings for a particular widget args.
1397
				 *
1398
				 * @param array          $args      The current widget instance's settings.
1399
				 * @param WP_Super_Duper $widget    The current widget settings.
1400
				 * @param array          $_instance An array of default widget arguments.
1401
				 *
1402
				 *@since 1.0.28
1403
				 *
1404
				 */
1405
				$args = apply_filters( 'wp_super_duper_widget_display_callback', $args, $this, $_instance );
1406
1407
				if ( ! is_array( $args ) ) {
1408
					return $args;
1409
				}
1410
			}
1411
1412
			$class = isset( $this->options['widget_ops']['classname'] ) ? esc_attr( $this->options['widget_ops']['classname'] ) : '';
1413
			$class .= " sdel-".$this->get_instance_hash();
1414
1415
			$class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this );
1416
			$class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this );
1417
1418
			$attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this );
0 ignored issues
show
Unused Code introduced by
The assignment to $attrs is dead and can be removed.
Loading history...
1419
			$attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this );
1420
1421
			$shortcode_args = array();
1422
			$output         = '';
1423
			$no_wrap        = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false;
1424
			if ( isset( $args['no_wrap'] ) && $args['no_wrap'] ) {
1425
				$no_wrap = true;
1426
			}
1427
			$main_content = $this->output( $args, $shortcode_args, $content );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $main_content is correct as $this->output($args, $shortcode_args, $content) targeting WP_Super_Duper::output() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1428
			if ( $main_content && ! $no_wrap ) {
0 ignored issues
show
introduced by
$main_content is defined implicitly as null, thus it is always evaluated to false.
Loading history...
1429
				// wrap the shortcode in a div with the same class as the widget
1430
				$output .= '<div class="' . $class . '" ' . $attrs . '>';
1431
				if ( ! empty( $args['title'] ) ) {
1432
					// if its a shortcode and there is a title try to grab the title wrappers
1433
					$shortcode_args = array( 'before_title' => '', 'after_title' => '' );
1434
					if ( empty( $instance ) ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $instance does not exist. Did you maybe mean $_instance?
Loading history...
1435
						global $wp_registered_sidebars;
1436
						if ( ! empty( $wp_registered_sidebars ) ) {
1437
							foreach ( $wp_registered_sidebars as $sidebar ) {
1438
								if ( ! empty( $sidebar['before_title'] ) ) {
1439
									$shortcode_args['before_title'] = $sidebar['before_title'];
1440
									$shortcode_args['after_title']  = $sidebar['after_title'];
1441
									break;
1442
								}
1443
							}
1444
						}
1445
					}
1446
					$output .= $this->output_title( $shortcode_args, $args );
1447
				}
1448
				$output .= $main_content;
1449
				$output .= '</div>';
1450
			} elseif ( $main_content && $no_wrap ) {
0 ignored issues
show
introduced by
$main_content is defined implicitly as null, thus it is always evaluated to false.
Loading history...
1451
				$output .= $main_content;
1452
			}
1453
1454
			// if preview show a placeholder if empty
1455
			if ( $this->is_preview() && $output == '' ) {
1456
				$output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" );
1457
			}
1458
1459
			return apply_filters( 'wp_super_duper_widget_output', $output, $args, $shortcode_args, $this );
1460
		}
1461
1462
		/**
1463
		 * Placeholder text to show if output is empty and we are on a preview/builder page.
1464
		 *
1465
		 * @param string $name
1466
		 *
1467
		 * @return string
1468
		 */
1469
		public function preview_placeholder_text( $name = '' ) {
1470
			return "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" . sprintf( __( 'Placeholder for: %s' ), $name ) . "</div>";
1471
		}
1472
1473
		/**
1474
		 * Sometimes booleans values can be turned to strings, so we fix that.
1475
		 *
1476
		 * @param $options
1477
		 *
1478
		 * @return mixed
1479
		 */
1480
		public function string_to_bool( $options ) {
1481
			// convert bool strings to booleans
1482
			foreach ( $options as $key => $val ) {
1483
				if ( $val == 'false' ) {
1484
					$options[ $key ] = false;
1485
				} elseif ( $val == 'true' ) {
1486
					$options[ $key ] = true;
1487
				}
1488
			}
1489
1490
			return $options;
1491
		}
1492
1493
		/**
1494
		 * Get the argument values that are also filterable.
1495
		 *
1496
		 * @param $instance
1497
		 *
1498
		 * @return array
1499
		 *@since 1.0.12 Don't set checkbox default value if the value is empty.
1500
		 *
1501
		 */
1502
		public function argument_values( $instance ) {
1503
			$argument_values = array();
1504
1505
			// set widget instance
1506
			$this->instance = $instance;
1507
1508
			if ( empty( $this->arguments ) ) {
1509
				$this->arguments = $this->get_arguments();
1510
			}
1511
1512
			if ( ! empty( $this->arguments ) ) {
1513
				foreach ( $this->arguments as $key => $args ) {
1514
					// set the input name from the key
1515
					$args['name'] = $key;
1516
					//
1517
					$argument_values[ $key ] = isset( $instance[ $key ] ) ? $instance[ $key ] : '';
1518
					if ( $args['type'] == 'checkbox' && $argument_values[ $key ] == '' ) {
1519
						// don't set default for an empty checkbox
1520
					} elseif ( $argument_values[ $key ] == '' && isset( $args['default'] ) ) {
1521
						$argument_values[ $key ] = $args['default'];
1522
					}
1523
				}
1524
			}
1525
1526
			return $argument_values;
1527
		}
1528
1529
		/**
1530
		 * Set arguments in super duper.
1531
		 *
1532
		 * @return array Set arguments.
1533
		 *@since 1.0.0
1534
		 *
1535
		 */
1536
		public function set_arguments() {
1537
			return $this->arguments;
1538
		}
1539
1540
		/**
1541
		 * Get arguments in super duper.
1542
		 *
1543
		 * @return array Get arguments.
1544
		 *@since 1.0.0
1545
		 *
1546
		 */
1547
		public function get_arguments() {
1548
			if ( empty( $this->arguments ) ) {
1549
				$this->arguments = $this->set_arguments();
1550
			}
1551
1552
			$this->arguments = apply_filters( 'wp_super_duper_arguments', $this->arguments, $this->options, $this->instance );
1553
			$this->arguments = $this->add_name_from_key( $this->arguments, true );
1554
1555
			return $this->arguments;
1556
		}
1557
1558
		/**
1559
		 * This is the main output class for all 3 items, widget, shortcode and block, it is extended in the calling class.
1560
		 *
1561
		 * @param array $args
1562
		 * @param array $widget_args
1563
		 * @param string $content
1564
		 */
1565
		public function output( $args = array(), $widget_args = array(), $content = '' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $widget_args is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1565
		public function output( $args = array(), /** @scrutinizer ignore-unused */ $widget_args = array(), $content = '' ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1566
1567
		}
1568
1569
		/**
1570
		 * Add the dynamic block code inline when the wp-block in enqueued.
1571
		 */
1572
		public function register_block() {
1573
			wp_add_inline_script( 'wp-blocks', $this->block() );
1574
			if ( class_exists( 'SiteOrigin_Panels' ) ) {
1575
				wp_add_inline_script( 'wp-blocks', $this->siteorigin_js() );
1576
			}
1577
		}
1578
1579
		/**
1580
		 * Check if we need to show advanced options.
1581
		 *
1582
		 * @return bool
1583
		 */
1584
		public function block_show_advanced() {
1585
1586
			$show      = false;
1587
			$arguments = $this->get_arguments();
1588
1589
			if ( ! empty( $arguments ) ) {
1590
				foreach ( $arguments as $argument ) {
1591
					if ( isset( $argument['advanced'] ) && $argument['advanced'] ) {
1592
						$show = true;
1593
						break; // no need to continue if we know we have it
1594
					}
1595
				}
1596
			}
1597
1598
			return $show;
1599
		}
1600
1601
		/**
1602
		 * Get the url path to the current folder.
1603
		 *
1604
		 * @return string
1605
		 */
1606
		public function get_url() {
1607
			$url = $this->url;
1608
1609
			if ( ! $url ) {
1610
				$content_dir = wp_normalize_path( untrailingslashit( WP_CONTENT_DIR ) );
1611
				$content_url = untrailingslashit( WP_CONTENT_URL );
1612
1613
				// Replace http:// to https://.
1614
				if ( strpos( $content_url, 'http://' ) === 0 && strpos( plugins_url(), 'https://' ) === 0 ) {
1615
					$content_url = str_replace( 'http://', 'https://', $content_url );
1616
				}
1617
1618
				// Check if we are inside a plugin
1619
				$file_dir = str_replace( "/includes", "", wp_normalize_path( dirname( __FILE__ ) ) );
1620
				$url = str_replace( $content_dir, $content_url, $file_dir );
1621
				$url = trailingslashit( $url );
1622
				$this->url = $url;
1623
			}
1624
1625
			return $url;
1626
		}
1627
1628
		/**
1629
		 * Get the url path to the current folder.
1630
		 *
1631
		 * @return string
1632
		 */
1633
		public function get_url_old() {
1634
1635
			$url = $this->url;
1636
1637
			if ( ! $url ) {
1638
				// check if we are inside a plugin
1639
				$file_dir = str_replace( "/includes", "", dirname( __FILE__ ) );
1640
1641
				$dir_parts = explode( "/wp-content/", $file_dir );
1642
				$url_parts = explode( "/wp-content/", plugins_url() );
1643
1644
				if ( ! empty( $url_parts[0] ) && ! empty( $dir_parts[1] ) ) {
1645
					$url       = trailingslashit( $url_parts[0] . "/wp-content/" . $dir_parts[1] );
1646
					$this->url = $url;
1647
				}
1648
			}
1649
1650
1651
			return $url;
1652
		}
1653
1654
		/**
1655
		 * Generate the block icon.
1656
		 *
1657
		 * Enables the use of Font Awesome icons.
1658
		 *
1659
		 * @note xlink:href is actually deprecated but href is not supported by all so we use both.
1660
		 *
1661
		 * @param $icon
1662
		 *
1663
		 * @return string
1664
		 *@since 1.1.0
1665
		 */
1666
		public function get_block_icon( $icon ) {
1667
1668
			// check if we have a Font Awesome icon
1669
			$fa_type = '';
1670
			if ( substr( $icon, 0, 7 ) === "fas fa-" ) {
1671
				$fa_type = 'solid';
1672
			} elseif ( substr( $icon, 0, 7 ) === "far fa-" ) {
1673
				$fa_type = 'regular';
1674
			} elseif ( substr( $icon, 0, 7 ) === "fab fa-" ) {
1675
				$fa_type = 'brands';
1676
			} else {
1677
				$icon = "'" . $icon . "'";
1678
			}
1679
1680
			// set the icon if we found one
1681
			if ( $fa_type ) {
1682
				$fa_icon = str_replace( array( "fas fa-", "far fa-", "fab fa-" ), "", $icon );
1683
				$icon    = "el('svg',{width: 20, height: 20, viewBox: '0 0 20 20'},el('use', {'xlink:href': '" . $this->get_url() . "icons/" . $fa_type . ".svg#" . $fa_icon . "','href': '" . $this->get_url() . "icons/" . $fa_type . ".svg#" . $fa_icon . "'}))";
1684
			}
1685
1686
			return $icon;
1687
		}
1688
1689
		public function group_arguments( $arguments ) {
1690
//			echo '###';print_r($arguments);
1691
			if ( ! empty( $arguments ) ) {
1692
				$temp_arguments = array();
1693
				$general        = __( "General" );
1694
				$add_sections   = false;
1695
				foreach ( $arguments as $key => $args ) {
1696
					if ( isset( $args['group'] ) ) {
1697
						$temp_arguments[ $args['group'] ][ $key ] = $args;
1698
						$add_sections                             = true;
1699
					} else {
1700
						$temp_arguments[ $general ][ $key ] = $args;
1701
					}
1702
				}
1703
1704
				// only add sections if more than one
1705
				if ( $add_sections ) {
1706
					$arguments = $temp_arguments;
1707
				}
1708
			}
1709
1710
//			echo '###';print_r($arguments);
1711
			return $arguments;
1712
		}
1713
1714
		/**
1715
		 * Parse used group tabs.
1716
		 *
1717
		 * @since 1.1.17
1718
		 */
1719
		public function group_block_tabs( $tabs, $arguments ) {
1720
			if ( ! empty( $tabs ) && ! empty( $arguments ) ) {
1721
				$has_sections = false;
1722
1723
				foreach ( $this->arguments as $key => $args ) {
1724
					if ( isset( $args['group'] ) ) {
1725
						$has_sections = true;
1726
						break;
1727
					}
1728
				}
1729
1730
				if ( ! $has_sections ) {
1731
					return $tabs;
1732
				}
1733
1734
				$new_tabs = array();
1735
1736
				foreach ( $tabs as $tab_key => $tab ) {
1737
					$new_groups = array();
1738
1739
					if ( ! empty( $tab['groups'] ) && is_array( $tab['groups'] ) ) {
1740
						foreach ( $tab['groups'] as $group ) {
1741
							if ( isset( $arguments[ $group ] ) ) {
1742
								$new_groups[] = $group;
1743
							}
1744
						}
1745
					}
1746
1747
					if ( ! empty( $new_groups ) ) {
1748
						$tab['groups'] = $new_groups;
1749
1750
						$new_tabs[ $tab_key ] = $tab;
1751
					}
1752
				}
1753
1754
				$tabs = $new_tabs;
1755
			}
1756
1757
			return $tabs;
1758
		}
1759
1760
		/**
1761
		 * Output the JS for building the dynamic Guntenberg block.
1762
		 *
1763
		 * @return mixed
1764
		 *@since 1.0.9 Save numbers as numbers and not strings.
1765
		 * @since 1.1.0 Font Awesome classes can be used for icons.
1766
		 * @since 1.0.4 Added block_wrap property which will set the block wrapping output element ie: div, span, p or empty for no wrap.
1767
		 */
1768
		public function block() {
1769
			global $sd_is_js_functions_loaded, $aui_bs5;
1770
1771
			$show_advanced = $this->block_show_advanced();
1772
1773
			ob_start();
1774
			?>
1775
			<script>
1776
			<?php
1777
			if ( ! $sd_is_js_functions_loaded ) {
1778
				$sd_is_js_functions_loaded = true;
1779
			?>
1780
function sd_show_view_options($this){
1781
	if(jQuery($this).html().length){
1782
		jQuery($this).html('');
1783
	}else{
1784
		jQuery($this).html('<div class="position-absolute d-flex flex-column bg-white p-1 rounded border shadow-lg " style="top:-80px;left:-5px;"><div class="dashicons dashicons-desktop mb-1" onclick="sd_set_view_type(\'Desktop\');"></div><div class="dashicons dashicons-tablet mb-1" onclick="sd_set_view_type(\'Tablet\');"></div><div class="dashicons dashicons-smartphone" onclick="sd_set_view_type(\'Mobile\');"></div></div>');
1785
	}
1786
}
1787
1788
function sd_set_view_type($device){
1789
	wp.data.dispatch('core/edit-site') ? wp.data.dispatch('core/edit-site').__experimentalSetPreviewDeviceType($device) : wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType($device);
1790
}
1791
1792
jQuery(function(){
1793
	sd_block_visibility_init();
1794
});
1795
function sd_block_visibility_init() {
1796
	jQuery(document).off('change', '.bs-vc-modal-form').on('change', '.bs-vc-modal-form', function() {
1797
		try {
1798
			aui_conditional_fields('.bs-vc-modal-form');
1799
		} catch(err) {
1800
			console.log(err.message);
1801
		}
1802
	});
1803
1804
	jQuery(document).off('click', '.bs-vc-save').on('click', '.bs-vc-save', function() {
1805
		var $bsvcModal = jQuery(this).closest('.bs-vc-modal'), $bsvcForm = $bsvcModal.find('.bs-vc-modal-form'), vOutput = jQuery('#bsvc_output', $bsvcForm).val(), rawValue = '', oVal = {}, oOut = {}, iRule = 0;
1806
		jQuery(this).addClass('disabled');
1807
		jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule').each(function(){
1808
			vRule = jQuery(this).find('.bsvc_rule').val(), oRule = {};
1809
			if (vRule == 'logged_in' || vRule == 'logged_out') {
1810
				oRule.type = vRule;
1811
			} else if (vRule == 'user_roles') {
1812
				oRule.type = vRule;
1813
				if (jQuery(this).find('.bsvc_user_roles:checked').length) {
1814
					var user_roles = jQuery(this).find('.bsvc_user_roles:checked').map(function() {
1815
						return jQuery(this).val();
1816
					}).get();
1817
					if (user_roles && user_roles.length) {
1818
						oRule.user_roles = user_roles.join(",");
1819
					}
1820
				}
1821
			} else if (vRule == 'gd_field') {
1822
				if (jQuery(this).find('.bsvc_gd_field ').val() && jQuery(this).find('.bsvc_gd_field_condition').val()) {
1823
					oRule.type = vRule;
1824
					oRule.field = jQuery(this).find('.bsvc_gd_field ').val();
1825
					oRule.condition = jQuery(this).find('.bsvc_gd_field_condition').val();
1826
					if (oRule.condition != 'is_empty' && oRule.condition != 'is_not_empty') {
1827
						oRule.search = jQuery(this).find('.bsvc_gd_field_search').val();
1828
					}
1829
				}
1830
			}
1831
			if (Object.keys(oRule).length > 0) {
1832
				iRule++;
1833
				oVal['rule'+iRule] = oRule;
1834
			}
1835
		});
1836
		if (vOutput == 'hide') {
1837
			oOut.type = vOutput;
1838
		} else if (vOutput == 'message') {
1839
			if (jQuery('#bsvc_message', $bsvcForm).val()) {
1840
				oOut.type = vOutput;
1841
				oOut.message = jQuery('#bsvc_message', $bsvcForm).val();
1842
				if (jQuery('#bsvc_message_type', $bsvcForm).val()) {
1843
					oOut.message_type = jQuery('#bsvc_message_type', $bsvcForm).val();
1844
				}
1845
			}
1846
		} else if (vOutput == 'page') {
1847
			if (jQuery('#bsvc_page', $bsvcForm).val()) {
1848
				oOut.type = vOutput;
1849
				oOut.page = jQuery('#bsvc_page', $bsvcForm).val();
1850
			}
1851
		} else if (vOutput == 'template_part') {
1852
			if (jQuery('#bsvc_tmpl_part', $bsvcForm).val()) {
1853
				oOut.type = vOutput;
1854
				oOut.template_part = jQuery('#bsvc_tmpl_part', $bsvcForm).val();
1855
			}
1856
		}
1857
		if (Object.keys(oOut).length > 0) {
1858
			oVal.output = oOut;
1859
		}
1860
		if (Object.keys(oVal).length > 0) {
1861
			rawValue = JSON.stringify(oVal);
1862
		}
1863
		$bsvcModal.find('[name="bsvc_raw_value"]').val(rawValue).trigger('change');
1864
		$bsvcModal.find('.bs-vc-close').trigger('click');
1865
	});
1866
	jQuery(document).off('click', '.bs-vc-add-rule').on('click', '.bs-vc-add-rule', function() {
1867
		var bsvcTmpl = jQuery('.bs-vc-rule-template').html();
1868
		var c = parseInt(jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last').data('bs-index'));
1869
		if (c > 0) {
1870
			c++;
1871
		} else {
1872
			c = 1;
1873
		}
1874
		bsvcTmpl = bsvcTmpl.replace(/BSVCINDEX/g, c);
1875
		jQuery('.bs-vc-modal-form .bs-vc-rule-sets').append(bsvcTmpl);
1876
		jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last').find('select').each(function(){
1877
			if (!jQuery(this).hasClass('no-select2')) {
1878
				jQuery(this).addClass('aui-select2');
1879
			}
1880
		});
1881
		if (!jQuery(this).hasClass('bs-vc-rendering')) {
1882
			if(typeof aui_init_select2 == 'function') {
1883
				aui_init_select2();
1884
			}
1885
			if(typeof aui_conditional_fields == 'function') {
1886
				aui_conditional_fields('.bs-vc-modal-form');
1887
			}
1888
		}
1889
	});
1890
	jQuery(document).off('click', '.bs-vc-remove-rule').on('click', '.bs-vc-remove-rule', function() {
1891
		jQuery(this).closest('.bs-vc-rule').remove();
1892
	});
1893
}
1894
function sd_block_visibility_render_fields(oValue) {
1895
	if (typeof oValue == 'object' && oValue.rule1 && typeof oValue.rule1 == 'object') {
1896
		for(k = 1; k <= Object.keys(oValue).length; k++) {
1897
			if (oValue['rule' + k] && oValue['rule' + k].type) {
1898
				var oRule = oValue['rule' + k];
1899
				jQuery('.bs-vc-modal-form .bs-vc-add-rule').addClass('bs-vc-rendering').trigger('click');
1900
				var elRule = jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last');
1901
				jQuery('select.bsvc_rule', elRule).val(oRule.type);
1902
				if (oRule.type == 'user_roles' && oRule.user_roles) {
1903
					var user_roles = oRule.user_roles;
1904
					if (typeof user_roles == 'string') {
1905
						user_roles = user_roles.split(",");
1906
					}
1907
					if (user_roles.length) {
1908
						jQuery.each(user_roles, function(i, role){
1909
							elRule.find("input[value='" + role + "']").prop('checked', true);
1910
						});
1911
					}
1912
					jQuery('select.bsvc_user_roles', elRule).val(oRule.user_roles);
1913
				} else if (oRule.type == 'gd_field') {
1914
					if (oRule.field) {
1915
						jQuery('select.bsvc_gd_field', elRule).val(oRule.field);
1916
						if (oRule.condition) {
1917
							jQuery('select.bsvc_gd_field_condition', elRule).val(oRule.condition);
1918
							if (typeof oRule.search != 'undefined' && oRule.condition != 'is_empty' && oRule.condition != 'is_not_empty') {
1919
								jQuery('input.bsvc_gd_field_search', elRule).val(oRule.search);
1920
							}
1921
						}
1922
					}
1923
				}
1924
				jQuery('.bs-vc-modal-form .bs-vc-add-rule').removeClass('bs-vc-rendering');
1925
			}
1926
		}
1927
1928
		if (oValue.output && oValue.output.type) {
1929
			jQuery('.bs-vc-modal-form #bsvc_output').val(oValue.output.type);
1930
			if (oValue.output.type == 'message' && typeof oValue.output.message != 'undefined') {
1931
				jQuery('.bs-vc-modal-form #bsvc_message').val(oValue.output.message);
1932
				if (typeof oValue.output.message_type != 'undefined') {
1933
					jQuery('.bs-vc-modal-form #bsvc_message_type').val(oValue.output.message_type);
1934
				}
1935
			} else if (oValue.output.type == 'page' && typeof oValue.output.page != 'undefined') {
1936
				jQuery('.bs-vc-modal-form #bsvc_page').val(oValue.output.page);
1937
			} else if (oValue.output.type == 'template_part' && typeof oValue.output.template_part != 'undefined') {
1938
				jQuery('.bs-vc-modal-form #bsvc_template_part').val(oValue.output.template_part);
1939
			}
1940
		}
1941
	}
1942
}
1943
/**
1944
 * Try to auto-recover blocks.
1945
 */
1946
function sd_auto_recover_blocks() {
1947
	var recursivelyRecoverInvalidBlockList = blocks => {
1948
		const _blocks = [...blocks]
1949
		let recoveryCalled = false
1950
		const recursivelyRecoverBlocks = willRecoverBlocks => {
1951
			willRecoverBlocks.forEach(_block => {
1952
				if (!_block.isValid) {
1953
					recoveryCalled = true
1954
					const newBlock = recoverBlock(_block)
1955
					for (const key in newBlock) {
1956
						_block[key] = newBlock[key]
1957
					}
1958
				}
1959
				if (_block.innerBlocks.length) {
1960
					recursivelyRecoverBlocks(_block.innerBlocks)
1961
				}
1962
			})
1963
		}
1964
		recursivelyRecoverBlocks(_blocks)
1965
		return [_blocks, recoveryCalled]
1966
	}
1967
	var recoverBlock = ({ name, attributes, innerBlocks }) => wp.blocks.createBlock(name, attributes, innerBlocks);
1968
	var recoverBlocks = blocks => {
1969
		return blocks.map(_block => {
1970
			const block = _block;
1971
			// If the block is a reusable block, recover the Stackable blocks inside it.
1972
			if (_block.name === 'core/block') {
1973
				const { attributes: { ref } } = _block
1974
				const parsedBlocks = wp.blocks.parse(wp.data.select('core').getEntityRecords('postType', 'wp_block', { include: [ref] })?.[0]?.content?.raw) || []
1975
				const [recoveredBlocks, recoveryCalled] = recursivelyRecoverInvalidBlockList(parsedBlocks)
1976
				if (recoveryCalled) {
1977
					console.log('Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.');
1978
					return { blocks: recoveredBlocks, isReusable: true, ref }
1979
				}
1980
			} else if (_block.name === 'core/template-part' && _block.attributes && _block.attributes.theme) {
1981
				var tmplPart = wp.data.select('core').getEntityRecord('postType', 'wp_template_part', _block.attributes.theme + '//' + _block.attributes.slug);
1982
				var tmplPartBlocks = block.innerBlocks && block.innerBlocks.length ? block.innerBlocks : wp.blocks.parse(tmplPart?.content?.raw) || [];
1983
				if (tmplPartBlocks && tmplPartBlocks.length && tmplPartBlocks.some(block => !block.isValid)) {
1984
					block.innerBlocks = tmplPartBlocks;
1985
					block.tmplPartId = _block.attributes.theme + '//' + _block.attributes.slug;
1986
				}
1987
			}
1988
			if (block.innerBlocks && block.innerBlocks.length) {
1989
				if (block.tmplPartId) {
1990
					console.log('Template part ' + block.tmplPartId + ' block ' + block.name + ' (' + block.clientId + ') starts');
1991
				}
1992
				const newInnerBlocks = recoverBlocks(block.innerBlocks)
1993
				if (newInnerBlocks.some(block => block.recovered)) {
1994
					block.innerBlocks = newInnerBlocks
1995
					block.replacedClientId = block.clientId
1996
					block.recovered = true
1997
				}
1998
				if (block.tmplPartId) {
1999
					console.log('Template part ' + block.tmplPartId + ' block ' + block.name + ' (' + block.clientId + ') ends');
2000
				}
2001
			}
2002
			if (!block.isValid) {
2003
				const newBlock = recoverBlock(block)
2004
				newBlock.replacedClientId = block.clientId
2005
				newBlock.recovered = true
2006
				console.log('Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.');
2007
				return newBlock
2008
			}
2009
			return block
2010
		})
2011
	}
2012
	// Recover all the blocks that we can find.
2013
	var mainBlocks = recoverBlocks(wp.data.select('core/block-editor').getBlocks());
2014
	// Replace the recovered blocks with the new ones.
2015
	mainBlocks.forEach(block => {
2016
		if (block.isReusable && block.ref) {
2017
			// Update the reusable blocks.
2018
			wp.data.dispatch('core').editEntityRecord('postType', 'wp_block', block.ref, {
2019
				content: wp.blocks.serialize(block.blocks)
2020
			}).then(() => {
2021
				// But don't save them, let the user do the saving themselves. Our goal is to get rid of the block error visually.
2022
			})
2023
		}
2024
		if (block.recovered && block.replacedClientId) {
2025
			wp.data.dispatch('core/block-editor').replaceBlock(block.replacedClientId, block)
2026
		}
2027
	})
2028
}
2029
2030
/**
2031
 * Try to auto-recover OUR blocks if traditional way fails.
2032
 */
2033
function sd_auto_recover_blocks_fallback() {
2034
	console.log('sd_auto_recover_blocks_fallback()');
2035
	jQuery(".edit-site-visual-editor__editor-canvas").contents().find('div[class*=" wp-block-blockstrap-"] .block-editor-warning__actions  .block-editor-warning__action .components-button.is-primary').not(":contains('Keep as HTML')").removeAttr('disabled').click();
2036
}
2037
2038
// Wait will window is loaded before calling.
2039
window.onload = function() {
2040
	sd_auto_recover_blocks();
2041
	// fire a second time incase of load delays.
2042
	setTimeout(function() {
2043
		sd_auto_recover_blocks();
2044
	}, 5000);
2045
2046
	setTimeout(function() {
2047
		sd_auto_recover_blocks_fallback();
2048
	}, 6000);
2049
2050
	setTimeout(function() {
2051
		sd_auto_recover_blocks_fallback();
2052
	}, 10000);
2053
2054
	setTimeout(function() {
2055
		sd_auto_recover_blocks_fallback();
2056
	}, 15000);
2057
2058
	setTimeout(function() {
2059
		sd_auto_recover_blocks_fallback();
2060
	}, 20000);
2061
};
2062
2063
// fire when URL changes also.
2064
let lastUrl = location.href;
2065
new MutationObserver(() => {
2066
    const url = location.href;
2067
    if (url !== lastUrl) {
2068
        lastUrl = url;
2069
        sd_auto_recover_blocks();
2070
        // fire a second time incase of load delays.
2071
        setTimeout(function() {
2072
            sd_auto_recover_blocks();
2073
			sd_auto_recover_blocks_fallback();
2074
        }, 2000);
2075
2076
		setTimeout(function() {
2077
		sd_auto_recover_blocks_fallback();
2078
		}, 10000);
2079
2080
		setTimeout(function() {
2081
		sd_auto_recover_blocks_fallback();
2082
		}, 15000);
2083
2084
		setTimeout(function() {
2085
		sd_auto_recover_blocks_fallback();
2086
		}, 20000);
2087
2088
    }
2089
}).observe(document, {
2090
    subtree: true,
2091
    childList: true
2092
});
2093
2094
2095
			/**
2096
			*
2097
* @param $args
2098
* @returns {*|{}}
2099
*/
2100
            function sd_build_aui_styles($args){
2101
2102
                $styles = {};
2103
                // background color
2104
                if ( $args['bg'] !== undefined && $args['bg'] !== '' ) {
2105
                   if( $args['bg'] == 'custom-color' ){
2106
                       $styles['background-color']=  $args['bg_color'];
2107
                   }else  if( $args['bg'] == 'custom-gradient' ){
2108
                       $styles['background-image']=  $args['bg_gradient'];
2109
2110
					    // use background on text
2111
						 if( $args['bg_on_text'] !== undefined && $args['bg_on_text'] ){
2112
							$styles['backgroundClip'] = "text";
2113
							$styles['WebkitBackgroundClip'] = "text";
2114
							$styles['text-fill-color'] = "transparent";
2115
							$styles['WebkitTextFillColor'] = "transparent";
2116
						 }
2117
                   }
2118
2119
                }
2120
2121
				let $bg_image = $args['bg_image'] !== undefined && $args['bg_image'] !== '' ? $args['bg_image'] : '';
2122
2123
				// maybe use featured image.
2124
				if( $args['bg_image_use_featured'] !== undefined && $args['bg_image_use_featured'] ){
2125
					$bg_image = '<?php echo $this->get_url();?>icons/placeholder.png';
2126
				}
2127
2128
                if( $bg_image !== undefined && $bg_image !== '' ){
2129
                    var hasImage = true
2130
                    if($styles['background-color'] !== undefined && $args['bg'] == 'custom-color'){
2131
                           $styles['background-image'] = "url("+$bg_image+")";
2132
                           $styles['background-blend-mode'] =  "overlay";
2133
                    }else if($styles['background-image'] !== undefined && $args['bg'] == 'custom-gradient'){
2134
                           $styles['background-image'] +=  ",url("+$bg_image+")";
2135
                    }else if($args['bg'] !== undefined && $args['bg'] != '' && $args['bg'] != 'transparent' ){
2136
                           // do nothing as we alreay have a preset
2137
                           hasImage = false;
2138
                    }else{
2139
                           $styles['background-image'] = "url("+$bg_image+")";
2140
                    }
2141
2142
                    if( hasImage){
2143
                         $styles['background-size'] = "cover";
2144
2145
						 if( $args['bg_image_fixed'] !== undefined && $args['bg_image_fixed'] ){
2146
							 $styles['background-attachment'] = "fixed";
2147
						 }
2148
                    }
2149
2150
                    if( hasImage && $args['bg_image_xy'].x !== undefined && $args['bg_image_xy'].x >=0 ){
2151
                          $styles['background-position'] =  ($args['bg_image_xy'].x * 100 ) + "% " + ( $args['bg_image_xy'].y * 100) + "%";
2152
                    }
2153
                }
2154
2155
2156
2157
				// sticky offset top
2158
				if( $args['sticky_offset_top'] !== undefined && $args['sticky_offset_top'] !== '' ){
2159
					$styles['top'] =  $args['sticky_offset_top'];
2160
				}
2161
2162
				// sticky offset bottom
2163
				if( $args['sticky_offset_bottom'] !== undefined && $args['sticky_offset_bottom'] !== '' ){
2164
					$styles['bottom'] =  $args['sticky_offset_bottom'];
2165
				}
2166
2167
				// font size
2168
				if( $args['font_size'] === undefined || $args['font_size'] === 'custom' ){
2169
					if( $args['font_size_custom'] !== undefined && $args['font_size_custom'] !== '' ){
2170
						$styles['fontSize'] =  $args['font_size_custom'] + "rem";
2171
					}
2172
				}
2173
2174
				// font color
2175
				if( $args['text_color'] === undefined || $args['text_color'] === 'custom' ){
2176
					if( $args['text_color_custom'] !== undefined && $args['text_color_custom'] !== '' ){
2177
						$styles['color'] =  $args['text_color_custom'];
2178
					}
2179
				}
2180
2181
				// font line height
2182
				if( $args['font_line_height'] !== undefined && $args['font_line_height'] !== '' ){
2183
					$styles['lineHeight'] =  $args['font_line_height'];
2184
				}
2185
2186
				// max height
2187
				if( $args['max_height'] !== undefined && $args['max_height'] !== '' ){
2188
					$styles['maxHeight'] =  $args['max_height'];
2189
				}
2190
2191
                return $styles;
2192
2193
            }
2194
2195
            function sd_build_aui_class($args){
2196
2197
                $classes = [];
2198
2199
				<?php
2200
				if($aui_bs5){
2201
					?>
2202
				$aui_bs5 = true;
2203
				$p_ml = 'ms-';
2204
				$p_mr = 'me-';
2205
2206
				$p_pl = 'ps-';
2207
				$p_pr = 'pe-';
2208
					<?php
2209
				}else{
2210
						?>
2211
				$aui_bs5 = false;
2212
				$p_ml = 'ml-';
2213
				$p_mr = 'mr-';
2214
2215
				$p_pl = 'pl-';
2216
				$p_pr = 'pr-';
2217
					<?php
2218
				}
2219
				?>
2220
2221
                // margins
2222
	            if ( $args['mt'] !== undefined && $args['mt'] !== '' ) { $classes.push( "mt-" + $args['mt'] );  $mt = $args['mt']; }else{$mt = null;}
2223
	            if ( $args['mr'] !== undefined && $args['mr'] !== '' ) { $classes.push( $p_mr + $args['mr'] );  $mr = $args['mr']; }else{$mr = null;}
2224
	            if ( $args['mb'] !== undefined && $args['mb'] !== '' ) { $classes.push( "mb-" + $args['mb'] );  $mb = $args['mb']; }else{$mb = null;}
2225
	            if ( $args['ml'] !== undefined && $args['ml'] !== '' ) { $classes.push( $p_ml + $args['ml'] );  $ml = $args['ml']; }else{$ml = null;}
2226
2227
                // margins tablet
2228
	            if ( $args['mt_md'] !== undefined && $args['mt_md'] !== '' ) { $classes.push( "mt-md-" + $args['mt_md'] );  $mt_md = $args['mt_md']; }else{$mt_md = null;}
2229
	            if ( $args['mr_md'] !== undefined && $args['mr_md'] !== '' ) { $classes.push( $p_mr + "md-" + $args['mr_md'] );  $mt_md = $args['mr_md']; }else{$mr_md = null;}
2230
	            if ( $args['mb_md'] !== undefined && $args['mb_md'] !== '' ) { $classes.push( "mb-md-" + $args['mb_md'] );  $mt_md = $args['mb_md']; }else{$mb_md = null;}
2231
	            if ( $args['ml_md'] !== undefined && $args['ml_md'] !== '' ) { $classes.push( $p_ml + "md-" + $args['ml_md'] );  $mt_md = $args['ml_md']; }else{$ml_md = null;}
2232
2233
                // margins desktop
2234
                if ( $args['mt_lg'] !== undefined && $args['mt_lg'] !== '' ) { if($mt == null && $mt_md == null){ $classes.push( "mt-" + $args['mt_lg'] ); }else{$classes.push( "mt-lg-" + $args['mt_lg'] ); } }
2235
	            if ( $args['mr_lg'] !== undefined && $args['mr_lg'] !== '' ) { if($mr == null && $mr_md == null){ $classes.push( $p_mr + $args['mr_lg'] ); }else{$classes.push( $p_mr + "lg-" + $args['mr_lg'] ); } }
2236
	            if ( $args['mb_lg'] !== undefined && $args['mb_lg'] !== '' ) { if($mb == null && $mb_md == null){ $classes.push( "mb-" + $args['mb_lg'] ); }else{$classes.push( "mb-lg-" + $args['mb_lg'] ); } }
2237
	            if ( $args['ml_lg'] !== undefined && $args['ml_lg'] !== '' ) { if($ml == null && $ml_md == null){ $classes.push( $p_ml + $args['ml_lg'] ); }else{$classes.push( $p_ml + "lg-" + $args['ml_lg'] ); } }
2238
2239
                // padding
2240
                if ( $args['pt'] !== undefined && $args['pt'] !== '' ) { $classes.push( "pt-" + $args['pt'] ); $pt = $args['pt']; }else{$pt = null;}
2241
	            if ( $args['pr'] !== undefined && $args['pr'] !== '' ) { $classes.push( $p_pr + $args['pr'] ); $pr = $args['pt']; }else{$pr = null;}
2242
	            if ( $args['pb'] !== undefined && $args['pb'] !== '' ) { $classes.push( "pb-" + $args['pb'] ); $pb = $args['pt']; }else{$pb = null;}
2243
	            if ( $args['pl'] !== undefined && $args['pl'] !== '' ) { $classes.push( $p_pl + $args['pl'] ); $pl = $args['pt']; }else{$pl = null;}
2244
2245
                // padding tablet
2246
                if ( $args['pt_md'] !== undefined && $args['pt_md'] !== '' ) { $classes.push( "pt-md-" + $args['pt_md'] ); $pt_md = $args['pt_md']; }else{$pt_md = null;}
2247
	            if ( $args['pr_md'] !== undefined && $args['pr_md'] !== '' ) { $classes.push( $p_pr + "md-" + $args['pr_md'] ); $pr_md = $args['pt_md']; }else{$pr_md = null;}
2248
	            if ( $args['pb_md'] !== undefined && $args['pb_md'] !== '' ) { $classes.push( "pb-md-" + $args['pb_md'] ); $pb_md = $args['pt_md']; }else{$pb_md = null;}
2249
	            if ( $args['pl_md'] !== undefined && $args['pl_md'] !== '' ) { $classes.push( $p_pl + "md-" + $args['pl_md'] ); $pl_md = $args['pt_md']; }else{$pl_md = null;}
2250
2251
                // padding desktop
2252
                if ( $args['pt_lg'] !== undefined && $args['pt_lg'] !== '' ) { if($pt == null && $pt_md == null){ $classes.push( "pt-" + $args['pt_lg'] ); }else{$classes.push( "pt-lg-" + $args['pt_lg'] ); } }
2253
	            if ( $args['pr_lg'] !== undefined && $args['pr_lg'] !== '' ) { if($pr == null && $pr_md == null){ $classes.push( $p_pr + $args['pr_lg'] ); }else{$classes.push( $p_pr + "lg-" + $args['pr_lg'] ); } }
2254
	            if ( $args['pb_lg'] !== undefined && $args['pb_lg'] !== '' ) { if($pb == null && $pb_md == null){ $classes.push( "pb-" + $args['pb_lg'] ); }else{$classes.push( "pb-lg-" + $args['pb_lg'] ); } }
2255
	            if ( $args['pl_lg'] !== undefined && $args['pl_lg'] !== '' ) { if($pl == null && $pl_md == null){ $classes.push( $p_pl + $args['pl_lg'] ); }else{$classes.push( $p_pl + "lg-" + $args['pl_lg'] ); } }
2256
2257
				// row cols, mobile, tablet, desktop
2258
	            if ( $args['row_cols'] !== undefined && $args['row_cols'] !== '' ) { $classes.push( "row-cols-" + $args['row_cols'] );  $row_cols = $args['row_cols']; }else{$row_cols = null;}
2259
	            if ( $args['row_cols_md'] !== undefined && $args['row_cols_md'] !== '' ) { $classes.push( "row-cols-md-" + $args['row_cols_md'] );  $row_cols_md = $args['row_cols_md']; }else{$row_cols_md = null;}
2260
                if ( $args['row_cols_lg'] !== undefined && $args['row_cols_lg'] !== '' ) { if($row_cols == null && $row_cols_md == null){ $classes.push( "row-cols-" + $args['row_cols_lg'] ); }else{$classes.push( "row-cols-lg-" + $args['row_cols_lg'] ); } }
2261
2262
				// columns , mobile, tablet, desktop
2263
	            if ( $args['col'] !== undefined && $args['col'] !== '' ) { $classes.push( "col-" + $args['col'] );  $col = $args['col']; }else{$col = null;}
2264
	            if ( $args['col_md'] !== undefined && $args['col_md'] !== '' ) { $classes.push( "col-md-" + $args['col_md'] );  $col_md = $args['col_md']; }else{$col_md = null;}
2265
                if ( $args['col_lg'] !== undefined && $args['col_lg'] !== '' ) { if($col == null && $col_md == null){ $classes.push( "col-" + $args['col_lg'] ); }else{$classes.push( "col-lg-" + $args['col_lg'] ); } }
2266
2267
2268
                // border
2269
                if ( $args['border'] === undefined || $args['border']=='')  { }
2270
                else if ( $args['border'] !== undefined && ( $args['border']=='none' || $args['border']==='0') ) { $classes.push( "border-0" ); }
2271
	            else if ( $args['border'] !== undefined ) {
2272
					if($aui_bs5 && $args['border_type'] !== undefined){
2273
						$args['border_type'] = $args['border_type'].replace('-left','-start').replace('-right','-end');
2274
					}
2275
					$border_class = 'border';
2276
					if ( $args['border_type'] !== undefined && ! $args['border_type'].includes( '-0' )  ) {
2277
						$border_class = '';
2278
					}
2279
					$classes.push( $border_class + " border-" + $args['border'] );
2280
				}
2281
2282
                // border radius type
2283
              //  if ( $args['rounded'] !== undefined && $args['rounded'] !== '' ) { $classes.push($args['rounded']); }
2284
2285
                // border radius size
2286
                if( $args['rounded_size'] !== undefined && ( $args['rounded_size']==='sm' || $args['rounded_size']==='lg' ) ){
2287
					if ( $args['rounded_size'] !== undefined && $args['rounded_size'] !== '' ) {
2288
						$classes.push("rounded-" + $args['rounded_size']);
2289
						// if we set a size then we need to remove "rounded" if set
2290
						var index = $classes.indexOf("rounded");
2291
						if (index !== -1) {
2292
						  $classes.splice(index, 1);
2293
						}
2294
                	}
2295
                }else{
2296
					// rounded_size , mobile, tablet, desktop
2297
					if ( $args['rounded_size'] !== undefined && $args['rounded_size'] !== '' ) { $classes.push( "rounded-" + $args['rounded_size'] );  $rounded_size = $args['rounded_size']; }else{$rounded_size = null;}
2298
					if ( $args['rounded_size_md'] !== undefined && $args['rounded_size_md'] !== '' ) { $classes.push( "rounded-md-" + $args['rounded_size_md'] );  $rounded_size_md = $args['rounded_size_md']; }else{$rounded_size_md = null;}
2299
					if ( $args['rounded_size_lg'] !== undefined && $args['rounded_size_lg'] !== '' ) { if($rounded_size == null && $rounded_size_md == null){ $classes.push( "rounded-" + $args['rounded_size_lg'] ); }else{$classes.push( "rounded-lg-" + $args['rounded_size_lg'] ); } }
2300
                }
2301
2302
2303
                // shadow
2304
               // if ( $args['shadow'] !== undefined && $args['shadow'] !== '' ) { $classes.push($args['shadow']); }
2305
2306
                // background
2307
                if ( $args['bg'] !== undefined  && $args['bg'] !== '' ) { $classes.push("bg-" + $args['bg']); }
2308
2309
                // text_color
2310
                if ( $args['text_color'] !== undefined && $args['text_color'] !== '' ) { $classes.push( "text-" + $args['text_color']); }
2311
2312
                // text_align
2313
                if ( $args['text_justify'] !== undefined && $args['text_justify'] ) { $classes.push('text-justify'); }
2314
                else{
2315
                    if ( $args['text_align'] !== undefined && $args['text_align'] !== '' ) {
2316
						if($aui_bs5){ $args['text_align'] = $args['text_align'].replace('-left','-start').replace('-right','-end'); }
2317
						$classes.push($args['text_align']); $text_align = $args['text_align'];
2318
					}else{$text_align = null;}
2319
                    if ( $args['text_align_md'] !== undefined && $args['text_align_md'] !== '' ) {
2320
						if($aui_bs5){ $args['text_align_md'] = $args['text_align_md'].replace('-left','-start').replace('-right','-end'); }
2321
						$classes.push($args['text_align_md']); $text_align_md = $args['text_align_md'];
2322
					}else{$text_align_md = null;}
2323
                    if ( $args['text_align_lg'] !== undefined && $args['text_align_lg'] !== '' ) {
2324
						if($aui_bs5){ $args['text_align_lg'] = $args['text_align_lg'].replace('-left','-start').replace('-right','-end'); }
2325
						if($text_align  == null && $text_align_md == null){ $classes.push($args['text_align_lg'].replace("-lg", ""));
2326
						}else{$classes.push($args['text_align_lg']);} }
2327
                }
2328
2329
				// display
2330
			  	if ( $args['display'] !== undefined && $args['display'] !== '' ) { $classes.push($args['display']); $display = $args['display']; }else{$display = null;}
2331
				if ( $args['display_md'] !== undefined && $args['display_md'] !== '' ) { $classes.push($args['display_md']); $display_md = $args['display_md']; }else{$display_md = null;}
2332
				if ( $args['display_lg'] !== undefined && $args['display_lg'] !== '' ) { if($display  == null && $display_md == null){ $classes.push($args['display_lg'].replace("-lg", "")); }else{$classes.push($args['display_lg']);} }
2333
2334
				// bgtus - background transparent until scroll
2335
                if ( $args['bgtus'] !== undefined && $args['bgtus'] ) { $classes.push("bg-transparent-until-scroll"); }
2336
2337
				// cscos - change color scheme on scroll
2338
                if ( $args['bgtus'] !== undefined && $args['bgtus'] && $args['cscos'] !== undefined && $args['cscos'] ) { $classes.push("color-scheme-flip-on-scroll"); }
2339
2340
				// hover animations
2341
                if ( $args['hover_animations'] !== undefined && $args['hover_animations'] ) { $classes.push($args['hover_animations'].toString().replace(',',' ')); }
2342
2343
				// absolute_position
2344
				if ( $args['absolute_position'] !== undefined ) {
2345
					if ( 'top-left' === $args['absolute_position'] ) {
2346
						$classes.push('start-0 top-0');
2347
					} else if ( 'top-center' === $args['absolute_position'] ) {
2348
						$classes.push('start-50 top-0 translate-middle');
2349
					} else if ( 'top-right' === $args['absolute_position'] ) {
2350
						$classes.push('end-0 top-0');
2351
					} else if ( 'center-left' === $args['absolute_position'] ) {
2352
						$classes.push('start-0 bottom-50');
2353
					} else if ( 'center' === $args['absolute_position'] ) {
2354
						$classes.push('start-50 top-50 translate-middle');
2355
					} else if ( 'center-right' === $args['absolute_position'] ) {
2356
						$classes.push('end-0 top-50');
2357
					} else if ( 'bottom-left' === $args['absolute_position'] ) {
2358
						$classes.push('start-0 bottom-0');
2359
					} else if ( 'bottom-center' === $args['absolute_position'] ) {
2360
						$classes.push('start-50 bottom-0 translate-middle');
2361
					} else if ( 'bottom-right' === $args['absolute_position'] ) {
2362
						$classes.push('end-0 bottom-0');
2363
					}
2364
				}
2365
2366
				// build classes from build keys
2367
				$build_keys = sd_get_class_build_keys();
2368
				if ( $build_keys.length ) {
2369
					$build_keys.forEach($key => {
2370
2371
						if($key.endsWith("-MTD")){
2372
2373
							$k = $key.replace("-MTD","");
2374
2375
							// Mobile, Tablet, Desktop
2376
							if ( $args[$k] !== undefined && $args[$k] !== '' ) { $classes.push( $args[$k] );  $v = $args[$k]; }else{$v = null;}
2377
							if ( $args[$k + '_md'] !== undefined && $args[$k + '_md'] !== '' ) { $classes.push( $args[$k + '_md'] );  $v_md = $args[$k + '_md']; }else{$v_md = null;}
2378
							if ( $args[$k + '_lg'] !== undefined && $args[$k + '_lg'] !== '' ) { if($v == null && $v_md == null){ $classes.push( $args[$k + '_lg'].replace('-lg','') ); }else{$classes.push( $args[$k + '_lg'] ); } }
2379
2380
						}else{
2381
							if ( $key == 'font_size' && $args[ $key ] == 'custom' ) {
2382
							 return;
2383
							}
2384
							if ( $args[$key] !== undefined && $args[$key] !== '' ) { $classes.push($args[$key]); }
2385
						}
2386
2387
					});
2388
				}
2389
2390
                return $classes.join(" ");
2391
            }
2392
2393
			function sd_get_class_build_keys(){
2394
				return <?php echo json_encode(sd_get_class_build_keys());?>;
0 ignored issues
show
Bug introduced by
Are you sure the usage of sd_get_class_build_keys() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
2395
			}
2396
2397
            <?php
2398
2399
2400
            }
2401
2402
			if(method_exists($this,'block_global_js')){
2403
					echo $this->block_global_js();
2404
			}
2405
			?>
2406
2407
jQuery(function() {
2408
2409
				/**
2410
				 * BLOCK: Basic
2411
				 *
2412
				 * Registering a basic block with Gutenberg.
2413
				 * Simple block, renders and saves the same content without any interactivity.
2414
				 *
2415
				 * Styles:
2416
				 *        editor.css — Editor styles for the block.
2417
				 *        style.css  — Editor & Front end styles for the block.
2418
				 */
2419
				(function (blocksx, elementx, blockEditor) {
2420
					var __ = wp.i18n.__; // The __() for internationalization.
2421
					var el = wp.element.createElement; // The wp.element.createElement() function to create elements.
2422
					var editable = wp.blocks.Editable;
2423
					var blocks = wp.blocks;
2424
					var registerBlockType = wp.blocks.registerBlockType; // The registerBlockType() to register blocks.
2425
					var is_fetching = false;
2426
					var prev_attributes = [];
2427
2428
                    var InnerBlocks = blockEditor.InnerBlocks;
2429
2430
					var term_query_type = '';
2431
					var post_type_rest_slugs = <?php if(! empty( $this->arguments ) && isset($this->arguments['post_type']['onchange_rest']['values'])){echo "[".json_encode($this->arguments['post_type']['onchange_rest']['values'])."]";}else{echo "[]";} ?>;
2432
					const taxonomies_<?php echo str_replace("-","_", $this->id);?> = [{label: "Please wait", value: 0}];
2433
					const sort_by_<?php echo str_replace("-","_", $this->id);?> = [{label: "Please wait", value: 0}];
2434
                    const MediaUpload = wp.blockEditor.MediaUpload;
2435
2436
					/**
2437
					 * Register Basic Block.
2438
					 *
2439
					 * Registers a new block provided a unique name and an object defining its
2440
					 * behavior. Once registered, the block is made available as an option to any
2441
					 * editor interface where blocks are implemented.
2442
					 *
2443
					 * @param  {string}   name     Block name.
2444
					 * @param  {Object}   settings Block settings.
2445
					 * @return {?WPBlock}          The block, if it has been successfully
2446
					 *                             registered; otherwise `undefined`.
2447
					 */
2448
					registerBlockType('<?php echo str_replace( "_", "-", sanitize_title_with_dashes( $this->options['textdomain'] ) . '/' . sanitize_title_with_dashes( $this->options['class_name'] ) );  ?>', { // Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
2449
						apiVersion: <?php echo isset($this->options['block-api-version']) ? absint($this->options['block-api-version']) : 2 ; ?>,
2450
                        title: '<?php echo addslashes( $this->options['name'] ); ?>', // Block title.
2451
						description: '<?php echo addslashes( $this->options['widget_ops']['description'] )?>', // Block title.
2452
						icon: <?php echo $this->get_block_icon( $this->options['block-icon'] );?>,//'<?php echo isset( $this->options['block-icon'] ) ? esc_attr( $this->options['block-icon'] ) : 'shield-alt';?>', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
2453
						supports: {
2454
							<?php
2455
							if ( isset( $this->options['block-supports'] ) ) {
2456
								echo $this->array_to_attributes( $this->options['block-supports'] );
2457
							}
2458
							?>
2459
						},
2460
						<?php
2461
						if ( isset( $this->options['block-label'] ) ) {
2462
						?>
2463
						__experimentalLabel( attributes, { context } ) {
2464
                            return <?php echo $this->options['block-label']; ?>;
2465
                        },
2466
                        <?php
2467
                        }
2468
                        ?>
2469
						category: '<?php echo isset( $this->options['block-category'] ) ? esc_attr( $this->options['block-category'] ) : 'common';?>', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
2470
						<?php if ( isset( $this->options['block-keywords'] ) ) {
2471
						echo "keywords : " . $this->options['block-keywords'] . ",";
2472
2473
//						// block hover preview.
2474
//						$example_args = array();
2475
//						if(!empty($this->arguments)){
2476
//							foreach($this->arguments as $key => $a_args){
2477
//								if(isset($a_args['example'])){
2478
//									$example_args[$key] = $a_args['example'];
2479
//								}
2480
//							}
2481
//						}
2482
//						$viewport_width = isset($this->options['example']['viewportWidth']) ? 'viewportWidth: '.absint($this->options['example']['viewportWidth']) : '';
2483
//						if( isset( $this->options['example'] ) && $this->options['example'] === false ){
2484
//							// no preview if set to false
2485
//						}elseif( !empty( $example_args ) ){
2486
//							echo "example : {attributes:{".$this->array_to_attributes( $example_args )."},$viewport_width},";
2487
//						}elseif( !empty( $this->options['example'] ) ){
2488
//							unset($this->options['example']['viewportWidth']);
2489
//							echo "example : {".$this->array_to_attributes( $this->options['example'] ).$viewport_width."},";
2490
//						}else{
2491
//							echo 'example : {'.$viewport_width.'},';
2492
//						}
2493
2494
                        }
2495
2496
						// maybe set no_wrap
2497
						$no_wrap = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false;
2498
						if ( isset( $this->arguments['no_wrap'] ) && $this->arguments['no_wrap'] ) {
2499
							$no_wrap = true;
2500
						}
2501
						if ( $no_wrap ) {
2502
							$this->options['block-wrap'] = '';
2503
						}
2504
2505
						// maybe load the drag/drop functions.
2506
						$img_drag_drop = false;
2507
2508
						$show_alignment = false;
2509
						// align feature
2510
						/*echo "supports: {";
2511
						echo "	align: true,";
2512
						echo "  html: false";
2513
						echo "},";*/
2514
2515
						if ( ! empty( $this->arguments ) ) {
2516
							echo "attributes : {";
2517
2518
							if ( $show_advanced ) {
2519
								echo "show_advanced: {";
2520
								echo "	type: 'boolean',";
2521
								echo "  default: false,";
2522
								echo "},";
2523
							}
2524
2525
							// block wrap element
2526
							if ( ! empty( $this->options['block-wrap'] ) ) { //@todo we should validate this?
2527
								echo "block_wrap: {";
2528
								echo "	type: 'string',";
2529
								echo "  default: '" . esc_attr( $this->options['block-wrap'] ) . "',";
2530
								echo "},";
2531
							}
2532
2533
2534
2535
							foreach ( $this->arguments as $key => $args ) {
2536
2537
								if( $args['type'] == 'image' ||  $args['type'] == 'images' ){
2538
									$img_drag_drop = true;
2539
								}
2540
2541
								// set if we should show alignment
2542
								if ( $key == 'alignment' ) {
2543
									$show_alignment = true;
2544
								}
2545
2546
								$extra = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $extra is dead and can be removed.
Loading history...
2547
2548
								if ( $args['type'] == 'notice' ||  $args['type'] == 'tab' ) {
2549
									continue;
2550
								}
2551
								elseif ( $args['type'] == 'checkbox' ) {
2552
									$type    = 'boolean';
2553
									$default = isset( $args['default'] ) && $args['default'] ? 'true' : 'false';
2554
								} elseif ( $args['type'] == 'number' ) {
2555
									$type    = 'number';
2556
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2557
								} elseif ( $args['type'] == 'select' && ! empty( $args['multiple'] ) ) {
2558
									$type = 'array';
2559
									if ( isset( $args['default'] ) && is_array( $args['default'] ) ) {
2560
										$default = ! empty( $args['default'] ) ? "['" . implode( "','", $args['default'] ) . "']" : "[]";
2561
									} else {
2562
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2563
									}
2564
								} elseif ( $args['type'] == 'tagselect' ) {
2565
									$type    = 'array';
2566
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2567
								} elseif ( $args['type'] == 'multiselect' ) {
2568
									$type    = 'array';
2569
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2570
								} elseif ( $args['type'] == 'image_xy' ) {
2571
									$type    = 'object';
2572
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2573
								} elseif ( $args['type'] == 'image' ) {
2574
									$type    = 'string';
2575
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2576
2577
                                    // add a field for ID
2578
//                                    echo $key . "_id : {";
2579
//                                    echo "type : 'number',";
2580
//                                    echo "},";
2581
//                                    echo $key . "_xy : {";
2582
//                                    echo "type : 'object',";
2583
//                                    echo "},";
2584
2585
								} else {
2586
									$type    = !empty($args['hidden_type']) ? esc_attr($args['hidden_type']) : 'string';
2587
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2588
2589
								}
2590
								echo $key . " : {";
2591
								echo "type : '$type',";
2592
								echo "default : $default,";
2593
								echo "},";
2594
							}
2595
2596
							echo "content : {type : 'string',default: 'Please select the attributes in the block settings'},";
2597
							echo "className: { type: 'string', default: '' },";
2598
2599
							echo "},";
2600
2601
						}
2602
2603
						?>
2604
2605
						// The "edit" property must be a valid function.
2606
						edit: function (props) {
2607
2608
2609
<?php
2610
// only include the drag/drop functions if required.
2611
if( $img_drag_drop ){
2612
2613
?>
2614
2615
function enableDragSort(listClass) {
2616
	setTimeout(function(){
2617
		 const sortableLists = document.getElementsByClassName(listClass);
2618
		 Array.prototype.map.call(sortableLists, (list) => {enableDragList(list)});
2619
	}, 300);
2620
}
2621
2622
function enableDragList(list) {
2623
  Array.prototype.map.call(list.children, (item) => {enableDragItem(item)});
2624
}
2625
2626
function enableDragItem(item) {
2627
  item.setAttribute('draggable', true)
2628
  item.ondrag = handleDrag;
2629
  item.ondragend = handleDrop;
2630
}
2631
2632
function handleDrag(item) {
2633
  const selectedItem = item.target,
2634
        list = selectedItem.parentNode,
2635
        x = event.clientX,
2636
        y = event.clientY;
2637
2638
  selectedItem.classList.add('drag-sort-active');
2639
  let swapItem = document.elementFromPoint(x, y) === null ? selectedItem : document.elementFromPoint(x, y);
2640
2641
  if (list === swapItem.parentNode) {
2642
    swapItem = swapItem !== selectedItem.nextSibling ? swapItem : swapItem.nextSibling;
2643
    list.insertBefore(selectedItem, swapItem);
2644
  }
2645
}
2646
2647
function handleDrop(item) {
2648
2649
	item.target.classList.remove('drag-sort-active');
2650
2651
	const newOrder = [];
2652
	let $parent = item.target.parentNode;
2653
	let $field = $parent.dataset.field;
2654
	let $imgs = JSON.parse('[' + props.attributes[$field] + ']');
2655
	item.target.parentNode.classList.add('xxx');
2656
	$children = $parent.children;
2657
2658
	Object.keys($children).forEach(function(key) {
2659
	  let $nKey = $children[key].dataset.index
2660
	  newOrder.push($imgs[$nKey]);
2661
	});
2662
2663
	// @todo find out why we need to empty the value first otherwise the order is wrong.
2664
	props.setAttributes({ [$field]: '' });
2665
	setTimeout(function(){
2666
		props.setAttributes({ [$field]: JSON.stringify(newOrder).replace('[','').replace(']','') });
2667
	}, 100);
2668
2669
}
2670
<?php } ?>
2671
2672
							if (typeof(props.attributes.styleid) !== 'undefined'){
2673
								if(props.attributes.styleid==''){ props.setAttributes({ 'styleid': 'block-'+(Math.random() + 1).toString(36).substring(2) } ); }
2674
							}
2675
2676
                            <?php
2677
                            if(!empty($this->options['block-edit-raw'])) {
2678
                                echo $this->options['block-edit-raw']; // strings have to be in single quotes, may cause issues
2679
                            }else{
2680
                            ?>
2681
2682
function hasSelectedInnerBlock(props) {
2683
    const select = wp.data.select('core/editor');
2684
    const selected = select.getBlockSelectionStart();
2685
    const inner = select.getBlock(props.clientId).innerBlocks;
2686
    for (let i = 0; i < inner.length; i++) {
2687
        if (inner[i].clientId === selected || inner[i].innerBlocks.length && hasSelectedInnerBlock(inner[i])) {
2688
            return true;
2689
        }
2690
    }
2691
    return false;
2692
};
2693
2694
const parentBlocksIDs = wp.data.select( 'core/block-editor' ).getBlockParents(props.clientId);
2695
const parentBlocks = wp.data.select('core/block-editor').getBlocksByClientId(parentBlocksIDs);
2696
// const isParentOfSelectedBlock = useSelect( ( select ) => wp.data.select( 'core/block-editor' ).hasSelectedInnerBlock( props.clientId, true ) ):
2697
    const block = wp.data.select('core/block-editor').getBlocksByClientId(props.clientId);//.[0].innerBlocks;
2698
    const childBlocks = block[0] == null ? '' : block[0].innerBlocks;
2699
2700
	var $value = '';
2701
	<?php
2702
	// if we have a post_type and a category then link them
2703
	if( isset($this->arguments['post_type']) && isset($this->arguments['category']) && !empty($this->arguments['category']['post_type_linked']) ){
2704
	?>
2705
	if(typeof(prev_attributes[props.clientId]) != 'undefined'){
2706
		$pt = props.attributes.post_type;
2707
		if(post_type_rest_slugs.length){
2708
			$value = post_type_rest_slugs[0][$pt];
2709
		}
2710
		var run = false;
2711
2712
		if($pt != term_query_type){
2713
			run = true;
2714
			term_query_type = $pt;
2715
		}
2716
<?php
2717
	$cat_path = '';
2718
	if ( ! empty( $this->arguments['post_type']['onchange_rest']['path'] ) ) {
2719
		$cat_path = esc_js( strip_tags( $this->arguments['post_type']['onchange_rest']['path'] ) );
2720
		$cat_path = str_replace( array( '&quot;', '&#039;' ), array( '"', "'" ), $cat_path );
2721
	}
2722
?>
2723
		/* taxonomies */
2724
		if($value && 'post_type' in prev_attributes[props.clientId] && 'category' in prev_attributes[props.clientId] && run){
2725
			if (!window.gdCPTCats) {
2726
				window.gdCPTCats = [];
2727
			}
2728
			var gdCatPath = "<?php echo ( ! empty( $cat_path ) ? $cat_path : "/wp/v2/" + $value + "/categories/?per_page=100" ); ?>";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $value seems to be never defined.
Loading history...
2729
			if (window.gdCPTCats[gdCatPath]) {
2730
				terms = window.gdCPTCats[gdCatPath];
2731
				while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2732
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2733
				}
2734
				taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2735
				jQuery.each( terms, function( key, val ) {
2736
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2737
				});
2738
2739
				/* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2740
				var $old_cat_value = props.attributes.category
2741
				props.setAttributes({category: [0] });
2742
				props.setAttributes({category: $old_cat_value });
2743
			} else {
2744
				wp.apiFetch({path: gdCatPath}).then(terms => {
2745
					window.gdCPTCats[gdCatPath] = terms;
2746
					while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2747
						taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2748
					}
2749
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2750
					jQuery.each( terms, function( key, val ) {
2751
						taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2752
					});
2753
2754
					/* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2755
					var $old_cat_value = props.attributes.category
2756
					props.setAttributes({category: [0] });
2757
					props.setAttributes({category: $old_cat_value });
2758
2759
					return taxonomies_<?php echo str_replace("-","_", $this->id);?>;
2760
				});
2761
			}
2762
		}
2763
2764
		/* sort_by */
2765
		if($value && 'post_type' in prev_attributes[props.clientId] && 'sort_by' in prev_attributes[props.clientId] && run){
2766
			if (!window.gdCPTSort) {
2767
				window.gdCPTSort = [];
2768
			}
2769
			if (window.gdCPTSort[$pt]) {
2770
				response = window.gdCPTSort[$pt];
2771
				while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2772
					sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2773
				}
2774
2775
				jQuery.each( response, function( key, val ) {
2776
					sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2777
				});
2778
2779
				// setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2780
				var $old_sort_by_value = props.attributes.sort_by
2781
				props.setAttributes({sort_by: [0] });
2782
				props.setAttributes({sort_by: $old_sort_by_value });
2783
			} else {
2784
				var data = {
2785
					'action': 'geodir_get_sort_options',
2786
					'post_type': $pt
2787
				};
2788
				jQuery.post(ajaxurl, data, function(response) {
2789
					response = JSON.parse(response);
2790
					window.gdCPTSort[$pt] = response;
2791
					while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2792
						sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2793
					}
2794
2795
					jQuery.each( response, function( key, val ) {
2796
						sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2797
					});
2798
2799
					// setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2800
					var $old_sort_by_value = props.attributes.sort_by
2801
					props.setAttributes({sort_by: [0] });
2802
					props.setAttributes({sort_by: $old_sort_by_value });
2803
2804
					return sort_by_<?php echo str_replace("-","_", $this->id);?>;
2805
				});
2806
			}
2807
		}
2808
	}
2809
	<?php } ?>
2810
<?php
2811
$current_screen = function_exists('get_current_screen') ? get_current_screen() : '';
0 ignored issues
show
Bug introduced by
Are you sure the usage of get_current_screen() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
2812
if(!empty($current_screen->base) && $current_screen->base==='widgets'){
0 ignored issues
show
Bug introduced by
The property base does not exist on string.
Loading history...
2813
	echo 'const { deviceType } = "";';
2814
}else{
2815
?>
2816
/** Get device type const. */
2817
const { deviceType } = wp.data.useSelect != 'undefined' ?  wp.data.useSelect(select => {
2818
	const { __experimentalGetPreviewDeviceType } = select('core/edit-site') ? select('core/edit-site') : select('core/edit-post') ? select('core/edit-post') : ''; // For sie editor https://github.com/WordPress/gutenberg/issues/39248
2819
	return {
2820
		deviceType: __experimentalGetPreviewDeviceType(),
2821
	}
2822
}, []) : '';
2823
<?php } ?>
2824
							var content = props.attributes.content;
2825
2826
							function onChangeContent($type) {
2827
// console.log(deviceType);
2828
								$refresh = false;
2829
								// Set the old content the same as the new one so we only compare all other attributes
2830
								if(typeof(prev_attributes[props.clientId]) != 'undefined'){
2831
									prev_attributes[props.clientId].content = props.attributes.content;
2832
								}else if(props.attributes.content === ""){
2833
									// if first load and content empty then refresh
2834
									$refresh = true;
2835
								}
2836
2837
								if ( ( !is_fetching &&  JSON.stringify(prev_attributes[props.clientId]) != JSON.stringify(props.attributes) ) || $refresh  ) {
2838
2839
									is_fetching = true;
2840
2841
									var data = {
2842
										'action': 'super_duper_output_shortcode',
2843
										'shortcode': '<?php echo $this->options['base_id'];?>',
2844
										'attributes': props.attributes,
2845
										'block_parent_name': parentBlocks.length ? parentBlocks[parentBlocks.length - 1].name : '',
2846
										'post_id': <?php global $post; if ( isset( $post->ID ) ) {
2847
										echo $post->ID;
2848
									}else{echo '0';}?>,
2849
										'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>'
2850
									};
2851
2852
									jQuery.post(ajaxurl, data, function (response) {
2853
										return response;
2854
									}).then(function (env) {
2855
2856
										// if the content is empty then we place some placeholder text
2857
										if (env == '') {
2858
											env = "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" + "<?php _e( 'Placeholder for: ' );?>" + props.name + "</div>";
2859
										}
2860
2861
                                         <?php
2862
                                        if(!empty($this->options['nested-block'])){
2863
                                            ?>
2864
                                            // props.setAttributes({content: env});
2865
										is_fetching = false;
2866
										prev_attributes[props.clientId] = props.attributes;
2867
                                             <?php
2868
                                        }else{
2869
                                        ?>
2870
                                        props.setAttributes({content: env});
2871
										is_fetching = false;
2872
										prev_attributes[props.clientId] = props.attributes;
2873
                                        <?php
2874
                                        }
2875
                                        ?>
2876
2877
2878
										// if AUI is active call the js init function
2879
										if (typeof aui_init === "function") {
2880
											aui_init();
2881
										}
2882
									});
2883
2884
2885
								}
2886
2887
2888
								return props.attributes.content;
2889
2890
							}
2891
2892
                            <?php
2893
                            if(!empty($this->options['block-edit-js'])) {
2894
                                echo  $this->options['block-edit-js'] ; // strings have to be in single quotes, may cause issues
2895
                            }
2896
2897
2898
2899
                            ?>
2900
2901
2902
2903
							return [
2904
2905
								el(wp.blockEditor.BlockControls, {key: 'controls'},
2906
2907
									<?php if($show_alignment){?>
2908
									el(
2909
										wp.blockEditor.AlignmentToolbar,
2910
										{
2911
											value: props.attributes.alignment,
2912
											onChange: function (alignment) {
2913
												props.setAttributes({alignment: alignment})
2914
											}
2915
										}
2916
									)
2917
									<?php }?>
2918
2919
								),
2920
2921
								el(wp.blockEditor.InspectorControls, {key: 'inspector'},
2922
2923
									<?php
2924
2925
									if(! empty( $this->arguments )){
2926
2927
									if ( $show_advanced ) {
2928
									?>
2929
									el('div', {
2930
											style: {'padding-left': '16px','padding-right': '16px'}
2931
										},
2932
										el(
2933
											wp.components.ToggleControl,
2934
											{
2935
												label: 'Show Advanced Settings?',
2936
												checked: props.attributes.show_advanced,
2937
												onChange: function (show_advanced) {
2938
													props.setAttributes({show_advanced: !props.attributes.show_advanced})
2939
												}
2940
											}
2941
										)
2942
									)
2943
									,
2944
									<?php
2945
									}
2946
2947
									$arguments = $this->group_arguments( $this->arguments );
2948
									$block_group_tabs = ! empty( $this->options['block_group_tabs'] ) ? $this->group_block_tabs( $this->options['block_group_tabs'], $arguments ) : array();
2949
2950
									// Do we have sections?
2951
									$has_sections = $arguments == $this->arguments ? false : true;
2952
2953
									if($has_sections){
2954
									$panel_count = 0;
2955
									$open_tab = '';
2956
2957
									$open_tab_groups = array();
2958
									$used_tabs = array();
2959
2960
									foreach ( $arguments as $key => $args ) {
2961
										$close_tab = false;
2962
										$close_tabs = false;
2963
2964
										 if ( ! empty( $block_group_tabs ) ) {
2965
											foreach ( $block_group_tabs as $tab_name => $tab_args ) {
2966
												if ( in_array( $key, $tab_args['groups'] ) ) {
2967
													$open_tab_groups[] = $key;
2968
2969
													if ( $open_tab != $tab_name ) {
2970
														$tab_args['tab']['tabs_open'] = $open_tab == '' ? true : false;
2971
														$tab_args['tab']['open'] = true;
2972
2973
														$this->block_tab_start( '', $tab_args );
2974
														$open_tab = $tab_name;
2975
														$used_tabs[] = $tab_name;
2976
													}
2977
2978
													if ( $open_tab_groups == $tab_args['groups'] ) {
2979
														$close_tab = true;
2980
														$open_tab_groups = array();
2981
2982
														if ( $used_tabs == array_keys( $block_group_tabs ) ) {
2983
															$close_tabs = true;
2984
														}
2985
													}
2986
												}
2987
											}
2988
										}
2989
										?>
2990
										el(wp.components.PanelBody, {
2991
												title: '<?php esc_attr_e( $key ); ?>',
2992
												initialOpen: <?php if ( $panel_count ) {
2993
												echo "false";
2994
											} else {
2995
												echo "true";
2996
											}?>
2997
											},
2998
											<?php
2999
											foreach ( $args as $k => $a ) {
3000
												$this->block_tab_start( $k, $a );
3001
												$this->block_row_start( $k, $a );
3002
												$this->build_block_arguments( $k, $a );
3003
												$this->block_row_end( $k, $a );
3004
												$this->block_tab_end( $k, $a );
3005
											}
3006
											?>
3007
										),
3008
										<?php
3009
										$panel_count ++;
3010
3011
										if($close_tab || $close_tabs){
3012
											$tab_args = array(
3013
												'tab'	=> array(
3014
													'tabs_close' => $close_tabs,
3015
												'close' => true,
3016
												)
3017
3018
											);
3019
											$this->block_tab_end( '', $tab_args );
3020
//											echo '###close'; print_r($tab_args);
3021
											$panel_count = 0;
3022
										}
3023
//
3024
3025
									}
3026
									}else {
3027
									?>
3028
									el(wp.components.PanelBody, {
3029
											title: '<?php esc_attr_e( "Settings" ); ?>',
3030
											initialOpen: true
3031
										},
3032
										<?php
3033
										foreach ( $this->arguments as $key => $args ) {
3034
											$this->block_row_start( $key, $args );
3035
											$this->build_block_arguments( $key, $args );
3036
											$this->block_row_end( $key, $args );
3037
										}
3038
										?>
3039
									),
3040
									<?php
3041
									}
3042
3043
									}
3044
									?>
3045
3046
								),
3047
3048
								<?php
3049
								// If the user sets block-output array then build it
3050
								if ( ! empty( $this->options['block-output'] ) ) {
3051
								$this->block_element( $this->options['block-output'] );
3052
							}elseif(!empty($this->options['block-edit-return'])){
3053
                                   echo $this->options['block-edit-return'];
3054
							}else{
3055
								// if no block-output is set then we try and get the shortcode html output via ajax.
3056
								$block_edit_wrap_tag = !empty($this->options['block_edit_wrap_tag']) ? esc_attr($this->options['block_edit_wrap_tag']) : 'div';
3057
								?>
3058
								el('<?php echo esc_attr($block_edit_wrap_tag); ?>', wp.blockEditor.useBlockProps({
3059
									dangerouslySetInnerHTML: {__html: onChangeContent()},
3060
									className: props.className,
3061
									style: {'minHeight': '30px'}
3062
								}))
3063
								<?php
3064
								}
3065
								?>
3066
							]; // end return
3067
3068
							<?php
3069
                            } // end block-edit-raw else
3070
                            ?>
3071
						},
3072
3073
						// The "save" property must be specified and must be a valid function.
3074
						save: function (props) {
3075
3076
							var attr = props.attributes;
3077
							var align = '';
3078
3079
							// build the shortcode.
3080
							var content = "[<?php echo $this->options['base_id'];?>";
3081
							$html = '';
3082
							<?php
3083
3084
							if(! empty( $this->arguments )){
3085
3086
							foreach($this->arguments as $key => $args){
3087
                               // if($args['type']=='tabs'){continue;}
3088
							?>
3089
							if (attr.hasOwnProperty("<?php echo esc_attr( $key );?>")) {
3090
								if ('<?php echo esc_attr( $key );?>' == 'html') {
3091
									$html = attr.<?php echo esc_attr( $key );?>;
3092
								} else if ('<?php echo esc_attr( $args['type'] );?>' == 'image_xy') {
3093
									content += " <?php echo esc_attr( $key );?>='{x:" + attr.<?php echo esc_attr( $key );?>.x + ",y:"+attr.<?php echo esc_attr( $key );?>.y +"}' ";
3094
								} else {
3095
									content += " <?php echo esc_attr( $key );?>='" + attr.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' ";
3096
								}
3097
							}
3098
							<?php
3099
							}
3100
							}
3101
3102
							?>
3103
							content += "]";
3104
3105
                            <?php
3106
//                            if(!empty($this->options['nested-block'])){
3107
//                                ?>
3108
//                                $html = 'el( InnerBlocks.Content )';
3109
//                                <?php
3110
//                            }
3111
                            ?>
3112
							// if has html element
3113
							if ($html) {
3114
								content += $html + "[/<?php echo $this->options['base_id'];?>]";
3115
							}
3116
3117
							// @todo should we add inline style here or just css classes?
3118
							if (attr.alignment) {
3119
								if (attr.alignment == 'left') {
3120
									align = 'alignleft';
3121
								}
3122
								if (attr.alignment == 'center') {
3123
									align = 'aligncenter';
3124
								}
3125
								if (attr.alignment == 'right') {
3126
									align = 'alignright';
3127
								}
3128
							}
3129
3130
							<?php
3131
//							if(!empty($this->options['nested-block'])){
3132
//                                ?x>
3133
//                              return el(
3134
//                                    'div',
3135
//                                    { className: props.className,
3136
//                                        style: {'minHeight': '300px','position':'relative','overflow':'hidden','backgroundImage': 'url(https://s.w.org/images/core/5.5/don-quixote-06.jpg)'}
3137
//                                    },
3138
//                                    el( InnerBlocks.Content ),
3139
//                                    el('div', {dangerouslySetInnerHTML: {__html: content}, className: align})
3140
//                                );
3141
//                                <x?php
3142
//							}else
3143
3144
                            if(!empty($this->options['block-output'])){
3145
//                               echo "return";
3146
//                               $this->block_element( $this->options['block-output'], true );
3147
//                               echo ";";
3148
3149
                               ?>
3150
                              return el(
3151
                                   '',
3152
                                   {},
3153
                                   el('', {dangerouslySetInnerHTML: {__html: content}}),
3154
                                   <?php $this->block_element( $this->options['block-output'], true ); ?>
3155
                                   el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
3156
                               );
3157
                                <?php
3158
3159
							}elseif(!empty($this->options['block-save-return'])){
3160
                                   echo 'return ' . $this->options['block-save-return'];
3161
							}elseif(!empty($this->options['nested-block'])){
3162
                                ?>
3163
                              return el(
3164
                                   '',
3165
                                   {},
3166
                                   el('', {dangerouslySetInnerHTML: {__html: content+"\n"}}),
3167
                                   InnerBlocks.Content ? el( InnerBlocks.Content ) : '', // @todo i think we need a comma here
3168
                                   el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
3169
                               );
3170
                                <?php
3171
							}elseif(!empty( $this->options['block-save-return'] ) ){
3172
                                echo "return ". $this->options['block-edit-return'].";";
3173
							}elseif(isset( $this->options['block-wrap'] ) && $this->options['block-wrap'] == ''){
3174
							?>
3175
							return content;
3176
							<?php
3177
							}else{
3178
							?>
3179
							var block_wrap = 'div';
3180
							if (attr.hasOwnProperty("block_wrap")) {
3181
								block_wrap = attr.block_wrap;
3182
							}
3183
							return el(block_wrap, wp.blockEditor.useBlockProps.save( {dangerouslySetInnerHTML: {__html: content}, className: align} ));
3184
							<?php
3185
							}
3186
							?>
3187
3188
3189
						}
3190
					});
3191
				})(
3192
                    window.wp.blocks,
3193
    window.wp.element,
3194
    window.wp.blockEditor
3195
				);
3196
3197
                });
3198
			</script>
3199
			<?php
3200
			$output = ob_get_clean();
3201
3202
			/*
3203
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
3204
			 */
3205
3206
			return str_replace( array(
3207
				'<script>',
3208
				'</script>'
3209
			), '', $output );
3210
		}
3211
3212
3213
3214
		public function block_row_start($key, $args){
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

3214
		public function block_row_start(/** @scrutinizer ignore-unused */ $key, $args){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3215
3216
			// check for row
3217
			if(!empty($args['row'])){
3218
3219
				if(!empty($args['row']['open'])){
3220
3221
				// element require
3222
				$element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3223
                $device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3224
                $device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3225
                $device_type_icon = '';
3226
                if($device_type=='Desktop'){
3227
                    $device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3228
                }elseif($device_type=='Tablet'){
3229
                    $device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3230
                }elseif($device_type=='Mobile'){
3231
                    $device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3232
                }
3233
				echo $element_require;
3234
                echo $device_type_require;
3235
3236
					if(false){?><script><?php }?>
3237
						el('div', {
3238
								className: 'bsui components-base-control',
3239
							},
3240
							<?php if(!empty($args['row']['title'])){ ?>
3241
							el('label', {
3242
									className: 'components-base-control__label position-relative',
3243
									style: {width:"100%"}
3244
								},
3245
								el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['row']['title'] ) ?>'}}),
3246
								<?php if($device_type_icon){ ?>
3247
                                    deviceType == '<?php echo $device_type;?>' && el('span',{dangerouslySetInnerHTML: {__html: '<?php echo $device_type_icon; ?>'},title: deviceType + ": Set preview mode to change",style: {right:"0",position:"absolute",color:"var(--wp-admin-theme-color)"}})
3248
								<?php
3249
                                }
3250
                                ?>
3251
3252
3253
							),
3254
							<?php }?>
3255
							<?php if(!empty($args['row']['desc'])){ ?>
3256
							el('p', {
3257
									className: 'components-base-control__help mb-0',
3258
								},
3259
								'<?php echo addslashes( $args['row']['desc'] ); ?>'
3260
							),
3261
							<?php }?>
3262
							el(
3263
								'div',
3264
								{
3265
									className: 'row mb-n2 <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>',
3266
								},
3267
								el(
3268
									'div',
3269
									{
3270
										className: 'col pr-2 pe-2',
3271
									},
3272
3273
					<?php
3274
					if(false){?></script><?php }
3275
				}elseif(!empty($args['row']['close'])){
3276
					if(false){?><script><?php }?>
3277
						el(
3278
							'div',
3279
							{
3280
								className: 'col pl-0 ps-0',
3281
							},
3282
					<?php
3283
					if(false){?></script><?php }
3284
				}else{
3285
					if(false){?><script><?php }?>
3286
						el(
3287
							'div',
3288
							{
3289
								className: 'col pl-0 ps-0 pr-2 pe-2',
3290
							},
3291
					<?php
3292
					if(false){?></script><?php }
3293
				}
3294
3295
			}
3296
3297
		}
3298
3299
		public function block_row_end($key, $args){
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

3299
		public function block_row_end(/** @scrutinizer ignore-unused */ $key, $args){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3300
3301
			if(!empty($args['row'])){
3302
				// maybe close
3303
				if(!empty($args['row']['close'])){
3304
					echo "))";
3305
				}
3306
3307
				echo "),";
3308
			}
3309
		}
3310
3311
		public function block_tab_start($key, $args){
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

3311
		public function block_tab_start(/** @scrutinizer ignore-unused */ $key, $args){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3312
3313
			// check for row
3314
			if(!empty($args['tab'])){
3315
3316
				if(!empty($args['tab']['tabs_open'])){
3317
3318
					if(false){?><script><?php }?>
3319
3320
el('div',{className: 'bsui'},
3321
3322
						el('hr', {className: 'm-0'}), el(
3323
									wp.components.TabPanel,
3324
									{
3325
                                        activeClass: 'is-active',
3326
                                        className: 'btn-groupx',
3327
                                        initialTabName: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3328
										tabs: [
3329
3330
					<?php
3331
					if(false){?></script><?php }
3332
				}
3333
3334
				if(!empty($args['tab']['open'])){
3335
3336
					if(false){?><script><?php }?>
3337
							{
3338
												name: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3339
												title: el('div', {dangerouslySetInnerHTML: {__html: '<?php echo addslashes( esc_attr( $args['tab']['title']) ); ?>'}}),
3340
												className: '<?php echo addslashes( esc_attr( $args['tab']['class']) ); ?>',
3341
												content: el('div',{}, <?php if(!empty($args['tab']['desc'])){ ?>el('p', {
3342
									className: 'components-base-control__help mb-0',
3343
									dangerouslySetInnerHTML: {__html:'<?php echo addslashes( $args['tab']['desc'] ); ?>'}
3344
								}),<?php }
3345
					if(false){?></script><?php }
3346
				}
3347
3348
			}
3349
3350
		}
3351
3352
		public function block_tab_end($key, $args){
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

3352
		public function block_tab_end(/** @scrutinizer ignore-unused */ $key, $args){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3353
3354
			if(!empty($args['tab'])){
3355
				// maybe close
3356
				if(!empty($args['tab']['close'])){
3357
					echo ")}, /* tab close */";
3358
				}
3359
3360
				if(!empty($args['tab']['tabs_close'])){
3361
					if(false){?><script><?php }?>
3362
						]}, ( tab ) => {
3363
								return tab.content;
3364
							}
3365
						)), /* tabs close */
3366
					<?php if(false){ ?></script><?php }
3367
				}
3368
			}
3369
		}
3370
3371
		public function build_block_arguments( $key, $args ) {
3372
			$custom_attributes = ! empty( $args['custom_attributes'] ) ? $this->array_to_attributes( $args['custom_attributes'] ) : '';
3373
			$options           = '';
3374
			$extra             = '';
3375
			$require           = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $require is dead and can be removed.
Loading history...
3376
            $inside_elements   = '';
3377
			$after_elements	   = '';
3378
3379
			// `content` is a protected and special argument
3380
			if ( $key == 'content' ) {
3381
				return;
3382
			}
3383
3384
            $device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3385
            $device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3386
            $device_type_icon = '';
3387
            if($device_type=='Desktop'){
3388
                $device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3389
            }elseif($device_type=='Tablet'){
3390
                $device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3391
            }elseif($device_type=='Mobile'){
3392
                $device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3393
            }
3394
3395
			// icon
3396
			$icon = '';
3397
			if( !empty( $args['icon'] ) ){
3398
				$icon .= "el('div', {";
3399
									$icon .= "dangerouslySetInnerHTML: {__html: '".self::get_widget_icon( esc_attr($args['icon']))."'},";
0 ignored issues
show
Bug Best Practice introduced by
The method WP_Super_Duper::get_widget_icon() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

3399
									$icon .= "dangerouslySetInnerHTML: {__html: '".self::/** @scrutinizer ignore-call */ get_widget_icon( esc_attr($args['icon']))."'},";
Loading history...
3400
									$icon .= "className: 'text-center',";
3401
									$icon .= "title: '".addslashes( $args['title'] )."',";
3402
								$icon .= "}),";
3403
3404
				// blank title as its added to the icon.
3405
				$args['title'] = '';
3406
			}
3407
3408
			// require advanced
3409
			$require_advanced = ! empty( $args['advanced'] ) ? "props.attributes.show_advanced && " : "";
3410
3411
			// element require
3412
			$element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3413
3414
3415
			$onchange  = "props.setAttributes({ $key: $key } )";
3416
			$onchangecomplete  = "";
3417
			$value     = "props.attributes.$key";
3418
			$text_type = array( 'text', 'password', 'number', 'email', 'tel', 'url', 'colorx','range' );
3419
			if ( in_array( $args['type'], $text_type ) ) {
3420
				$type = 'TextControl';
3421
				// Save numbers as numbers and not strings
3422
				if ( $args['type'] == 'number' ) {
3423
					$onchange = "props.setAttributes({ $key: $key ? Number($key) : '' } )";
3424
				}
3425
			}
3426
//			else if ( $args['type'] == 'popup' ) {
3427
//				$type = 'TextControl';
3428
//				$args['type'] == 'text';
3429
//				$after_elements .= "el( wp.components.Button, {
3430
//                          className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3431
//                          onClick: function(){
3432
//							  aui_modal('','<input id=\'zzz\' value= />');
3433
//							  const source = document.getElementById('zzz');
3434
//							  source.value = props.attributes.$key;
3435
//							  source.addEventListener('input', function(e){props.setAttributes({ $key: e.target.value });});
3436
//                          }
3437
//                        },
3438
//                        'test'
3439
//                        ),";
3440
//
3441
//				$value     = "props.attributes.$key ? props.attributes.$key : ''";
3442
//			}
3443
			else if ( $args['type'] == 'styleid' ) {
3444
				$type = 'TextControl';
3445
				$args['type'] == 'text';
3446
				// Save numbers as numbers and not strings
3447
				$value     = "props.attributes.$key ? props.attributes.$key : ''";
3448
			}else if ( $args['type'] == 'notice' ) {
3449
3450
				$notice_message = !empty($args['desc']) ? addslashes($args['desc']) : '';
3451
				$notice_status = !empty($args['status']) ? esc_attr($args['status']) : 'info';
3452
3453
				$notice = "el('div',{className:'bsui'},el(wp.components.Notice, {status: '$notice_status',isDismissible: false,className: 'm-0 pr-0 pe-0 mb-3'},el('div',{dangerouslySetInnerHTML: {__html: '$notice_message'}}))),";
3454
				echo $notice_message ? $element_require . $notice : '';
3455
				return;
3456
			}
3457
			/*
3458
			 * https://www.wptricks.com/question/set-current-tab-on-a-gutenberg-tabpanel-component-from-outside-that-component/ es5 layout
3459
						elseif($args['type']=='tabs'){
3460
							?>
3461
								el(
3462
									wp.components.TabPanel,
3463
									{
3464
                                        activeClass: 'active-tab',
3465
                                        initialTabName: deviceType,
3466
										tabs: [
3467
											{
3468
												name: 'Desktop',
3469
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-desktop"></i>'}}),
3470
												className: 'tab-one' + deviceType == 'Desktop' ? ' active-tab' : '',
3471
												content: el('div', {dangerouslySetInnerHTML: {__html: 'ddd'}})
3472
											},
3473
											{
3474
												name: 'Tablet',
3475
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-tablet-alt"></i>'}}),
3476
												className: 'tab-two' + deviceType == 'Tablet' ? ' active-tab' : '',
3477
												content: el('div', {dangerouslySetInnerHTML: {__html: 'ttt'}})
3478
											},
3479
											{
3480
												name: 'Mobile',
3481
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-mobile-alt"></i>'}}),
3482
												className: 'tab-two' + deviceType == 'Mobile' ? ' active-tab' : '',
3483
												content: el('div', {dangerouslySetInnerHTML: {__html: 'mmm'}})
3484
											},
3485
										],
3486
									},
3487
									( tab ) => {
3488
3489
// @todo https://github.com/WordPress/gutenberg/issues/39248
3490
									if(tab.name=='Desktop'){
3491
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Desktop');
3492
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3493
									}else if(tab.name=='Tablet'){
3494
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Tablet');
3495
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3496
									}else if(tab.name=='Mobile'){
3497
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Mobile');
3498
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3499
									}
3500
3501
									return tab.content;
3502
3503
								}
3504
								),
3505
3506
							<?php
3507
							return;
3508
						}
3509
*/
3510
			elseif ( $args['type'] == 'color' ) {
3511
				$type = 'ColorPicker';
3512
				$onchange = "";
3513
				$extra = "color: $value,";
3514
				if(!empty($args['disable_alpha'])){
3515
					$extra .= "disableAlpha: true,";
3516
				}
3517
				$onchangecomplete = "onChangeComplete: function($key) {
3518
				value =  $key.rgb.a && $key.rgb.a < 1 ? \"rgba(\"+$key.rgb.r+\",\"+$key.rgb.g+\",\"+$key.rgb.b+\",\"+$key.rgb.a+\")\" : $key.hex;
3519
                        props.setAttributes({
3520
                            $key: value
3521
                        });
3522
                    },";
3523
			}elseif ( $args['type'] == 'gradient' ) {
3524
				$type = 'GradientPicker';
3525
				$extra .= "gradients: [{
3526
			name: 'Vivid cyan blue to vivid purple',
3527
			gradient:
3528
				'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
3529
			slug: 'vivid-cyan-blue-to-vivid-purple',
3530
		},
3531
		{
3532
			name: 'Light green cyan to vivid green cyan',
3533
			gradient:
3534
				'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)',
3535
			slug: 'light-green-cyan-to-vivid-green-cyan',
3536
		},
3537
		{
3538
			name: 'Luminous vivid amber to luminous vivid orange',
3539
			gradient:
3540
				'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)',
3541
			slug: 'luminous-vivid-amber-to-luminous-vivid-orange',
3542
		},
3543
		{
3544
			name: 'Luminous vivid orange to vivid red',
3545
			gradient:
3546
				'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)',
3547
			slug: 'luminous-vivid-orange-to-vivid-red',
3548
		},
3549
		{
3550
			name: 'Very light gray to cyan bluish gray',
3551
			gradient:
3552
				'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)',
3553
			slug: 'very-light-gray-to-cyan-bluish-gray',
3554
		},
3555
		{
3556
			name: 'Cool to warm spectrum',
3557
			gradient:
3558
				'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)',
3559
			slug: 'cool-to-warm-spectrum',
3560
		}],";
3561
3562
			}elseif ( $args['type'] == 'image' ) {
3563
//                print_r($args);
3564
3565
                $img_preview = isset($args['focalpoint']) && !$args['focalpoint'] ? " props.attributes.$key && el('img', { src: props.attributes.$key,style: {maxWidth:'100%',background: '#ccc'}})," : " ( props.attributes.$key ||  props.attributes.{$key}_use_featured ) && el(wp.components.FocalPointPicker,{
3566
                            url:  props.attributes.{$key}_use_featured === true ? '".$this->get_url()."icons/placeholder.png'  : props.attributes.$key,
3567
                            value: props.attributes.{$key}_xy.x !== undefined && props.attributes.{$key}_xy.x >= 0 ? props.attributes.{$key}_xy  : {x: 0.5,y: 0.5,},
3568
//                            value: props.attributes.{$key}_xy,
3569
                            onChange: function(focalPoint){
3570
                            console.log(props.attributes);
3571
                                              return props.setAttributes({
3572
                                                  {$key}_xy: focalPoint
3573
                                                });
3574
                                    },
3575
                                    // @todo for some reason this does not work as expected.
3576
//                         onDrag: function(focalPointTemp){
3577
//                                  return props.setAttributes({
3578
//                                      {$key}_xy: focalPointTemp
3579
//                                    });
3580
//                        }
3581
3582
3583
                        }), ";
3584
3585
3586
                $value = '""';
3587
				$type = 'MediaUpload';
3588
                $extra .= "onSelect: function(media){
3589
                      return props.setAttributes({
3590
                          $key: media.url,
3591
                          {$key}_id: media.id
3592
                        });
3593
                      },";
3594
                   $extra .= "type: 'image',";
3595
                   $extra .= "render: function (obj) {
3596
                        return el( 'div',{},
3597
                        ( !props.attributes.$key && !props.attributes.{$key}_use_featured ) && el( wp.components.Button, {
3598
                          className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3599
                          onClick: obj.open
3600
                        },
3601
                        'Upload Image'
3602
                        ),
3603
                       $img_preview
3604
                        props.attributes.$key && el( wp.components.Button, {
3605
                                      className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3606
                                      style: {margin:'8px 0',display: 'block'},
3607
                                      onClick: function(){
3608
                                              return props.setAttributes({
3609
                                                  $key: '',
3610
                                                  {$key}_id: ''
3611
                                                });
3612
                                    }
3613
                                    },
3614
                                    props.attributes.$key? 'Clear' : ''
3615
                            )
3616
                       )
3617
3618
3619
3620
                      }";
3621
                $onchange = "";
3622
3623
                //$inside_elements = ",el('div',{},'file upload')";
3624
			} else if ( $args['type'] == 'images' ) {
3625
				$img_preview = "props.attributes.$key && (function() {
3626
	let uploads = JSON.parse('['+props.attributes.$key+']');
3627
	let images = [];
3628
	uploads.map((upload, index) => (
3629
		images.push( el('div',{ className: 'col p-2', draggable: 'true', 'data-index': index }, 
3630
			el('img', {
3631
				src: (upload.sizes && upload.sizes.thumbnail ? upload.sizes.thumbnail.url : upload.url),
3632
				style: { maxWidth:'100%', background: '#ccc', pointerEvents:'none' }
3633
			}),
3634
			el('i',{
3635
				className: 'fas fa-times-circle text-danger position-absolute  ml-n2 mt-n1 bg-white rounded-circle c-pointer',
3636
				onClick: function() {
3637
					aui_confirm('".esc_attr__('Are you sure?')."', '".esc_attr__('Delete')."', '".esc_attr__('Cancel')."', true).then(function(confirmed) {
3638
						if (confirmed) {
3639
							let new_uploads = JSON.parse('['+props.attributes.$key+']');
3640
							new_uploads.splice(index, 1);
3641
								return props.setAttributes({ {$key}: JSON.stringify( new_uploads ).replace('[','').replace(']','') });
3642
							}
3643
					});
3644
				}},
3645
			'')
3646
		))
3647
	));
3648
	return images;
3649
})(),";
3650
3651
3652
				$value = '""';
3653
				$type = 'MediaUpload';
3654
				$extra .= "onSelect: function(media){
3655
	let slim_images = props.attributes.$key ? JSON.parse('['+props.attributes.$key+']') : [];
3656
	if(media.length){
3657
		for (var i=0; i < media.length; i++) {
3658
			slim_images.push({id: media[i].id, caption: media[i].caption, description: media[i].description,title: media[i].title,alt: media[i].alt,sizes: media[i].sizes, url: media[i].url});
3659
		}
3660
	}
3661
	var slimImagesV = JSON.stringify(slim_images);
3662
	if (slimImagesV) {
3663
		slimImagesV = slimImagesV.replace('[','').replace(']','').replace(/'/g, '&#39;');
3664
	}
3665
	return props.setAttributes({ $key: slimImagesV});
3666
},";
3667
				$extra .= "type: 'image',";
3668
				$extra .= "multiple: true,";
3669
				$extra .= "render: function (obj) {
3670
	/* Init the sort */
3671
	enableDragSort('sd-sortable');
3672
	return el( 'div',{},
3673
		el( wp.components.Button, {
3674
				className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3675
				onClick: obj.open
3676
			},
3677
			'Upload Images'
3678
		),
3679
		el('div',{
3680
				className: 'row row-cols-3 px-2 sd-sortable',
3681
				'data-field':'$key'
3682
			},
3683
			$img_preview
3684
		),
3685
		props.attributes.$key && el( wp.components.Button, {
3686
				className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3687
				style: {margin:'8px 0'},
3688
				onClick: function(){
3689
					return props.setAttributes({ $key: '' });
3690
				}
3691
			},
3692
			props.attributes.$key ? 'Clear All' : ''
3693
		)
3694
	)
3695
}";
3696
                $onchange = "";
3697
3698
                //$inside_elements = ",el('div',{},'file upload')";
3699
			}
3700
			elseif ( $args['type'] == 'checkbox' ) {
3701
				$type = 'CheckboxControl';
3702
				$extra .= "checked: props.attributes.$key,";
3703
				$onchange = "props.setAttributes({ $key: ! props.attributes.$key } )";
3704
			} elseif ( $args['type'] == 'textarea' ) {
3705
				$type = 'TextareaControl';
3706
3707
			} elseif ( $args['type'] == 'select' || $args['type'] == 'multiselect' ) {
3708
				$type = 'SelectControl';
3709
3710
				if($args['name'] == 'category' && !empty($args['post_type_linked'])){
3711
					$options .= "options: taxonomies_".str_replace("-","_", $this->id).",";
3712
				}elseif($args['name'] == 'sort_by' && !empty($args['post_type_linked'])){
3713
					$options .= "options: sort_by_".str_replace("-","_", $this->id).",";
3714
				}else {
3715
3716
					if ( ! empty( $args['options'] ) ) {
3717
						$options .= "options: [";
3718
						foreach ( $args['options'] as $option_val => $option_label ) {
3719
							$options .= "{ value: '" . esc_attr( $option_val ) . "', label: '" . addslashes( $option_label ) . "' },";
3720
						}
3721
						$options .= "],";
3722
					}
3723
				}
3724
				if ( isset( $args['multiple'] ) && $args['multiple'] ) { //@todo multiselect does not work at the moment: https://github.com/WordPress/gutenberg/issues/5550
3725
					$extra .= ' multiple:true,style:{height:"auto",paddingRight:"8px","overflow-y":"auto"}, ';
3726
				}
3727
3728
				if($args['type'] == 'multiselect' ||  ( isset( $args['multiple'] ) && $args['multiple'] ) ){
3729
					$after_elements	 .= "props.attributes.$key && el( wp.components.Button, {
3730
                                      className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3731
                                      style: {margin:'-8px 0 8px 0',display: 'block'},
3732
                                      onClick: function(){
3733
                                              return props.setAttributes({
3734
                                                  $key: '',
3735
                                                });
3736
                                    }
3737
                                    },
3738
                                    'Clear'
3739
                            ),";
3740
				}
3741
			} elseif ( $args['type'] == 'tagselect' ) {
3742
//				$type = 'FormTokenField';
3743
//
3744
//				if ( ! empty( $args['options'] ) ) {
3745
//						$options .= "suggestions: [";
3746
//						foreach ( $args['options'] as $option_val => $option_label ) {
3747
//							$options .= "{ value: '" . esc_attr( $option_val ) . "', title: '" . addslashes( $option_label ) . "' },";
3748
////							$options .= "'" . esc_attr( $option_val ) . "':'" . addslashes( $option_label ) . "',";
3749
//						}
3750
//						$options .= "],";
3751
//				}
3752
//
3753
//				$onchangex  = "{ ( selectedItems ) => {
3754
//						// Build array of selected posts.
3755
//						let selectedPostsArray = [];
3756
//						selectedPosts.map(
3757
//							( postName ) => {
3758
//								const matchingPost = posts.find( ( post ) => {
3759
//									return post.title.raw === postName;
3760
//
3761
//								} );
3762
//								if ( matchingPost !== undefined ) {
3763
//									selectedPostsArray.push( matchingPost.id );
3764
//								}
3765
//							}
3766
//						)
3767
//
3768
//						setAttributes( { selectedPosts: selectedPostsArray } );
3769
//					} } ";
3770
//				$onchange  = '';// "props.setAttributes({ $key: [ props.attributes.$key ] } )";
3771
//
3772
////				$options  = "";
3773
//				$value     = "[]";
3774
//				$extra .= ' __experimentalExpandOnFocus: true,';
3775
3776
			} else if ( $args['type'] == 'alignment' ) {
3777
				$type = 'AlignmentToolbar'; // @todo this does not seem to work but cant find a example
3778
			} else if ( $args['type'] == 'margins' ) {
3779
3780
			} else if ( $args['type'] == 'visibility_conditions' && ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) ) {
3781
				$type = 'TextControl';
3782
				$value = "(props.attributes.$key ? props.attributes.$key : '')";
3783
				$args['type'] = 'text';
3784
				$options .= 'disabled:true,';
3785
				$bsvc_title = esc_attr( addslashes( $args['title'] ) );
3786
				$bsvc_body = $this->block_visibility_fields( $args );
3787
				// @TODO reset button
3788
				$bsvc_footer = '<button type="button" class="btn btn-danger d-none">' . __( 'Reset', 'super-duper' ) . '</button><button type="button" class="btn btn-secondary bs-vc-close text-white" data-bs-dismiss="modal">' . __( 'Close', 'super-duper' ) . '</button><button type="button" class="btn btn-primary bs-vc-save">' . __( 'Save Rules', 'super-duper' ) . '</button>';
3789
				$after_elements .= "el('div', {className: 'components-base-control bs-vc-button-wrap'}, el(wp.components.Button, {
3790
						className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3791
						onClick: function() {
3792
							var sValue = props.attributes." . $key . ";
3793
							var oValue;
3794
							try {oValue = JSON.parse(sValue);} catch(err) {}
3795
							jQuery(document).off('show.bs.modal', '.bs-vc-modal').on('show.bs.modal', '.bs-vc-modal', function (e) {
3796
								if (e.target && jQuery(e.target).hasClass('bs-vc-modal')) {
3797
									sd_block_visibility_render_fields(oValue);
3798
									if (!jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule').length) {
3799
										jQuery('.bs-vc-modal-form .bs-vc-add-rule').trigger('click');
3800
									}
3801
									if(typeof aui_init_select2 == 'function') {
3802
										aui_init_select2();
3803
									}
3804
									jQuery('.bs-vc-modal-form').trigger('change');
3805
								}
3806
							});
3807
							aui_modal('" . $bsvc_title . "', '" . addslashes( $bsvc_body ) . "', '" . $bsvc_footer . "', true, 'bs-vc-modal', 'modal-lg', '');
3808
							jQuery(document).off('change', '#bsvc_raw_value').on('change', '#bsvc_raw_value', function(e) {
3809
								props.setAttributes({" . $key . ": e.target.value});
3810
							});
3811
						}
3812
					},
3813
					'" . addslashes( ! empty( $args['button_title'] ) ? $args['button_title'] : $args['title'] ) . "'
3814
				) ),";
3815
			} else {
3816
				return;// if we have not implemented the control then don't break the JS.
3817
			}
3818
3819
			// color input does not show the labels so we add them
3820
			if($args['type']=='color'){
3821
				// add show only if advanced
3822
				echo $require_advanced;
3823
				// add setting require if defined
3824
				echo $element_require;
3825
				echo "el('div', {style: {'marginBottom': '8px'}}, '".addslashes( $args['title'] )."'),";
3826
			}
3827
3828
			// add show only if advanced
3829
			echo $require_advanced;
3830
			// add setting require if defined
3831
			echo $element_require;
3832
            echo $device_type_require;
3833
3834
			// icon
3835
			echo $icon;
3836
			?>
3837
			el( <?php echo $args['type'] == 'image' || $args['type'] == 'images' ? $type  : "wp.components.".$type; ?>, {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.
Loading history...
3838
			label: <?php if ( empty( $args['title'] ) ) { echo "''"; } else if ( empty( $args['row'] ) && ! empty( $args['device_type'] ) ) { ?>el('label',{className:'components-base-control__label',style:{width:"100%"}},el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['title'] ) ?>'}}),<?php if ( $device_type_icon ) { ?>deviceType == '<?php echo $device_type;?>' && el('span',{dangerouslySetInnerHTML: {__html: '<?php echo $device_type_icon; ?>'},title: deviceType + ": Set preview mode to change",style: {right:"0",position:"absolute",color:"var(--wp-admin-theme-color)"}})<?php } ?>)<?php
3839
			} else { ?>'<?php echo addslashes( trim( esc_html( $args['title'] ) ) ); ?>'<?php } ?>,
3840
			help: <?php echo ( isset( $args['desc'] ) ? "el('span', {dangerouslySetInnerHTML: {__html: '" . trim( wp_kses_post( addslashes( $args['desc'] ) ) ) . "'}})" : "''" ); ?>,
3841
			value: <?php echo $value; ?>,
3842
			<?php if ( $type == 'TextControl' && $args['type'] != 'text' ) {
3843
				echo "type: '" . addslashes( $args['type'] ) . "',";
3844
			} ?>
3845
			<?php if ( ! empty( $args['placeholder'] ) ) {
3846
				echo "placeholder: '" . addslashes( trim( esc_html( $args['placeholder'] ) ) ) . "',";
3847
			} ?>
3848
			<?php echo $options; ?>
3849
			<?php echo $extra; ?>
3850
			<?php echo $custom_attributes; ?>
3851
			<?php echo $onchangecomplete; ?>
3852
			<?php if ( $onchange ) { ?>
3853
			onChange: function ( <?php echo $key; ?> ) {
3854
				<?php echo $onchange; ?>
3855
			}
3856
			<?php } ?>
3857
		} <?php echo $inside_elements; ?> ),
3858
			<?php
3859
			echo $after_elements;
3860
		}
3861
3862
		/**
3863
		 * Convert an array of attributes to block string.
3864
		 *
3865
		 * @param $custom_attributes
3866
		 *
3867
		 * @return string
3868
		 *@todo there is prob a faster way to do this, also we could add some validation here.
3869
		 *
3870
		 */
3871
		public function array_to_attributes( $custom_attributes, $html = false ) {
3872
			$attributes = '';
3873
			if ( ! empty( $custom_attributes ) ) {
3874
3875
				foreach ( $custom_attributes as $key => $val ) {
3876
					if(is_array($val)){
3877
						$attributes .= $key.': {'.$this->array_to_attributes( $val, $html ).'},';
3878
					}else{
3879
						$attributes .= $html ?  " $key='$val' " : "'$key': '$val',";
3880
					}
3881
				}
3882
3883
			}
3884
3885
			return $attributes;
3886
		}
3887
3888
3889
3890
		/**
3891
		 * A self looping function to create the output for JS block elements.
3892
		 *
3893
		 * This is what is output in the WP Editor visual view.
3894
		 *
3895
		 * @param $args
3896
		 */
3897
		public function block_element( $args, $save = false ) {
3898
3899
3900
			if ( ! empty( $args ) ) {
3901
				foreach ( $args as $element => $new_args ) {
3902
3903
					if ( is_array( $new_args ) ) { // its an element
3904
3905
3906
						if ( isset( $new_args['element'] ) ) {
3907
3908
							if ( isset( $new_args['element_require'] ) ) {
3909
								echo str_replace( array(
3910
										"'+",
3911
										"+'"
3912
									), '', $this->block_props_replace( $new_args['element_require'] ) ) . " &&  ";
3913
								unset( $new_args['element_require'] );
3914
							}
3915
3916
                            if($new_args['element']=='InnerBlocks'){
3917
                                echo "\n el( InnerBlocks, {";
3918
                            }elseif($new_args['element']=='innerBlocksProps'){
3919
                                $element = isset($new_args['inner_element']) ? esc_attr($new_args['inner_element']) : 'div';
3920
                              //  echo "\n el( 'section', wp.blockEditor.useInnerBlocksProps( blockProps, {";
3921
//                                echo $save ? "\n el( '$element', wp.blockEditor.useInnerBlocksProps.save( " : "\n el( '$element', wp.blockEditor.useInnerBlocksProps( ";
3922
                                echo $save ? "\n el( '$element', wp.blockEditor.useInnerBlocksProps.save( " : "\n el( '$element', wp.blockEditor.useInnerBlocksProps( ";
3923
                                echo $save ? "wp.blockEditor.useBlockProps.save( {" : "wp.blockEditor.useBlockProps( {";
3924
                                echo !empty($new_args['blockProps']) ? $this->block_element( $new_args['blockProps'],$save ) : '';
3925
3926
                                echo "} ), {";
3927
                                echo !empty($new_args['innerBlocksProps']) && !$save ? $this->block_element( $new_args['innerBlocksProps'],$save ) : '';
3928
                            //    echo '###';
3929
3930
                              //  echo '###';
3931
                            }elseif($new_args['element']=='BlocksProps'){
3932
3933
								if ( isset($new_args['if_inner_element']) ) {
3934
									$element = $new_args['if_inner_element'];
3935
								}else {
3936
									$element = isset($new_args['inner_element']) ? "'".esc_attr($new_args['inner_element'])."'" : "'div'";
3937
								}
3938
3939
								unset($new_args['inner_element']);
3940
                                echo $save ? "\n el( $element, wp.blockEditor.useBlockProps.save( {" : "\n el( $element, wp.blockEditor.useBlockProps( {";
3941
                                echo !empty($new_args['blockProps']) ? $this->block_element( $new_args['blockProps'],$save ) : '';
3942
3943
3944
                               // echo "} ),";
3945
3946
                            }else{
3947
                                echo "\n el( '" . $new_args['element'] . "', {";
3948
                            }
3949
3950
3951
							// get the attributes
3952
							foreach ( $new_args as $new_key => $new_value ) {
3953
3954
3955
								if ( $new_key == 'element' || $new_key == 'content'|| $new_key == 'if_content' || $new_key == 'element_require' || $new_key == 'element_repeat' || is_array( $new_value ) ) {
3956
									// do nothing
3957
								} else {
3958
									echo $this->block_element( array( $new_key => $new_value ),$save );
3959
								}
3960
							}
3961
3962
							echo $new_args['element']=='BlocksProps' ? '} ),' : "},";// end attributes
3963
3964
							// get the content
3965
							$first_item = 0;
3966
							foreach ( $new_args as $new_key => $new_value ) {
3967
								if ( $new_key === 'content' || $new_key === 'if_content' || is_array( $new_value ) ) {
3968
3969
									if ( $new_key === 'content' ) {
3970
										echo "'" . $this->block_props_replace( wp_slash( $new_value ) ) . "'";
3971
									}else if ( $new_key === 'if_content' ) {
3972
										echo  $this->block_props_replace(  $new_value  );
3973
									}
3974
3975
									if ( is_array( $new_value ) ) {
3976
3977
										if ( isset( $new_value['element_require'] ) ) {
3978
											echo str_replace( array(
3979
													"'+",
3980
													"+'"
3981
												), '', $this->block_props_replace( $new_value['element_require'] ) ) . " &&  ";
3982
											unset( $new_value['element_require'] );
3983
										}
3984
3985
										if ( isset( $new_value['element_repeat'] ) ) {
3986
											$x = 1;
3987
											while ( $x <= absint( $new_value['element_repeat'] ) ) {
3988
												$this->block_element( array( '' => $new_value ),$save );
3989
												$x ++;
3990
											}
3991
										} else {
3992
											$this->block_element( array( '' => $new_value ),$save );
3993
										}
3994
									}
3995
									$first_item ++;
3996
								}
3997
							}
3998
3999
                            if($new_args['element']=='innerBlocksProps' || $new_args['element']=='xBlocksProps'){
4000
                                echo "))";// end content
4001
                            }else{
4002
                                echo ")";// end content
4003
                            }
4004
4005
4006
							echo ", \n";
4007
4008
						}
4009
					} else {
4010
4011
						if ( substr( $element, 0, 3 ) === "if_" ) {
4012
							$extra = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $extra is dead and can be removed.
Loading history...
4013
							if( strpos($new_args, '[%WrapClass%]') !== false ){
4014
								$new_args = str_replace('[%WrapClass%]"','" + sd_build_aui_class(props.attributes)',$new_args);
4015
								$new_args = str_replace('[%WrapClass%]','+ sd_build_aui_class(props.attributes)',$new_args);
4016
							}
4017
							echo str_replace( "if_", "", $element ) . ": " . $this->block_props_replace( $new_args, true ) . ",";
4018
						} elseif ( $element == 'style' &&  strpos($new_args, '[%WrapStyle%]') !== false ) {
4019
                            $new_args = str_replace('[%WrapStyle%]','',$new_args);
4020
                            echo $element . ": {..." . $this->block_props_replace( $new_args ) . " , ...sd_build_aui_styles(props.attributes) },";
4021
//                            echo $element . ": " . $this->block_props_replace( $new_args ) . ",";
4022
						} elseif ( $element == 'style' ) {
4023
							echo $element . ": " . $this->block_props_replace( $new_args ) . ",";
4024
						} elseif ( ( $element == 'class' || $element == 'className'  ) &&  strpos($new_args, '[%WrapClass%]') !== false ) {
4025
                            $new_args = str_replace('[%WrapClass%]','',$new_args);
4026
                            echo $element . ": '" . $this->block_props_replace( $new_args ) . "' + sd_build_aui_class(props.attributes),";
4027
						} elseif ( $element == 'template' && $new_args ) {
4028
							echo $element . ": $new_args,";
4029
						} else {
4030
							echo $element . ": '" . $this->block_props_replace( $new_args ) . "',";
4031
						}
4032
4033
					}
4034
				}
4035
			}
4036
		}
4037
4038
		/**
4039
		 * Replace block attributes placeholders with the proper naming.
4040
		 *
4041
		 * @param $string
4042
		 *
4043
		 * @return mixed
4044
		 */
4045
		public function block_props_replace( $string, $no_wrap = false ) {
4046
4047
			if ( $no_wrap ) {
4048
				$string = str_replace( array( "[%", "%]" ), array( "props.attributes.", "" ), $string );
4049
			} else {
4050
				$string = str_replace( array( "[%", "%]" ), array( "'+props.attributes.", "+'" ), $string );
4051
			}
4052
4053
			return $string;
4054
		}
4055
4056
		/**
4057
		 * Outputs the content of the widget
4058
		 *
4059
		 * @param array $args
4060
		 * @param array $instance
4061
		 */
4062
		public function widget( $args, $instance ) {
4063
			if ( ! is_array( $args ) ) {
0 ignored issues
show
introduced by
The condition is_array($args) is always true.
Loading history...
4064
				$args = array();
4065
			}
4066
4067
			// Get the filtered values
4068
			$argument_values = $this->argument_values( $instance );
4069
			$argument_values = $this->string_to_bool( $argument_values );
4070
			$output          = $this->output( $argument_values, $args );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $output is correct as $this->output($argument_values, $args) targeting WP_Super_Duper::output() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
4071
4072
			$no_wrap = false;
4073
			if ( isset( $argument_values['no_wrap'] ) && $argument_values['no_wrap'] ) {
4074
				$no_wrap = true;
4075
			}
4076
4077
			ob_start();
4078
			if ( $output && ! $no_wrap ) {
0 ignored issues
show
introduced by
$output is defined implicitly as null, thus it is always evaluated to false.
Loading history...
4079
4080
				$class_original = $this->options['widget_ops']['classname'];
4081
				$class = $this->options['widget_ops']['classname']." sdel-".$this->get_instance_hash();
4082
4083
				// Before widget
4084
				$before_widget = ! empty( $args['before_widget'] ) ? $args['before_widget'] : '';
4085
				$before_widget = $before_widget ? str_replace( $class_original, $class, $before_widget ) : $before_widget;
4086
				$before_widget = apply_filters( 'wp_super_duper_before_widget', $before_widget, $args, $instance, $this );
4087
				$before_widget = apply_filters( 'wp_super_duper_before_widget_' . $this->base_id, $before_widget, $args, $instance, $this );
4088
4089
				// After widget
4090
				$after_widget = ! empty( $args['after_widget'] ) ? $args['after_widget'] : '';
4091
				$after_widget = apply_filters( 'wp_super_duper_after_widget', $after_widget, $args, $instance, $this );
4092
				$after_widget = apply_filters( 'wp_super_duper_after_widget_' . $this->base_id, $after_widget, $args, $instance, $this );
4093
4094
				echo $before_widget;
4095
				// elementor strips the widget wrapping div so we check for and add it back if needed
4096
				if ( $this->is_elementor_widget_output() ) {
4097
					// Filter class & attrs for elementor widget output.
4098
					$class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this );
4099
					$class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this );
4100
4101
					$attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this );
0 ignored issues
show
Unused Code introduced by
The assignment to $attrs is dead and can be removed.
Loading history...
4102
					$attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this );
4103
4104
					echo "<span class='" . esc_attr( $class  ) . "' " . $attrs . ">";
4105
				}
4106
				echo $this->output_title( $args, $instance );
4107
				echo $output;
4108
				if ( $this->is_elementor_widget_output() ) {
4109
					echo "</span>";
4110
				}
4111
				echo $after_widget;
4112
			} elseif ( $this->is_preview() && $output == '' ) {// if preview show a placeholder if empty
4113
				$output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" );
4114
				echo $output;
4115
			} elseif ( $output && $no_wrap ) {
0 ignored issues
show
introduced by
$output is defined implicitly as null, thus it is always evaluated to false.
Loading history...
4116
				echo $output;
4117
			}
4118
			$output = ob_get_clean();
4119
4120
			$output = apply_filters( 'wp_super_duper_widget_output', $output, $instance, $args, $this );
4121
4122
			echo $output;
4123
		}
4124
4125
		/**
4126
		 * Tests if the current output is inside a elementor container.
4127
		 *
4128
		 * @return bool
4129
		 *@since 1.0.4
4130
		 */
4131
		public function is_elementor_widget_output() {
4132
			$result = false;
4133
			if ( defined( 'ELEMENTOR_VERSION' ) && isset( $this->number ) && $this->number == 'REPLACE_TO_ID' ) {
4134
				$result = true;
4135
			}
4136
4137
			return $result;
4138
		}
4139
4140
		/**
4141
		 * Tests if the current output is inside a elementor preview.
4142
		 *
4143
		 * @return bool
4144
		 *@since 1.0.4
4145
		 */
4146
		public function is_elementor_preview() {
4147
			$result = false;
4148
			if ( isset( $_REQUEST['elementor-preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) || ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor_ajax' ) ) {
4149
				$result = true;
4150
			}
4151
4152
			return $result;
4153
		}
4154
4155
		/**
4156
		 * Tests if the current output is inside a Divi preview.
4157
		 *
4158
		 * @return bool
4159
		 *@since 1.0.6
4160
		 */
4161
		public function is_divi_preview() {
4162
			$result = false;
4163
			if ( isset( $_REQUEST['et_fb'] ) || isset( $_REQUEST['et_pb_preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) ) {
4164
				$result = true;
4165
			}
4166
4167
			return $result;
4168
		}
4169
4170
		/**
4171
		 * Tests if the current output is inside a Beaver builder preview.
4172
		 *
4173
		 * @return bool
4174
		 *@since 1.0.6
4175
		 */
4176
		public function is_beaver_preview() {
4177
			$result = false;
4178
			if ( isset( $_REQUEST['fl_builder'] ) ) {
4179
				$result = true;
4180
			}
4181
4182
			return $result;
4183
		}
4184
4185
		/**
4186
		 * Tests if the current output is inside a siteorigin builder preview.
4187
		 *
4188
		 * @return bool
4189
		 *@since 1.0.6
4190
		 */
4191
		public function is_siteorigin_preview() {
4192
			$result = false;
4193
			if ( ! empty( $_REQUEST['siteorigin_panels_live_editor'] ) ) {
4194
				$result = true;
4195
			}
4196
4197
			return $result;
4198
		}
4199
4200
		/**
4201
		 * Tests if the current output is inside a cornerstone builder preview.
4202
		 *
4203
		 * @return bool
4204
		 *@since 1.0.8
4205
		 */
4206
		public function is_cornerstone_preview() {
4207
			$result = false;
4208
			if ( ! empty( $_REQUEST['cornerstone_preview'] ) || basename( $_SERVER['REQUEST_URI'] ) == 'cornerstone-endpoint' ) {
4209
				$result = true;
4210
			}
4211
4212
			return $result;
4213
		}
4214
4215
		/**
4216
		 * Tests if the current output is inside a fusion builder preview.
4217
		 *
4218
		 * @return bool
4219
		 *@since 1.1.0
4220
		 */
4221
		public function is_fusion_preview() {
4222
			$result = false;
4223
			if ( ! empty( $_REQUEST['fb-edit'] ) || ! empty( $_REQUEST['fusion_load_nonce'] ) ) {
4224
				$result = true;
4225
			}
4226
4227
			return $result;
4228
		}
4229
4230
		/**
4231
		 * Tests if the current output is inside a Oxygen builder preview.
4232
		 *
4233
		 * @return bool
4234
		 *@since 1.0.18
4235
		 */
4236
		public function is_oxygen_preview() {
4237
			$result = false;
4238
			if ( ! empty( $_REQUEST['ct_builder'] ) || ( ! empty( $_REQUEST['action'] ) && ( substr( $_REQUEST['action'], 0, 11 ) === "oxy_render_" || substr( $_REQUEST['action'], 0, 10 ) === "ct_render_" ) ) ) {
4239
				$result = true;
4240
			}
4241
4242
			return $result;
4243
		}
4244
4245
		/**
4246
		 * Check for Kallyas theme Zion builder preview.
4247
		 *
4248
		 * @since 1.1.22
4249
		 *
4250
		 * @return bool True when preview page otherwise false.
4251
		 */
4252
		public function is_kallyas_zion_preview() {
4253
			$result = false;
4254
4255
			if ( function_exists( 'znhg_kallyas_theme_config' ) && ! empty( $_REQUEST['zn_pb_edit'] ) ) {
4256
				$result = true;
4257
			}
4258
4259
			return $result;
4260
		}
4261
4262
		/**
4263
		 * General function to check if we are in a preview situation.
4264
		 *
4265
		 * @return bool
4266
		 *@since 1.0.6
4267
		 */
4268
		public function is_preview() {
4269
			$preview = false;
4270
			if ( $this->is_divi_preview() ) {
4271
				$preview = true;
4272
			} elseif ( $this->is_elementor_preview() ) {
4273
				$preview = true;
4274
			} elseif ( $this->is_beaver_preview() ) {
4275
				$preview = true;
4276
			} elseif ( $this->is_siteorigin_preview() ) {
4277
				$preview = true;
4278
			} elseif ( $this->is_cornerstone_preview() ) {
4279
				$preview = true;
4280
			} elseif ( $this->is_fusion_preview() ) {
4281
				$preview = true;
4282
			} elseif ( $this->is_oxygen_preview() ) {
4283
				$preview = true;
4284
			} elseif( $this->is_kallyas_zion_preview() ) {
4285
				$preview = true;
4286
			} elseif( $this->is_block_content_call() ) {
4287
				$preview = true;
4288
			}
4289
4290
			return $preview;
4291
		}
4292
4293
		/**
4294
		 * Output the super title.
4295
		 *
4296
		 * @param $args
4297
		 * @param array $instance
4298
		 *
4299
		 * @return string
4300
		 */
4301
		public function output_title( $args, $instance = array() ) {
4302
			$output = '';
4303
			if ( ! empty( $instance['title'] ) ) {
4304
				/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
4305
				$title  = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
4306
4307
				if(empty($instance['widget_title_tag'])){
4308
					$output = $args['before_title'] . $title . $args['after_title'];
4309
				}else{
4310
					$title_tag = esc_attr( $instance['widget_title_tag'] );
4311
4312
					// classes
4313
					$title_classes = array();
4314
					$title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : '';
4315
					$title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : '';
4316
					$title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : '';
4317
					$title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : '';
4318
					$title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : '';
4319
					$title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : '';
4320
					$title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : '';
4321
					$title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : '';
4322
					$title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : '';
4323
					$title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : '';
4324
					$title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : '';
4325
					$title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : '';
4326
					$title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : '';
4327
4328
					$class = !empty( $title_classes ) ? implode(" ",$title_classes) : '';
4329
					$output = "<$title_tag class='$class' >$title</$title_tag>";
4330
				}
4331
4332
			}
4333
4334
			return $output;
4335
		}
4336
4337
		/**
4338
		 * Outputs the options form inputs for the widget.
4339
		 *
4340
		 * @param array $instance The widget options.
4341
		 */
4342
		public function form( $instance ) {
4343
4344
			// set widget instance
4345
			$this->instance = $instance;
4346
4347
			// set it as a SD widget
4348
			echo $this->widget_advanced_toggle();
4349
4350
			echo "<p>" . esc_attr( $this->options['widget_ops']['description'] ) . "</p>";
4351
			$arguments_raw = $this->get_arguments();
4352
4353
			if ( is_array( $arguments_raw ) ) {
0 ignored issues
show
introduced by
The condition is_array($arguments_raw) is always true.
Loading history...
4354
4355
				$arguments = $this->group_arguments( $arguments_raw );
4356
4357
				// Do we have sections?
4358
				$has_sections = $arguments == $arguments_raw ? false : true;
4359
4360
4361
				if ( $has_sections ) {
4362
					$panel_count = 0;
4363
					foreach ( $arguments as $key => $args ) {
4364
4365
						?>
4366
						<script>
4367
							//							jQuery(this).find("i").toggleClass("fas fa-chevron-up fas fa-chevron-down");jQuery(this).next().toggle();
4368
						</script>
4369
						<?php
4370
4371
						$hide       = $panel_count ? ' style="display:none;" ' : '';
4372
						$icon_class = $panel_count ? 'fas fa-chevron-up' : 'fas fa-chevron-down';
4373
						echo "<button onclick='jQuery(this).find(\"i\").toggleClass(\"fas fa-chevron-up fas fa-chevron-down\");jQuery(this).next().slideToggle();' type='button' class='sd-toggle-group-button sd-input-group-toggle" . sanitize_title_with_dashes( $key ) . "'>" . esc_attr( $key ) . " <i style='float:right;' class='" . $icon_class . "'></i></button>";
4374
						echo "<div class='sd-toggle-group sd-input-group-" . sanitize_title_with_dashes( $key ) . "' $hide>";
4375
4376
						foreach ( $args as $k => $a ) {
4377
4378
							$this->widget_inputs_row_start($k, $a);
4379
							$this->widget_inputs( $a, $instance );
4380
							$this->widget_inputs_row_end($k, $a);
4381
4382
						}
4383
4384
						echo "</div>";
4385
4386
						$panel_count ++;
4387
4388
					}
4389
				} else {
4390
					foreach ( $arguments as $key => $args ) {
4391
						$this->widget_inputs_row_start($key, $args);
4392
						$this->widget_inputs( $args, $instance );
4393
						$this->widget_inputs_row_end($key, $args);
4394
					}
4395
				}
4396
4397
			}
4398
		}
4399
4400
		public function widget_inputs_row_start($key, $args){
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

4400
		public function widget_inputs_row_start(/** @scrutinizer ignore-unused */ $key, $args){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
4401
			if(!empty($args['row'])){
4402
				// maybe open
4403
				if(!empty($args['row']['open'])){
4404
					?>
4405
					<div class='bsui sd-argument ' data-argument='<?php echo esc_attr( $args['row']['key'] ); ?>' data-element_require='<?php if ( !empty($args['row']['element_require'])) {
4406
						echo $this->convert_element_require( $args['row']['element_require'] );
4407
					} ?>'>
4408
					<?php if(!empty($args['row']['title'])){ ?>
4409
					<label class="mb-0 "><?php echo esc_attr( $args['row']['title'] ); ?><?php echo $this->widget_field_desc( $args['row'] ); ?></label>
4410
					<?php }?>
4411
					<div class='row <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>'>
4412
					<div class='col pr-2'>
4413
					<?php
4414
				}elseif(!empty($args['row']['close'])){
4415
					echo "<div class='col pl-0 ps-0'>";
4416
				}else{
4417
					echo "<div class='col pl-0 ps-0 pr-2 pe-2'>";
4418
				}
4419
			}
4420
		}
4421
4422
		public function widget_inputs_row_end($key, $args){
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

4422
		public function widget_inputs_row_end(/** @scrutinizer ignore-unused */ $key, $args){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
4423
4424
			if(!empty($args['row'])){
4425
				// maybe close
4426
				if(!empty($args['row']['close'])){
4427
					echo "</div></div>";
4428
				}
4429
4430
				echo "</div>";
4431
			}
4432
		}
4433
4434
		/**
4435
		 * Get the hidden input that when added makes the advanced button show on widget settings.
4436
		 *
4437
		 * @return string
4438
		 */
4439
		public function widget_advanced_toggle() {
4440
4441
			$output = '';
4442
			if ( $this->block_show_advanced() ) {
4443
				$val = 1;
4444
			} else {
4445
				$val = 0;
4446
			}
4447
4448
			$output .= "<input type='hidden'  class='sd-show-advanced' value='$val' />";
4449
4450
			return $output;
4451
		}
4452
4453
		/**
4454
		 * Convert require element.
4455
		 *
4456
		 * @param string $input Input element.
4457
		 *
4458
		 * @return string $output
4459
		 *@since 1.0.0
4460
		 *
4461
		 */
4462
		public function convert_element_require( $input ) {
4463
4464
			$input = str_replace( "'", '"', $input );// we only want double quotes
4465
4466
			$output = esc_attr( str_replace( array( "[%", "%]" ), array(
4467
				"jQuery(form).find('[data-argument=\"",
4468
				"\"]').find('input,select,textarea').val()"
4469
			), $input ) );
4470
4471
			return $output;
4472
		}
4473
4474
		/**
4475
		 * Builds the inputs for the widget options.
4476
		 *
4477
		 * @param $args
4478
		 * @param $instance
4479
		 */
4480
		public function widget_inputs( $args, $instance ) {
4481
4482
			$class             = "";
4483
			$element_require   = "";
4484
			$custom_attributes = "";
4485
4486
			// get value
4487
			if ( isset( $instance[ $args['name'] ] ) ) {
4488
				$value = $instance[ $args['name'] ];
4489
			} elseif ( ! isset( $instance[ $args['name'] ] ) && ! empty( $args['default'] ) ) {
4490
				$value = is_array( $args['default'] ) ? array_map( "esc_html", $args['default'] ) : esc_html( $args['default'] );
4491
			} else {
4492
				$value = '';
4493
			}
4494
4495
			// get placeholder
4496
			if ( ! empty( $args['placeholder'] ) ) {
4497
				$placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'";
4498
			} else {
4499
				$placeholder = '';
4500
			}
4501
4502
			// get if advanced
4503
			if ( isset( $args['advanced'] ) && $args['advanced'] ) {
4504
				$class .= " sd-advanced-setting ";
4505
			}
4506
4507
			// element_require
4508
			if ( isset( $args['element_require'] ) && $args['element_require'] ) {
4509
				$element_require = $args['element_require'];
4510
			}
4511
4512
			// custom_attributes
4513
			if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) {
4514
				$custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true );
4515
			}
4516
4517
			// before wrapper
4518
			?>
4519
			<p class="sd-argument <?php echo esc_attr( $class ); ?>" data-argument='<?php echo esc_attr( $args['name'] ); ?>' data-element_require='<?php if ( $element_require ) { echo $this->convert_element_require( $element_require );} ?>'>
4520
			<?php
4521
			switch ( $args['type'] ) {
4522
				//array('text','password','number','email','tel','url','color')
4523
				case "text":
4524
				case "password":
4525
				case "number":
4526
				case "email":
4527
				case "tel":
4528
				case "url":
4529
				case "color":
4530
					?>
4531
					<label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args );?><?php echo $this->widget_field_desc( $args ); ?></label>
4532
					<input <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="<?php echo esc_attr( $args['type'] ); ?>" value="<?php echo esc_attr( $value ); ?>">
4533
					<?php
4534
4535
					break;
4536
				case "select":
4537
					$multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false;
4538
					if ( $multiple ) {
4539
						if ( empty( $value ) ) {
4540
							$value = array();
4541
						}
4542
					}
4543
					?>
4544
					<label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args ); ?><?php echo $this->widget_field_desc( $args ); ?></label>
4545
					<select <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); if ( $multiple ) { echo "[]"; } ?>"
4546
						<?php if ( $multiple ) {
4547
							echo "multiple";
4548
						} //@todo not implemented yet due to gutenberg not supporting it
4549
						?>>
4550
						<?php
4551
4552
						if ( ! empty( $args['options'] ) ) {
4553
							foreach ( $args['options'] as $val => $label ) {
4554
								if ( $multiple ) {
4555
									$selected = in_array( $val, $value ) ? 'selected="selected"' : '';
4556
								} else {
4557
									$selected = selected( $value, $val, false );
4558
								}
4559
								echo "<option value='$val' " . $selected . ">$label</option>";
4560
							}
4561
						}
4562
						?>
4563
					</select>
4564
					<?php
4565
					break;
4566
				case "checkbox":
4567
					?>
4568
					<input <?php echo $placeholder; ?> <?php checked( 1, $value, true ) ?> <?php echo $custom_attributes; ?> class="widefat" id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="checkbox" value="1">
4569
					<label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args );?><?php echo $this->widget_field_desc( $args ); ?></label>
4570
					<?php
4571
					break;
4572
				case "textarea":
4573
					?>
4574
					<label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args ); ?><?php echo $this->widget_field_desc( $args ); ?></label>
4575
					<textarea <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>"><?php echo esc_attr( $value ); ?></textarea>
4576
					<?php
4577
4578
					break;
4579
				case "hidden":
4580
					?>
4581
					<input id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="hidden" value="<?php echo esc_attr( $value ); ?>">
4582
					<?php
4583
					break;
4584
				default:
4585
					echo "No input type found!"; // @todo we need to add more input types.
4586
			}
4587
			// after wrapper
4588
			?></p><?php
4589
		}
4590
4591
		public function get_widget_icon($icon = 'box-top', $title = ''){
4592
			if($icon=='box-top'){
4593
				return '<svg title="'.esc_attr($title).'" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" role="img" aria-hidden="true" focusable="false"><rect x="2.714" y="5.492" width="1.048" height="9.017" fill="#555D66"></rect><rect x="16.265" y="5.498" width="1.023" height="9.003" fill="#555D66"></rect><rect x="5.518" y="2.186" width="8.964" height="2.482" fill="#272B2F"></rect><rect x="5.487" y="16.261" width="9.026" height="1.037" fill="#555D66"></rect></svg>';
4594
			}elseif($icon=='box-right'){
4595
				return '<svg title="'.esc_attr($title).'" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" role="img" aria-hidden="true" focusable="false"><rect x="2.714" y="5.492" width="1.046" height="9.017" fill="#555D66"></rect><rect x="15.244" y="5.498" width="2.518" height="9.003" fill="#272B2F"></rect><rect x="5.518" y="2.719" width="8.964" height="0.954" fill="#555D66"></rect><rect x="5.487" y="16.308" width="9.026" height="0.99" fill="#555D66"></rect></svg>';
4596
			}elseif($icon=='box-bottom'){
4597
				return '<svg title="'.esc_attr($title).'" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" role="img" aria-hidden="true" focusable="false"><rect x="2.714" y="5.492" width="1" height="9.017" fill="#555D66"></rect><rect x="16.261" y="5.498" width="1.027" height="9.003" fill="#555D66"></rect><rect x="5.518" y="2.719" width="8.964" height="0.968" fill="#555D66"></rect><rect x="5.487" y="15.28" width="9.026" height="2.499" fill="#272B2F"></rect></svg>';
4598
			}elseif($icon=='box-left'){
4599
				return '<svg title="'.esc_attr($title).'" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" role="img" aria-hidden="true" focusable="false"><rect x="2.202" y="5.492" width="2.503" height="9.017" fill="#272B2F"></rect><rect x="16.276" y="5.498" width="1.012" height="9.003" fill="#555D66"></rect><rect x="5.518" y="2.719" width="8.964" height="0.966" fill="#555D66"></rect><rect x="5.487" y="16.303" width="9.026" height="0.995" fill="#555D66"></rect></svg>';
4600
			}
4601
		}
4602
4603
		/**
4604
		 * Get the widget input description html.
4605
		 *
4606
		 * @param $args
4607
		 *
4608
		 * @return string
4609
		 * @todo, need to make its own tooltip script
4610
		 */
4611
		public function widget_field_desc( $args ) {
4612
4613
			$description = '';
4614
			if ( isset( $args['desc'] ) && $args['desc'] ) {
4615
				if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) {
4616
					$description = $this->desc_tip( $args['desc'] );
4617
				} else {
4618
					$description = '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>';
4619
				}
4620
			}
4621
4622
			return $description;
4623
		}
4624
4625
		/**
4626
		 * Get the widget input title html.
4627
		 *
4628
		 * @param $args
4629
		 *
4630
		 * @return string
4631
		 */
4632
		public function widget_field_title( $args ) {
4633
4634
			$title = '';
4635
			if ( isset( $args['title'] ) && $args['title'] ) {
4636
				if ( isset( $args['icon'] ) && $args['icon'] ) {
4637
					$title = self::get_widget_icon( $args['icon'], $args['title']  );
0 ignored issues
show
Bug Best Practice introduced by
The method WP_Super_Duper::get_widget_icon() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

4637
					/** @scrutinizer ignore-call */ 
4638
     $title = self::get_widget_icon( $args['icon'], $args['title']  );
Loading history...
4638
				} else {
4639
					$title = esc_attr($args['title']);
4640
				}
4641
			}
4642
4643
			return $title;
4644
		}
4645
4646
		/**
4647
		 * Get the tool tip html.
4648
		 *
4649
		 * @param $tip
4650
		 * @param bool $allow_html
4651
		 *
4652
		 * @return string
4653
		 */
4654
		function desc_tip( $tip, $allow_html = false ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
4655
			if ( $allow_html ) {
4656
				$tip = $this->sanitize_tooltip( $tip );
4657
			} else {
4658
				$tip = esc_attr( $tip );
4659
			}
4660
4661
			return '<span class="gd-help-tip dashicons dashicons-editor-help" title="' . $tip . '"></span>';
4662
		}
4663
4664
		/**
4665
		 * Sanitize a string destined to be a tooltip.
4666
		 *
4667
		 * @param string $var
4668
		 *
4669
		 * @return string
4670
		 */
4671
		public function sanitize_tooltip( $var ) {
4672
			return htmlspecialchars( wp_kses( html_entity_decode( $var ), array(
4673
				'br'     => array(),
4674
				'em'     => array(),
4675
				'strong' => array(),
4676
				'small'  => array(),
4677
				'span'   => array(),
4678
				'ul'     => array(),
4679
				'li'     => array(),
4680
				'ol'     => array(),
4681
				'p'      => array(),
4682
			) ) );
4683
		}
4684
4685
		/**
4686
		 * Processing widget options on save
4687
		 *
4688
		 * @param array $new_instance The new options
4689
		 * @param array $old_instance The previous options
4690
		 *
4691
		 * @return array
4692
		 * @todo we should add some sanitation here.
4693
		 */
4694
		public function update( $new_instance, $old_instance ) {
4695
4696
			//save the widget
4697
			$instance = array_merge( (array) $old_instance, (array) $new_instance );
4698
4699
			// set widget instance
4700
			$this->instance = $instance;
4701
4702
			if ( empty( $this->arguments ) ) {
4703
				$this->get_arguments();
4704
			}
4705
4706
			// check for checkboxes
4707
			if ( ! empty( $this->arguments ) ) {
4708
				foreach ( $this->arguments as $argument ) {
4709
					if ( isset( $argument['type'] ) && $argument['type'] == 'checkbox' && ! isset( $new_instance[ $argument['name'] ] ) ) {
4710
						$instance[ $argument['name'] ] = '0';
4711
					}
4712
				}
4713
			}
4714
4715
			return $instance;
4716
		}
4717
4718
		/**
4719
		 * Checks if the current call is a ajax call to get the block content.
4720
		 *
4721
		 * This can be used in your widget to return different content as the block content.
4722
		 *
4723
		 * @return bool
4724
		 *@since 1.0.3
4725
		 */
4726
		public function is_block_content_call() {
4727
			$result = false;
4728
			if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'super_duper_output_shortcode' ) {
4729
				$result = true;
4730
			}
4731
4732
			return $result;
4733
		}
4734
4735
		/**
4736
		 * Get an instance hash that will be unique to the type and settings.
4737
		 *
4738
		 * @return string
4739
		 *@since 1.0.20
4740
		 */
4741
		public function get_instance_hash(){
4742
			$instance_string = $this->base_id.serialize($this->instance);
4743
			return hash('crc32b',$instance_string);
4744
		}
4745
4746
		/**
4747
		 * Generate and return inline styles from CSS rules that will match the unique class of the instance.
4748
		 *
4749
		 * @param array $rules
4750
		 *
4751
		 * @return string
4752
		 *@since 1.0.20
4753
		 */
4754
		public function get_instance_style($rules = array()){
4755
			$css = '';
4756
4757
			if(!empty($rules)){
4758
				$rules = array_unique($rules);
4759
				$instance_hash = $this->get_instance_hash();
4760
				$css .= "<style>";
4761
				foreach($rules as $rule){
4762
					$css .= ".sdel-$instance_hash $rule";
4763
				}
4764
				$css .= "</style>";
4765
			}
4766
4767
			return $css;
4768
		}
4769
4770
		/**
4771
		 * Encode shortcodes tags.
4772
		 *
4773
		 * @param string $content Content to search for shortcode tags.
4774
		 *
4775
*@return string Content with shortcode tags removed.
4776
		 *@since 1.0.28
4777
		 *
4778
		 */
4779
		public function encode_shortcodes( $content ) {
4780
			// Avoids existing encoded tags.
4781
			$trans   = array(
4782
				'&#91;' => '&#091;',
4783
				'&#93;' => '&#093;',
4784
				'&amp;#91;' => '&#091;',
4785
				'&amp;#93;' => '&#093;',
4786
				'&lt;' => '&0lt;',
4787
				'&gt;' => '&0gt;',
4788
				'&amp;lt;' => '&0lt;',
4789
				'&amp;gt;' => '&0gt;',
4790
			);
4791
4792
			$content = strtr( $content, $trans );
4793
4794
			$trans   = array(
4795
				'[' => '&#91;',
4796
				']' => '&#93;',
4797
				'<' => '&lt;',
4798
				'>' => '&gt;',
4799
				'"' => '&quot;',
4800
				"'" => '&#39;',
4801
			);
4802
4803
			$content = strtr( $content, $trans );
4804
4805
			return $content;
4806
		}
4807
4808
		/**
4809
		 * Remove encoded shortcod tags.
4810
		 *
4811
		 * @param string $content Content to search for shortcode tags.
4812
		 *
4813
*@return string Content with decoded shortcode tags.
4814
		 *@since 1.0.28
4815
		 *
4816
		 */
4817
		public function decode_shortcodes( $content ) {
4818
			$trans   = array(
4819
				'&#91;' => '[',
4820
				'&#93;' => ']',
4821
				'&amp;#91;' => '[',
4822
				'&amp;#93;' => ']',
4823
				'&lt;' => '<',
4824
				'&gt;' => '>',
4825
				'&amp;lt;' => '<',
4826
				'&amp;gt;' => '>',
4827
				'&quot;' => '"',
4828
				'&apos;' => "'",
4829
			);
4830
4831
			$content = strtr( $content, $trans );
4832
4833
			$trans   = array(
4834
				'&#091;' => '&#91;',
4835
				'&#093;' => '&#93;',
4836
				'&amp;#091;' => '&#91;',
4837
				'&amp;#093;' => '&#93;',
4838
				'&0lt;' => '&lt;',
4839
				'&0gt;' => '&gt;',
4840
				'&amp;0lt;' => '&lt;',
4841
				'&amp;0gt;' => '&gt;',
4842
			);
4843
4844
			$content = strtr( $content, $trans );
4845
4846
			return $content;
4847
		}
4848
4849
		public function block_visibility_fields( $args ) {
4850
			$value = ! empty( $args['value'] ) ? esc_attr( $args['value'] ) : '';
4851
			$content = '<div class="bs-vc-rule-template d-none">';
4852
				$content .= '<div class="p-3 pb-0 mb-3 border border-1 rounded-1 position-relative bs-vc-rule" data-bs-index="BSVCINDEX" >';
4853
					$content .= '<div class="row">';
4854
						$content .= '<div class="col-sm-12">';
4855
							$content .= '<div class="bs-rule-action position-absolute top-0 end-0 p-2 zindex-5"><span class="text-danger c-pointer bs-vc-remove-rule" title="' . esc_attr__( 'Remove Rule', 'super-duper' ) . '"><i class="fas fa-circle-minus fs-6"></i></span></div>';
4856
							$content .= aui()->select(
4857
								array(
4858
									'id'          => 'bsvc_rule_BSVCINDEX',
4859
									'name'        => 'bsvc_rule_BSVCINDEX',
4860
									'label'       => __( 'Rule', 'super-duper' ),
4861
									'placeholder' => __( 'Select Rule...', 'super-duper' ),
4862
									'class'       => 'bsvc_rule form-select-sm',
4863
									'options'     => sd_visibility_rules_options(),
4864
									'default'     => '',
4865
									'value'       => '',
4866
									'label_type'  => '',
4867
									'select2'     => false,
4868
									'input_group_left' => __( 'Rule:', 'super-duper' ),
4869
									'extra_attributes' => array(
4870
										'data-minimum-results-for-search' => '-1'
4871
									)
4872
								)
4873
							);
4874
4875
						$content .= '</div>';
4876
4877
						if ( class_exists( 'GeoDirectory' ) ) {
4878
							$content .= '<div class="col-md-7 col-sm-12">';
4879
4880
								$content .= aui()->select(
4881
									array(
4882
										'id'          => 'bsvc_gd_field_BSVCINDEX',
4883
										'name'        => 'bsvc_gd_field_BSVCINDEX',
4884
										'label'       => __( 'FIELD', 'super-duper' ),
4885
										'placeholder' => __( 'FIELD', 'super-duper' ),
4886
										'class'       => 'bsvc_gd_field form-select-sm',
4887
										'options'     => sd_visibility_gd_field_options(),
4888
										'default'     => '',
4889
										'value'       => '',
4890
										'label_type'  => '',
4891
										'select2'     => false,
4892
										'element_require'  => '[%bsvc_rule_BSVCINDEX%]=="gd_field"',
4893
										'extra_attributes' => array(
4894
											'data-minimum-results-for-search' => '-1'
4895
										)
4896
									)
4897
								);
4898
4899
							$content .= '</div>';
4900
							$content .= '<div class="col-md-5 col-sm-12">';
4901
4902
								$content .= aui()->select(
4903
									array(
4904
										'id'          => 'bsvc_gd_field_condition_BSVCINDEX',
4905
										'name'        => 'bsvc_gd_field_condition_BSVCINDEX',
4906
										'label'       => __( 'CONDITION', 'super-duper' ),
4907
										'placeholder' => __( 'CONDITION', 'super-duper' ),
4908
										'class'       => 'bsvc_gd_field_condition form-select-sm',
4909
										'options'     => sd_visibility_field_condition_options(),
4910
										'default'     => '',
4911
										'value'       => '',
4912
										'label_type'  => '',
4913
										'select2'     => false,
4914
										'element_require'  => '[%bsvc_rule_BSVCINDEX%]=="gd_field"',
4915
										'extra_attributes' => array(
4916
											'data-minimum-results-for-search' => '-1'
4917
										)
4918
									)
4919
								);
4920
4921
							$content .= '</div>';
4922
							$content .= '<div class="col-sm-12">';
4923
4924
								$content .= aui()->input(
4925
									array(
4926
										'type'            => 'text',
4927
										'id'              => 'bsvc_gd_field_search_BSVCINDEX',
4928
										'name'            => 'bsvc_gd_field_search_BSVCINDEX',
4929
										'label'           => __( 'VALUE TO MATCH', 'super-duper' ),
4930
										'class'           => 'bsvc_gd_field_search form-control-sm',
4931
										'placeholder'     => __( 'VALUE TO MATCH', 'super-duper' ),
4932
										'label_type'      => '',
4933
										'value'           => '',
4934
										'element_require' => '([%bsvc_rule_BSVCINDEX%]=="gd_field" && [%bsvc_gd_field_condition_BSVCINDEX%] && [%bsvc_gd_field_condition_BSVCINDEX%]!="is_empty" && [%bsvc_gd_field_condition_BSVCINDEX%]!="is_not_empty")'
4935
									)
4936
								);
4937
4938
							$content .= '</div>';
4939
						}
4940
4941
					$content .= '</div>';
4942
4943
					$content .= '<div class="row aui-conditional-field" data-element-require="jQuery(form).find(\'[name=bsvc_rule_BSVCINDEX]\').val()==\'user_roles\'" data-argument="bsvc_user_roles_BSVCINDEX_1"><label for="bsvc_user_roles_BSVCINDEX_1" class="form-label mb-3">' . __( 'Select User Roles:', 'super-duper' ) . '</label>';
4944
						$role_options = sd_user_roles_options();
4945
4946
						$role_option_i = 0;
4947
						foreach ( $role_options as $role_option_key => $role_option_name ) {
4948
							$role_option_i++;
4949
4950
							$content .= '<div class="col-sm-6">';
4951
							$content .= aui()->input(
4952
								array(
4953
									'id'               => 'bsvc_user_roles_BSVCINDEX_' . $role_option_i,
4954
									'name'             => 'bsvc_user_roles_BSVCINDEX[]',
4955
									'type'             => 'checkbox',
4956
									'label'            => $role_option_name,
4957
									'label_type'       => 'hidden',
4958
									'class'            => 'bsvc_user_roles',
4959
									'value'            => $role_option_key,
4960
									'switch'           => 'md',
4961
									'no_wrap'          => true
4962
								)
4963
							);
4964
							$content .= '</div>';
4965
						}
4966
					$content .= '</div>';
4967
				$content .= '</div>';
4968
			$content .= '</div>';
4969
			$content .= '<form id="bs-vc-modal-form" class="bs-vc-modal-form">';
4970
			$content .= '<div class="bs-vc-rule-sets"></div>';
4971
			$content .= '<div class="row"><div class="col-sm-12 text-center pt-1 pb-4"><button type="button" class="btn btn-sm btn-primary d-block w-100 bs-vc-add-rule"><i class="fas fa-plus"></i> ' . __( 'Add Rule', 'super-duper' ) . '</button></div></div>';
4972
			$content .= '<div class="row"><div class="col-md-6 col-sm-12">';
4973
			$content .= aui()->select(
4974
				array(
4975
					'id'          => 'bsvc_output',
4976
					'name'        => 'bsvc_output',
4977
					'label'       => __( 'What should happen if rules met.', 'super-duper' ),
4978
					'placeholder' => __( 'Default Output', 'super-duper' ),
4979
					'class'       => 'bsvc_output form-select-sm',
4980
					'options'     => sd_visibility_output_options(),
4981
					'default'     => '',
4982
					'value'       => '',
4983
					'label_type'  => 'top',
4984
					'select2'     => true,
4985
					'extra_attributes' => array(
4986
						'data-minimum-results-for-search' => '-1'
4987
					)
4988
				)
4989
			);
4990
4991
			$content .= '</div><div class="col-md-6 col-sm-12">';
4992
4993
			$content .= aui()->select(
4994
				array(
4995
					'id'              => 'bsvc_page',
4996
					'name'            => 'bsvc_page',
4997
					'label'           => __( 'Page Content', 'super-duper' ),
4998
					'placeholder'     => __( 'Select Page ID...', 'super-duper' ),
4999
					'class'           => 'bsvc_page form-select-sm',
5000
					'options'         => sd_template_page_options(),
5001
					'default'         => '',
5002
					'value'           => '',
5003
					'label_type'      => 'top',
5004
					'select2'         => true,
5005
					'element_require' => '[%bsvc_output%]=="page"'
5006
				)
5007
			);
5008
5009
			$content .= aui()->select(
5010
				array(
5011
					'id'          => 'bsvc_tmpl_part',
5012
					'name'        => 'bsvc_tmpl_part',
5013
					'label'       => __( 'Template Part', 'super-duper' ),
5014
					'placeholder' => __( 'Select Template Part...', 'super-duper' ),
5015
					'class'       => 'bsvc_tmpl_part form-select-sm',
5016
					'options'     => sd_template_part_options(),
5017
					'default'     => '',
5018
					'value'       => '',
5019
					'label_type'  => 'top',
5020
					'select2'     => true,
5021
					'element_require'  => '[%bsvc_output%]=="template_part"',
5022
					'extra_attributes' => array(
5023
						'data-minimum-results-for-search' => '-1'
5024
					)
5025
				)
5026
			);
5027
5028
			$content .= aui()->select(
5029
				array(
5030
					'id'               => 'bsvc_message_type',
5031
					'name'             => 'bsvc_message_type',
5032
					'label'            => __( 'Custom Message Type', 'super-duper' ),
5033
					'placeholder'      => __( 'Default (none)', 'super-duper' ),
5034
					'class'            => 'bsvc_message_type form-select-sm',
5035
					'options'          => sd_aui_colors(),
5036
					'default'          => '',
5037
					'value'            => '',
5038
					'label_type'       => 'top',
5039
					'select2'          => true,
5040
					'element_require'  => '[%bsvc_output%]=="message"',
5041
					'extra_attributes' => array(
5042
						'data-minimum-results-for-search' => '-1'
5043
					)
5044
				)
5045
			);
5046
5047
			$content .= '</div><div class="col-sm-12">';
5048
5049
			$content .= aui()->input(
5050
				array(
5051
					'type'            => 'text',
5052
					'id'              => 'bsvc_message',
5053
					'name'            => 'bsvc_message',
5054
					'label'           => '',
5055
					'class'           => 'bsvc_message form-control-sm',
5056
					'placeholder'     => __( 'CUSTOM MESSAGE TO SHOW', 'super-duper' ),
5057
					'label_type'      => '',
5058
					'value'           => '',
5059
					'form_group_class' => ' ',
5060
					'element_require' => '[%bsvc_output%]=="message"',
5061
				)
5062
			);
5063
5064
			$content .= '</div></div></form><input type="hidden" id="bsvc_raw_value" name="bsvc_raw_value" value="' . $value . '">';
5065
5066
			return $content;
5067
		}
5068
	}
5069
}
5070