Passed
Push — master ( b5d6c7...020c1f )
by Stiofan
06:03
created

WP_Super_Duper::is_bricks_preview()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 4
nc 2
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
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.33' );
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' ), 99 );
134
				add_action( 'wp_head', array( $this, 'generator' ), 99 );
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", 'ayecode-connect' ), '1' => __( "Yes", 'ayecode-connect' ) );
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', 'ayecode-connect' ) . "</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', 'ayecode-connect' ); ?></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' . esc_attr( $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', 'ayecode-connect' );?>" 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 || (jQuery(this).closest('.wp-editor-wrap').length && jQuery(this).closest('.wp-editor-wrap').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
					// Fusion 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', 'ayecode-connect' );?>" 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;'>" . wp_sprintf( __( 'Placeholder for: %s', 'ayecode-connect' ), $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
			if ( ! empty( $arguments ) ) {
1691
				$temp_arguments = array();
1692
				$general        = __( "General", 'ayecode-connect' );
1693
				$add_sections   = false;
1694
				foreach ( $arguments as $key => $args ) {
1695
					if ( isset( $args['group'] ) ) {
1696
						$temp_arguments[ $args['group'] ][ $key ] = $args;
1697
						$add_sections                             = true;
1698
					} else {
1699
						$temp_arguments[ $general ][ $key ] = $args;
1700
					}
1701
				}
1702
1703
				// only add sections if more than one
1704
				if ( $add_sections ) {
1705
					$arguments = $temp_arguments;
1706
				}
1707
			}
1708
1709
			return $arguments;
1710
		}
1711
1712
		/**
1713
		 * Parse used group tabs.
1714
		 *
1715
		 * @since 1.1.17
1716
		 */
1717
		public function group_block_tabs( $tabs, $arguments ) {
1718
			if ( ! empty( $tabs ) && ! empty( $arguments ) ) {
1719
				$has_sections = false;
1720
1721
				foreach ( $this->arguments as $key => $args ) {
1722
					if ( isset( $args['group'] ) ) {
1723
						$has_sections = true;
1724
						break;
1725
					}
1726
				}
1727
1728
				if ( ! $has_sections ) {
1729
					return $tabs;
1730
				}
1731
1732
				$new_tabs = array();
1733
1734
				foreach ( $tabs as $tab_key => $tab ) {
1735
					$new_groups = array();
1736
1737
					if ( ! empty( $tab['groups'] ) && is_array( $tab['groups'] ) ) {
1738
						foreach ( $tab['groups'] as $group ) {
1739
							if ( isset( $arguments[ $group ] ) ) {
1740
								$new_groups[] = $group;
1741
							}
1742
						}
1743
					}
1744
1745
					if ( ! empty( $new_groups ) ) {
1746
						$tab['groups'] = $new_groups;
1747
1748
						$new_tabs[ $tab_key ] = $tab;
1749
					}
1750
				}
1751
1752
				$tabs = $new_tabs;
1753
			}
1754
1755
			return $tabs;
1756
		}
1757
1758
		/**
1759
		 * Output the JS for building the dynamic Guntenberg block.
1760
		 *
1761
		 * @return mixed
1762
		 *@since 1.0.9 Save numbers as numbers and not strings.
1763
		 * @since 1.1.0 Font Awesome classes can be used for icons.
1764
		 * @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.
1765
		 */
1766
		public function block() {
1767
			global $sd_is_js_functions_loaded, $aui_bs5;
1768
1769
			$show_advanced = $this->block_show_advanced();
1770
1771
			ob_start();
1772
			?>
1773
			<script>
1774
			<?php
1775
			if ( ! $sd_is_js_functions_loaded ) {
1776
				$sd_is_js_functions_loaded = true;
1777
			?>
1778
function sd_show_view_options($this){
1779
	if(jQuery($this).html().length){
1780
		jQuery($this).html('');
1781
	}else{
1782
		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>');
1783
	}
1784
}
1785
1786
function sd_set_view_type($device){
1787
	wp.data.dispatch('core/edit-site') ? wp.data.dispatch('core/edit-site').__experimentalSetPreviewDeviceType($device) : wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType($device);
1788
}
1789
1790
jQuery(function(){
1791
	sd_block_visibility_init();
1792
});
1793
function sd_block_visibility_init() {
1794
	jQuery(document).off('change', '.bs-vc-modal-form').on('change', '.bs-vc-modal-form', function() {
1795
		try {
1796
			aui_conditional_fields('.bs-vc-modal-form');
1797
		} catch(err) {
1798
			console.log(err.message);
1799
		}
1800
	});
1801
1802
	jQuery(document).off('click', '.bs-vc-save').on('click', '.bs-vc-save', function() {
1803
		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;
1804
		jQuery(this).addClass('disabled');
1805
		jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule').each(function(){
1806
			vRule = jQuery(this).find('.bsvc_rule').val(), oRule = {};
1807
			if (vRule == 'logged_in' || vRule == 'logged_out') {
1808
				oRule.type = vRule;
1809
			} else if (vRule == 'user_roles') {
1810
				oRule.type = vRule;
1811
				if (jQuery(this).find('.bsvc_user_roles:checked').length) {
1812
					var user_roles = jQuery(this).find('.bsvc_user_roles:checked').map(function() {
1813
						return jQuery(this).val();
1814
					}).get();
1815
					if (user_roles && user_roles.length) {
1816
						oRule.user_roles = user_roles.join(",");
1817
					}
1818
				}
1819
			} else if (vRule == 'gd_field') {
1820
				if (jQuery(this).find('.bsvc_gd_field ').val() && jQuery(this).find('.bsvc_gd_field_condition').val()) {
1821
					oRule.type = vRule;
1822
					oRule.field = jQuery(this).find('.bsvc_gd_field ').val();
1823
					oRule.condition = jQuery(this).find('.bsvc_gd_field_condition').val();
1824
					if (oRule.condition != 'is_empty' && oRule.condition != 'is_not_empty') {
1825
						oRule.search = jQuery(this).find('.bsvc_gd_field_search').val();
1826
					}
1827
				}
1828
			}
1829
			if (Object.keys(oRule).length > 0) {
1830
				iRule++;
1831
				oVal['rule'+iRule] = oRule;
1832
			}
1833
		});
1834
		if (vOutput == 'hide') {
1835
			oOut.type = vOutput;
1836
		} else if (vOutput == 'message') {
1837
			if (jQuery('#bsvc_message', $bsvcForm).val()) {
1838
				oOut.type = vOutput;
1839
				oOut.message = jQuery('#bsvc_message', $bsvcForm).val();
1840
				if (jQuery('#bsvc_message_type', $bsvcForm).val()) {
1841
					oOut.message_type = jQuery('#bsvc_message_type', $bsvcForm).val();
1842
				}
1843
			}
1844
		} else if (vOutput == 'page') {
1845
			if (jQuery('#bsvc_page', $bsvcForm).val()) {
1846
				oOut.type = vOutput;
1847
				oOut.page = jQuery('#bsvc_page', $bsvcForm).val();
1848
			}
1849
		} else if (vOutput == 'template_part') {
1850
			if (jQuery('#bsvc_tmpl_part', $bsvcForm).val()) {
1851
				oOut.type = vOutput;
1852
				oOut.template_part = jQuery('#bsvc_tmpl_part', $bsvcForm).val();
1853
			}
1854
		}
1855
		if (Object.keys(oOut).length > 0) {
1856
			oVal.output = oOut;
1857
		}
1858
		if (Object.keys(oVal).length > 0) {
1859
			rawValue = JSON.stringify(oVal);
1860
		}
1861
		$bsvcModal.find('[name="bsvc_raw_value"]').val(rawValue).trigger('change');
1862
		$bsvcModal.find('.bs-vc-close').trigger('click');
1863
	});
1864
	jQuery(document).off('click', '.bs-vc-add-rule').on('click', '.bs-vc-add-rule', function() {
1865
		var bsvcTmpl = jQuery('.bs-vc-rule-template').html();
1866
		var c = parseInt(jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last').data('bs-index'));
1867
		if (c > 0) {
1868
			c++;
1869
		} else {
1870
			c = 1;
1871
		}
1872
		bsvcTmpl = bsvcTmpl.replace(/BSVCINDEX/g, c);
1873
		jQuery('.bs-vc-modal-form .bs-vc-rule-sets').append(bsvcTmpl);
1874
		jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last').find('select').each(function(){
1875
			if (!jQuery(this).hasClass('no-select2')) {
1876
				jQuery(this).addClass('aui-select2');
1877
			}
1878
		});
1879
		if (!jQuery(this).hasClass('bs-vc-rendering')) {
1880
			if(typeof aui_init_select2 == 'function') {
1881
				aui_init_select2();
1882
			}
1883
			if(typeof aui_conditional_fields == 'function') {
1884
				aui_conditional_fields('.bs-vc-modal-form');
1885
			}
1886
		}
1887
	});
1888
	jQuery(document).off('click', '.bs-vc-remove-rule').on('click', '.bs-vc-remove-rule', function() {
1889
		jQuery(this).closest('.bs-vc-rule').remove();
1890
	});
1891
}
1892
function sd_block_visibility_render_fields(oValue) {
1893
	if (typeof oValue == 'object' && oValue.rule1 && typeof oValue.rule1 == 'object') {
1894
		for(k = 1; k <= Object.keys(oValue).length; k++) {
1895
			if (oValue['rule' + k] && oValue['rule' + k].type) {
1896
				var oRule = oValue['rule' + k];
1897
				jQuery('.bs-vc-modal-form .bs-vc-add-rule').addClass('bs-vc-rendering').trigger('click');
1898
				var elRule = jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last');
1899
				jQuery('select.bsvc_rule', elRule).val(oRule.type);
1900
				if (oRule.type == 'user_roles' && oRule.user_roles) {
1901
					var user_roles = oRule.user_roles;
1902
					if (typeof user_roles == 'string') {
1903
						user_roles = user_roles.split(",");
1904
					}
1905
					if (user_roles.length) {
1906
						jQuery.each(user_roles, function(i, role){
1907
							elRule.find("input[value='" + role + "']").prop('checked', true);
1908
						});
1909
					}
1910
					jQuery('select.bsvc_user_roles', elRule).val(oRule.user_roles);
1911
				} else if (oRule.type == 'gd_field') {
1912
					if (oRule.field) {
1913
						jQuery('select.bsvc_gd_field', elRule).val(oRule.field);
1914
						if (oRule.condition) {
1915
							jQuery('select.bsvc_gd_field_condition', elRule).val(oRule.condition);
1916
							if (typeof oRule.search != 'undefined' && oRule.condition != 'is_empty' && oRule.condition != 'is_not_empty') {
1917
								jQuery('input.bsvc_gd_field_search', elRule).val(oRule.search);
1918
							}
1919
						}
1920
					}
1921
				}
1922
				jQuery('.bs-vc-modal-form .bs-vc-add-rule').removeClass('bs-vc-rendering');
1923
			}
1924
		}
1925
1926
		if (oValue.output && oValue.output.type) {
1927
			jQuery('.bs-vc-modal-form #bsvc_output').val(oValue.output.type);
1928
			if (oValue.output.type == 'message' && typeof oValue.output.message != 'undefined') {
1929
				jQuery('.bs-vc-modal-form #bsvc_message').val(oValue.output.message);
1930
				if (typeof oValue.output.message_type != 'undefined') {
1931
					jQuery('.bs-vc-modal-form #bsvc_message_type').val(oValue.output.message_type);
1932
				}
1933
			} else if (oValue.output.type == 'page' && typeof oValue.output.page != 'undefined') {
1934
				jQuery('.bs-vc-modal-form #bsvc_page').val(oValue.output.page);
1935
			} else if (oValue.output.type == 'template_part' && typeof oValue.output.template_part != 'undefined') {
1936
				jQuery('.bs-vc-modal-form #bsvc_template_part').val(oValue.output.template_part);
1937
			}
1938
		}
1939
	}
1940
}
1941
/**
1942
 * Try to auto-recover blocks.
1943
 */
1944
function sd_auto_recover_blocks() {
1945
	var recursivelyRecoverInvalidBlockList = blocks => {
1946
		const _blocks = [...blocks]
1947
		let recoveryCalled = false
1948
		const recursivelyRecoverBlocks = willRecoverBlocks => {
1949
			willRecoverBlocks.forEach(_block => {
1950
				if (!_block.isValid) {
1951
					recoveryCalled = true
1952
					const newBlock = recoverBlock(_block)
1953
					for (const key in newBlock) {
1954
						_block[key] = newBlock[key]
1955
					}
1956
				}
1957
				if (_block.innerBlocks.length) {
1958
					recursivelyRecoverBlocks(_block.innerBlocks)
1959
				}
1960
			})
1961
		}
1962
		recursivelyRecoverBlocks(_blocks)
1963
		return [_blocks, recoveryCalled]
1964
	}
1965
	var recoverBlock = ({ name, attributes, innerBlocks }) => wp.blocks.createBlock(name, attributes, innerBlocks);
1966
	var recoverBlocks = blocks => {
1967
		return blocks.map(_block => {
1968
			const block = _block;
1969
			// If the block is a reusable block, recover the Stackable blocks inside it.
1970
			if (_block.name === 'core/block') {
1971
				const { attributes: { ref } } = _block
1972
				const parsedBlocks = wp.blocks.parse(wp.data.select('core').getEntityRecords('postType', 'wp_block', { include: [ref] })?.[0]?.content?.raw) || []
1973
				const [recoveredBlocks, recoveryCalled] = recursivelyRecoverInvalidBlockList(parsedBlocks)
1974
				if (recoveryCalled) {
1975
					console.log('Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.');
1976
					return { blocks: recoveredBlocks, isReusable: true, ref }
1977
				}
1978
			} else if (_block.name === 'core/template-part' && _block.attributes && _block.attributes.theme) {
1979
				var tmplPart = wp.data.select('core').getEntityRecord('postType', 'wp_template_part', _block.attributes.theme + '//' + _block.attributes.slug);
1980
				var tmplPartBlocks = block.innerBlocks && block.innerBlocks.length ? block.innerBlocks : wp.blocks.parse(tmplPart?.content?.raw) || [];
1981
				if (tmplPartBlocks && tmplPartBlocks.length && tmplPartBlocks.some(block => !block.isValid)) {
1982
					block.innerBlocks = tmplPartBlocks;
1983
					block.tmplPartId = _block.attributes.theme + '//' + _block.attributes.slug;
1984
				}
1985
			}
1986
			if (block.innerBlocks && block.innerBlocks.length) {
1987
				if (block.tmplPartId) {
1988
					console.log('Template part ' + block.tmplPartId + ' block ' + block.name + ' (' + block.clientId + ') starts');
1989
				}
1990
				const newInnerBlocks = recoverBlocks(block.innerBlocks)
1991
				if (newInnerBlocks.some(block => block.recovered)) {
1992
					block.innerBlocks = newInnerBlocks
1993
					block.replacedClientId = block.clientId
1994
					block.recovered = true
1995
				}
1996
				if (block.tmplPartId) {
1997
					console.log('Template part ' + block.tmplPartId + ' block ' + block.name + ' (' + block.clientId + ') ends');
1998
				}
1999
			}
2000
			if (!block.isValid) {
2001
				const newBlock = recoverBlock(block)
2002
				newBlock.replacedClientId = block.clientId
2003
				newBlock.recovered = true
2004
				console.log('Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.');
2005
				return newBlock
2006
			}
2007
			return block
2008
		})
2009
	}
2010
	// Recover all the blocks that we can find.
2011
	var mainBlocks = recoverBlocks(wp.data.select('core/block-editor').getBlocks());
2012
	// Replace the recovered blocks with the new ones.
2013
	mainBlocks.forEach(block => {
2014
		if (block.isReusable && block.ref) {
2015
			// Update the reusable blocks.
2016
			wp.data.dispatch('core').editEntityRecord('postType', 'wp_block', block.ref, {
2017
				content: wp.blocks.serialize(block.blocks)
2018
			}).then(() => {
2019
				// But don't save them, let the user do the saving themselves. Our goal is to get rid of the block error visually.
2020
			})
2021
		}
2022
		if (block.recovered && block.replacedClientId) {
2023
			wp.data.dispatch('core/block-editor').replaceBlock(block.replacedClientId, block)
2024
		}
2025
	})
2026
}
2027
2028
/**
2029
 * Try to auto-recover OUR blocks if traditional way fails.
2030
 */
2031
function sd_auto_recover_blocks_fallback(editTmpl) {
2032
	console.log('sd_auto_recover_blocks_fallback()');
2033
	var $bsRecoverBtn = 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')");
2034
	if ($bsRecoverBtn.length) {
2035
		if (!editTmpl && jQuery('.edit-site-page-panels__edit-template-button').length && !jQuery('.edit-site-page-panels__edit-template-button').hasClass('bs-edit-tmpl-clicked')) {
2036
			jQuery('.edit-site-page-panels__edit-template-button').addClass('bs-edit-tmpl-clicked').trigger('click');
2037
			jQuery('body').addClass('bs-edit-tmpl-untick');
2038
		}
2039
		if(jQuery('.edit-site-layout.is-edit-mode').length){
2040
			$bsRecoverBtn.removeAttr('disabled').trigger('click');
2041
		}
2042
	} else {
2043
		if (jQuery('body').hasClass('bs-edit-tmpl-untick')) {
2044
			jQuery('body').removeClass('bs-edit-tmpl-untick');
2045
			jQuery('.components-button.edit-site-document-actions__back').trigger('click');
2046
		}
2047
	}
2048
}
2049
2050
// Wait will window is loaded before calling.
2051
window.onload = function() {
2052
	sd_auto_recover_blocks();
2053
	// fire a second time incase of load delays.
2054
	setTimeout(function() {
2055
		sd_auto_recover_blocks();
2056
	}, 5000);
2057
2058
	setTimeout(function() {
2059
		sd_auto_recover_blocks_fallback();
2060
	}, 6000);
2061
2062
	setTimeout(function() {
2063
		sd_auto_recover_blocks_fallback();
2064
	}, 10000);
2065
2066
	setTimeout(function() {
2067
		sd_auto_recover_blocks_fallback();
2068
	}, 15000);
2069
2070
	setTimeout(function() {
2071
		sd_auto_recover_blocks_fallback();
2072
	}, 20000);
2073
	
2074
	setTimeout(function() {
2075
		sd_auto_recover_blocks_fallback();
2076
	}, 30000);
2077
	
2078
	setTimeout(function() {
2079
		sd_auto_recover_blocks_fallback();
2080
	}, 60000);
2081
2082
	jQuery('.edit-site-page-panels__edit-template-button').on('click', function() {
2083
		setTimeout(function() {
2084
			sd_auto_recover_blocks_fallback(true);
2085
			jQuery('.edit-site-page-panels__edit-template-button').addClass('bs-edit-tmpl-clicked');
2086
		}, 100);
2087
	});
2088
};
2089
2090
// fire when URL changes also.
2091
let lastUrl = location.href;
2092
new MutationObserver(() => {
2093
    const url = location.href;
2094
    if (url !== lastUrl) {
2095
        lastUrl = url;
2096
        sd_auto_recover_blocks();
2097
        // fire a second time incase of load delays.
2098
        setTimeout(function() {
2099
            sd_auto_recover_blocks();
2100
			sd_auto_recover_blocks_fallback();
2101
        }, 2000);
2102
2103
		setTimeout(function() {
2104
		sd_auto_recover_blocks_fallback();
2105
		}, 10000);
2106
2107
		setTimeout(function() {
2108
		sd_auto_recover_blocks_fallback();
2109
		}, 15000);
2110
2111
		setTimeout(function() {
2112
		sd_auto_recover_blocks_fallback();
2113
		}, 20000);
2114
2115
    }
2116
}).observe(document, {
2117
    subtree: true,
2118
    childList: true
2119
});
2120
2121
2122
			/**
2123
			*
2124
* @param $args
2125
* @returns {*|{}}
2126
*/
2127
            function sd_build_aui_styles($args){
2128
2129
                $styles = {};
2130
                // background color
2131
                if ( $args['bg'] !== undefined && $args['bg'] !== '' ) {
2132
                   if( $args['bg'] == 'custom-color' ){
2133
                       $styles['background-color']=  $args['bg_color'];
2134
                   }else  if( $args['bg'] == 'custom-gradient' ){
2135
                       $styles['background-image']=  $args['bg_gradient'];
2136
2137
					    // use background on text
2138
						 if( $args['bg_on_text'] !== undefined && $args['bg_on_text'] ){
2139
							$styles['backgroundClip'] = "text";
2140
							$styles['WebkitBackgroundClip'] = "text";
2141
							$styles['text-fill-color'] = "transparent";
2142
							$styles['WebkitTextFillColor'] = "transparent";
2143
						 }
2144
                   }
2145
2146
                }
2147
2148
				let $bg_image = $args['bg_image'] !== undefined && $args['bg_image'] !== '' ? $args['bg_image'] : '';
2149
2150
				// maybe use featured image.
2151
				if( $args['bg_image_use_featured'] !== undefined && $args['bg_image_use_featured'] ){
2152
					$bg_image = '<?php echo $this->get_url();?>icons/placeholder.png';
2153
				}
2154
2155
                if( $bg_image !== undefined && $bg_image !== '' ){
2156
                    var hasImage = true
2157
                    if($styles['background-color'] !== undefined && $args['bg'] == 'custom-color'){
2158
                           $styles['background-image'] = "url("+$bg_image+")";
2159
                           $styles['background-blend-mode'] =  "overlay";
2160
                    }else if($styles['background-image'] !== undefined && $args['bg'] == 'custom-gradient'){
2161
                           $styles['background-image'] +=  ",url("+$bg_image+")";
2162
                    }else if($args['bg'] !== undefined && $args['bg'] != '' && $args['bg'] != 'transparent' ){
2163
                           // do nothing as we already have a preset
2164
                           hasImage = false;
2165
                    }else{
2166
                           $styles['background-image'] = "url("+$bg_image+")";
2167
                    }
2168
2169
                    if( hasImage){
2170
                         $styles['background-size'] = "cover";
2171
2172
						 if( $args['bg_image_fixed'] !== undefined && $args['bg_image_fixed'] ){
2173
							 $styles['background-attachment'] = "fixed";
2174
						 }
2175
                    }
2176
2177
                    if( hasImage && $args['bg_image_xy'].x !== undefined && $args['bg_image_xy'].x >=0 ){
2178
                          $styles['background-position'] =  ($args['bg_image_xy'].x * 100 ) + "% " + ( $args['bg_image_xy'].y * 100) + "%";
2179
                    }
2180
                }
2181
2182
2183
2184
				// sticky offset top
2185
				if( $args['sticky_offset_top'] !== undefined && $args['sticky_offset_top'] !== '' ){
2186
					$styles['top'] =  $args['sticky_offset_top'];
2187
				}
2188
2189
				// sticky offset bottom
2190
				if( $args['sticky_offset_bottom'] !== undefined && $args['sticky_offset_bottom'] !== '' ){
2191
					$styles['bottom'] =  $args['sticky_offset_bottom'];
2192
				}
2193
2194
				// font size
2195
				if( $args['font_size'] === undefined || $args['font_size'] === 'custom' ){
2196
					if( $args['font_size_custom'] !== undefined && $args['font_size_custom'] !== '' ){
2197
						$styles['fontSize'] =  $args['font_size_custom'] + "rem";
2198
					}
2199
				}
2200
2201
				// font color
2202
				if( $args['text_color'] === undefined || $args['text_color'] === 'custom' ){
2203
					if( $args['text_color_custom'] !== undefined && $args['text_color_custom'] !== '' ){
2204
						$styles['color'] =  $args['text_color_custom'];
2205
					}
2206
				}
2207
2208
				// font line height
2209
				if( $args['font_line_height'] !== undefined && $args['font_line_height'] !== '' ){
2210
					$styles['lineHeight'] =  $args['font_line_height'];
2211
				}
2212
2213
				// max height
2214
				if( $args['max_height'] !== undefined && $args['max_height'] !== '' ){
2215
					$styles['maxHeight'] =  $args['max_height'];
2216
				}
2217
2218
                return $styles;
2219
2220
            }
2221
2222
            function sd_build_aui_class($args){
2223
2224
                $classes = [];
2225
2226
				<?php
2227
				if($aui_bs5){
2228
					?>
2229
				$aui_bs5 = true;
2230
				$p_ml = 'ms-';
2231
				$p_mr = 'me-';
2232
2233
				$p_pl = 'ps-';
2234
				$p_pr = 'pe-';
2235
					<?php
2236
				}else{
2237
						?>
2238
				$aui_bs5 = false;
2239
				$p_ml = 'ml-';
2240
				$p_mr = 'mr-';
2241
2242
				$p_pl = 'pl-';
2243
				$p_pr = 'pr-';
2244
					<?php
2245
				}
2246
				?>
2247
2248
                // margins
2249
	            if ( $args['mt'] !== undefined && $args['mt'] !== '' ) { $classes.push( "mt-" + $args['mt'] );  $mt = $args['mt']; }else{$mt = null;}
2250
	            if ( $args['mr'] !== undefined && $args['mr'] !== '' ) { $classes.push( $p_mr + $args['mr'] );  $mr = $args['mr']; }else{$mr = null;}
2251
	            if ( $args['mb'] !== undefined && $args['mb'] !== '' ) { $classes.push( "mb-" + $args['mb'] );  $mb = $args['mb']; }else{$mb = null;}
2252
	            if ( $args['ml'] !== undefined && $args['ml'] !== '' ) { $classes.push( $p_ml + $args['ml'] );  $ml = $args['ml']; }else{$ml = null;}
2253
2254
                // margins tablet
2255
	            if ( $args['mt_md'] !== undefined && $args['mt_md'] !== '' ) { $classes.push( "mt-md-" + $args['mt_md'] );  $mt_md = $args['mt_md']; }else{$mt_md = null;}
2256
	            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;}
2257
	            if ( $args['mb_md'] !== undefined && $args['mb_md'] !== '' ) { $classes.push( "mb-md-" + $args['mb_md'] );  $mt_md = $args['mb_md']; }else{$mb_md = null;}
2258
	            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;}
2259
2260
                // margins desktop
2261
                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'] ); } }
2262
	            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'] ); } }
2263
	            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'] ); } }
2264
	            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'] ); } }
2265
2266
                // padding
2267
                if ( $args['pt'] !== undefined && $args['pt'] !== '' ) { $classes.push( "pt-" + $args['pt'] ); $pt = $args['pt']; }else{$pt = null;}
2268
	            if ( $args['pr'] !== undefined && $args['pr'] !== '' ) { $classes.push( $p_pr + $args['pr'] ); $pr = $args['pt']; }else{$pr = null;}
2269
	            if ( $args['pb'] !== undefined && $args['pb'] !== '' ) { $classes.push( "pb-" + $args['pb'] ); $pb = $args['pt']; }else{$pb = null;}
2270
	            if ( $args['pl'] !== undefined && $args['pl'] !== '' ) { $classes.push( $p_pl + $args['pl'] ); $pl = $args['pt']; }else{$pl = null;}
2271
2272
                // padding tablet
2273
                if ( $args['pt_md'] !== undefined && $args['pt_md'] !== '' ) { $classes.push( "pt-md-" + $args['pt_md'] ); $pt_md = $args['pt_md']; }else{$pt_md = null;}
2274
	            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;}
2275
	            if ( $args['pb_md'] !== undefined && $args['pb_md'] !== '' ) { $classes.push( "pb-md-" + $args['pb_md'] ); $pb_md = $args['pt_md']; }else{$pb_md = null;}
2276
	            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;}
2277
2278
                // padding desktop
2279
                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'] ); } }
2280
	            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'] ); } }
2281
	            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'] ); } }
2282
	            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'] ); } }
2283
2284
				// row cols, mobile, tablet, desktop
2285
	            if ( $args['row_cols'] !== undefined && $args['row_cols'] !== '' ) { $classes.push( "row-cols-" + $args['row_cols'] );  $row_cols = $args['row_cols']; }else{$row_cols = null;}
2286
	            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;}
2287
                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'] ); } }
2288
2289
				// columns , mobile, tablet, desktop
2290
	            if ( $args['col'] !== undefined && $args['col'] !== '' ) { $classes.push( "col-" + $args['col'] );  $col = $args['col']; }else{$col = null;}
2291
	            if ( $args['col_md'] !== undefined && $args['col_md'] !== '' ) { $classes.push( "col-md-" + $args['col_md'] );  $col_md = $args['col_md']; }else{$col_md = null;}
2292
                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'] ); } }
2293
2294
2295
                // border
2296
                if ( $args['border'] === undefined || $args['border']=='')  { }
2297
                else if ( $args['border'] !== undefined && ( $args['border']=='none' || $args['border']==='0') ) { $classes.push( "border-0" ); }
2298
	            else if ( $args['border'] !== undefined ) {
2299
					if($aui_bs5 && $args['border_type'] !== undefined){
2300
						$args['border_type'] = $args['border_type'].replace('-left','-start').replace('-right','-end');
2301
					}
2302
					$border_class = 'border';
2303
					if ( $args['border_type'] !== undefined && ! $args['border_type'].includes( '-0' )  ) {
2304
						$border_class = '';
2305
					}
2306
					$classes.push( $border_class + " border-" + $args['border'] );
2307
				}
2308
2309
                // border radius type
2310
              //  if ( $args['rounded'] !== undefined && $args['rounded'] !== '' ) { $classes.push($args['rounded']); }
2311
2312
                // border radius size
2313
                if( $args['rounded_size'] !== undefined && ( $args['rounded_size']==='sm' || $args['rounded_size']==='lg' ) ){
2314
					if ( $args['rounded_size'] !== undefined && $args['rounded_size'] !== '' ) {
2315
						$classes.push("rounded-" + $args['rounded_size']);
2316
						// if we set a size then we need to remove "rounded" if set
2317
						var index = $classes.indexOf("rounded");
2318
						if (index !== -1) {
2319
						  $classes.splice(index, 1);
2320
						}
2321
                	}
2322
                }else{
2323
					// rounded_size , mobile, tablet, desktop
2324
					if ( $args['rounded_size'] !== undefined && $args['rounded_size'] !== '' ) { $classes.push( "rounded-" + $args['rounded_size'] );  $rounded_size = $args['rounded_size']; }else{$rounded_size = null;}
2325
					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;}
2326
					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'] ); } }
2327
                }
2328
2329
2330
                // shadow
2331
               // if ( $args['shadow'] !== undefined && $args['shadow'] !== '' ) { $classes.push($args['shadow']); }
2332
2333
                // background
2334
                if ( $args['bg'] !== undefined  && $args['bg'] !== '' ) { $classes.push("bg-" + $args['bg']); }
2335
2336
                // text_color
2337
                if ( $args['text_color'] !== undefined && $args['text_color'] !== '' ) { $classes.push( "text-" + $args['text_color']); }
2338
2339
                // text_align
2340
                if ( $args['text_justify'] !== undefined && $args['text_justify'] ) { $classes.push('text-justify'); }
2341
                else{
2342
                    if ( $args['text_align'] !== undefined && $args['text_align'] !== '' ) {
2343
						if($aui_bs5){ $args['text_align'] = $args['text_align'].replace('-left','-start').replace('-right','-end'); }
2344
						$classes.push($args['text_align']); $text_align = $args['text_align'];
2345
					}else{$text_align = null;}
2346
                    if ( $args['text_align_md'] !== undefined && $args['text_align_md'] !== '' ) {
2347
						if($aui_bs5){ $args['text_align_md'] = $args['text_align_md'].replace('-left','-start').replace('-right','-end'); }
2348
						$classes.push($args['text_align_md']); $text_align_md = $args['text_align_md'];
2349
					}else{$text_align_md = null;}
2350
                    if ( $args['text_align_lg'] !== undefined && $args['text_align_lg'] !== '' ) {
2351
						if($aui_bs5){ $args['text_align_lg'] = $args['text_align_lg'].replace('-left','-start').replace('-right','-end'); }
2352
						if($text_align  == null && $text_align_md == null){ $classes.push($args['text_align_lg'].replace("-lg", ""));
2353
						}else{$classes.push($args['text_align_lg']);} }
2354
                }
2355
2356
				// display
2357
			  	if ( $args['display'] !== undefined && $args['display'] !== '' ) { $classes.push($args['display']); $display = $args['display']; }else{$display = null;}
2358
				if ( $args['display_md'] !== undefined && $args['display_md'] !== '' ) { $classes.push($args['display_md']); $display_md = $args['display_md']; }else{$display_md = null;}
2359
				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']);} }
2360
2361
				// bgtus - background transparent until scroll
2362
                if ( $args['bgtus'] !== undefined && $args['bgtus'] ) { $classes.push("bg-transparent-until-scroll"); }
2363
2364
				// cscos - change color scheme on scroll
2365
                if ( $args['bgtus'] !== undefined && $args['bgtus'] && $args['cscos'] !== undefined && $args['cscos'] ) { $classes.push("color-scheme-flip-on-scroll"); }
2366
2367
				// hover animations
2368
                if ( $args['hover_animations'] !== undefined && $args['hover_animations'] ) { $classes.push($args['hover_animations'].toString().replace(',',' ')); }
2369
2370
				// absolute_position
2371
				if ( $args['absolute_position'] !== undefined ) {
2372
					if ( 'top-left' === $args['absolute_position'] ) {
2373
						$classes.push('start-0 top-0');
2374
					} else if ( 'top-center' === $args['absolute_position'] ) {
2375
						$classes.push('start-50 top-0 translate-middle');
2376
					} else if ( 'top-right' === $args['absolute_position'] ) {
2377
						$classes.push('end-0 top-0');
2378
					} else if ( 'center-left' === $args['absolute_position'] ) {
2379
						$classes.push('start-0 bottom-50');
2380
					} else if ( 'center' === $args['absolute_position'] ) {
2381
						$classes.push('start-50 top-50 translate-middle');
2382
					} else if ( 'center-right' === $args['absolute_position'] ) {
2383
						$classes.push('end-0 top-50');
2384
					} else if ( 'bottom-left' === $args['absolute_position'] ) {
2385
						$classes.push('start-0 bottom-0');
2386
					} else if ( 'bottom-center' === $args['absolute_position'] ) {
2387
						$classes.push('start-50 bottom-0 translate-middle');
2388
					} else if ( 'bottom-right' === $args['absolute_position'] ) {
2389
						$classes.push('end-0 bottom-0');
2390
					}
2391
				}
2392
2393
				// build classes from build keys
2394
				$build_keys = sd_get_class_build_keys();
2395
				if ( $build_keys.length ) {
2396
					$build_keys.forEach($key => {
2397
2398
						if($key.endsWith("-MTD")){
2399
2400
							$k = $key.replace("-MTD","");
2401
2402
							// Mobile, Tablet, Desktop
2403
							if ( $args[$k] !== undefined && $args[$k] !== '' ) { $classes.push( $args[$k] );  $v = $args[$k]; }else{$v = null;}
2404
							if ( $args[$k + '_md'] !== undefined && $args[$k + '_md'] !== '' ) { $classes.push( $args[$k + '_md'] );  $v_md = $args[$k + '_md']; }else{$v_md = null;}
2405
							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'] ); } }
2406
2407
						}else{
2408
							if ( $key == 'font_size' && $args[ $key ] == 'custom' ) {
2409
							 return;
2410
							}
2411
							if ( $args[$key] !== undefined && $args[$key] !== '' ) { $classes.push($args[$key]); }
2412
						}
2413
2414
					});
2415
				}
2416
2417
                return $classes.join(" ");
2418
            }
2419
2420
			function sd_get_class_build_keys(){
2421
				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...
2422
			}
2423
2424
            <?php
2425
2426
2427
            }
2428
2429
			if(method_exists($this,'block_global_js')){
2430
					echo $this->block_global_js();
2431
			}
2432
			?>
2433
2434
jQuery(function() {
2435
2436
				/**
2437
				 * BLOCK: Basic
2438
				 *
2439
				 * Registering a basic block with Gutenberg.
2440
				 * Simple block, renders and saves the same content without any interactivity.
2441
				 *
2442
				 * Styles:
2443
				 *        editor.css — Editor styles for the block.
2444
				 *        style.css  — Editor & Front end styles for the block.
2445
				 */
2446
				(function (blocksx, elementx, blockEditor) {
2447
					var __ = wp.i18n.__; // The __() for internationalization.
2448
					var el = wp.element.createElement; // The wp.element.createElement() function to create elements.
2449
					var editable = wp.blocks.Editable;
2450
					var blocks = wp.blocks;
2451
					var registerBlockType = wp.blocks.registerBlockType; // The registerBlockType() to register blocks.
2452
					var is_fetching = false;
2453
					var prev_attributes = [];
2454
2455
                    var InnerBlocks = blockEditor.InnerBlocks;
2456
2457
					var term_query_type = '';
2458
					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 "[]";} ?>;
2459
					const taxonomies_<?php echo str_replace("-","_", $this->id);?> = [{label: "Please wait", value: 0}];
2460
					const sort_by_<?php echo str_replace("-","_", $this->id);?> = [{label: "Please wait", value: 0}];
2461
                    const MediaUpload = wp.blockEditor.MediaUpload;
2462
2463
					/**
2464
					 * Register Basic Block.
2465
					 *
2466
					 * Registers a new block provided a unique name and an object defining its
2467
					 * behavior. Once registered, the block is made available as an option to any
2468
					 * editor interface where blocks are implemented.
2469
					 *
2470
					 * @param  {string}   name     Block name.
2471
					 * @param  {Object}   settings Block settings.
2472
					 * @return {?WPBlock}          The block, if it has been successfully
2473
					 *                             registered; otherwise `undefined`.
2474
					 */
2475
					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.
2476
						apiVersion: <?php echo isset($this->options['block-api-version']) ? absint($this->options['block-api-version']) : 2 ; ?>,
2477
                        title: '<?php echo addslashes( $this->options['name'] ); ?>', // Block title.
2478
						description: '<?php echo addslashes( $this->options['widget_ops']['description'] )?>', // Block title.
2479
						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/.
2480
						supports: {
2481
							<?php
2482
							if ( isset( $this->options['block-supports'] ) ) {
2483
								echo $this->array_to_attributes( $this->options['block-supports'] );
2484
							}
2485
							?>
2486
						},
2487
						<?php
2488
						if ( isset( $this->options['block-label'] ) ) {
2489
						?>
2490
						__experimentalLabel( attributes, { context } ) {
2491
                            return <?php echo $this->options['block-label']; ?>;
2492
                        },
2493
                        <?php
2494
                        }
2495
                        ?>
2496
						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.
2497
						<?php if ( isset( $this->options['block-keywords'] ) ) {
2498
						echo "keywords : " . $this->options['block-keywords'] . ",";
2499
2500
//						// block hover preview.
2501
//						$example_args = array();
2502
//						if(!empty($this->arguments)){
2503
//							foreach($this->arguments as $key => $a_args){
2504
//								if(isset($a_args['example'])){
2505
//									$example_args[$key] = $a_args['example'];
2506
//								}
2507
//							}
2508
//						}
2509
//						$viewport_width = isset($this->options['example']['viewportWidth']) ? 'viewportWidth: '.absint($this->options['example']['viewportWidth']) : '';
2510
//						if( isset( $this->options['example'] ) && $this->options['example'] === false ){
2511
//							// no preview if set to false
2512
//						}elseif( !empty( $example_args ) ){
2513
//							echo "example : {attributes:{".$this->array_to_attributes( $example_args )."},$viewport_width},";
2514
//						}elseif( !empty( $this->options['example'] ) ){
2515
//							unset($this->options['example']['viewportWidth']);
2516
//							echo "example : {".$this->array_to_attributes( $this->options['example'] ).$viewport_width."},";
2517
//						}else{
2518
//							echo 'example : {'.$viewport_width.'},';
2519
//						}
2520
2521
                        }
2522
2523
						// maybe set no_wrap
2524
						$no_wrap = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false;
2525
						if ( isset( $this->arguments['no_wrap'] ) && $this->arguments['no_wrap'] ) {
2526
							$no_wrap = true;
2527
						}
2528
						if ( $no_wrap ) {
2529
							$this->options['block-wrap'] = '';
2530
						}
2531
2532
						// maybe load the drag/drop functions.
2533
						$img_drag_drop = false;
2534
2535
						$show_alignment = false;
2536
						// align feature
2537
						/*echo "supports: {";
2538
						echo "	align: true,";
2539
						echo "  html: false";
2540
						echo "},";*/
2541
2542
						if ( ! empty( $this->arguments ) ) {
2543
							echo "attributes : {";
2544
2545
							if ( $show_advanced ) {
2546
								echo "show_advanced: {";
2547
								echo "	type: 'boolean',";
2548
								echo "  default: false,";
2549
								echo "},";
2550
							}
2551
2552
							// block wrap element
2553
							if ( ! empty( $this->options['block-wrap'] ) ) { //@todo we should validate this?
2554
								echo "block_wrap: {";
2555
								echo "	type: 'string',";
2556
								echo "  default: '" . esc_attr( $this->options['block-wrap'] ) . "',";
2557
								echo "},";
2558
							}
2559
2560
2561
2562
							foreach ( $this->arguments as $key => $args ) {
2563
2564
								if( $args['type'] == 'image' ||  $args['type'] == 'images' ){
2565
									$img_drag_drop = true;
2566
								}
2567
2568
								// set if we should show alignment
2569
								if ( $key == 'alignment' ) {
2570
									$show_alignment = true;
2571
								}
2572
2573
								$extra = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $extra is dead and can be removed.
Loading history...
2574
2575
								if ( $args['type'] == 'notice' ||  $args['type'] == 'tab' ) {
2576
									continue;
2577
								}
2578
								elseif ( $args['type'] == 'checkbox' ) {
2579
									$type    = 'boolean';
2580
									$default = isset( $args['default'] ) && $args['default'] ? 'true' : 'false';
2581
								} elseif ( $args['type'] == 'number' ) {
2582
									$type    = 'number';
2583
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2584
								} elseif ( $args['type'] == 'select' && ! empty( $args['multiple'] ) ) {
2585
									$type = 'array';
2586
									if ( isset( $args['default'] ) && is_array( $args['default'] ) ) {
2587
										$default = ! empty( $args['default'] ) ? "['" . implode( "','", $args['default'] ) . "']" : "[]";
2588
									} else {
2589
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2590
									}
2591
								} elseif ( $args['type'] == 'tagselect' ) {
2592
									$type    = 'array';
2593
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2594
								} elseif ( $args['type'] == 'multiselect' ) {
2595
									$type    = 'array';
2596
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2597
								} elseif ( $args['type'] == 'image_xy' ) {
2598
									$type    = 'object';
2599
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2600
								} elseif ( $args['type'] == 'image' ) {
2601
									$type    = 'string';
2602
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2603
2604
                                    // add a field for ID
2605
//                                    echo $key . "_id : {";
2606
//                                    echo "type : 'number',";
2607
//                                    echo "},";
2608
//                                    echo $key . "_xy : {";
2609
//                                    echo "type : 'object',";
2610
//                                    echo "},";
2611
2612
								} else {
2613
									$type    = !empty($args['hidden_type']) ? esc_attr($args['hidden_type']) : 'string';
2614
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2615
2616
								}
2617
								echo $key . " : {";
2618
								echo "type : '$type',";
2619
								echo "default : $default,";
2620
								echo "},";
2621
							}
2622
2623
							echo "content : {type : 'string',default: 'Please select the attributes in the block settings'},";
2624
							echo "className: { type: 'string', default: '' },";
2625
2626
							echo "},";
2627
2628
						}
2629
2630
						?>
2631
2632
						// The "edit" property must be a valid function.
2633
						edit: function (props) {
2634
2635
2636
<?php
2637
// only include the drag/drop functions if required.
2638
if( $img_drag_drop ){
2639
2640
?>
2641
2642
function enableDragSort(listClass) {
2643
	setTimeout(function(){
2644
		 const sortableLists = document.getElementsByClassName(listClass);
2645
		 Array.prototype.map.call(sortableLists, (list) => {enableDragList(list)});
2646
	}, 300);
2647
}
2648
2649
function enableDragList(list) {
2650
  Array.prototype.map.call(list.children, (item) => {enableDragItem(item)});
2651
}
2652
2653
function enableDragItem(item) {
2654
  item.setAttribute('draggable', true)
2655
  item.ondrag = handleDrag;
2656
  item.ondragend = handleDrop;
2657
}
2658
2659
function handleDrag(item) {
2660
  const selectedItem = item.target,
2661
        list = selectedItem.parentNode,
2662
        x = event.clientX,
2663
        y = event.clientY;
2664
2665
  selectedItem.classList.add('drag-sort-active');
2666
  let swapItem = document.elementFromPoint(x, y) === null ? selectedItem : document.elementFromPoint(x, y);
2667
2668
  if (list === swapItem.parentNode) {
2669
    swapItem = swapItem !== selectedItem.nextSibling ? swapItem : swapItem.nextSibling;
2670
    list.insertBefore(selectedItem, swapItem);
2671
  }
2672
}
2673
2674
function handleDrop(item) {
2675
2676
	item.target.classList.remove('drag-sort-active');
2677
2678
	const newOrder = [];
2679
	let $parent = item.target.parentNode;
2680
	let $field = $parent.dataset.field;
2681
	let $imgs = JSON.parse('[' + props.attributes[$field] + ']');
2682
	item.target.parentNode.classList.add('xxx');
2683
	$children = $parent.children;
2684
2685
	Object.keys($children).forEach(function(key) {
2686
	  let $nKey = $children[key].dataset.index
2687
	  newOrder.push($imgs[$nKey]);
2688
	});
2689
2690
	// @todo find out why we need to empty the value first otherwise the order is wrong.
2691
	props.setAttributes({ [$field]: '' });
2692
	setTimeout(function(){
2693
		props.setAttributes({ [$field]: JSON.stringify(newOrder).replace('[','').replace(']','') });
2694
	}, 100);
2695
2696
}
2697
<?php } ?>
2698
2699
							if (typeof(props.attributes.styleid) !== 'undefined'){
2700
								if(props.attributes.styleid==''){ props.setAttributes({ 'styleid': 'block-'+(Math.random() + 1).toString(36).substring(2) } ); }
2701
							}
2702
2703
                            <?php
2704
                            if(!empty($this->options['block-edit-raw'])) {
2705
                                echo $this->options['block-edit-raw']; // strings have to be in single quotes, may cause issues
2706
                            }else{
2707
                            ?>
2708
2709
function hasSelectedInnerBlock(props) {
2710
    const select = wp.data.select('core/editor');
2711
    const selected = select.getBlockSelectionStart();
2712
    const inner = select.getBlock(props.clientId).innerBlocks;
2713
    for (let i = 0; i < inner.length; i++) {
2714
        if (inner[i].clientId === selected || inner[i].innerBlocks.length && hasSelectedInnerBlock(inner[i])) {
2715
            return true;
2716
        }
2717
    }
2718
    return false;
2719
};
2720
2721
const parentBlocksIDs = wp.data.select( 'core/block-editor' ).getBlockParents(props.clientId);
2722
const parentBlocks = wp.data.select('core/block-editor').getBlocksByClientId(parentBlocksIDs);
2723
// const isParentOfSelectedBlock = useSelect( ( select ) => wp.data.select( 'core/block-editor' ).hasSelectedInnerBlock( props.clientId, true ) ):
2724
    const block = wp.data.select('core/block-editor').getBlocksByClientId(props.clientId);//.[0].innerBlocks;
2725
    const childBlocks = block[0] == null ? '' : block[0].innerBlocks;
2726
2727
	var $value = '';
2728
	<?php
2729
	// if we have a post_type and a category then link them
2730
	if( isset($this->arguments['post_type']) && isset($this->arguments['category']) && !empty($this->arguments['category']['post_type_linked']) ){
2731
	?>
2732
	if(typeof(prev_attributes[props.clientId]) != 'undefined'){
2733
		$pt = props.attributes.post_type;
2734
		if(post_type_rest_slugs.length){
2735
			$value = post_type_rest_slugs[0][$pt];
2736
		}
2737
		var run = false;
2738
2739
		if($pt != term_query_type){
2740
			run = true;
2741
			term_query_type = $pt;
2742
		}
2743
<?php
2744
	$cat_path = '';
2745
	if ( ! empty( $this->arguments['post_type']['onchange_rest']['path'] ) ) {
2746
		$cat_path = esc_js( strip_tags( $this->arguments['post_type']['onchange_rest']['path'] ) );
2747
		$cat_path = str_replace( array( '&quot;', '&#039;' ), array( '"', "'" ), $cat_path );
2748
	}
2749
?>
2750
		/* taxonomies */
2751
		if($value && 'post_type' in prev_attributes[props.clientId] && 'category' in prev_attributes[props.clientId] && run){
2752
			if (!window.gdCPTCats) {
2753
				window.gdCPTCats = [];
2754
			}
2755
			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...
2756
			if (window.gdCPTCats[gdCatPath]) {
2757
				terms = window.gdCPTCats[gdCatPath];
2758
				while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2759
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2760
				}
2761
				taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2762
				jQuery.each( terms, function( key, val ) {
2763
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2764
				});
2765
2766
				/* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2767
				var $old_cat_value = props.attributes.category
2768
				props.setAttributes({category: [0] });
2769
				props.setAttributes({category: $old_cat_value });
2770
			} else {
2771
				wp.apiFetch({path: gdCatPath}).then(terms => {
2772
					window.gdCPTCats[gdCatPath] = terms;
2773
					while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2774
						taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2775
					}
2776
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2777
					jQuery.each( terms, function( key, val ) {
2778
						taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2779
					});
2780
2781
					/* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2782
					var $old_cat_value = props.attributes.category
2783
					props.setAttributes({category: [0] });
2784
					props.setAttributes({category: $old_cat_value });
2785
2786
					return taxonomies_<?php echo str_replace("-","_", $this->id);?>;
2787
				});
2788
			}
2789
		}
2790
2791
		/* sort_by */
2792
		if($value && 'post_type' in prev_attributes[props.clientId] && 'sort_by' in prev_attributes[props.clientId] && run){
2793
			if (!window.gdCPTSort) {
2794
				window.gdCPTSort = [];
2795
			}
2796
			if (window.gdCPTSort[$pt]) {
2797
				response = window.gdCPTSort[$pt];
2798
				while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2799
					sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2800
				}
2801
2802
				jQuery.each( response, function( key, val ) {
2803
					sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2804
				});
2805
2806
				// setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2807
				var $old_sort_by_value = props.attributes.sort_by
2808
				props.setAttributes({sort_by: [0] });
2809
				props.setAttributes({sort_by: $old_sort_by_value });
2810
			} else {
2811
				var data = {
2812
					'action': 'geodir_get_sort_options',
2813
					'post_type': $pt
2814
				};
2815
				jQuery.post(ajaxurl, data, function(response) {
2816
					response = JSON.parse(response);
2817
					window.gdCPTSort[$pt] = response;
2818
					while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2819
						sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2820
					}
2821
2822
					jQuery.each( response, function( key, val ) {
2823
						sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2824
					});
2825
2826
					// setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2827
					var $old_sort_by_value = props.attributes.sort_by
2828
					props.setAttributes({sort_by: [0] });
2829
					props.setAttributes({sort_by: $old_sort_by_value });
2830
2831
					return sort_by_<?php echo str_replace("-","_", $this->id);?>;
2832
				});
2833
			}
2834
		}
2835
	}
2836
	<?php } ?>
2837
<?php
2838
$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...
2839
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...
2840
	echo 'const { deviceType } = "";';
2841
}else{
2842
?>
2843
/** Get device type const. */
2844
const { deviceType } = wp.data.useSelect != 'undefined' ?  wp.data.useSelect(select => {
2845
	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
2846
	return {
2847
		deviceType: __experimentalGetPreviewDeviceType(),
2848
	}
2849
}, []) : '';
2850
<?php } ?>
2851
							var content = props.attributes.content;
2852
2853
							function onChangeContent($type) {
2854
// console.log(deviceType);
2855
								$refresh = false;
2856
								// Set the old content the same as the new one so we only compare all other attributes
2857
								if(typeof(prev_attributes[props.clientId]) != 'undefined'){
2858
									prev_attributes[props.clientId].content = props.attributes.content;
2859
								}else if(props.attributes.content === ""){
2860
									// if first load and content empty then refresh
2861
									$refresh = true;
2862
								}
2863
2864
								if ( ( !is_fetching &&  JSON.stringify(prev_attributes[props.clientId]) != JSON.stringify(props.attributes) ) || $refresh  ) {
2865
2866
									is_fetching = true;
2867
2868
									var data = {
2869
										'action': 'super_duper_output_shortcode',
2870
										'shortcode': '<?php echo $this->options['base_id'];?>',
2871
										'attributes': props.attributes,
2872
										'block_parent_name': parentBlocks.length ? parentBlocks[parentBlocks.length - 1].name : '',
2873
										'post_id': <?php global $post; if ( isset( $post->ID ) ) {
2874
										echo $post->ID;
2875
									}else{echo '0';}?>,
2876
										'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>'
2877
									};
2878
2879
									jQuery.post(ajaxurl, data, function (response) {
2880
										return response;
2881
									}).then(function (env) {
2882
2883
										// if the content is empty then we place some placeholder text
2884
										if (env == '') {
2885
											env = "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" + "<?php _e( 'Placeholder for:', 'ayecode-connect' );?> " + props.name + "</div>";
2886
										}
2887
2888
                                         <?php
2889
                                        if(!empty($this->options['nested-block'])){
2890
                                            ?>
2891
                                            // props.setAttributes({content: env});
2892
										is_fetching = false;
2893
										prev_attributes[props.clientId] = props.attributes;
2894
                                             <?php
2895
                                        }else{
2896
                                        ?>
2897
                                        props.setAttributes({content: env});
2898
										is_fetching = false;
2899
										prev_attributes[props.clientId] = props.attributes;
2900
                                        <?php
2901
                                        }
2902
                                        ?>
2903
2904
2905
										// if AUI is active call the js init function
2906
										if (typeof aui_init === "function") {
2907
											aui_init();
2908
										}
2909
									});
2910
2911
2912
								}
2913
2914
2915
								return props.attributes.content;
2916
2917
							}
2918
2919
                            <?php
2920
                            if(!empty($this->options['block-edit-js'])) {
2921
                                echo  $this->options['block-edit-js'] ; // strings have to be in single quotes, may cause issues
2922
                            }
2923
2924
2925
2926
                            ?>
2927
2928
2929
2930
							return [
2931
2932
								el(wp.blockEditor.BlockControls, {key: 'controls'},
2933
2934
									<?php if($show_alignment){?>
2935
									el(
2936
										wp.blockEditor.AlignmentToolbar,
2937
										{
2938
											value: props.attributes.alignment,
2939
											onChange: function (alignment) {
2940
												props.setAttributes({alignment: alignment})
2941
											}
2942
										}
2943
									)
2944
									<?php }?>
2945
2946
								),
2947
2948
								el(wp.blockEditor.InspectorControls, {key: 'inspector'},
2949
2950
									<?php
2951
2952
									if(! empty( $this->arguments )){
2953
2954
									if ( $show_advanced ) {
2955
									?>
2956
									el('div', {
2957
											style: {'padding-left': '16px','padding-right': '16px'}
2958
										},
2959
										el(
2960
											wp.components.ToggleControl,
2961
											{
2962
												label: 'Show Advanced Settings?',
2963
												checked: props.attributes.show_advanced,
2964
												onChange: function (show_advanced) {
2965
													props.setAttributes({show_advanced: !props.attributes.show_advanced})
2966
												}
2967
											}
2968
										)
2969
									)
2970
									,
2971
									<?php
2972
									}
2973
2974
									$arguments = $this->group_arguments( $this->arguments );
2975
									$block_group_tabs = ! empty( $this->options['block_group_tabs'] ) ? $this->group_block_tabs( $this->options['block_group_tabs'], $arguments ) : array();
2976
2977
									// Do we have sections?
2978
									$has_sections = $arguments == $this->arguments ? false : true;
2979
2980
									if($has_sections){
2981
									$panel_count = 0;
2982
									$open_tab = '';
2983
2984
									$open_tab_groups = array();
2985
									$used_tabs = array();
2986
2987
									foreach ( $arguments as $key => $args ) {
2988
										$close_tab = false;
2989
										$close_tabs = false;
2990
2991
										 if ( ! empty( $block_group_tabs ) ) {
2992
											foreach ( $block_group_tabs as $tab_name => $tab_args ) {
2993
												if ( in_array( $key, $tab_args['groups'] ) ) {
2994
													$open_tab_groups[] = $key;
2995
2996
													if ( $open_tab != $tab_name ) {
2997
														$tab_args['tab']['tabs_open'] = $open_tab == '' ? true : false;
2998
														$tab_args['tab']['open'] = true;
2999
3000
														$this->block_tab_start( '', $tab_args );
3001
														$open_tab = $tab_name;
3002
														$used_tabs[] = $tab_name;
3003
													}
3004
3005
													if ( $open_tab_groups == $tab_args['groups'] ) {
3006
														$close_tab = true;
3007
														$open_tab_groups = array();
3008
3009
														if ( $used_tabs == array_keys( $block_group_tabs ) ) {
3010
															$close_tabs = true;
3011
														}
3012
													}
3013
												}
3014
											}
3015
										}
3016
										?>
3017
										el(wp.components.PanelBody, {
3018
												title: '<?php esc_attr_e( $key ); ?>',
3019
												initialOpen: <?php if ( $panel_count ) {
3020
												echo "false";
3021
											} else {
3022
												echo "true";
3023
											}?>
3024
											},
3025
											<?php
3026
											foreach ( $args as $k => $a ) {
3027
												$this->block_tab_start( $k, $a );
3028
												$this->block_row_start( $k, $a );
3029
												$this->build_block_arguments( $k, $a );
3030
												$this->block_row_end( $k, $a );
3031
												$this->block_tab_end( $k, $a );
3032
											}
3033
											?>
3034
										),
3035
										<?php
3036
										$panel_count ++;
3037
3038
										if($close_tab || $close_tabs){
3039
											$tab_args = array(
3040
												'tab'	=> array(
3041
													'tabs_close' => $close_tabs,
3042
												'close' => true,
3043
												)
3044
3045
											);
3046
											$this->block_tab_end( '', $tab_args );
3047
//											echo '###close'; print_r($tab_args);
3048
											$panel_count = 0;
3049
										}
3050
//
3051
3052
									}
3053
									}else {
3054
									?>
3055
									el(wp.components.PanelBody, {
3056
											title: '<?php esc_attr_e( "Settings", 'ayecode-connect' ); ?>',
3057
											initialOpen: true
3058
										},
3059
										<?php
3060
										foreach ( $this->arguments as $key => $args ) {
3061
											$this->block_row_start( $key, $args );
3062
											$this->build_block_arguments( $key, $args );
3063
											$this->block_row_end( $key, $args );
3064
										}
3065
										?>
3066
									),
3067
									<?php
3068
									}
3069
3070
									}
3071
									?>
3072
3073
								),
3074
3075
								<?php
3076
								// If the user sets block-output array then build it
3077
								if ( ! empty( $this->options['block-output'] ) ) {
3078
								$this->block_element( $this->options['block-output'] );
3079
							}elseif(!empty($this->options['block-edit-return'])){
3080
                                   echo $this->options['block-edit-return'];
3081
							}else{
3082
								// if no block-output is set then we try and get the shortcode html output via ajax.
3083
								$block_edit_wrap_tag = !empty($this->options['block_edit_wrap_tag']) ? esc_attr($this->options['block_edit_wrap_tag']) : 'div';
3084
								?>
3085
								el('<?php echo esc_attr($block_edit_wrap_tag); ?>', wp.blockEditor.useBlockProps({
3086
									dangerouslySetInnerHTML: {__html: onChangeContent()},
3087
									className: props.className,
3088
									style: {'minHeight': '30px'}
3089
								}))
3090
								<?php
3091
								}
3092
								?>
3093
							]; // end return
3094
3095
							<?php
3096
                            } // end block-edit-raw else
3097
                            ?>
3098
						},
3099
3100
						// The "save" property must be specified and must be a valid function.
3101
						save: function (props) {
3102
3103
							var attr = props.attributes;
3104
							var align = '';
3105
3106
							// build the shortcode.
3107
							var content = "[<?php echo $this->options['base_id'];?>";
3108
							$html = '';
3109
							<?php
3110
3111
							if(! empty( $this->arguments )){
3112
3113
							foreach($this->arguments as $key => $args){
3114
                               // if($args['type']=='tabs'){continue;}
3115
							?>
3116
							if (attr.hasOwnProperty("<?php echo esc_attr( $key );?>")) {
3117
								if ('<?php echo esc_attr( $key );?>' == 'html') {
3118
									$html = attr.<?php echo esc_attr( $key );?>;
3119
								} else if ('<?php echo esc_attr( $args['type'] );?>' == 'image_xy') {
3120
									content += " <?php echo esc_attr( $key );?>='{x:" + attr.<?php echo esc_attr( $key );?>.x + ",y:"+attr.<?php echo esc_attr( $key );?>.y +"}' ";
3121
								} else {
3122
									content += " <?php echo esc_attr( $key );?>='" + attr.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' ";
3123
								}
3124
							}
3125
							<?php
3126
							}
3127
							}
3128
3129
							?>
3130
							content += "]";
3131
3132
                            <?php
3133
//                            if(!empty($this->options['nested-block'])){
3134
//                                ?>
3135
//                                $html = 'el( InnerBlocks.Content )';
3136
//                                <?php
3137
//                            }
3138
                            ?>
3139
							// if has html element
3140
							if ($html) {
3141
								content += $html + "[/<?php echo $this->options['base_id'];?>]";
3142
							}
3143
3144
							// @todo should we add inline style here or just css classes?
3145
							if (attr.alignment) {
3146
								if (attr.alignment == 'left') {
3147
									align = 'alignleft';
3148
								}
3149
								if (attr.alignment == 'center') {
3150
									align = 'aligncenter';
3151
								}
3152
								if (attr.alignment == 'right') {
3153
									align = 'alignright';
3154
								}
3155
							}
3156
3157
							<?php
3158
//							if(!empty($this->options['nested-block'])){
3159
//                                ?x>
3160
//                              return el(
3161
//                                    'div',
3162
//                                    { className: props.className,
3163
//                                        style: {'minHeight': '300px','position':'relative','overflow':'hidden','backgroundImage': 'url(https://s.w.org/images/core/5.5/don-quixote-06.jpg)'}
3164
//                                    },
3165
//                                    el( InnerBlocks.Content ),
3166
//                                    el('div', {dangerouslySetInnerHTML: {__html: content}, className: align})
3167
//                                );
3168
//                                <x?php
3169
//							}else
3170
3171
                            if(!empty($this->options['block-output'])){
3172
//                               echo "return";
3173
//                               $this->block_element( $this->options['block-output'], true );
3174
//                               echo ";";
3175
3176
                               ?>
3177
                              return el(
3178
                                   '',
3179
                                   {},
3180
                                   el('', {dangerouslySetInnerHTML: {__html: content}}),
3181
                                   <?php $this->block_element( $this->options['block-output'], true ); ?>
3182
                                   el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
3183
                               );
3184
                                <?php
3185
3186
							}elseif(!empty($this->options['block-save-return'])){
3187
                                   echo 'return ' . $this->options['block-save-return'];
3188
							}elseif(!empty($this->options['nested-block'])){
3189
                                ?>
3190
                              return el(
3191
                                   '',
3192
                                   {},
3193
                                   el('', {dangerouslySetInnerHTML: {__html: content+"\n"}}),
3194
                                   InnerBlocks.Content ? el( InnerBlocks.Content ) : '', // @todo i think we need a comma here
3195
                                   el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
3196
                               );
3197
                                <?php
3198
							}elseif(!empty( $this->options['block-save-return'] ) ){
3199
                                echo "return ". $this->options['block-edit-return'].";";
3200
							}elseif(isset( $this->options['block-wrap'] ) && $this->options['block-wrap'] == ''){
3201
							?>
3202
							return content;
3203
							<?php
3204
							}else{
3205
							?>
3206
							var block_wrap = 'div';
3207
							if (attr.hasOwnProperty("block_wrap")) {
3208
								block_wrap = attr.block_wrap;
3209
							}
3210
							return el(block_wrap, wp.blockEditor.useBlockProps.save( {dangerouslySetInnerHTML: {__html: content}, className: align} ));
3211
							<?php
3212
							}
3213
							?>
3214
3215
3216
						}
3217
					});
3218
				})(
3219
                    window.wp.blocks,
3220
    window.wp.element,
3221
    window.wp.blockEditor
3222
				);
3223
3224
                });
3225
			</script>
3226
			<?php
3227
			$output = ob_get_clean();
3228
3229
			/*
3230
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
3231
			 */
3232
3233
			return str_replace( array(
3234
				'<script>',
3235
				'</script>'
3236
			), '', $output );
3237
		}
3238
3239
3240
3241
		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

3241
		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...
3242
3243
			// check for row
3244
			if(!empty($args['row'])){
3245
3246
				if(!empty($args['row']['open'])){
3247
3248
				// element require
3249
				$element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3250
                $device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3251
                $device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3252
                $device_type_icon = '';
3253
                if($device_type=='Desktop'){
3254
                    $device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3255
                }elseif($device_type=='Tablet'){
3256
                    $device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3257
                }elseif($device_type=='Mobile'){
3258
                    $device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3259
                }
3260
				echo $element_require;
3261
                echo $device_type_require;
3262
3263
					if(false){?><script><?php }?>
3264
						el('div', {
3265
								className: 'bsui components-base-control',
3266
							},
3267
							<?php if(!empty($args['row']['title'])){ ?>
3268
							el('label', {
3269
									className: 'components-base-control__label position-relative',
3270
									style: {width:"100%"}
3271
								},
3272
								el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['row']['title'] ) ?>'}}),
3273
								<?php if($device_type_icon){ ?>
3274
                                    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)"}})
3275
								<?php
3276
                                }
3277
                                ?>
3278
3279
3280
							),
3281
							<?php }?>
3282
							<?php if(!empty($args['row']['desc'])){ ?>
3283
							el('p', {
3284
									className: 'components-base-control__help mb-0',
3285
								},
3286
								'<?php echo addslashes( $args['row']['desc'] ); ?>'
3287
							),
3288
							<?php }?>
3289
							el(
3290
								'div',
3291
								{
3292
									className: 'row mb-n2 <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>',
3293
								},
3294
								el(
3295
									'div',
3296
									{
3297
										className: 'col pr-2 pe-2',
3298
									},
3299
3300
					<?php
3301
					if(false){?></script><?php }
3302
				}elseif(!empty($args['row']['close'])){
3303
					if(false){?><script><?php }?>
3304
						el(
3305
							'div',
3306
							{
3307
								className: 'col pl-0 ps-0',
3308
							},
3309
					<?php
3310
					if(false){?></script><?php }
3311
				}else{
3312
					if(false){?><script><?php }?>
3313
						el(
3314
							'div',
3315
							{
3316
								className: 'col pl-0 ps-0 pr-2 pe-2',
3317
							},
3318
					<?php
3319
					if(false){?></script><?php }
3320
				}
3321
3322
			}
3323
3324
		}
3325
3326
		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

3326
		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...
3327
3328
			if(!empty($args['row'])){
3329
				// maybe close
3330
				if(!empty($args['row']['close'])){
3331
					echo "))";
3332
				}
3333
3334
				echo "),";
3335
			}
3336
		}
3337
3338
		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

3338
		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...
3339
3340
			// check for row
3341
			if(!empty($args['tab'])){
3342
3343
				if(!empty($args['tab']['tabs_open'])){
3344
3345
					if(false){?><script><?php }?>
3346
3347
el('div',{className: 'bsui'},
3348
3349
						el('hr', {className: 'm-0'}), el(
3350
									wp.components.TabPanel,
3351
									{
3352
                                        activeClass: 'is-active',
3353
                                        className: 'btn-groupx',
3354
                                        initialTabName: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3355
										tabs: [
3356
3357
					<?php
3358
					if(false){?></script><?php }
3359
				}
3360
3361
				if(!empty($args['tab']['open'])){
3362
3363
					if(false){?><script><?php }?>
3364
							{
3365
												name: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3366
												title: el('div', {dangerouslySetInnerHTML: {__html: '<?php echo addslashes( esc_attr( $args['tab']['title']) ); ?>'}}),
3367
												className: '<?php echo addslashes( esc_attr( $args['tab']['class']) ); ?>',
3368
												content: el('div',{}, <?php if(!empty($args['tab']['desc'])){ ?>el('p', {
3369
									className: 'components-base-control__help mb-0',
3370
									dangerouslySetInnerHTML: {__html:'<?php echo addslashes( $args['tab']['desc'] ); ?>'}
3371
								}),<?php }
3372
					if(false){?></script><?php }
3373
				}
3374
3375
			}
3376
3377
		}
3378
3379
		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

3379
		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...
3380
3381
			if(!empty($args['tab'])){
3382
				// maybe close
3383
				if(!empty($args['tab']['close'])){
3384
					echo ")}, /* tab close */";
3385
				}
3386
3387
				if(!empty($args['tab']['tabs_close'])){
3388
					if(false){?><script><?php }?>
3389
						]}, ( tab ) => {
3390
								return tab.content;
3391
							}
3392
						)), /* tabs close */
3393
					<?php if(false){ ?></script><?php }
3394
				}
3395
			}
3396
		}
3397
3398
		public function build_block_arguments( $key, $args ) {
3399
			$custom_attributes = ! empty( $args['custom_attributes'] ) ? $this->array_to_attributes( $args['custom_attributes'] ) : '';
3400
			$options           = '';
3401
			$extra             = '';
3402
			$require           = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $require is dead and can be removed.
Loading history...
3403
            $inside_elements   = '';
3404
			$after_elements	   = '';
3405
3406
			// `content` is a protected and special argument
3407
			if ( $key == 'content' ) {
3408
				return;
3409
			}
3410
3411
            $device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3412
            $device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3413
            $device_type_icon = '';
3414
            if($device_type=='Desktop'){
3415
                $device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3416
            }elseif($device_type=='Tablet'){
3417
                $device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3418
            }elseif($device_type=='Mobile'){
3419
                $device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3420
            }
3421
3422
			// icon
3423
			$icon = '';
3424
			if( !empty( $args['icon'] ) ){
3425
				$icon .= "el('div', {";
3426
									$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

3426
									$icon .= "dangerouslySetInnerHTML: {__html: '".self::/** @scrutinizer ignore-call */ get_widget_icon( esc_attr($args['icon']))."'},";
Loading history...
3427
									$icon .= "className: 'text-center',";
3428
									$icon .= "title: '".addslashes( $args['title'] )."',";
3429
								$icon .= "}),";
3430
3431
				// blank title as its added to the icon.
3432
				$args['title'] = '';
3433
			}
3434
3435
			// require advanced
3436
			$require_advanced = ! empty( $args['advanced'] ) ? "props.attributes.show_advanced && " : "";
3437
3438
			// element require
3439
			$element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3440
3441
3442
			$onchange  = "props.setAttributes({ $key: $key } )";
3443
			$onchangecomplete  = "";
3444
			$value     = "props.attributes.$key";
3445
			$text_type = array( 'text', 'password', 'number', 'email', 'tel', 'url', 'colorx','range' );
3446
			if ( in_array( $args['type'], $text_type ) ) {
3447
				$type = 'TextControl';
3448
				// Save numbers as numbers and not strings
3449
				if ( $args['type'] == 'number' ) {
3450
					$onchange = "props.setAttributes({ $key: $key ? Number($key) : '' } )";
3451
				}
3452
			}
3453
//			else if ( $args['type'] == 'popup' ) {
3454
//				$type = 'TextControl';
3455
//				$args['type'] == 'text';
3456
//				$after_elements .= "el( wp.components.Button, {
3457
//                          className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3458
//                          onClick: function(){
3459
//							  aui_modal('','<input id=\'zzz\' value= />');
3460
//							  const source = document.getElementById('zzz');
3461
//							  source.value = props.attributes.$key;
3462
//							  source.addEventListener('input', function(e){props.setAttributes({ $key: e.target.value });});
3463
//                          }
3464
//                        },
3465
//                        'test'
3466
//                        ),";
3467
//
3468
//				$value     = "props.attributes.$key ? props.attributes.$key : ''";
3469
//			}
3470
			else if ( $args['type'] == 'styleid' ) {
3471
				$type = 'TextControl';
3472
				$args['type'] == 'text';
3473
				// Save numbers as numbers and not strings
3474
				$value     = "props.attributes.$key ? props.attributes.$key : ''";
3475
			}else if ( $args['type'] == 'notice' ) {
3476
3477
				$notice_message = !empty($args['desc']) ? addslashes($args['desc']) : '';
3478
				$notice_status = !empty($args['status']) ? esc_attr($args['status']) : 'info';
3479
3480
				$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'}}))),";
3481
				echo $notice_message ? $element_require . $notice : '';
3482
				return;
3483
			}
3484
			/*
3485
			 * https://www.wptricks.com/question/set-current-tab-on-a-gutenberg-tabpanel-component-from-outside-that-component/ es5 layout
3486
						elseif($args['type']=='tabs'){
3487
							?>
3488
								el(
3489
									wp.components.TabPanel,
3490
									{
3491
                                        activeClass: 'active-tab',
3492
                                        initialTabName: deviceType,
3493
										tabs: [
3494
											{
3495
												name: 'Desktop',
3496
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-desktop"></i>'}}),
3497
												className: 'tab-one' + deviceType == 'Desktop' ? ' active-tab' : '',
3498
												content: el('div', {dangerouslySetInnerHTML: {__html: 'ddd'}})
3499
											},
3500
											{
3501
												name: 'Tablet',
3502
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-tablet-alt"></i>'}}),
3503
												className: 'tab-two' + deviceType == 'Tablet' ? ' active-tab' : '',
3504
												content: el('div', {dangerouslySetInnerHTML: {__html: 'ttt'}})
3505
											},
3506
											{
3507
												name: 'Mobile',
3508
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-mobile-alt"></i>'}}),
3509
												className: 'tab-two' + deviceType == 'Mobile' ? ' active-tab' : '',
3510
												content: el('div', {dangerouslySetInnerHTML: {__html: 'mmm'}})
3511
											},
3512
										],
3513
									},
3514
									( tab ) => {
3515
3516
// @todo https://github.com/WordPress/gutenberg/issues/39248
3517
									if(tab.name=='Desktop'){
3518
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Desktop');
3519
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3520
									}else if(tab.name=='Tablet'){
3521
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Tablet');
3522
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3523
									}else if(tab.name=='Mobile'){
3524
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Mobile');
3525
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3526
									}
3527
3528
									return tab.content;
3529
3530
								}
3531
								),
3532
3533
							<?php
3534
							return;
3535
						}
3536
*/
3537
			elseif ( $args['type'] == 'color' ) {
3538
				$type = 'ColorPicker';
3539
				$onchange = "";
3540
				$extra = "color: $value,";
3541
				if(!empty($args['disable_alpha'])){
3542
					$extra .= "disableAlpha: true,";
3543
				}
3544
				$onchangecomplete = "onChangeComplete: function($key) {
3545
				value =  $key.rgb.a && $key.rgb.a < 1 ? \"rgba(\"+$key.rgb.r+\",\"+$key.rgb.g+\",\"+$key.rgb.b+\",\"+$key.rgb.a+\")\" : $key.hex;
3546
                        props.setAttributes({
3547
                            $key: value
3548
                        });
3549
                    },";
3550
			}elseif ( $args['type'] == 'gradient' ) {
3551
				$type = 'GradientPicker';
3552
				$extra .= "gradients: [{
3553
			name: 'Vivid cyan blue to vivid purple',
3554
			gradient:
3555
				'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
3556
			slug: 'vivid-cyan-blue-to-vivid-purple',
3557
		},
3558
		{
3559
			name: 'Light green cyan to vivid green cyan',
3560
			gradient:
3561
				'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)',
3562
			slug: 'light-green-cyan-to-vivid-green-cyan',
3563
		},
3564
		{
3565
			name: 'Luminous vivid amber to luminous vivid orange',
3566
			gradient:
3567
				'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)',
3568
			slug: 'luminous-vivid-amber-to-luminous-vivid-orange',
3569
		},
3570
		{
3571
			name: 'Luminous vivid orange to vivid red',
3572
			gradient:
3573
				'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)',
3574
			slug: 'luminous-vivid-orange-to-vivid-red',
3575
		},
3576
		{
3577
			name: 'Very light gray to cyan bluish gray',
3578
			gradient:
3579
				'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)',
3580
			slug: 'very-light-gray-to-cyan-bluish-gray',
3581
		},
3582
		{
3583
			name: 'Cool to warm spectrum',
3584
			gradient:
3585
				'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%)',
3586
			slug: 'cool-to-warm-spectrum',
3587
		}],";
3588
3589
			}elseif ( $args['type'] == 'image' ) {
3590
//                print_r($args);
3591
3592
                $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,{
3593
                            url:  props.attributes.{$key}_use_featured === true ? '".$this->get_url()."icons/placeholder.png'  : props.attributes.$key,
3594
                            value: props.attributes.{$key}_xy.x !== undefined && props.attributes.{$key}_xy.x >= 0 ? props.attributes.{$key}_xy  : {x: 0.5,y: 0.5,},
3595
//                            value: props.attributes.{$key}_xy,
3596
                            onChange: function(focalPoint){
3597
                            console.log(props.attributes);
3598
                                              return props.setAttributes({
3599
                                                  {$key}_xy: focalPoint
3600
                                                });
3601
                                    },
3602
                                    // @todo for some reason this does not work as expected.
3603
//                         onDrag: function(focalPointTemp){
3604
//                                  return props.setAttributes({
3605
//                                      {$key}_xy: focalPointTemp
3606
//                                    });
3607
//                        }
3608
3609
3610
                        }), ";
3611
3612
3613
                $value = '""';
3614
				$type = 'MediaUpload';
3615
                $extra .= "onSelect: function(media){
3616
                      return props.setAttributes({
3617
                          $key: media.url,
3618
                          {$key}_id: media.id
3619
                        });
3620
                      },";
3621
                   $extra .= "type: 'image',";
3622
                   $extra .= "render: function (obj) {
3623
                        return el( 'div',{},
3624
                        ( !props.attributes.$key && !props.attributes.{$key}_use_featured ) && el( wp.components.Button, {
3625
                          className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3626
                          onClick: obj.open
3627
                        },
3628
                        'Upload Image'
3629
                        ),
3630
                       $img_preview
3631
                        props.attributes.$key && el( wp.components.Button, {
3632
                                      className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3633
                                      style: {margin:'8px 0',display: 'block'},
3634
                                      onClick: function(){
3635
                                              return props.setAttributes({
3636
                                                  $key: '',
3637
                                                  {$key}_id: ''
3638
                                                });
3639
                                    }
3640
                                    },
3641
                                    props.attributes.$key? 'Clear' : ''
3642
                            )
3643
                       )
3644
3645
3646
3647
                      }";
3648
                $onchange = "";
3649
3650
                //$inside_elements = ",el('div',{},'file upload')";
3651
			} else if ( $args['type'] == 'images' ) {
3652
				$img_preview = "props.attributes.$key && (function() {
3653
	let uploads = JSON.parse('['+props.attributes.$key+']');
3654
	let images = [];
3655
	uploads.map((upload, index) => (
3656
		images.push( el('div',{ className: 'col p-2', draggable: 'true', 'data-index': index }, 
3657
			el('img', {
3658
				src: (upload.sizes && upload.sizes.thumbnail ? upload.sizes.thumbnail.url : upload.url),
3659
				style: { maxWidth:'100%', background: '#ccc', pointerEvents:'none' }
3660
			}),
3661
			el('i',{
3662
				className: 'fas fa-times-circle text-danger position-absolute  ml-n2 mt-n1 bg-white rounded-circle c-pointer',
3663
				onClick: function() {
3664
					aui_confirm('".esc_attr__('Are you sure?')."', '".esc_attr__('Delete')."', '".esc_attr__('Cancel')."', true).then(function(confirmed) {
3665
						if (confirmed) {
3666
							let new_uploads = JSON.parse('['+props.attributes.$key+']');
3667
							new_uploads.splice(index, 1);
3668
								return props.setAttributes({ {$key}: JSON.stringify( new_uploads ).replace('[','').replace(']','') });
3669
							}
3670
					});
3671
				}},
3672
			'')
3673
		))
3674
	));
3675
	return images;
3676
})(),";
3677
3678
3679
				$value = '""';
3680
				$type = 'MediaUpload';
3681
				$extra .= "onSelect: function(media){
3682
	let slim_images = props.attributes.$key ? JSON.parse('['+props.attributes.$key+']') : [];
3683
	if(media.length){
3684
		for (var i=0; i < media.length; i++) {
3685
			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});
3686
		}
3687
	}
3688
	var slimImagesV = JSON.stringify(slim_images);
3689
	if (slimImagesV) {
3690
		slimImagesV = slimImagesV.replace('[','').replace(']','').replace(/'/g, '&#39;');
3691
	}
3692
	return props.setAttributes({ $key: slimImagesV});
3693
},";
3694
				$extra .= "type: 'image',";
3695
				$extra .= "multiple: true,";
3696
				$extra .= "render: function (obj) {
3697
	/* Init the sort */
3698
	enableDragSort('sd-sortable');
3699
	return el( 'div',{},
3700
		el( wp.components.Button, {
3701
				className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3702
				onClick: obj.open
3703
			},
3704
			'Upload Images'
3705
		),
3706
		el('div',{
3707
				className: 'row row-cols-3 px-2 sd-sortable',
3708
				'data-field':'$key'
3709
			},
3710
			$img_preview
3711
		),
3712
		props.attributes.$key && el( wp.components.Button, {
3713
				className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3714
				style: {margin:'8px 0'},
3715
				onClick: function(){
3716
					return props.setAttributes({ $key: '' });
3717
				}
3718
			},
3719
			props.attributes.$key ? 'Clear All' : ''
3720
		)
3721
	)
3722
}";
3723
                $onchange = "";
3724
3725
                //$inside_elements = ",el('div',{},'file upload')";
3726
			}
3727
			elseif ( $args['type'] == 'checkbox' ) {
3728
				$type = 'CheckboxControl';
3729
				$extra .= "checked: props.attributes.$key,";
3730
				$onchange = "props.setAttributes({ $key: ! props.attributes.$key } )";
3731
			} elseif ( $args['type'] == 'textarea' ) {
3732
				$type = 'TextareaControl';
3733
3734
			} elseif ( $args['type'] == 'select' || $args['type'] == 'multiselect' ) {
3735
				$type = 'SelectControl';
3736
3737
				if($args['name'] == 'category' && !empty($args['post_type_linked'])){
3738
					$options .= "options: taxonomies_".str_replace("-","_", $this->id).",";
3739
				}elseif($args['name'] == 'sort_by' && !empty($args['post_type_linked'])){
3740
					$options .= "options: sort_by_".str_replace("-","_", $this->id).",";
3741
				}else {
3742
3743
					if ( ! empty( $args['options'] ) ) {
3744
						$options .= "options: [";
3745
						foreach ( $args['options'] as $option_val => $option_label ) {
3746
							$options .= "{ value: '" . esc_attr( $option_val ) . "', label: '" . esc_js( addslashes( $option_label ) ) . "' },";
3747
						}
3748
						$options .= "],";
3749
					}
3750
				}
3751
				if ( isset( $args['multiple'] ) && $args['multiple'] ) { //@todo multiselect does not work at the moment: https://github.com/WordPress/gutenberg/issues/5550
3752
					$extra .= ' multiple:true,style:{height:"auto",paddingRight:"8px","overflow-y":"auto"}, ';
3753
				}
3754
3755
				if($args['type'] == 'multiselect' ||  ( isset( $args['multiple'] ) && $args['multiple'] ) ){
3756
					$after_elements	 .= "props.attributes.$key && el( wp.components.Button, {
3757
                                      className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3758
                                      style: {margin:'-8px 0 8px 0',display: 'block'},
3759
                                      onClick: function(){
3760
                                              return props.setAttributes({
3761
                                                  $key: '',
3762
                                                });
3763
                                    }
3764
                                    },
3765
                                    'Clear'
3766
                            ),";
3767
				}
3768
			} elseif ( $args['type'] == 'tagselect' ) {
3769
//				$type = 'FormTokenField';
3770
//
3771
//				if ( ! empty( $args['options'] ) ) {
3772
//						$options .= "suggestions: [";
3773
//						foreach ( $args['options'] as $option_val => $option_label ) {
3774
//							$options .= "{ value: '" . esc_attr( $option_val ) . "', title: '" . addslashes( $option_label ) . "' },";
3775
////							$options .= "'" . esc_attr( $option_val ) . "':'" . addslashes( $option_label ) . "',";
3776
//						}
3777
//						$options .= "],";
3778
//				}
3779
//
3780
//				$onchangex  = "{ ( selectedItems ) => {
3781
//						// Build array of selected posts.
3782
//						let selectedPostsArray = [];
3783
//						selectedPosts.map(
3784
//							( postName ) => {
3785
//								const matchingPost = posts.find( ( post ) => {
3786
//									return post.title.raw === postName;
3787
//
3788
//								} );
3789
//								if ( matchingPost !== undefined ) {
3790
//									selectedPostsArray.push( matchingPost.id );
3791
//								}
3792
//							}
3793
//						)
3794
//
3795
//						setAttributes( { selectedPosts: selectedPostsArray } );
3796
//					} } ";
3797
//				$onchange  = '';// "props.setAttributes({ $key: [ props.attributes.$key ] } )";
3798
//
3799
////				$options  = "";
3800
//				$value     = "[]";
3801
//				$extra .= ' __experimentalExpandOnFocus: true,';
3802
3803
			} else if ( $args['type'] == 'alignment' ) {
3804
				$type = 'AlignmentToolbar'; // @todo this does not seem to work but cant find a example
3805
			} else if ( $args['type'] == 'margins' ) {
3806
3807
			} else if ( $args['type'] == 'visibility_conditions' && ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) ) {
3808
				$type = 'TextControl';
3809
				$value = "(props.attributes.$key ? props.attributes.$key : '')";
3810
				$args['type'] = 'text';
3811
				$options .= 'disabled:true,';
3812
				$bsvc_title = esc_attr( addslashes( $args['title'] ) );
3813
				$bsvc_body = $this->block_visibility_fields( $args );
3814
				// @TODO reset button
3815
				$bsvc_footer = '<button type="button" class="btn btn-danger d-none">' . __( 'Reset', 'ayecode-connect' ) . '</button><button type="button" class="btn btn-secondary bs-vc-close text-white" data-bs-dismiss="modal">' . __( 'Close', 'ayecode-connect' ) . '</button><button type="button" class="btn btn-primary bs-vc-save">' . __( 'Save Rules', 'ayecode-connect' ) . '</button>';
3816
				$after_elements .= "el('div', {className: 'components-base-control bs-vc-button-wrap'}, el(wp.components.Button, {
3817
						className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3818
						onClick: function() {
3819
							var sValue = props.attributes." . $key . ";
3820
							var oValue;
3821
							try {oValue = JSON.parse(sValue);} catch(err) {}
3822
							jQuery(document).off('show.bs.modal', '.bs-vc-modal').on('show.bs.modal', '.bs-vc-modal', function (e) {
3823
								if (e.target && jQuery(e.target).hasClass('bs-vc-modal')) {
3824
									sd_block_visibility_render_fields(oValue);
3825
									if (!jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule').length) {
3826
										jQuery('.bs-vc-modal-form .bs-vc-add-rule').trigger('click');
3827
									}
3828
									if(typeof aui_init_select2 == 'function') {
3829
										aui_init_select2();
3830
									}
3831
									jQuery('.bs-vc-modal-form').trigger('change');
3832
								}
3833
							});
3834
							aui_modal('" . $bsvc_title . "', '" . addslashes( $bsvc_body ) . "', '" . $bsvc_footer . "', true, 'bs-vc-modal', 'modal-lg', '');
3835
							jQuery(document).off('change', '#bsvc_raw_value').on('change', '#bsvc_raw_value', function(e) {
3836
								props.setAttributes({" . $key . ": e.target.value});
3837
							});
3838
						}
3839
					},
3840
					'" . addslashes( ! empty( $args['button_title'] ) ? $args['button_title'] : $args['title'] ) . "'
3841
				) ),";
3842
			} else {
3843
				return;// if we have not implemented the control then don't break the JS.
3844
			}
3845
3846
			// color input does not show the labels so we add them
3847
			if($args['type']=='color'){
3848
				// add show only if advanced
3849
				echo $require_advanced;
3850
				// add setting require if defined
3851
				echo $element_require;
3852
				echo "el('div', {style: {'marginBottom': '8px'}}, '".addslashes( $args['title'] )."'),";
3853
			}
3854
3855
			// add show only if advanced
3856
			echo $require_advanced;
3857
			// add setting require if defined
3858
			echo $element_require;
3859
            echo $device_type_require;
3860
3861
			// icon
3862
			echo $icon;
3863
			?>
3864
			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...
3865
			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
3866
			} else { ?>'<?php echo addslashes( trim( esc_html( $args['title'] ) ) ); ?>'<?php } ?>,
3867
			help: <?php echo ( isset( $args['desc'] ) ? "el('span', {dangerouslySetInnerHTML: {__html: '" . trim( wp_kses_post( addslashes( $args['desc'] ) ) ) . "'}})" : "''" ); ?>,
3868
			value: <?php echo $value; ?>,
3869
			<?php if ( $type == 'TextControl' && $args['type'] != 'text' ) {
3870
				echo "type: '" . addslashes( $args['type'] ) . "',";
3871
			} ?>
3872
			<?php if ( ! empty( $args['placeholder'] ) ) {
3873
				echo "placeholder: '" . esc_js( addslashes( trim( esc_html( $args['placeholder'] ) ) ) ) . "',";
3874
			} ?>
3875
			<?php echo $options; ?>
3876
			<?php echo $extra; ?>
3877
			<?php echo $custom_attributes; ?>
3878
			<?php echo $onchangecomplete; ?>
3879
			<?php if ( $onchange ) { ?>
3880
			onChange: function ( <?php echo $key; ?> ) {
3881
				<?php echo $onchange; ?>
3882
			}
3883
			<?php } ?>
3884
		} <?php echo $inside_elements; ?> ),
3885
			<?php
3886
			echo $after_elements;
3887
		}
3888
3889
		/**
3890
		 * Convert an array of attributes to block string.
3891
		 *
3892
		 * @param $custom_attributes
3893
		 *
3894
		 * @return string
3895
		 *@todo there is prob a faster way to do this, also we could add some validation here.
3896
		 *
3897
		 */
3898
		public function array_to_attributes( $custom_attributes, $html = false ) {
3899
			$attributes = '';
3900
			if ( ! empty( $custom_attributes ) ) {
3901
3902
				foreach ( $custom_attributes as $key => $val ) {
3903
					if(is_array($val)){
3904
						$attributes .= $key.': {'.$this->array_to_attributes( $val, $html ).'},';
3905
					}else{
3906
						$attributes .= $html ?  " $key='$val' " : "'$key': '$val',";
3907
					}
3908
				}
3909
3910
			}
3911
3912
			return $attributes;
3913
		}
3914
3915
3916
3917
		/**
3918
		 * A self looping function to create the output for JS block elements.
3919
		 *
3920
		 * This is what is output in the WP Editor visual view.
3921
		 *
3922
		 * @param $args
3923
		 */
3924
		public function block_element( $args, $save = false ) {
3925
3926
3927
			if ( ! empty( $args ) ) {
3928
				foreach ( $args as $element => $new_args ) {
3929
3930
					if ( is_array( $new_args ) ) { // its an element
3931
3932
3933
						if ( isset( $new_args['element'] ) ) {
3934
3935
							if ( isset( $new_args['element_require'] ) ) {
3936
								echo str_replace( array(
3937
										"'+",
3938
										"+'"
3939
									), '', $this->block_props_replace( $new_args['element_require'] ) ) . " &&  ";
3940
								unset( $new_args['element_require'] );
3941
							}
3942
3943
                            if($new_args['element']=='InnerBlocks'){
3944
                                echo "\n el( InnerBlocks, {";
3945
                            }elseif($new_args['element']=='innerBlocksProps'){
3946
                                $element = isset($new_args['inner_element']) ? esc_attr($new_args['inner_element']) : 'div';
3947
                              //  echo "\n el( 'section', wp.blockEditor.useInnerBlocksProps( blockProps, {";
3948
//                                echo $save ? "\n el( '$element', wp.blockEditor.useInnerBlocksProps.save( " : "\n el( '$element', wp.blockEditor.useInnerBlocksProps( ";
3949
                                echo $save ? "\n el( '$element', wp.blockEditor.useInnerBlocksProps.save( " : "\n el( '$element', wp.blockEditor.useInnerBlocksProps( ";
3950
                                echo $save ? "wp.blockEditor.useBlockProps.save( {" : "wp.blockEditor.useBlockProps( {";
3951
                                echo !empty($new_args['blockProps']) ? $this->block_element( $new_args['blockProps'],$save ) : '';
3952
3953
                                echo "} ), {";
3954
                                echo !empty($new_args['innerBlocksProps']) && !$save ? $this->block_element( $new_args['innerBlocksProps'],$save ) : '';
3955
                            //    echo '###';
3956
3957
                              //  echo '###';
3958
                            }elseif($new_args['element']=='BlocksProps'){
3959
3960
								if ( isset($new_args['if_inner_element']) ) {
3961
									$element = $new_args['if_inner_element'];
3962
								}else {
3963
									$element = isset($new_args['inner_element']) ? "'".esc_attr($new_args['inner_element'])."'" : "'div'";
3964
								}
3965
3966
								unset($new_args['inner_element']);
3967
                                echo $save ? "\n el( $element, wp.blockEditor.useBlockProps.save( {" : "\n el( $element, wp.blockEditor.useBlockProps( {";
3968
                                echo !empty($new_args['blockProps']) ? $this->block_element( $new_args['blockProps'],$save ) : '';
3969
3970
3971
                               // echo "} ),";
3972
3973
                            }else{
3974
                                echo "\n el( '" . $new_args['element'] . "', {";
3975
                            }
3976
3977
3978
							// get the attributes
3979
							foreach ( $new_args as $new_key => $new_value ) {
3980
3981
3982
								if ( $new_key == 'element' || $new_key == 'content'|| $new_key == 'if_content' || $new_key == 'element_require' || $new_key == 'element_repeat' || is_array( $new_value ) ) {
3983
									// do nothing
3984
								} else {
3985
									echo $this->block_element( array( $new_key => $new_value ),$save );
3986
								}
3987
							}
3988
3989
							echo $new_args['element']=='BlocksProps' ? '} ),' : "},";// end attributes
3990
3991
							// get the content
3992
							$first_item = 0;
3993
							foreach ( $new_args as $new_key => $new_value ) {
3994
								if ( $new_key === 'content' || $new_key === 'if_content' || is_array( $new_value ) ) {
3995
3996
									if ( $new_key === 'content' ) {
3997
										echo "'" . $this->block_props_replace( wp_slash( $new_value ) ) . "'";
3998
									}else if ( $new_key === 'if_content' ) {
3999
										echo  $this->block_props_replace(  $new_value  );
4000
									}
4001
4002
									if ( is_array( $new_value ) ) {
4003
4004
										if ( isset( $new_value['element_require'] ) ) {
4005
											echo str_replace( array(
4006
													"'+",
4007
													"+'"
4008
												), '', $this->block_props_replace( $new_value['element_require'] ) ) . " &&  ";
4009
											unset( $new_value['element_require'] );
4010
										}
4011
4012
										if ( isset( $new_value['element_repeat'] ) ) {
4013
											$x = 1;
4014
											while ( $x <= absint( $new_value['element_repeat'] ) ) {
4015
												$this->block_element( array( '' => $new_value ),$save );
4016
												$x ++;
4017
											}
4018
										} else {
4019
											$this->block_element( array( '' => $new_value ),$save );
4020
										}
4021
									}
4022
									$first_item ++;
4023
								}
4024
							}
4025
4026
                            if($new_args['element']=='innerBlocksProps' || $new_args['element']=='xBlocksProps'){
4027
                                echo "))";// end content
4028
                            }else{
4029
                                echo ")";// end content
4030
                            }
4031
4032
4033
							echo ", \n";
4034
4035
						}
4036
					} else {
4037
4038
						if ( substr( $element, 0, 3 ) === "if_" ) {
4039
							$extra = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $extra is dead and can be removed.
Loading history...
4040
							if( strpos($new_args, '[%WrapClass%]') !== false ){
4041
								$new_args = str_replace('[%WrapClass%]"','" + sd_build_aui_class(props.attributes)',$new_args);
4042
								$new_args = str_replace('[%WrapClass%]','+ sd_build_aui_class(props.attributes)',$new_args);
4043
							}
4044
							echo str_replace( "if_", "", $element ) . ": " . $this->block_props_replace( $new_args, true ) . ",";
4045
						} elseif ( $element == 'style' &&  strpos($new_args, '[%WrapStyle%]') !== false ) {
4046
                            $new_args = str_replace('[%WrapStyle%]','',$new_args);
4047
                            echo $element . ": {..." . $this->block_props_replace( $new_args ) . " , ...sd_build_aui_styles(props.attributes) },";
4048
//                            echo $element . ": " . $this->block_props_replace( $new_args ) . ",";
4049
						} elseif ( $element == 'style' ) {
4050
							echo $element . ": " . $this->block_props_replace( $new_args ) . ",";
4051
						} elseif ( ( $element == 'class' || $element == 'className'  ) &&  strpos($new_args, '[%WrapClass%]') !== false ) {
4052
                            $new_args = str_replace('[%WrapClass%]','',$new_args);
4053
                            echo $element . ": '" . $this->block_props_replace( $new_args ) . "' + sd_build_aui_class(props.attributes),";
4054
						} elseif ( $element == 'template' && $new_args ) {
4055
							echo $element . ": $new_args,";
4056
						} else {
4057
							echo $element . ": '" . $this->block_props_replace( $new_args ) . "',";
4058
						}
4059
4060
					}
4061
				}
4062
			}
4063
		}
4064
4065
		/**
4066
		 * Replace block attributes placeholders with the proper naming.
4067
		 *
4068
		 * @param $string
4069
		 *
4070
		 * @return mixed
4071
		 */
4072
		public function block_props_replace( $string, $no_wrap = false ) {
4073
			if ( $no_wrap ) {
4074
				$string = str_replace( array( "[%", "%]", "%:checked]" ), array( "props.attributes.", "", "" ), $string );
4075
			} else {
4076
				$string = str_replace( array( "![%", "[%", "%]", "%:checked]" ), array( "'+!props.attributes.", "'+props.attributes.", "+'", "+'" ), $string );
4077
			}
4078
4079
			return $string;
4080
		}
4081
4082
		/**
4083
		 * Outputs the content of the widget
4084
		 *
4085
		 * @param array $args
4086
		 * @param array $instance
4087
		 */
4088
		public function widget( $args, $instance ) {
4089
			if ( ! is_array( $args ) ) {
0 ignored issues
show
introduced by
The condition is_array($args) is always true.
Loading history...
4090
				$args = array();
4091
			}
4092
4093
			// Get the filtered values
4094
			$argument_values = $this->argument_values( $instance );
4095
			$argument_values = $this->string_to_bool( $argument_values );
4096
			$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...
4097
4098
			$no_wrap = false;
4099
			if ( isset( $argument_values['no_wrap'] ) && $argument_values['no_wrap'] ) {
4100
				$no_wrap = true;
4101
			}
4102
4103
			ob_start();
4104
			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...
4105
4106
				$class_original = $this->options['widget_ops']['classname'];
4107
				$class = $this->options['widget_ops']['classname']." sdel-".$this->get_instance_hash();
4108
4109
				// Before widget
4110
				$before_widget = ! empty( $args['before_widget'] ) ? $args['before_widget'] : '';
4111
				$before_widget = $before_widget ? str_replace( $class_original, $class, $before_widget ) : $before_widget;
4112
				$before_widget = apply_filters( 'wp_super_duper_before_widget', $before_widget, $args, $instance, $this );
4113
				$before_widget = apply_filters( 'wp_super_duper_before_widget_' . $this->base_id, $before_widget, $args, $instance, $this );
4114
4115
				// After widget
4116
				$after_widget = ! empty( $args['after_widget'] ) ? $args['after_widget'] : '';
4117
				$after_widget = apply_filters( 'wp_super_duper_after_widget', $after_widget, $args, $instance, $this );
4118
				$after_widget = apply_filters( 'wp_super_duper_after_widget_' . $this->base_id, $after_widget, $args, $instance, $this );
4119
4120
				echo $before_widget;
4121
				// elementor strips the widget wrapping div so we check for and add it back if needed
4122
				if ( $this->is_elementor_widget_output() ) {
4123
					// Filter class & attrs for elementor widget output.
4124
					$class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this );
4125
					$class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this );
4126
4127
					$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...
4128
					$attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this );
4129
4130
					echo "<span class='" . esc_attr( $class  ) . "' " . $attrs . ">";
4131
				}
4132
				echo $this->output_title( $args, $instance );
4133
				echo $output;
4134
				if ( $this->is_elementor_widget_output() ) {
4135
					echo "</span>";
4136
				}
4137
				echo $after_widget;
4138
			} elseif ( $this->is_preview() && $output == '' ) {// if preview show a placeholder if empty
4139
				$output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" );
4140
				echo $output;
4141
			} 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...
4142
				echo $output;
4143
			}
4144
			$output = ob_get_clean();
4145
4146
			$output = apply_filters( 'wp_super_duper_widget_output', $output, $instance, $args, $this );
4147
4148
			echo $output;
4149
		}
4150
4151
		/**
4152
		 * Tests if the current output is inside a elementor container.
4153
		 *
4154
		 * @return bool
4155
		 *@since 1.0.4
4156
		 */
4157
		public function is_elementor_widget_output() {
4158
			$result = false;
4159
			if ( defined( 'ELEMENTOR_VERSION' ) && isset( $this->number ) && $this->number == 'REPLACE_TO_ID' ) {
4160
				$result = true;
4161
			}
4162
4163
			return $result;
4164
		}
4165
4166
		/**
4167
		 * Tests if the current output is inside a elementor preview.
4168
		 *
4169
		 * @return bool
4170
		 *@since 1.0.4
4171
		 */
4172
		public function is_elementor_preview() {
4173
			$result = false;
4174
			if ( isset( $_REQUEST['elementor-preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) || ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor_ajax' ) ) {
4175
				$result = true;
4176
			}
4177
4178
			return $result;
4179
		}
4180
4181
		/**
4182
		 * Tests if the current output is inside a Divi preview.
4183
		 *
4184
		 * @return bool
4185
		 *@since 1.0.6
4186
		 */
4187
		public function is_divi_preview() {
4188
			$result = false;
4189
			if ( isset( $_REQUEST['et_fb'] ) || isset( $_REQUEST['et_pb_preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) ) {
4190
				$result = true;
4191
			}
4192
4193
			return $result;
4194
		}
4195
4196
		/**
4197
		 * Tests if the current output is inside a Beaver builder preview.
4198
		 *
4199
		 * @return bool
4200
		 *@since 1.0.6
4201
		 */
4202
		public function is_beaver_preview() {
4203
			$result = false;
4204
			if ( isset( $_REQUEST['fl_builder'] ) ) {
4205
				$result = true;
4206
			}
4207
4208
			return $result;
4209
		}
4210
4211
		/**
4212
		 * Tests if the current output is inside a siteorigin builder preview.
4213
		 *
4214
		 * @return bool
4215
		 *@since 1.0.6
4216
		 */
4217
		public function is_siteorigin_preview() {
4218
			$result = false;
4219
			if ( ! empty( $_REQUEST['siteorigin_panels_live_editor'] ) ) {
4220
				$result = true;
4221
			}
4222
4223
			return $result;
4224
		}
4225
4226
		/**
4227
		 * Tests if the current output is inside a cornerstone builder preview.
4228
		 *
4229
		 * @return bool
4230
		 *@since 1.0.8
4231
		 */
4232
		public function is_cornerstone_preview() {
4233
			$result = false;
4234
			if ( ! empty( $_REQUEST['cornerstone_preview'] ) || basename( $_SERVER['REQUEST_URI'] ) == 'cornerstone-endpoint' ) {
4235
				$result = true;
4236
			}
4237
4238
			return $result;
4239
		}
4240
4241
		/**
4242
		 * Tests if the current output is inside a fusion builder preview.
4243
		 *
4244
		 * @return bool
4245
		 *@since 1.1.0
4246
		 */
4247
		public function is_fusion_preview() {
4248
			$result = false;
4249
			if ( ! empty( $_REQUEST['fb-edit'] ) || ! empty( $_REQUEST['fusion_load_nonce'] ) ) {
4250
				$result = true;
4251
			}
4252
4253
			return $result;
4254
		}
4255
4256
		/**
4257
		 * Tests if the current output is inside a Oxygen builder preview.
4258
		 *
4259
		 * @return bool
4260
		 *@since 1.0.18
4261
		 */
4262
		public function is_oxygen_preview() {
4263
			$result = false;
4264
			if ( ! empty( $_REQUEST['ct_builder'] ) || ( ! empty( $_REQUEST['action'] ) && ( substr( $_REQUEST['action'], 0, 11 ) === "oxy_render_" || substr( $_REQUEST['action'], 0, 10 ) === "ct_render_" ) ) ) {
4265
				$result = true;
4266
			}
4267
4268
			return $result;
4269
		}
4270
4271
		/**
4272
		 * Check for Kallyas theme Zion builder preview.
4273
		 *
4274
		 * @since 1.1.22
4275
		 *
4276
		 * @return bool True when preview page otherwise false.
4277
		 */
4278
		public function is_kallyas_zion_preview() {
4279
			$result = false;
4280
4281
			if ( function_exists( 'znhg_kallyas_theme_config' ) && ! empty( $_REQUEST['zn_pb_edit'] ) ) {
4282
				$result = true;
4283
			}
4284
4285
			return $result;
4286
		}
4287
4288
		/**
4289
		 * Check for Bricks theme builder preview.
4290
		 *
4291
		 * @since 1.1.31
4292
		 *
4293
		 * @return bool True when preview page otherwise false.
4294
		 */
4295
		public function is_bricks_preview() {
4296
			$result = false;
4297
4298
			if ( function_exists( 'bricks_is_builder' ) && ( bricks_is_builder() || bricks_is_builder_call() ) ) {
0 ignored issues
show
Bug introduced by
The function bricks_is_builder_call 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

4298
			if ( function_exists( 'bricks_is_builder' ) && ( bricks_is_builder() || /** @scrutinizer ignore-call */ bricks_is_builder_call() ) ) {
Loading history...
4299
				$result = true;
4300
			}
4301
4302
			return $result;
4303
		}
4304
4305
		/**
4306
		 * General function to check if we are in a preview situation.
4307
		 *
4308
		 * @return bool
4309
		 *@since 1.0.6
4310
		 */
4311
		public function is_preview() {
4312
			$preview = false;
4313
			if ( $this->is_divi_preview() ) {
4314
				$preview = true;
4315
			} elseif ( $this->is_elementor_preview() ) {
4316
				$preview = true;
4317
			} elseif ( $this->is_beaver_preview() ) {
4318
				$preview = true;
4319
			} elseif ( $this->is_siteorigin_preview() ) {
4320
				$preview = true;
4321
			} elseif ( $this->is_cornerstone_preview() ) {
4322
				$preview = true;
4323
			} elseif ( $this->is_fusion_preview() ) {
4324
				$preview = true;
4325
			} elseif ( $this->is_oxygen_preview() ) {
4326
				$preview = true;
4327
			} elseif( $this->is_kallyas_zion_preview() ) {
4328
				$preview = true;
4329
			} elseif( $this->is_block_content_call() ) {
4330
				$preview = true;
4331
			} elseif( $this->is_bricks_preview() ) {
4332
				$preview = true;
4333
			}
4334
4335
			return $preview;
4336
		}
4337
4338
		/**
4339
		 * Output the super title.
4340
		 *
4341
		 * @param $args
4342
		 * @param array $instance
4343
		 *
4344
		 * @return string
4345
		 */
4346
		public function output_title( $args, $instance = array() ) {
4347
			$output = '';
4348
			if ( ! empty( $instance['title'] ) ) {
4349
				/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
4350
				$title  = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
4351
4352
				if(empty($instance['widget_title_tag'])){
4353
					$output = $args['before_title'] . $title . $args['after_title'];
4354
				}else{
4355
					$title_tag = esc_attr( $instance['widget_title_tag'] );
4356
4357
					// classes
4358
					$title_classes = array();
4359
					$title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : '';
4360
					$title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : '';
4361
					$title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : '';
4362
					$title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : '';
4363
					$title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : '';
4364
					$title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : '';
4365
					$title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : '';
4366
					$title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : '';
4367
					$title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : '';
4368
					$title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : '';
4369
					$title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : '';
4370
					$title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : '';
4371
					$title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : '';
4372
4373
					$class = !empty( $title_classes ) ? implode(" ",$title_classes) : '';
4374
					$output = "<$title_tag class='$class' >$title</$title_tag>";
4375
				}
4376
4377
			}
4378
4379
			return $output;
4380
		}
4381
4382
		/**
4383
		 * Outputs the options form inputs for the widget.
4384
		 *
4385
		 * @param array $instance The widget options.
4386
		 */
4387
		public function form( $instance ) {
4388
4389
			// set widget instance
4390
			$this->instance = $instance;
4391
4392
			// set it as a SD widget
4393
			echo $this->widget_advanced_toggle();
4394
4395
			echo "<p>" . esc_attr( $this->options['widget_ops']['description'] ) . "</p>";
4396
			$arguments_raw = $this->get_arguments();
4397
4398
			if ( is_array( $arguments_raw ) ) {
0 ignored issues
show
introduced by
The condition is_array($arguments_raw) is always true.
Loading history...
4399
4400
				$arguments = $this->group_arguments( $arguments_raw );
4401
4402
				// Do we have sections?
4403
				$has_sections = $arguments == $arguments_raw ? false : true;
4404
4405
4406
				if ( $has_sections ) {
4407
					$panel_count = 0;
4408
					foreach ( $arguments as $key => $args ) {
4409
4410
						?>
4411
						<script>
4412
							//							jQuery(this).find("i").toggleClass("fas fa-chevron-up fas fa-chevron-down");jQuery(this).next().toggle();
4413
						</script>
4414
						<?php
4415
4416
						$hide       = $panel_count ? ' style="display:none;" ' : '';
4417
						$icon_class = $panel_count ? 'fas fa-chevron-up' : 'fas fa-chevron-down';
4418
						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>";
4419
						echo "<div class='sd-toggle-group sd-input-group-" . sanitize_title_with_dashes( $key ) . "' $hide>";
4420
4421
						foreach ( $args as $k => $a ) {
4422
4423
							$this->widget_inputs_row_start($k, $a);
4424
							$this->widget_inputs( $a, $instance );
4425
							$this->widget_inputs_row_end($k, $a);
4426
4427
						}
4428
4429
						echo "</div>";
4430
4431
						$panel_count ++;
4432
4433
					}
4434
				} else {
4435
					foreach ( $arguments as $key => $args ) {
4436
						$this->widget_inputs_row_start($key, $args);
4437
						$this->widget_inputs( $args, $instance );
4438
						$this->widget_inputs_row_end($key, $args);
4439
					}
4440
				}
4441
4442
			}
4443
		}
4444
4445
		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

4445
		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...
4446
			if ( ! empty( $args['row'] ) ) {
4447
				// Maybe open
4448
				if ( ! empty( $args['row']['open'] ) ) {
4449
					?>
4450
					<div class='bsui sd-argument' data-argument='<?php echo esc_attr( $args['row']['key'] ); ?>' data-element_require='<?php echo ( ! empty( $args['row']['element_require'] ) ? $this->convert_element_require( $args['row']['element_require'] ) : '' ); ?>'>
4451
					<?php if ( ! empty( $args['row']['title'] ) ) { ?>
4452
					<?php 
4453
						if ( isset( $args['row']['icon'] ) ) {
4454
							$args['row']['icon'] = '';
4455
						}
4456
4457
						if ( ! isset( $args['row']['device_type'] ) && isset( $args['device_type'] ) ) {
4458
							$args['row']['device_type'] = $args['device_type'];
4459
						}
4460
					?>
4461
					<label class="mb-0"><?php echo $this->widget_field_title( $args['row'] ); ?><?php echo $this->widget_field_desc( $args['row'] ); ?></label>
4462
					<?php } ?>
4463
					<div class='row<?php echo ( ! empty( $args['row']['class'] ) ? ' ' . esc_attr( $args['row']['class'] ) : '' ); ?>'>
4464
					<div class='col pr-2'>
4465
					<?php
4466
				} else if ( ! empty( $args['row']['close'] ) ) {
4467
					echo "<div class='col pl-0 ps-0'>";
4468
				} else {
4469
					echo "<div class='col pl-0 ps-0 pr-2 pe-2'>";
4470
				}
4471
			}
4472
		}
4473
4474
		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

4474
		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...
4475
			if ( ! empty( $args['row'] ) ) {
4476
				// Maybe close
4477
				if ( ! empty( $args['row']['close'] ) ) {
4478
					echo "</div></div>";
4479
				}
4480
				echo "</div>";
4481
			}
4482
		}
4483
4484
		/**
4485
		 * Get the hidden input that when added makes the advanced button show on widget settings.
4486
		 *
4487
		 * @return string
4488
		 */
4489
		public function widget_advanced_toggle() {
4490
4491
			$output = '';
4492
			if ( $this->block_show_advanced() ) {
4493
				$val = 1;
4494
			} else {
4495
				$val = 0;
4496
			}
4497
4498
			$output .= "<input type='hidden'  class='sd-show-advanced' value='$val' />";
4499
4500
			return $output;
4501
		}
4502
4503
		/**
4504
		 * Convert require element.
4505
		 *
4506
		 * @param string $input Input element.
4507
		 *
4508
		 * @return string $output
4509
		 *@since 1.0.0
4510
		 *
4511
		 */
4512
		public function convert_element_require( $input ) {
4513
			$input = str_replace( "'", '"', $input );// we only want double quotes
4514
4515
			$output = esc_attr( str_replace( array( "[%", "%]", "%:checked]" ), array(
4516
				"jQuery(form).find('[data-argument=\"",
4517
				"\"]').find('input,select,textarea').val()",
4518
				"\"]').find('input:checked').val()"
4519
			), $input ) );
4520
4521
			return $output;
4522
		}
4523
4524
		/**
4525
		 * Builds the inputs for the widget options.
4526
		 *
4527
		 * @param $args
4528
		 * @param $instance
4529
		 */
4530
		public function widget_inputs( $args, $instance ) {
4531
4532
			$class             = "";
4533
			$element_require   = "";
4534
			$custom_attributes = "";
4535
4536
			// get value
4537
			if ( isset( $instance[ $args['name'] ] ) ) {
4538
				$value = $instance[ $args['name'] ];
4539
			} elseif ( ! isset( $instance[ $args['name'] ] ) && ! empty( $args['default'] ) ) {
4540
				$value = is_array( $args['default'] ) ? array_map( "esc_html", $args['default'] ) : esc_html( $args['default'] );
4541
			} else {
4542
				$value = '';
4543
			}
4544
4545
			// get placeholder
4546
			if ( ! empty( $args['placeholder'] ) ) {
4547
				$placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'";
4548
			} else {
4549
				$placeholder = '';
4550
			}
4551
4552
			// get if advanced
4553
			if ( isset( $args['advanced'] ) && $args['advanced'] ) {
4554
				$class .= " sd-advanced-setting ";
4555
			}
4556
4557
			// element_require
4558
			if ( isset( $args['element_require'] ) && $args['element_require'] ) {
4559
				$element_require = $args['element_require'];
4560
			}
4561
4562
			// custom_attributes
4563
			if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) {
4564
				$custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true );
4565
			}
4566
4567
			// before wrapper
4568
			?>
4569
			<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 );} ?>'>
4570
			<?php
4571
			switch ( $args['type'] ) {
4572
				//array('text','password','number','email','tel','url','color')
4573
				case "text":
4574
				case "password":
4575
				case "number":
4576
				case "email":
4577
				case "tel":
4578
				case "url":
4579
				case "color":
4580
					?>
4581
					<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>
4582
					<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 ); ?>">
4583
					<?php
4584
4585
					break;
4586
				case "select":
4587
					$multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false;
4588
					if ( $multiple ) {
4589
						if ( empty( $value ) ) {
4590
							$value = array();
4591
						}
4592
					}
4593
					?>
4594
					<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>
4595
					<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 "[]"; } ?>"
4596
						<?php if ( $multiple ) {
4597
							echo "multiple";
4598
						} //@todo not implemented yet due to gutenberg not supporting it
4599
						?>>
4600
						<?php
4601
4602
						if ( ! empty( $args['options'] ) ) {
4603
							foreach ( $args['options'] as $val => $label ) {
4604
								if ( $multiple ) {
4605
									$selected = in_array( $val, $value ) ? 'selected="selected"' : '';
4606
								} else {
4607
									$selected = selected( $value, $val, false );
4608
								}
4609
								echo "<option value='$val' " . $selected . ">$label</option>";
4610
							}
4611
						}
4612
						?>
4613
					</select>
4614
					<?php
4615
					break;
4616
				case "checkbox":
4617
					?>
4618
					<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">
4619
					<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>
4620
					<?php
4621
					break;
4622
				case "textarea":
4623
					?>
4624
					<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>
4625
					<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>
4626
					<?php
4627
4628
					break;
4629
				case "hidden":
4630
					?>
4631
					<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 ); ?>">
4632
					<?php
4633
					break;
4634
				default:
4635
					echo "No input type found!"; // @todo we need to add more input types.
4636
			}
4637
			// after wrapper
4638
			?></p><?php
4639
		}
4640
4641
		public function get_widget_icon($icon = 'box-top', $title = ''){
4642
			if($icon=='box-top'){
4643
				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>';
4644
			}elseif($icon=='box-right'){
4645
				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>';
4646
			}elseif($icon=='box-bottom'){
4647
				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>';
4648
			}elseif($icon=='box-left'){
4649
				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>';
4650
			}
4651
		}
4652
4653
		/**
4654
		 * Get the widget input description html.
4655
		 *
4656
		 * @param $args
4657
		 *
4658
		 * @return string
4659
		 * @todo, need to make its own tooltip script
4660
		 */
4661
		public function widget_field_desc( $args ) {
4662
4663
			$description = '';
4664
			if ( isset( $args['desc'] ) && $args['desc'] ) {
4665
				if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) {
4666
					$description = $this->desc_tip( $args['desc'] );
4667
				} else {
4668
					$description = '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>';
4669
				}
4670
			}
4671
4672
			return $description;
4673
		}
4674
4675
		/**
4676
		 * Get the widget input title html.
4677
		 *
4678
		 * @param $args
4679
		 *
4680
		 * @return string
4681
		 */
4682
		public function widget_field_title( $args ) {
4683
			$title = '';
4684
4685
			if ( isset( $args['title'] ) && $args['title'] ) {
4686
				if ( ! empty( $args['device_type'] ) ) {
4687
					$args['title'] .= ' (' . $args['device_type'] . ')'; // Append device type to title.
4688
				}
4689
4690
				if ( isset( $args['icon'] ) && $args['icon'] ) {
4691
					$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

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