Passed
Push — master ( 98a9e1...506bd5 )
by Brian
07:05
created

WP_Super_Duper::widget()   C

Complexity

Conditions 14
Paths 70

Size

Total Lines 58
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 37
nc 70
nop 2
dl 0
loc 58
rs 6.2666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
if ( ! class_exists( 'WP_Super_Duper' ) ) {
7
8
	define( 'SUPER_DUPER_VER', '1.1.15' );
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 admin head
133
				add_action( 'admin_head', array( $this, 'generator' ) );
134
			}
135
136
			do_action( 'wp_super_duper_widget_init', $options, $this );
137
		}
138
139
        /**
140
         * The register widget function
141
         * @return void
142
         */
143
		public function _register() {
144
            if(empty($this->options['output_types']) || in_array('widget',$this->options['output_types'])){
145
                parent::_register();
146
			}
147
		}
148
149
		/**
150
		 * Add our widget CSS to elementor editor.
151
		 */
152
		public function elementor_editor_styles() {
153
			wp_add_inline_style( 'elementor-editor', $this->widget_css( false ) );
154
		}
155
156
		public function register_fusion_element() {
157
158
			$options = $this->options;
159
160
			if ( $this->base_id ) {
161
162
				$params = $this->get_fusion_params();
163
164
				$args = array(
165
					'name'            => $options['name'],
166
					'shortcode'       => $this->base_id,
167
					'icon'            => $options['block-icon'] ? $options['block-icon'] : 'far fa-square',
168
					'allow_generator' => true,
169
				);
170
171
				if ( ! empty( $params ) ) {
172
					$args['params'] = $params;
173
				}
174
175
				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

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

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...
1365
			}
1366
			wp_die();
1367
		}
1368
1369
		/**
1370
		 * Output the shortcode.
1371
		 *
1372
		 * @param array $args
1373
		 * @param string $content
1374
		 *
1375
		 * @return string
1376
		 */
1377
		public function shortcode_output( $args = array(), $content = '' ) {
1378
			$_instance = $args;
1379
1380
			$args = $this->argument_values( $args );
1381
1382
			// add extra argument so we know its a output to gutenberg
1383
			//$args
1384
			$args = $this->string_to_bool( $args );
1385
1386
			// if we have a enclosed shortcode we add it to the special `html` argument
1387
			if ( ! empty( $content ) ) {
1388
				$args['html'] = $content;
1389
			}
1390
1391
			if ( ! $this->is_preview() ) {
1392
				/**
1393
				 * Filters the settings for a particular widget args.
1394
				 *
1395
				 * @param array          $args      The current widget instance's settings.
1396
				 * @param WP_Super_Duper $widget    The current widget settings.
1397
				 * @param array          $_instance An array of default widget arguments.
1398
				 *
1399
				 *@since 1.0.28
1400
				 *
1401
				 */
1402
				$args = apply_filters( 'wp_super_duper_widget_display_callback', $args, $this, $_instance );
1403
1404
				if ( ! is_array( $args ) ) {
1405
					return $args;
1406
				}
1407
			}
1408
1409
			$class = isset( $this->options['widget_ops']['classname'] ) ? esc_attr( $this->options['widget_ops']['classname'] ) : '';
1410
			$class .= " sdel-".$this->get_instance_hash();
1411
1412
			$class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this );
1413
			$class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this );
1414
1415
			$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...
1416
			$attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this );
1417
1418
			$shortcode_args = array();
1419
			$output         = '';
1420
			$no_wrap        = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false;
1421
			if ( isset( $args['no_wrap'] ) && $args['no_wrap'] ) {
1422
				$no_wrap = true;
1423
			}
1424
			$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...
1425
			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...
1426
				// wrap the shortcode in a div with the same class as the widget
1427
				$output .= '<div class="' . $class . '" ' . $attrs . '>';
1428
				if ( ! empty( $args['title'] ) ) {
1429
					// if its a shortcode and there is a title try to grab the title wrappers
1430
					$shortcode_args = array( 'before_title' => '', 'after_title' => '' );
1431
					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...
1432
						global $wp_registered_sidebars;
1433
						if ( ! empty( $wp_registered_sidebars ) ) {
1434
							foreach ( $wp_registered_sidebars as $sidebar ) {
1435
								if ( ! empty( $sidebar['before_title'] ) ) {
1436
									$shortcode_args['before_title'] = $sidebar['before_title'];
1437
									$shortcode_args['after_title']  = $sidebar['after_title'];
1438
									break;
1439
								}
1440
							}
1441
						}
1442
					}
1443
					$output .= $this->output_title( $shortcode_args, $args );
1444
				}
1445
				$output .= $main_content;
1446
				$output .= '</div>';
1447
			} 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...
1448
				$output .= $main_content;
1449
			}
1450
1451
			// if preview show a placeholder if empty
1452
			if ( $this->is_preview() && $output == '' ) {
1453
				$output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" );
1454
			}
1455
1456
			return apply_filters( 'wp_super_duper_widget_output', $output, $args, $shortcode_args, $this );
1457
		}
1458
1459
		/**
1460
		 * Placeholder text to show if output is empty and we are on a preview/builder page.
1461
		 *
1462
		 * @param string $name
1463
		 *
1464
		 * @return string
1465
		 */
1466
		public function preview_placeholder_text( $name = '' ) {
1467
			return "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" . sprintf( __( 'Placeholder for: %s' ), $name ) . "</div>";
1468
		}
1469
1470
		/**
1471
		 * Sometimes booleans values can be turned to strings, so we fix that.
1472
		 *
1473
		 * @param $options
1474
		 *
1475
		 * @return mixed
1476
		 */
1477
		public function string_to_bool( $options ) {
1478
			// convert bool strings to booleans
1479
			foreach ( $options as $key => $val ) {
1480
				if ( $val == 'false' ) {
1481
					$options[ $key ] = false;
1482
				} elseif ( $val == 'true' ) {
1483
					$options[ $key ] = true;
1484
				}
1485
			}
1486
1487
			return $options;
1488
		}
1489
1490
		/**
1491
		 * Get the argument values that are also filterable.
1492
		 *
1493
		 * @param $instance
1494
		 *
1495
		 * @return array
1496
		 *@since 1.0.12 Don't set checkbox default value if the value is empty.
1497
		 *
1498
		 */
1499
		public function argument_values( $instance ) {
1500
			$argument_values = array();
1501
1502
			// set widget instance
1503
			$this->instance = $instance;
1504
1505
			if ( empty( $this->arguments ) ) {
1506
				$this->arguments = $this->get_arguments();
1507
			}
1508
1509
			if ( ! empty( $this->arguments ) ) {
1510
				foreach ( $this->arguments as $key => $args ) {
1511
					// set the input name from the key
1512
					$args['name'] = $key;
1513
					//
1514
					$argument_values[ $key ] = isset( $instance[ $key ] ) ? $instance[ $key ] : '';
1515
					if ( $args['type'] == 'checkbox' && $argument_values[ $key ] == '' ) {
1516
						// don't set default for an empty checkbox
1517
					} elseif ( $argument_values[ $key ] == '' && isset( $args['default'] ) ) {
1518
						$argument_values[ $key ] = $args['default'];
1519
					}
1520
				}
1521
			}
1522
1523
			return $argument_values;
1524
		}
1525
1526
		/**
1527
		 * Set arguments in super duper.
1528
		 *
1529
		 * @return array Set arguments.
1530
		 *@since 1.0.0
1531
		 *
1532
		 */
1533
		public function set_arguments() {
1534
			return $this->arguments;
1535
		}
1536
1537
		/**
1538
		 * Get arguments in super duper.
1539
		 *
1540
		 * @return array Get arguments.
1541
		 *@since 1.0.0
1542
		 *
1543
		 */
1544
		public function get_arguments() {
1545
			if ( empty( $this->arguments ) ) {
1546
				$this->arguments = $this->set_arguments();
1547
			}
1548
1549
			$this->arguments = apply_filters( 'wp_super_duper_arguments', $this->arguments, $this->options, $this->instance );
1550
			$this->arguments = $this->add_name_from_key( $this->arguments, true );
1551
1552
			return $this->arguments;
1553
		}
1554
1555
		/**
1556
		 * This is the main output class for all 3 items, widget, shortcode and block, it is extended in the calling class.
1557
		 *
1558
		 * @param array $args
1559
		 * @param array $widget_args
1560
		 * @param string $content
1561
		 */
1562
		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

1562
		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...
1563
1564
		}
1565
1566
		/**
1567
		 * Add the dynamic block code inline when the wp-block in enqueued.
1568
		 */
1569
		public function register_block() {
1570
			wp_add_inline_script( 'wp-blocks', $this->block() );
1571
			if ( class_exists( 'SiteOrigin_Panels' ) ) {
1572
				wp_add_inline_script( 'wp-blocks', $this->siteorigin_js() );
1573
			}
1574
		}
1575
1576
		/**
1577
		 * Check if we need to show advanced options.
1578
		 *
1579
		 * @return bool
1580
		 */
1581
		public function block_show_advanced() {
1582
1583
			$show      = false;
1584
			$arguments = $this->get_arguments();
1585
1586
			if ( ! empty( $arguments ) ) {
1587
				foreach ( $arguments as $argument ) {
1588
					if ( isset( $argument['advanced'] ) && $argument['advanced'] ) {
1589
						$show = true;
1590
						break; // no need to continue if we know we have it
1591
					}
1592
				}
1593
			}
1594
1595
			return $show;
1596
		}
1597
1598
		/**
1599
		 * Get the url path to the current folder.
1600
		 *
1601
		 * @return string
1602
		 */
1603
		public function get_url() {
1604
			$url = $this->url;
1605
1606
			if ( ! $url ) {
1607
				$content_dir = wp_normalize_path( untrailingslashit( WP_CONTENT_DIR ) );
1608
				$content_url = untrailingslashit( WP_CONTENT_URL );
1609
1610
				// Replace http:// to https://.
1611
				if ( strpos( $content_url, 'http://' ) === 0 && strpos( plugins_url(), 'https://' ) === 0 ) {
1612
					$content_url = str_replace( 'http://', 'https://', $content_url );
1613
				}
1614
1615
				// Check if we are inside a plugin
1616
				$file_dir = str_replace( "/includes", "", wp_normalize_path( dirname( __FILE__ ) ) );
1617
				$url = str_replace( $content_dir, $content_url, $file_dir );
1618
				$url = trailingslashit( $url );
1619
				$this->url = $url;
1620
			}
1621
1622
			return $url;
1623
		}
1624
1625
		/**
1626
		 * Get the url path to the current folder.
1627
		 *
1628
		 * @return string
1629
		 */
1630
		public function get_url_old() {
1631
1632
			$url = $this->url;
1633
1634
			if ( ! $url ) {
1635
				// check if we are inside a plugin
1636
				$file_dir = str_replace( "/includes", "", dirname( __FILE__ ) );
1637
1638
				$dir_parts = explode( "/wp-content/", $file_dir );
1639
				$url_parts = explode( "/wp-content/", plugins_url() );
1640
1641
				if ( ! empty( $url_parts[0] ) && ! empty( $dir_parts[1] ) ) {
1642
					$url       = trailingslashit( $url_parts[0] . "/wp-content/" . $dir_parts[1] );
1643
					$this->url = $url;
1644
				}
1645
			}
1646
1647
1648
			return $url;
1649
		}
1650
1651
		/**
1652
		 * Generate the block icon.
1653
		 *
1654
		 * Enables the use of Font Awesome icons.
1655
		 *
1656
		 * @note xlink:href is actually deprecated but href is not supported by all so we use both.
1657
		 *
1658
		 * @param $icon
1659
		 *
1660
		 * @return string
1661
		 *@since 1.1.0
1662
		 */
1663
		public function get_block_icon( $icon ) {
1664
1665
			// check if we have a Font Awesome icon
1666
			$fa_type = '';
1667
			if ( substr( $icon, 0, 7 ) === "fas fa-" ) {
1668
				$fa_type = 'solid';
1669
			} elseif ( substr( $icon, 0, 7 ) === "far fa-" ) {
1670
				$fa_type = 'regular';
1671
			} elseif ( substr( $icon, 0, 7 ) === "fab fa-" ) {
1672
				$fa_type = 'brands';
1673
			} else {
1674
				$icon = "'" . $icon . "'";
1675
			}
1676
1677
			// set the icon if we found one
1678
			if ( $fa_type ) {
1679
				$fa_icon = str_replace( array( "fas fa-", "far fa-", "fab fa-" ), "", $icon );
1680
				$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 . "'}))";
1681
			}
1682
1683
			return $icon;
1684
		}
1685
1686
		public function group_arguments( $arguments ) {
1687
//			echo '###';print_r($arguments);
1688
			if ( ! empty( $arguments ) ) {
1689
				$temp_arguments = array();
1690
				$general        = __( "General" );
1691
				$add_sections   = false;
1692
				foreach ( $arguments as $key => $args ) {
1693
					if ( isset( $args['group'] ) ) {
1694
						$temp_arguments[ $args['group'] ][ $key ] = $args;
1695
						$add_sections                             = true;
1696
					} else {
1697
						$temp_arguments[ $general ][ $key ] = $args;
1698
					}
1699
				}
1700
1701
				// only add sections if more than one
1702
				if ( $add_sections ) {
1703
					$arguments = $temp_arguments;
1704
				}
1705
			}
1706
1707
//			echo '###';print_r($arguments);
1708
			return $arguments;
1709
		}
1710
1711
1712
		/**
1713
		 * Output the JS for building the dynamic Guntenberg block.
1714
		 *
1715
		 * @return mixed
1716
		 *@since 1.0.9 Save numbers as numbers and not strings.
1717
		 * @since 1.1.0 Font Awesome classes can be used for icons.
1718
		 * @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.
1719
		 */
1720
		public function block() {
1721
            global $sd_is_js_functions_loaded, $aui_bs5;
1722
1723
			ob_start();
1724
1725
			$show_advanced = $this->block_show_advanced();
1726
1727
1728
			?>
1729
			<script>
1730
1731
			<?php
1732
			if(!$sd_is_js_functions_loaded){
1733
                $sd_is_js_functions_loaded = true;
1734
            ?>
1735
1736
function sd_show_view_options($this){
1737
	if(jQuery($this).html().length){
1738
		jQuery($this).html('');
1739
	}else{
1740
		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>');
1741
	}
1742
}
1743
1744
function sd_set_view_type($device){
1745
	wp.data.dispatch('core/edit-site') ? wp.data.dispatch('core/edit-site').__experimentalSetPreviewDeviceType($device) : wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType($device);
1746
}
1747
/**
1748
 * Try to auto-recover blocks.
1749
 */
1750
function sd_auto_recover_blocks() {
1751
	var recursivelyRecoverInvalidBlockList = blocks => {
1752
		const _blocks = [...blocks]
1753
		let recoveryCalled = false
1754
		const recursivelyRecoverBlocks = willRecoverBlocks => {
1755
			willRecoverBlocks.forEach(_block => {
1756
				if (!_block.isValid) {
1757
					recoveryCalled = true
1758
					const newBlock = recoverBlock(_block)
1759
					for (const key in newBlock) {
1760
						_block[key] = newBlock[key]
1761
					}
1762
				}
1763
				if (_block.innerBlocks.length) {
1764
					recursivelyRecoverBlocks(_block.innerBlocks)
1765
				}
1766
			})
1767
		}
1768
		recursivelyRecoverBlocks(_blocks)
1769
		return [_blocks, recoveryCalled]
1770
	}
1771
	var recoverBlock = ({ name, attributes, innerBlocks }) => wp.blocks.createBlock(name, attributes, innerBlocks);
1772
	var recoverBlocks = blocks => {
1773
		return blocks.map(_block => {
1774
			const block = _block;
1775
			// If the block is a reusable block, recover the Stackable blocks inside it.
1776
			if (_block.name === 'core/block') {
1777
				const { attributes: { ref } } = _block
1778
				const parsedBlocks = wp.blocks.parse(wp.data.select('core').getEntityRecords('postType', 'wp_block', { include: [ref] })?.[0]?.content?.raw) || []
1779
				const [recoveredBlocks, recoveryCalled] = recursivelyRecoverInvalidBlockList(parsedBlocks)
1780
				if (recoveryCalled) {
1781
					console.log('Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.');
1782
					return { blocks: recoveredBlocks, isReusable: true, ref }
1783
				}
1784
			} else if (_block.name === 'core/template-part' && _block.attributes && _block.attributes.theme) {
1785
				var tmplPart = wp.data.select('core').getEntityRecord('postType', 'wp_template_part', _block.attributes.theme + '//' + _block.attributes.slug);
1786
				var tmplPartBlocks = block.innerBlocks && block.innerBlocks.length ? block.innerBlocks : wp.blocks.parse(tmplPart?.content?.raw) || [];
1787
				if (tmplPartBlocks && tmplPartBlocks.length && tmplPartBlocks.some(block => !block.isValid)) {
1788
					block.innerBlocks = tmplPartBlocks;
1789
					block.tmplPartId = _block.attributes.theme + '//' + _block.attributes.slug;
1790
				}
1791
			}
1792
			if (block.innerBlocks && block.innerBlocks.length) {
1793
				if (block.tmplPartId) {
1794
					console.log('Template part ' + block.tmplPartId + ' block ' + block.name + ' (' + block.clientId + ') starts');
1795
				}
1796
				const newInnerBlocks = recoverBlocks(block.innerBlocks)
1797
				if (newInnerBlocks.some(block => block.recovered)) {
1798
					block.innerBlocks = newInnerBlocks
1799
					block.replacedClientId = block.clientId
1800
					block.recovered = true
1801
				}
1802
				if (block.tmplPartId) {
1803
					console.log('Template part ' + block.tmplPartId + ' block ' + block.name + ' (' + block.clientId + ') ends');
1804
				}
1805
			}
1806
			if (!block.isValid) {
1807
				const newBlock = recoverBlock(block)
1808
				newBlock.replacedClientId = block.clientId
1809
				newBlock.recovered = true
1810
				console.log('Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.');
1811
				return newBlock
1812
			}
1813
			return block
1814
		})
1815
	}
1816
	// Recover all the blocks that we can find.
1817
	var mainBlocks = recoverBlocks(wp.data.select('core/block-editor').getBlocks());
1818
	// Replace the recovered blocks with the new ones.
1819
	mainBlocks.forEach(block => {
1820
		if (block.isReusable && block.ref) {
1821
			// Update the reusable blocks.
1822
			wp.data.dispatch('core').editEntityRecord('postType', 'wp_block', block.ref, {
1823
				content: wp.blocks.serialize(block.blocks)
1824
			}).then(() => {
1825
				// But don't save them, let the user do the saving themselves. Our goal is to get rid of the block error visually.
1826
			})
1827
		}
1828
		if (block.recovered && block.replacedClientId) {
1829
			wp.data.dispatch('core/block-editor').replaceBlock(block.replacedClientId, block)
1830
		}
1831
	})
1832
}
1833
1834
// Wait will window is loaded before calling.
1835
window.onload = function() {
1836
	sd_auto_recover_blocks();
1837
	// fire a second time incase of load delays.
1838
	setTimeout(function() {
1839
		sd_auto_recover_blocks();
1840
	}, 5000);
1841
};
1842
1843
// fire when URL changes also.
1844
let lastUrl = location.href;
1845
new MutationObserver(() => {
1846
    const url = location.href;
1847
    if (url !== lastUrl) {
1848
        lastUrl = url;
1849
        sd_auto_recover_blocks();
1850
        // fire a second time incase of load delays.
1851
        setTimeout(function() {
1852
            sd_auto_recover_blocks();
1853
        }, 2000);
1854
    }
1855
}).observe(document, {
1856
    subtree: true,
1857
    childList: true
1858
});
1859
1860
1861
			/**
1862
			*
1863
* @param $args
1864
* @returns {*|{}}
1865
*/
1866
            function sd_build_aui_styles($args){
1867
1868
                $styles = {};
1869
                // background color
1870
                if ( $args['bg'] !== undefined && $args['bg'] !== '' ) {
1871
                   if( $args['bg'] == 'custom-color' ){
1872
                       $styles['background-color']=  $args['bg_color'];
1873
                   }else  if( $args['bg'] == 'custom-gradient' ){
1874
                       $styles['background-image']=  $args['bg_gradient'];
1875
1876
					    // use background on text
1877
						 if( $args['bg_on_text'] !== undefined && $args['bg_on_text'] ){
1878
							$styles['backgroundClip'] = "text";
1879
							$styles['WebkitBackgroundClip'] = "text";
1880
							$styles['text-fill-color'] = "transparent";
1881
							$styles['WebkitTextFillColor'] = "transparent";
1882
						 }
1883
                   }
1884
1885
                }
1886
1887
				let $bg_image = $args['bg_image'] !== undefined && $args['bg_image'] !== '' ? $args['bg_image'] : '';
1888
1889
				// maybe use featured image.
1890
				if( $args['bg_image_use_featured'] !== undefined && $args['bg_image_use_featured'] ){
1891
					$bg_image = '<?php echo $this->get_url();?>icons/placeholder.png';
1892
				}
1893
1894
                if( $bg_image !== undefined && $bg_image !== '' ){
1895
                    var hasImage = true
1896
                    if($styles['background-color'] !== undefined && $args['bg'] == 'custom-color'){
1897
                           $styles['background-image'] = "url("+$bg_image+")";
1898
                           $styles['background-blend-mode'] =  "overlay";
1899
                    }else if($styles['background-image'] !== undefined && $args['bg'] == 'custom-gradient'){
1900
                           $styles['background-image'] +=  ",url("+$bg_image+")";
1901
                    }else if($args['bg'] !== undefined && $args['bg'] != '' && $args['bg'] != 'transparent' ){
1902
                           // do nothing as we alreay have a preset
1903
                           hasImage = false;
1904
                    }else{
1905
                           $styles['background-image'] = "url("+$bg_image+")";
1906
                    }
1907
1908
                    if( hasImage){
1909
                         $styles['background-size'] = "cover";
1910
1911
						 if( $args['bg_image_fixed'] !== undefined && $args['bg_image_fixed'] ){
1912
							 $styles['background-attachment'] = "fixed";
1913
						 }
1914
                    }
1915
1916
                    if( hasImage && $args['bg_image_xy'].x !== undefined && $args['bg_image_xy'].x >=0 ){
1917
                          $styles['background-position'] =  ($args['bg_image_xy'].x * 100 ) + "% " + ( $args['bg_image_xy'].y * 100) + "%";
1918
                    }
1919
                }
1920
1921
1922
1923
				// sticky offset top
1924
				if( $args['sticky_offset_top'] !== undefined && $args['sticky_offset_top'] !== '' ){
1925
					$styles['top'] =  $args['sticky_offset_top'];
1926
				}
1927
1928
				// sticky offset bottom
1929
				if( $args['sticky_offset_bottom'] !== undefined && $args['sticky_offset_bottom'] !== '' ){
1930
					$styles['bottom'] =  $args['sticky_offset_bottom'];
1931
				}
1932
1933
				// font size
1934
				if( $args['font_size'] === undefined || $args['font_size'] === 'custom' ){
1935
					if( $args['font_size_custom'] !== undefined && $args['font_size_custom'] !== '' ){
1936
						$styles['fontSize'] =  $args['font_size_custom'] + "rem";
1937
					}
1938
				}
1939
1940
				// font color
1941
				if( $args['text_color'] === undefined || $args['text_color'] === 'custom' ){
1942
					if( $args['text_color_custom'] !== undefined && $args['text_color_custom'] !== '' ){
1943
						$styles['color'] =  $args['text_color_custom'];
1944
					}
1945
				}
1946
1947
				// font line height
1948
				if( $args['font_line_height'] !== undefined && $args['font_line_height'] !== '' ){
1949
					$styles['lineHeight'] =  $args['font_line_height'];
1950
				}
1951
1952
				// max height
1953
				if( $args['max_height'] !== undefined && $args['max_height'] !== '' ){
1954
					$styles['maxHeight'] =  $args['max_height'];
1955
				}
1956
1957
                return $styles;
1958
1959
            }
1960
1961
            function sd_build_aui_class($args){
1962
1963
                $classes = [];
1964
1965
				<?php
1966
				if($aui_bs5){
1967
					?>
1968
				$aui_bs5 = true;
1969
				$p_ml = 'ms-';
1970
				$p_mr = 'me-';
1971
1972
				$p_pl = 'ps-';
1973
				$p_pr = 'pe-';
1974
					<?php
1975
				}else{
1976
						?>
1977
				$aui_bs5 = false;
1978
				$p_ml = 'ml-';
1979
				$p_mr = 'mr-';
1980
1981
				$p_pl = 'pl-';
1982
				$p_pr = 'pr-';
1983
					<?php
1984
				}
1985
				?>
1986
1987
                // margins
1988
	            if ( $args['mt'] !== undefined && $args['mt'] !== '' ) { $classes.push( "mt-" + $args['mt'] );  $mt = $args['mt']; }else{$mt = null;}
1989
	            if ( $args['mr'] !== undefined && $args['mr'] !== '' ) { $classes.push( $p_mr + $args['mr'] );  $mr = $args['mr']; }else{$mr = null;}
1990
	            if ( $args['mb'] !== undefined && $args['mb'] !== '' ) { $classes.push( "mb-" + $args['mb'] );  $mb = $args['mb']; }else{$mb = null;}
1991
	            if ( $args['ml'] !== undefined && $args['ml'] !== '' ) { $classes.push( $p_ml + $args['ml'] );  $ml = $args['ml']; }else{$ml = null;}
1992
1993
                // margins tablet
1994
	            if ( $args['mt_md'] !== undefined && $args['mt_md'] !== '' ) { $classes.push( "mt-md-" + $args['mt_md'] );  $mt_md = $args['mt_md']; }else{$mt_md = null;}
1995
	            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;}
1996
	            if ( $args['mb_md'] !== undefined && $args['mb_md'] !== '' ) { $classes.push( "mb-md-" + $args['mb_md'] );  $mt_md = $args['mb_md']; }else{$mb_md = null;}
1997
	            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;}
1998
1999
                // margins desktop
2000
                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'] ); } }
2001
	            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'] ); } }
2002
	            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'] ); } }
2003
	            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'] ); } }
2004
2005
                // padding
2006
                if ( $args['pt'] !== undefined && $args['pt'] !== '' ) { $classes.push( "pt-" + $args['pt'] ); $pt = $args['pt']; }else{$pt = null;}
2007
	            if ( $args['pr'] !== undefined && $args['pr'] !== '' ) { $classes.push( $p_pr + $args['pr'] ); $pr = $args['pt']; }else{$pr = null;}
2008
	            if ( $args['pb'] !== undefined && $args['pb'] !== '' ) { $classes.push( "pb-" + $args['pb'] ); $pb = $args['pt']; }else{$pb = null;}
2009
	            if ( $args['pl'] !== undefined && $args['pl'] !== '' ) { $classes.push( $p_pl + $args['pl'] ); $pl = $args['pt']; }else{$pl = null;}
2010
2011
                // padding tablet
2012
                if ( $args['pt_md'] !== undefined && $args['pt_md'] !== '' ) { $classes.push( "pt-md-" + $args['pt_md'] ); $pt_md = $args['pt_md']; }else{$pt_md = null;}
2013
	            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;}
2014
	            if ( $args['pb_md'] !== undefined && $args['pb_md'] !== '' ) { $classes.push( "pb-md-" + $args['pb_md'] ); $pb_md = $args['pt_md']; }else{$pb_md = null;}
2015
	            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;}
2016
2017
                // padding desktop
2018
                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'] ); } }
2019
	            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'] ); } }
2020
	            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'] ); } }
2021
	            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'] ); } }
2022
2023
				// row cols, mobile, tablet, desktop
2024
	            if ( $args['row_cols'] !== undefined && $args['row_cols'] !== '' ) { $classes.push( "row-cols-" + $args['row_cols'] );  $row_cols = $args['row_cols']; }else{$row_cols = null;}
2025
	            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;}
2026
                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'] ); } }
2027
2028
				// columns , mobile, tablet, desktop
2029
	            if ( $args['col'] !== undefined && $args['col'] !== '' ) { $classes.push( "col-" + $args['col'] );  $col = $args['col']; }else{$col = null;}
2030
	            if ( $args['col_md'] !== undefined && $args['col_md'] !== '' ) { $classes.push( "col-md-" + $args['col_md'] );  $col_md = $args['col_md']; }else{$col_md = null;}
2031
                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'] ); } }
2032
2033
2034
                // border
2035
                if ( $args['border'] === undefined || $args['border']=='')  { }
2036
                else if ( $args['border'] !== undefined && ( $args['border']=='none' || $args['border']==='0') ) { $classes.push( "border-0" ); }
2037
	            else if ( $args['border'] !== undefined ) {
2038
					if($aui_bs5 && $args['border_type'] !== undefined){
2039
						$args['border_type'] = $args['border_type'].replace('-left','-start').replace('-right','-end');
2040
					}
2041
					$border_class = 'border';
2042
					if ( $args['border_type'] !== undefined && ! $args['border_type'].includes( '-0' )  ) {
2043
						$border_class = '';
2044
					}
2045
					$classes.push( $border_class + " border-" + $args['border'] );
2046
				}
2047
2048
                // border radius type
2049
              //  if ( $args['rounded'] !== undefined && $args['rounded'] !== '' ) { $classes.push($args['rounded']); }
2050
2051
                // border radius size
2052
                if( $args['rounded_size'] !== undefined && ( $args['rounded_size']==='sm' || $args['rounded_size']==='lg' ) ){
2053
					if ( $args['rounded_size'] !== undefined && $args['rounded_size'] !== '' ) {
2054
						$classes.push("rounded-" + $args['rounded_size']);
2055
						// if we set a size then we need to remove "rounded" if set
2056
						var index = $classes.indexOf("rounded");
2057
						if (index !== -1) {
2058
						  $classes.splice(index, 1);
2059
						}
2060
                	}
2061
                }else{
2062
					// rounded_size , mobile, tablet, desktop
2063
					if ( $args['rounded_size'] !== undefined && $args['rounded_size'] !== '' ) { $classes.push( "rounded-" + $args['rounded_size'] );  $rounded_size = $args['rounded_size']; }else{$rounded_size = null;}
2064
					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;}
2065
					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'] ); } }
2066
                }
2067
2068
2069
                // shadow
2070
               // if ( $args['shadow'] !== undefined && $args['shadow'] !== '' ) { $classes.push($args['shadow']); }
2071
2072
                // background
2073
                if ( $args['bg'] !== undefined  && $args['bg'] !== '' ) { $classes.push("bg-" + $args['bg']); }
2074
2075
                // text_color
2076
                if ( $args['text_color'] !== undefined && $args['text_color'] !== '' ) { $classes.push( "text-" + $args['text_color']); }
2077
2078
                // text_align
2079
                if ( $args['text_justify'] !== undefined && $args['text_justify'] ) { $classes.push('text-justify'); }
2080
                else{
2081
                    if ( $args['text_align'] !== undefined && $args['text_align'] !== '' ) {
2082
						if($aui_bs5){ $args['text_align'] = $args['text_align'].replace('-left','-start').replace('-right','-end'); }
2083
						$classes.push($args['text_align']); $text_align = $args['text_align'];
2084
					}else{$text_align = null;}
2085
                    if ( $args['text_align_md'] !== undefined && $args['text_align_md'] !== '' ) {
2086
						if($aui_bs5){ $args['text_align_md'] = $args['text_align_md'].replace('-left','-start').replace('-right','-end'); }
2087
						$classes.push($args['text_align_md']); $text_align_md = $args['text_align_md'];
2088
					}else{$text_align_md = null;}
2089
                    if ( $args['text_align_lg'] !== undefined && $args['text_align_lg'] !== '' ) {
2090
						if($aui_bs5){ $args['text_align_lg'] = $args['text_align_lg'].replace('-left','-start').replace('-right','-end'); }
2091
						if($text_align  == null && $text_align_md == null){ $classes.push($args['text_align_lg'].replace("-lg", ""));
2092
						}else{$classes.push($args['text_align_lg']);} }
2093
                }
2094
2095
				// display
2096
			  	if ( $args['display'] !== undefined && $args['display'] !== '' ) { $classes.push($args['display']); $display = $args['display']; }else{$display = null;}
2097
				if ( $args['display_md'] !== undefined && $args['display_md'] !== '' ) { $classes.push($args['display_md']); $display_md = $args['display_md']; }else{$display_md = null;}
2098
				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']);} }
2099
2100
				// bgtus - background transparent until scroll
2101
                if ( $args['bgtus'] !== undefined && $args['bgtus'] ) { $classes.push("bg-transparent-until-scroll"); }
2102
2103
				// cscos - change color scheme on scroll
2104
                if ( $args['bgtus'] !== undefined && $args['bgtus'] && $args['cscos'] !== undefined && $args['cscos'] ) { $classes.push("color-scheme-flip-on-scroll"); }
2105
2106
				// hover animations
2107
                if ( $args['hover_animations'] !== undefined && $args['hover_animations'] ) { $classes.push($args['hover_animations'].toString().replace(',',' ')); }
2108
2109
				// absolute_position
2110
				if ( $args['absolute_position'] !== undefined ) {
2111
					if ( 'top-left' === $args['absolute_position'] ) {
2112
						$classes.push('start-0 top-0');
2113
					} else if ( 'top-center' === $args['absolute_position'] ) {
2114
						$classes.push('start-50 top-0 translate-middle');
2115
					} else if ( 'top-right' === $args['absolute_position'] ) {
2116
						$classes.push('end-0 top-0');
2117
					} else if ( 'center-left' === $args['absolute_position'] ) {
2118
						$classes.push('start-0 bottom-50');
2119
					} else if ( 'center' === $args['absolute_position'] ) {
2120
						$classes.push('start-50 top-50 translate-middle');
2121
					} else if ( 'center-right' === $args['absolute_position'] ) {
2122
						$classes.push('end-0 top-50');
2123
					} else if ( 'bottom-left' === $args['absolute_position'] ) {
2124
						$classes.push('start-0 bottom-0');
2125
					} else if ( 'bottom-center' === $args['absolute_position'] ) {
2126
						$classes.push('start-50 bottom-0 translate-middle');
2127
					} else if ( 'bottom-right' === $args['absolute_position'] ) {
2128
						$classes.push('end-0 bottom-0');
2129
					}
2130
				}
2131
2132
				// build classes from build keys
2133
				$build_keys = sd_get_class_build_keys();
2134
				if ( $build_keys.length ) {
2135
					$build_keys.forEach($key => {
2136
2137
						if($key.endsWith("-MTD")){
2138
2139
							$k = $key.replace("-MTD","");
2140
2141
							// Mobile, Tablet, Desktop
2142
							if ( $args[$k] !== undefined && $args[$k] !== '' ) { $classes.push( $args[$k] );  $v = $args[$k]; }else{$v = null;}
2143
							if ( $args[$k + '_md'] !== undefined && $args[$k + '_md'] !== '' ) { $classes.push( $args[$k + '_md'] );  $v_md = $args[$k + '_md']; }else{$v_md = null;}
2144
							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'] ); } }
2145
2146
						}else{
2147
							if ( $key == 'font_size' && $args[ $key ] == 'custom' ) {
2148
							 return;
2149
							}
2150
							if ( $args[$key] !== undefined && $args[$key] !== '' ) { $classes.push($args[$key]); }
2151
						}
2152
2153
					});
2154
				}
2155
2156
                return $classes.join(" ");
2157
            }
2158
2159
			function sd_get_class_build_keys(){
2160
				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...
2161
			}
2162
2163
            <?php
2164
2165
2166
            }
2167
2168
			if(method_exists($this,'block_global_js')){
2169
					echo $this->block_global_js();
2170
			}
2171
			?>
2172
2173
jQuery(function() {
2174
2175
				/**
2176
				 * BLOCK: Basic
2177
				 *
2178
				 * Registering a basic block with Gutenberg.
2179
				 * Simple block, renders and saves the same content without any interactivity.
2180
				 *
2181
				 * Styles:
2182
				 *        editor.css — Editor styles for the block.
2183
				 *        style.css  — Editor & Front end styles for the block.
2184
				 */
2185
				(function (blocksx, elementx, blockEditor) {
2186
					var __ = wp.i18n.__; // The __() for internationalization.
2187
					var el = wp.element.createElement; // The wp.element.createElement() function to create elements.
2188
					var editable = wp.blocks.Editable;
2189
					var blocks = wp.blocks;
2190
					var registerBlockType = wp.blocks.registerBlockType; // The registerBlockType() to register blocks.
2191
					var is_fetching = false;
2192
					var prev_attributes = [];
2193
2194
                    var InnerBlocks = blockEditor.InnerBlocks;
2195
2196
					var term_query_type = '';
2197
					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 "[]";} ?>;
2198
					const taxonomies_<?php echo str_replace("-","_", $this->id);?> = [{label: "Please wait", value: 0}];
2199
					const sort_by_<?php echo str_replace("-","_", $this->id);?> = [{label: "Please wait", value: 0}];
2200
                    const MediaUpload = wp.blockEditor.MediaUpload;
2201
2202
					/**
2203
					 * Register Basic Block.
2204
					 *
2205
					 * Registers a new block provided a unique name and an object defining its
2206
					 * behavior. Once registered, the block is made available as an option to any
2207
					 * editor interface where blocks are implemented.
2208
					 *
2209
					 * @param  {string}   name     Block name.
2210
					 * @param  {Object}   settings Block settings.
2211
					 * @return {?WPBlock}          The block, if it has been successfully
2212
					 *                             registered; otherwise `undefined`.
2213
					 */
2214
					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.
2215
						apiVersion: <?php echo isset($this->options['block-api-version']) ? absint($this->options['block-api-version']) : 2 ; ?>,
2216
                        title: '<?php echo addslashes( $this->options['name'] ); ?>', // Block title.
2217
						description: '<?php echo addslashes( $this->options['widget_ops']['description'] )?>', // Block title.
2218
						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/.
2219
						supports: {
2220
							<?php
2221
							if ( isset( $this->options['block-supports'] ) ) {
2222
								echo $this->array_to_attributes( $this->options['block-supports'] );
2223
							}
2224
							?>
2225
						},
2226
						<?php
2227
						if ( isset( $this->options['block-label'] ) ) {
2228
						?>
2229
						__experimentalLabel( attributes, { context } ) {
2230
                            return <?php echo $this->options['block-label']; ?>;
2231
                        },
2232
                        <?php
2233
                        }
2234
                        ?>
2235
						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.
2236
						<?php if ( isset( $this->options['block-keywords'] ) ) {
2237
						echo "keywords : " . $this->options['block-keywords'] . ",";
2238
2239
//						// block hover preview.
2240
//						$example_args = array();
2241
//						if(!empty($this->arguments)){
2242
//							foreach($this->arguments as $key => $a_args){
2243
//								if(isset($a_args['example'])){
2244
//									$example_args[$key] = $a_args['example'];
2245
//								}
2246
//							}
2247
//						}
2248
//						$viewport_width = isset($this->options['example']['viewportWidth']) ? 'viewportWidth: '.absint($this->options['example']['viewportWidth']) : '';
2249
//						if( isset( $this->options['example'] ) && $this->options['example'] === false ){
2250
//							// no preview if set to false
2251
//						}elseif( !empty( $example_args ) ){
2252
//							echo "example : {attributes:{".$this->array_to_attributes( $example_args )."},$viewport_width},";
2253
//						}elseif( !empty( $this->options['example'] ) ){
2254
//							unset($this->options['example']['viewportWidth']);
2255
//							echo "example : {".$this->array_to_attributes( $this->options['example'] ).$viewport_width."},";
2256
//						}else{
2257
//							echo 'example : {'.$viewport_width.'},';
2258
//						}
2259
2260
                        }
2261
2262
						// maybe set no_wrap
2263
						$no_wrap = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false;
2264
						if ( isset( $this->arguments['no_wrap'] ) && $this->arguments['no_wrap'] ) {
2265
							$no_wrap = true;
2266
						}
2267
						if ( $no_wrap ) {
2268
							$this->options['block-wrap'] = '';
2269
						}
2270
2271
						// maybe load the drag/drop functions.
2272
						$img_drag_drop = false;
2273
2274
						$show_alignment = false;
2275
						// align feature
2276
						/*echo "supports: {";
2277
						echo "	align: true,";
2278
						echo "  html: false";
2279
						echo "},";*/
2280
2281
						if ( ! empty( $this->arguments ) ) {
2282
							echo "attributes : {";
2283
2284
							if ( $show_advanced ) {
2285
								echo "show_advanced: {";
2286
								echo "	type: 'boolean',";
2287
								echo "  default: false,";
2288
								echo "},";
2289
							}
2290
2291
							// block wrap element
2292
							if ( ! empty( $this->options['block-wrap'] ) ) { //@todo we should validate this?
2293
								echo "block_wrap: {";
2294
								echo "	type: 'string',";
2295
								echo "  default: '" . esc_attr( $this->options['block-wrap'] ) . "',";
2296
								echo "},";
2297
							}
2298
2299
2300
2301
							foreach ( $this->arguments as $key => $args ) {
2302
2303
								if( $args['type'] == 'image' ||  $args['type'] == 'images' ){
2304
									$img_drag_drop = true;
2305
								}
2306
2307
								// set if we should show alignment
2308
								if ( $key == 'alignment' ) {
2309
									$show_alignment = true;
2310
								}
2311
2312
								$extra = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $extra is dead and can be removed.
Loading history...
2313
2314
								if ( $args['type'] == 'notice' ||  $args['type'] == 'tab' ) {
2315
									continue;
2316
								}
2317
								elseif ( $args['type'] == 'checkbox' ) {
2318
									$type    = 'boolean';
2319
									$default = isset( $args['default'] ) && $args['default'] ? 'true' : 'false';
2320
								} elseif ( $args['type'] == 'number' ) {
2321
									$type    = 'number';
2322
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2323
								} elseif ( $args['type'] == 'select' && ! empty( $args['multiple'] ) ) {
2324
									$type = 'array';
2325
									if ( isset( $args['default'] ) && is_array( $args['default'] ) ) {
2326
										$default = ! empty( $args['default'] ) ? "['" . implode( "','", $args['default'] ) . "']" : "[]";
2327
									} else {
2328
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2329
									}
2330
								} elseif ( $args['type'] == 'tagselect' ) {
2331
									$type    = 'array';
2332
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2333
								} elseif ( $args['type'] == 'multiselect' ) {
2334
									$type    = 'array';
2335
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2336
								} elseif ( $args['type'] == 'image_xy' ) {
2337
									$type    = 'object';
2338
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2339
								} elseif ( $args['type'] == 'image' ) {
2340
									$type    = 'string';
2341
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2342
2343
                                    // add a field for ID
2344
//                                    echo $key . "_id : {";
2345
//                                    echo "type : 'number',";
2346
//                                    echo "},";
2347
//                                    echo $key . "_xy : {";
2348
//                                    echo "type : 'object',";
2349
//                                    echo "},";
2350
2351
								} else {
2352
									$type    = !empty($args['hidden_type']) ? esc_attr($args['hidden_type']) : 'string';
2353
									$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2354
2355
								}
2356
								echo $key . " : {";
2357
								echo "type : '$type',";
2358
								echo "default : $default,";
2359
								echo "},";
2360
							}
2361
2362
							echo "content : {type : 'string',default: 'Please select the attributes in the block settings'},";
2363
							echo "className: { type: 'string', default: '' },";
2364
2365
							echo "},";
2366
2367
						}
2368
2369
						?>
2370
2371
						// The "edit" property must be a valid function.
2372
						edit: function (props) {
2373
2374
2375
<?php
2376
// only include the drag/drop functions if required.
2377
if( $img_drag_drop ){
2378
2379
?>
2380
2381
function enableDragSort(listClass) {
2382
	setTimeout(function(){
2383
		 const sortableLists = document.getElementsByClassName(listClass);
2384
		 Array.prototype.map.call(sortableLists, (list) => {enableDragList(list)});
2385
	}, 300);
2386
}
2387
2388
function enableDragList(list) {
2389
  Array.prototype.map.call(list.children, (item) => {enableDragItem(item)});
2390
}
2391
2392
function enableDragItem(item) {
2393
  item.setAttribute('draggable', true)
2394
  item.ondrag = handleDrag;
2395
  item.ondragend = handleDrop;
2396
}
2397
2398
function handleDrag(item) {
2399
  const selectedItem = item.target,
2400
        list = selectedItem.parentNode,
2401
        x = event.clientX,
2402
        y = event.clientY;
2403
2404
  selectedItem.classList.add('drag-sort-active');
2405
  let swapItem = document.elementFromPoint(x, y) === null ? selectedItem : document.elementFromPoint(x, y);
2406
2407
  if (list === swapItem.parentNode) {
2408
    swapItem = swapItem !== selectedItem.nextSibling ? swapItem : swapItem.nextSibling;
2409
    list.insertBefore(selectedItem, swapItem);
2410
  }
2411
}
2412
2413
function handleDrop(item) {
2414
2415
	item.target.classList.remove('drag-sort-active');
2416
2417
	const newOrder = [];
2418
	let $parent = item.target.parentNode;
2419
	let $field = $parent.dataset.field;
2420
	let $imgs = JSON.parse('[' + props.attributes[$field] + ']');
2421
	item.target.parentNode.classList.add('xxx');
2422
	$children = $parent.children;
2423
2424
	Object.keys($children).forEach(function(key) {
2425
	  let $nKey = $children[key].dataset.index
2426
	  newOrder.push($imgs[$nKey]);
2427
	});
2428
2429
	// @todo find out why we need to empty the value first otherwise the order is wrong.
2430
	props.setAttributes({ [$field]: '' });
2431
	setTimeout(function(){
2432
		props.setAttributes({ [$field]: JSON.stringify(newOrder).replace('[','').replace(']','') });
2433
	}, 100);
2434
2435
}
2436
<?php } ?>
2437
2438
							if (typeof(props.attributes.styleid) !== 'undefined'){
2439
								if(props.attributes.styleid==''){ props.setAttributes({ 'styleid': 'block-'+(Math.random() + 1).toString(36).substring(2) } ); }
2440
							}
2441
2442
                            <?php
2443
                            if(!empty($this->options['block-edit-raw'])) {
2444
                                echo $this->options['block-edit-raw']; // strings have to be in single quotes, may cause issues
2445
                            }else{
2446
                            ?>
2447
2448
function hasSelectedInnerBlock(props) {
2449
    const select = wp.data.select('core/editor');
2450
    const selected = select.getBlockSelectionStart();
2451
    const inner = select.getBlock(props.clientId).innerBlocks;
2452
    for (let i = 0; i < inner.length; i++) {
2453
        if (inner[i].clientId === selected || inner[i].innerBlocks.length && hasSelectedInnerBlock(inner[i])) {
2454
            return true;
2455
        }
2456
    }
2457
    return false;
2458
};
2459
2460
const parentBlocksIDs = wp.data.select( 'core/block-editor' ).getBlockParents(props.clientId);
2461
const parentBlocks = wp.data.select('core/block-editor').getBlocksByClientId(parentBlocksIDs);
2462
// const isParentOfSelectedBlock = useSelect( ( select ) => wp.data.select( 'core/block-editor' ).hasSelectedInnerBlock( props.clientId, true ) ):
2463
    const block = wp.data.select('core/block-editor').getBlocksByClientId(props.clientId);//.[0].innerBlocks;
2464
    const childBlocks = block[0].innerBlocks;
2465
2466
	var $value = '';
2467
	<?php
2468
	// if we have a post_type and a category then link them
2469
	if( isset($this->arguments['post_type']) && isset($this->arguments['category']) && !empty($this->arguments['category']['post_type_linked']) ){
2470
	?>
2471
	if(typeof(prev_attributes[props.clientId]) != 'undefined'){
2472
		$pt = props.attributes.post_type;
2473
		if(post_type_rest_slugs.length){
2474
			$value = post_type_rest_slugs[0][$pt];
2475
		}
2476
		var run = false;
2477
2478
		if($pt != term_query_type){
2479
			run = true;
2480
			term_query_type = $pt;
2481
		}
2482
<?php
2483
	$cat_path = '';
2484
	if ( ! empty( $this->arguments['post_type']['onchange_rest']['path'] ) ) {
2485
		$cat_path = esc_js( strip_tags( $this->arguments['post_type']['onchange_rest']['path'] ) );
2486
		$cat_path = str_replace( array( '&quot;', '&#039;' ), array( '"', "'" ), $cat_path );
2487
	}
2488
?>
2489
		/* taxonomies */
2490
		if($value && 'post_type' in prev_attributes[props.clientId] && 'category' in prev_attributes[props.clientId] && run){
2491
			if (!window.gdCPTCats) {
2492
				window.gdCPTCats = [];
2493
			}
2494
			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...
2495
			if (window.gdCPTCats[gdCatPath]) {
2496
				terms = window.gdCPTCats[gdCatPath];
2497
				while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2498
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2499
				}
2500
				taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2501
				jQuery.each( terms, function( key, val ) {
2502
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2503
				});
2504
2505
				/* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2506
				var $old_cat_value = props.attributes.category
2507
				props.setAttributes({category: [0] });
2508
				props.setAttributes({category: $old_cat_value });
2509
			} else {
2510
				wp.apiFetch({path: gdCatPath}).then(terms => {
2511
					window.gdCPTCats[gdCatPath] = terms;
2512
					while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2513
						taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2514
					}
2515
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2516
					jQuery.each( terms, function( key, val ) {
2517
						taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2518
					});
2519
2520
					/* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2521
					var $old_cat_value = props.attributes.category
2522
					props.setAttributes({category: [0] });
2523
					props.setAttributes({category: $old_cat_value });
2524
2525
					return taxonomies_<?php echo str_replace("-","_", $this->id);?>;
2526
				});
2527
			}
2528
		}
2529
2530
		/* sort_by */
2531
		if($value && 'post_type' in prev_attributes[props.clientId] && 'sort_by' in prev_attributes[props.clientId] && run){
2532
			if (!window.gdCPTSort) {
2533
				window.gdCPTSort = [];
2534
			}
2535
			if (window.gdCPTSort[$pt]) {
2536
				response = window.gdCPTSort[$pt];
2537
				while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2538
					sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2539
				}
2540
2541
				jQuery.each( response, function( key, val ) {
2542
					sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2543
				});
2544
2545
				// setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2546
				var $old_sort_by_value = props.attributes.sort_by
2547
				props.setAttributes({sort_by: [0] });
2548
				props.setAttributes({sort_by: $old_sort_by_value });
2549
			} else {
2550
				var data = {
2551
					'action': 'geodir_get_sort_options',
2552
					'post_type': $pt
2553
				};
2554
				jQuery.post(ajaxurl, data, function(response) {
2555
					response = JSON.parse(response);
2556
					window.gdCPTSort[$pt] = response;
2557
					while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2558
						sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2559
					}
2560
2561
					jQuery.each( response, function( key, val ) {
2562
						sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2563
					});
2564
2565
					// setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2566
					var $old_sort_by_value = props.attributes.sort_by
2567
					props.setAttributes({sort_by: [0] });
2568
					props.setAttributes({sort_by: $old_sort_by_value });
2569
2570
					return sort_by_<?php echo str_replace("-","_", $this->id);?>;
2571
				});
2572
			}
2573
		}
2574
	}
2575
	<?php } ?>
2576
<?php
2577
$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...
2578
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...
2579
	echo 'const { deviceType } = "";';
2580
}else{
2581
?>
2582
/** Get device type const. */
2583
const { deviceType } = wp.data.useSelect != 'undefined' ?  wp.data.useSelect(select => {
2584
	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
2585
	return {
2586
		deviceType: __experimentalGetPreviewDeviceType(),
2587
	}
2588
}, []) : '';
2589
<?php } ?>
2590
							var content = props.attributes.content;
2591
2592
							function onChangeContent($type) {
2593
// console.log(deviceType);
2594
								$refresh = false;
2595
								// Set the old content the same as the new one so we only compare all other attributes
2596
								if(typeof(prev_attributes[props.clientId]) != 'undefined'){
2597
									prev_attributes[props.clientId].content = props.attributes.content;
2598
								}else if(props.attributes.content === ""){
2599
									// if first load and content empty then refresh
2600
									$refresh = true;
2601
								}
2602
2603
								if ( ( !is_fetching &&  JSON.stringify(prev_attributes[props.clientId]) != JSON.stringify(props.attributes) ) || $refresh  ) {
2604
2605
									is_fetching = true;
2606
2607
									var data = {
2608
										'action': 'super_duper_output_shortcode',
2609
										'shortcode': '<?php echo $this->options['base_id'];?>',
2610
										'attributes': props.attributes,
2611
										'block_parent_name': parentBlocks.length ? parentBlocks[parentBlocks.length - 1].name : '',
2612
										'post_id': <?php global $post; if ( isset( $post->ID ) ) {
2613
										echo $post->ID;
2614
									}else{echo '0';}?>,
2615
										'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>'
2616
									};
2617
2618
									jQuery.post(ajaxurl, data, function (response) {
2619
										return response;
2620
									}).then(function (env) {
2621
2622
										// if the content is empty then we place some placeholder text
2623
										if (env == '') {
2624
											env = "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" + "<?php _e( 'Placeholder for: ' );?>" + props.name + "</div>";
2625
										}
2626
2627
                                         <?php
2628
                                        if(!empty($this->options['nested-block'])){
2629
                                            ?>
2630
                                            // props.setAttributes({content: env});
2631
										is_fetching = false;
2632
										prev_attributes[props.clientId] = props.attributes;
2633
                                             <?php
2634
                                        }else{
2635
                                        ?>
2636
                                        props.setAttributes({content: env});
2637
										is_fetching = false;
2638
										prev_attributes[props.clientId] = props.attributes;
2639
                                        <?php
2640
                                        }
2641
                                        ?>
2642
2643
2644
										// if AUI is active call the js init function
2645
										if (typeof aui_init === "function") {
2646
											aui_init();
2647
										}
2648
									});
2649
2650
2651
								}
2652
2653
2654
								return props.attributes.content;
2655
2656
							}
2657
2658
                            <?php
2659
                            if(!empty($this->options['block-edit-js'])) {
2660
                                echo  $this->options['block-edit-js'] ; // strings have to be in single quotes, may cause issues
2661
                            }
2662
2663
2664
2665
                            ?>
2666
2667
2668
2669
							return [
2670
2671
								el(wp.blockEditor.BlockControls, {key: 'controls'},
2672
2673
									<?php if($show_alignment){?>
2674
									el(
2675
										wp.blockEditor.AlignmentToolbar,
2676
										{
2677
											value: props.attributes.alignment,
2678
											onChange: function (alignment) {
2679
												props.setAttributes({alignment: alignment})
2680
											}
2681
										}
2682
									)
2683
									<?php }?>
2684
2685
								),
2686
2687
								el(wp.blockEditor.InspectorControls, {key: 'inspector'},
2688
2689
									<?php
2690
2691
									if(! empty( $this->arguments )){
2692
2693
									if ( $show_advanced ) {
2694
									?>
2695
									el('div', {
2696
											style: {'padding-left': '16px','padding-right': '16px'}
2697
										},
2698
										el(
2699
											wp.components.ToggleControl,
2700
											{
2701
												label: 'Show Advanced Settings?',
2702
												checked: props.attributes.show_advanced,
2703
												onChange: function (show_advanced) {
2704
													props.setAttributes({show_advanced: !props.attributes.show_advanced})
2705
												}
2706
											}
2707
										)
2708
									)
2709
									,
2710
									<?php
2711
2712
									}
2713
2714
								//	print_r( $this->arguments);
2715
2716
									//echo '####';
2717
2718
									$arguments = $this->group_arguments( $this->arguments );
2719
//print_r($arguments ); exit;
2720
									// Do we have sections?
2721
									$has_sections = $arguments == $this->arguments ? false : true;
2722
2723
2724
									if($has_sections){
2725
									$panel_count = 0;
2726
									$open_tab = '';
2727
2728
									$open_tab_groups = array();
2729
									$used_tabs = array();
2730
									foreach($arguments as $key => $args){
2731
2732
										$close_tab = false;
2733
										$close_tabs = false;
2734
2735
										 if(!empty($this->options['block_group_tabs'])) {
2736
											foreach($this->options['block_group_tabs'] as $tab_name => $tab_args){
2737
												if(in_array($key,$tab_args['groups'])){
2738
2739
													$open_tab_groups[] = $key;
2740
2741
													if($open_tab != $tab_name){
2742
														$tab_args['tab']['tabs_open'] = $open_tab == '' ? true : false;
2743
														$tab_args['tab']['open'] = true;
2744
2745
														$this->block_tab_start( '', $tab_args );
2746
//														echo '###open'.$tab_name;print_r($tab_args);
2747
														$open_tab = $tab_name;
2748
														$used_tabs[] = $tab_name;
2749
													}
2750
2751
													if($open_tab_groups == $tab_args['groups']){
2752
														//$open_tab = '';
2753
														$close_tab = true;
2754
														$open_tab_groups = array();
2755
2756
//													print_r(array_keys($this->options['block_group_tabs']));echo '####';print_r($used_tabs);
2757
													if($used_tabs == array_keys($this->options['block_group_tabs'])){
2758
//														echo '@@@';
2759
															$close_tabs = true;
2760
														}
2761
													}
2762
2763
												}
2764
											}
2765
										}
2766
2767
//
2768
2769
									//	print_r($arguments);exit;
2770
2771
										?>
2772
										el(wp.components.PanelBody, {
2773
												title: '<?php esc_attr_e( $key ); ?>',
2774
												initialOpen: <?php if ( $panel_count ) {
2775
												echo "false";
2776
											} else {
2777
												echo "true";
2778
											}?>
2779
											},
2780
											<?php
2781
2782
2783
2784
											foreach ( $args as $k => $a ) {
2785
2786
												$this->block_tab_start( $k, $a );
2787
												$this->block_row_start( $k, $a );
2788
												$this->build_block_arguments( $k, $a );
2789
												$this->block_row_end( $k, $a );
2790
												$this->block_tab_end( $k, $a );
2791
											}
2792
											?>
2793
										),
2794
										<?php
2795
										$panel_count ++;
2796
2797
2798
										if($close_tab || $close_tabs){
2799
											$tab_args = array(
2800
												'tab'	=> array(
2801
													'tabs_close' => $close_tabs,
2802
												'close' => true,
2803
												)
2804
2805
											);
2806
											$this->block_tab_end( '', $tab_args );
2807
//											echo '###close'; print_r($tab_args);
2808
											$panel_count = 0;
2809
										}
2810
//
2811
2812
									}
2813
									}else {
2814
									?>
2815
									el(wp.components.PanelBody, {
2816
											title: '<?php esc_attr_e( "Settings" ); ?>',
2817
											initialOpen: true
2818
										},
2819
										<?php
2820
										foreach ( $this->arguments as $key => $args ) {
2821
											$this->block_row_start( $key, $args );
2822
											$this->build_block_arguments( $key, $args );
2823
											$this->block_row_end( $key, $args );
2824
										}
2825
										?>
2826
									),
2827
									<?php
2828
									}
2829
2830
									}
2831
									?>
2832
2833
								),
2834
2835
								<?php
2836
								// If the user sets block-output array then build it
2837
								if ( ! empty( $this->options['block-output'] ) ) {
2838
								$this->block_element( $this->options['block-output'] );
2839
							}elseif(!empty($this->options['block-edit-return'])){
2840
                                   echo $this->options['block-edit-return'];
2841
							}else{
2842
								// if no block-output is set then we try and get the shortcode html output via ajax.
2843
								$block_edit_wrap_tag = !empty($this->options['block_edit_wrap_tag']) ? esc_attr($this->options['block_edit_wrap_tag']) : 'div';
2844
								?>
2845
								el('<?php echo esc_attr($block_edit_wrap_tag); ?>', wp.blockEditor.useBlockProps({
2846
									dangerouslySetInnerHTML: {__html: onChangeContent()},
2847
									className: props.className,
2848
									style: {'minHeight': '30px'}
2849
								}))
2850
								<?php
2851
								}
2852
								?>
2853
							]; // end return
2854
2855
							<?php
2856
                            } // end block-edit-raw else
2857
                            ?>
2858
						},
2859
2860
						// The "save" property must be specified and must be a valid function.
2861
						save: function (props) {
2862
2863
							var attr = props.attributes;
2864
							var align = '';
2865
2866
							// build the shortcode.
2867
							var content = "[<?php echo $this->options['base_id'];?>";
2868
							$html = '';
2869
							<?php
2870
2871
							if(! empty( $this->arguments )){
2872
2873
							foreach($this->arguments as $key => $args){
2874
                               // if($args['type']=='tabs'){continue;}
2875
							?>
2876
							if (attr.hasOwnProperty("<?php echo esc_attr( $key );?>")) {
2877
								if ('<?php echo esc_attr( $key );?>' == 'html') {
2878
									$html = attr.<?php echo esc_attr( $key );?>;
2879
								} else if ('<?php echo esc_attr( $args['type'] );?>' == 'image_xy') {
2880
									content += " <?php echo esc_attr( $key );?>='{x:" + attr.<?php echo esc_attr( $key );?>.x + ",y:"+attr.<?php echo esc_attr( $key );?>.y +"}' ";
2881
								} else {
2882
									content += " <?php echo esc_attr( $key );?>='" + attr.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' ";
2883
								}
2884
							}
2885
							<?php
2886
							}
2887
							}
2888
2889
							?>
2890
							content += "]";
2891
2892
                            <?php
2893
//                            if(!empty($this->options['nested-block'])){
2894
//                                ?>
2895
//                                $html = 'el( InnerBlocks.Content )';
2896
//                                <?php
2897
//                            }
2898
                            ?>
2899
							// if has html element
2900
							if ($html) {
2901
								content += $html + "[/<?php echo $this->options['base_id'];?>]";
2902
							}
2903
2904
							// @todo should we add inline style here or just css classes?
2905
							if (attr.alignment) {
2906
								if (attr.alignment == 'left') {
2907
									align = 'alignleft';
2908
								}
2909
								if (attr.alignment == 'center') {
2910
									align = 'aligncenter';
2911
								}
2912
								if (attr.alignment == 'right') {
2913
									align = 'alignright';
2914
								}
2915
							}
2916
2917
							<?php
2918
//							if(!empty($this->options['nested-block'])){
2919
//                                ?x>
2920
//                              return el(
2921
//                                    'div',
2922
//                                    { className: props.className,
2923
//                                        style: {'minHeight': '300px','position':'relative','overflow':'hidden','backgroundImage': 'url(https://s.w.org/images/core/5.5/don-quixote-06.jpg)'}
2924
//                                    },
2925
//                                    el( InnerBlocks.Content ),
2926
//                                    el('div', {dangerouslySetInnerHTML: {__html: content}, className: align})
2927
//                                );
2928
//                                <x?php
2929
//							}else
2930
2931
                            if(!empty($this->options['block-output'])){
2932
//                               echo "return";
2933
//                               $this->block_element( $this->options['block-output'], true );
2934
//                               echo ";";
2935
2936
                               ?>
2937
                              return el(
2938
                                   '',
2939
                                   {},
2940
                                   el('', {dangerouslySetInnerHTML: {__html: content}}),
2941
                                   <?php $this->block_element( $this->options['block-output'], true ); ?>
2942
                                   el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
2943
                               );
2944
                                <?php
2945
2946
							}elseif(!empty($this->options['block-save-return'])){
2947
                                   echo 'return ' . $this->options['block-save-return'];
2948
							}elseif(!empty($this->options['nested-block'])){
2949
                                ?>
2950
                              return el(
2951
                                   '',
2952
                                   {},
2953
                                   el('', {dangerouslySetInnerHTML: {__html: content+"\n"}}),
2954
                                   InnerBlocks.Content ? el( InnerBlocks.Content ) : '', // @todo i think we need a comma here
2955
                                   el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
2956
                               );
2957
                                <?php
2958
							}elseif(!empty( $this->options['block-save-return'] ) ){
2959
                                echo "return ". $this->options['block-edit-return'].";";
2960
							}elseif(isset( $this->options['block-wrap'] ) && $this->options['block-wrap'] == ''){
2961
							?>
2962
							return content;
2963
							<?php
2964
							}else{
2965
							?>
2966
							var block_wrap = 'div';
2967
							if (attr.hasOwnProperty("block_wrap")) {
2968
								block_wrap = attr.block_wrap;
2969
							}
2970
							return el(block_wrap, wp.blockEditor.useBlockProps.save( {dangerouslySetInnerHTML: {__html: content}, className: align} ));
2971
							<?php
2972
							}
2973
							?>
2974
2975
2976
						}
2977
					});
2978
				})(
2979
                    window.wp.blocks,
2980
    window.wp.element,
2981
    window.wp.blockEditor
2982
				);
2983
2984
                });
2985
			</script>
2986
			<?php
2987
			$output = ob_get_clean();
2988
2989
			/*
2990
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
2991
			 */
2992
2993
			return str_replace( array(
2994
				'<script>',
2995
				'</script>'
2996
			), '', $output );
2997
		}
2998
2999
3000
3001
		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

3001
		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...
3002
3003
			// check for row
3004
			if(!empty($args['row'])){
3005
3006
				if(!empty($args['row']['open'])){
3007
3008
				// element require
3009
				$element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3010
                $device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3011
                $device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3012
                $device_type_icon = '';
3013
                if($device_type=='Desktop'){
3014
                    $device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3015
                }elseif($device_type=='Tablet'){
3016
                    $device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3017
                }elseif($device_type=='Mobile'){
3018
                    $device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3019
                }
3020
				echo $element_require;
3021
                echo $device_type_require;
3022
3023
					if(false){?><script><?php }?>
3024
						el('div', {
3025
								className: 'bsui components-base-control',
3026
							},
3027
							<?php if(!empty($args['row']['title'])){ ?>
3028
							el('label', {
3029
									className: 'components-base-control__label position-relative',
3030
									style: {width:"100%"}
3031
								},
3032
								el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['row']['title'] ) ?>'}}),
3033
								<?php if($device_type_icon){ ?>
3034
                                    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)"}})
3035
								<?php
3036
                                }
3037
                                ?>
3038
3039
3040
							),
3041
							<?php }?>
3042
							<?php if(!empty($args['row']['desc'])){ ?>
3043
							el('p', {
3044
									className: 'components-base-control__help mb-0',
3045
								},
3046
								'<?php echo addslashes( $args['row']['desc'] ); ?>'
3047
							),
3048
							<?php }?>
3049
							el(
3050
								'div',
3051
								{
3052
									className: 'row mb-n2 <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>',
3053
								},
3054
								el(
3055
									'div',
3056
									{
3057
										className: 'col pr-2 pe-2',
3058
									},
3059
3060
					<?php
3061
					if(false){?></script><?php }
3062
				}elseif(!empty($args['row']['close'])){
3063
					if(false){?><script><?php }?>
3064
						el(
3065
							'div',
3066
							{
3067
								className: 'col pl-0 ps-0',
3068
							},
3069
					<?php
3070
					if(false){?></script><?php }
3071
				}else{
3072
					if(false){?><script><?php }?>
3073
						el(
3074
							'div',
3075
							{
3076
								className: 'col pl-0 ps-0 pr-2 pe-2',
3077
							},
3078
					<?php
3079
					if(false){?></script><?php }
3080
				}
3081
3082
			}
3083
3084
		}
3085
3086
		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

3086
		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...
3087
3088
			if(!empty($args['row'])){
3089
				// maybe close
3090
				if(!empty($args['row']['close'])){
3091
					echo "))";
3092
				}
3093
3094
				echo "),";
3095
			}
3096
		}
3097
3098
		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

3098
		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...
3099
3100
			// check for row
3101
			if(!empty($args['tab'])){
3102
3103
				if(!empty($args['tab']['tabs_open'])){
3104
3105
					if(false){?><script><?php }?>
3106
3107
el('div',{className: 'bsui'},
3108
3109
						el('hr', {className: 'm-0'}), el(
3110
									wp.components.TabPanel,
3111
									{
3112
                                        activeClass: 'is-active',
3113
                                        className: 'btn-groupx',
3114
                                        initialTabName: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3115
										tabs: [
3116
3117
					<?php
3118
					if(false){?></script><?php }
3119
				}
3120
3121
				if(!empty($args['tab']['open'])){
3122
3123
					if(false){?><script><?php }?>
3124
							{
3125
												name: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3126
												title: el('div', {dangerouslySetInnerHTML: {__html: '<?php echo addslashes( esc_attr( $args['tab']['title']) ); ?>'}}),
3127
												className: '<?php echo addslashes( esc_attr( $args['tab']['class']) ); ?>',
3128
												content: el('div',{}, <?php if(!empty($args['tab']['desc'])){ ?>el('p', {
3129
									className: 'components-base-control__help mb-0',
3130
									dangerouslySetInnerHTML: {__html:'<?php echo addslashes( $args['tab']['desc'] ); ?>'}
3131
								}),<?php }
3132
					if(false){?></script><?php }
3133
				}
3134
3135
			}
3136
3137
		}
3138
3139
		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

3139
		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...
3140
3141
			if(!empty($args['tab'])){
3142
				// maybe close
3143
				if(!empty($args['tab']['close'])){
3144
					echo ")}, /* tab close */";
3145
				}
3146
3147
				if(!empty($args['tab']['tabs_close'])){
3148
					if(false){?><script><?php }?>
3149
							],
3150
									},
3151
									( tab ) => {
3152
3153
									return tab.content;
3154
3155
								}
3156
								)), /* tabs close */
3157
					<?php if(false){ ?></script><?php }
3158
				}
3159
			}
3160
		}
3161
3162
		public function build_block_arguments( $key, $args ) {
3163
			$custom_attributes = ! empty( $args['custom_attributes'] ) ? $this->array_to_attributes( $args['custom_attributes'] ) : '';
3164
			$options           = '';
3165
			$extra             = '';
3166
			$require           = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $require is dead and can be removed.
Loading history...
3167
            $inside_elements   = '';
3168
			$after_elements	   = '';
3169
3170
			// `content` is a protected and special argument
3171
			if ( $key == 'content' ) {
3172
				return;
3173
			}
3174
3175
            $device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3176
            $device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3177
            $device_type_icon = '';
3178
            if($device_type=='Desktop'){
3179
                $device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3180
            }elseif($device_type=='Tablet'){
3181
                $device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3182
            }elseif($device_type=='Mobile'){
3183
                $device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3184
            }
3185
3186
			// icon
3187
			$icon = '';
3188
			if( !empty( $args['icon'] ) ){
3189
				$icon .= "el('div', {";
3190
									$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

3190
									$icon .= "dangerouslySetInnerHTML: {__html: '".self::/** @scrutinizer ignore-call */ get_widget_icon( esc_attr($args['icon']))."'},";
Loading history...
3191
									$icon .= "className: 'text-center',";
3192
									$icon .= "title: '".addslashes( $args['title'] )."',";
3193
								$icon .= "}),";
3194
3195
				// blank title as its added to the icon.
3196
				$args['title'] = '';
3197
			}
3198
3199
			// require advanced
3200
			$require_advanced = ! empty( $args['advanced'] ) ? "props.attributes.show_advanced && " : "";
3201
3202
			// element require
3203
			$element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3204
3205
3206
			$onchange  = "props.setAttributes({ $key: $key } )";
3207
			$onchangecomplete  = "";
3208
			$value     = "props.attributes.$key";
3209
			$text_type = array( 'text', 'password', 'number', 'email', 'tel', 'url', 'colorx','range' );
3210
			if ( in_array( $args['type'], $text_type ) ) {
3211
				$type = 'TextControl';
3212
				// Save numbers as numbers and not strings
3213
				if ( $args['type'] == 'number' ) {
3214
					$onchange = "props.setAttributes({ $key: $key ? Number($key) : '' } )";
3215
				}
3216
			}else if ( $args['type'] == 'styleid' ) {
3217
				$type = 'TextControl';
3218
				$args['type'] == 'text';
3219
				// Save numbers as numbers and not strings
3220
				$value     = "props.attributes.$key ? props.attributes.$key : 'aaabbbccc'";
3221
			}else if ( $args['type'] == 'notice' ) {
3222
3223
				$notice_message = !empty($args['desc']) ? addslashes($args['desc']) : '';
3224
				$notice_status = !empty($args['status']) ? esc_attr($args['status']) : 'info';
3225
3226
				$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'}}))),";
3227
				echo $notice_message ? $element_require . $notice : '';
3228
				return;
3229
			}
3230
			/*
3231
			 * https://www.wptricks.com/question/set-current-tab-on-a-gutenberg-tabpanel-component-from-outside-that-component/ es5 layout
3232
						elseif($args['type']=='tabs'){
3233
							?>
3234
								el(
3235
									wp.components.TabPanel,
3236
									{
3237
                                        activeClass: 'active-tab',
3238
                                        initialTabName: deviceType,
3239
										tabs: [
3240
											{
3241
												name: 'Desktop',
3242
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-desktop"></i>'}}),
3243
												className: 'tab-one' + deviceType == 'Desktop' ? ' active-tab' : '',
3244
												content: el('div', {dangerouslySetInnerHTML: {__html: 'ddd'}})
3245
											},
3246
											{
3247
												name: 'Tablet',
3248
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-tablet-alt"></i>'}}),
3249
												className: 'tab-two' + deviceType == 'Tablet' ? ' active-tab' : '',
3250
												content: el('div', {dangerouslySetInnerHTML: {__html: 'ttt'}})
3251
											},
3252
											{
3253
												name: 'Mobile',
3254
												title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-mobile-alt"></i>'}}),
3255
												className: 'tab-two' + deviceType == 'Mobile' ? ' active-tab' : '',
3256
												content: el('div', {dangerouslySetInnerHTML: {__html: 'mmm'}})
3257
											},
3258
										],
3259
									},
3260
									( tab ) => {
3261
3262
// @todo https://github.com/WordPress/gutenberg/issues/39248
3263
									if(tab.name=='Desktop'){
3264
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Desktop');
3265
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3266
									}else if(tab.name=='Tablet'){
3267
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Tablet');
3268
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3269
									}else if(tab.name=='Mobile'){
3270
									wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Mobile');
3271
wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3272
									}
3273
3274
									return tab.content;
3275
3276
								}
3277
								),
3278
3279
							<?php
3280
							return;
3281
						}
3282
*/
3283
			elseif ( $args['type'] == 'color' ) {
3284
				$type = 'ColorPicker';
3285
				$onchange = "";
3286
				$extra = "color: $value,";
3287
				if(!empty($args['disable_alpha'])){
3288
					$extra .= "disableAlpha: true,";
3289
				}
3290
				$onchangecomplete = "onChangeComplete: function($key) {
3291
				value =  $key.rgb.a && $key.rgb.a < 1 ? \"rgba(\"+$key.rgb.r+\",\"+$key.rgb.g+\",\"+$key.rgb.b+\",\"+$key.rgb.a+\")\" : $key.hex;
3292
                        props.setAttributes({
3293
                            $key: value
3294
                        });
3295
                    },";
3296
			}elseif ( $args['type'] == 'gradient' ) {
3297
				$type = 'GradientPicker';
3298
3299
			}elseif ( $args['type'] == 'image' ) {
3300
//                print_r($args);
3301
3302
                $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,{
3303
                            url:  props.attributes.{$key}_use_featured === true ? '".$this->get_url()."icons/placeholder.png'  : props.attributes.$key,
3304
                            value: props.attributes.{$key}_xy.x !== undefined && props.attributes.{$key}_xy.x >= 0 ? props.attributes.{$key}_xy  : {x: 0.5,y: 0.5,},
3305
//                            value: props.attributes.{$key}_xy,
3306
                            onChange: function(focalPoint){
3307
                            console.log(props.attributes);
3308
                                              return props.setAttributes({
3309
                                                  {$key}_xy: focalPoint
3310
                                                });
3311
                                    },
3312
                                    // @todo for some reason this does not work as expected.
3313
//                         onDrag: function(focalPointTemp){
3314
//                                  return props.setAttributes({
3315
//                                      {$key}_xy: focalPointTemp
3316
//                                    });
3317
//                        }
3318
3319
3320
                        }), ";
3321
3322
3323
                $value = '""';
3324
				$type = 'MediaUpload';
3325
                $extra .= "onSelect: function(media){
3326
                      return props.setAttributes({
3327
                          $key: media.url,
3328
                          {$key}_id: media.id
3329
                        });
3330
                      },";
3331
                   $extra .= "type: 'image',";
3332
                   $extra .= "render: function (obj) {
3333
                        return el( 'div',{},
3334
                        ( !props.attributes.$key && !props.attributes.{$key}_use_featured ) && el( wp.components.Button, {
3335
                          className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3336
                          onClick: obj.open
3337
                        },
3338
                        'Upload Image'
3339
                        ),
3340
                       $img_preview
3341
                        props.attributes.$key && el( wp.components.Button, {
3342
                                      className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3343
                                      style: {margin:'8px 0',display: 'block'},
3344
                                      onClick: function(){
3345
                                              return props.setAttributes({
3346
                                                  $key: '',
3347
                                                  {$key}_id: ''
3348
                                                });
3349
                                    }
3350
                                    },
3351
                                    props.attributes.$key? 'Clear' : ''
3352
                            )
3353
                       )
3354
3355
3356
3357
                      }";
3358
                $onchange = "";
3359
3360
                //$inside_elements = ",el('div',{},'file upload')";
3361
			}elseif ( $args['type'] == 'images' ) {
3362
				//                print_r($args);
3363
3364
                $img_preview = "props.attributes.$key && (function() {
3365
3366
                        let uploads = JSON.parse('['+props.attributes.$key+']');
3367
						let images = [];
3368
                      uploads.map((upload, index) => (
3369
3370
							images.push( el('div',{className: 'col p-2',draggable: 'true','data-index': index}, el('img', { src: upload.sizes.thumbnail.url,style: {maxWidth:'100%',background: '#ccc',pointerEvents:'none'}}),el('i',{
3371
							className: 'fas fa-times-circle text-danger position-absolute  ml-n2 mt-n1 bg-white rounded-circle c-pointer',
3372
							onClick: function(){
3373
							    aui_confirm('".esc_attr__('Are you sure?')."', '".esc_attr__('Delete')."', '".esc_attr__('Cancel')."', true).then(function(confirmed) {
3374
if (confirmed) {
3375
											let new_uploads = JSON.parse('['+props.attributes.$key+']');
3376
											new_uploads.splice(index, 1); //remove
3377
                                              return props.setAttributes({
3378
                                                  {$key}: JSON.stringify( new_uploads ).replace('[','').replace(']',''),
3379
                                                });
3380
                                                }
3381
                                           });
3382
                                    }},'') ) )
3383
						));
3384
3385
3386
						return images;
3387
})(),";
3388
3389
3390
                $value = '""';
3391
				$type = 'MediaUpload';
3392
                $extra .= "onSelect: function(media){
3393
3394
                let slim_images = props.attributes.$key ? JSON.parse('['+props.attributes.$key+']') : [];
3395
				if(media.length){
3396
						for (var i=0; i < media.length; i++) {
3397
							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});
3398
						}
3399
				}
3400
3401
                      return props.setAttributes({
3402
                          $key: JSON.stringify(slim_images).replace('[','').replace(']',''),
3403
                        });
3404
                      },";
3405
                   $extra .= "type: 'image',";
3406
                   $extra .= "multiple: true,";
3407
                   $extra .= "render: function (obj) {
3408
3409
                   // init the sort
3410
				enableDragSort('sd-sortable');
3411
                        return el( 'div',{},
3412
                        el( wp.components.Button, {
3413
                          className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3414
                          onClick: obj.open
3415
                        },
3416
                        'Upload Images'
3417
                        ),
3418
3419
3420
						el('div',{className: 'row row-cols-3 px-2 sd-sortable','data-field':'$key'},
3421
3422
                       $img_preview
3423
3424
                       ),
3425
                        props.attributes.$key && el( wp.components.Button, {
3426
                                      className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3427
                                      style: {margin:'8px 0'},
3428
                                      onClick: function(){
3429
                                              return props.setAttributes({
3430
                                                  $key: '',
3431
                                                });
3432
                                    }
3433
                                    },
3434
                                    props.attributes.$key? 'Clear All' : ''
3435
                            )
3436
                       )
3437
3438
3439
3440
3441
3442
                      }";
3443
                $onchange = "";
3444
3445
                //$inside_elements = ",el('div',{},'file upload')";
3446
			}
3447
			elseif ( $args['type'] == 'checkbox' ) {
3448
				$type = 'CheckboxControl';
3449
				$extra .= "checked: props.attributes.$key,";
3450
				$onchange = "props.setAttributes({ $key: ! props.attributes.$key } )";
3451
			} elseif ( $args['type'] == 'textarea' ) {
3452
				$type = 'TextareaControl';
3453
3454
			} elseif ( $args['type'] == 'select' || $args['type'] == 'multiselect' ) {
3455
				$type = 'SelectControl';
3456
3457
				if($args['name'] == 'category' && !empty($args['post_type_linked'])){
3458
					$options .= "options: taxonomies_".str_replace("-","_", $this->id).",";
3459
				}elseif($args['name'] == 'sort_by' && !empty($args['post_type_linked'])){
3460
					$options .= "options: sort_by_".str_replace("-","_", $this->id).",";
3461
				}else {
3462
3463
					if ( ! empty( $args['options'] ) ) {
3464
						$options .= "options: [";
3465
						foreach ( $args['options'] as $option_val => $option_label ) {
3466
							$options .= "{ value: '" . esc_attr( $option_val ) . "', label: '" . addslashes( $option_label ) . "' },";
3467
						}
3468
						$options .= "],";
3469
					}
3470
				}
3471
				if ( isset( $args['multiple'] ) && $args['multiple'] ) { //@todo multiselect does not work at the moment: https://github.com/WordPress/gutenberg/issues/5550
3472
					$extra .= ' multiple:true,style:{height:"auto",paddingRight:"8px","overflow-y":"auto"}, ';
3473
				}
3474
3475
				if($args['type'] == 'multiselect' ||  ( isset( $args['multiple'] ) && $args['multiple'] ) ){
3476
					$after_elements	 .= "props.attributes.$key && el( wp.components.Button, {
3477
                                      className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3478
                                      style: {margin:'-8px 0 8px 0',display: 'block'},
3479
                                      onClick: function(){
3480
                                              return props.setAttributes({
3481
                                                  $key: '',
3482
                                                });
3483
                                    }
3484
                                    },
3485
                                    'Clear'
3486
                            ),";
3487
				}
3488
			} elseif ( $args['type'] == 'tagselect' ) {
3489
//				$type = 'FormTokenField';
3490
//
3491
//				if ( ! empty( $args['options'] ) ) {
3492
//						$options .= "suggestions: [";
3493
//						foreach ( $args['options'] as $option_val => $option_label ) {
3494
//							$options .= "{ value: '" . esc_attr( $option_val ) . "', title: '" . addslashes( $option_label ) . "' },";
3495
////							$options .= "'" . esc_attr( $option_val ) . "':'" . addslashes( $option_label ) . "',";
3496
//						}
3497
//						$options .= "],";
3498
//				}
3499
//
3500
//				$onchangex  = "{ ( selectedItems ) => {
3501
//						// Build array of selected posts.
3502
//						let selectedPostsArray = [];
3503
//						selectedPosts.map(
3504
//							( postName ) => {
3505
//								const matchingPost = posts.find( ( post ) => {
3506
//									return post.title.raw === postName;
3507
//
3508
//								} );
3509
//								if ( matchingPost !== undefined ) {
3510
//									selectedPostsArray.push( matchingPost.id );
3511
//								}
3512
//							}
3513
//						)
3514
//
3515
//						setAttributes( { selectedPosts: selectedPostsArray } );
3516
//					} } ";
3517
//				$onchange  = '';// "props.setAttributes({ $key: [ props.attributes.$key ] } )";
3518
//
3519
////				$options  = "";
3520
//				$value     = "[]";
3521
//				$extra .= ' __experimentalExpandOnFocus: true,';
3522
3523
			} elseif ( $args['type'] == 'alignment' ) {
3524
				$type = 'AlignmentToolbar'; // @todo this does not seem to work but cant find a example
3525
			}elseif ( $args['type'] == 'margins' ) {
3526
3527
			} else {
3528
				return;// if we have not implemented the control then don't break the JS.
3529
			}
3530
3531
3532
3533
			// color input does not show the labels so we add them
3534
			if($args['type']=='color'){
3535
				// add show only if advanced
3536
				echo $require_advanced;
3537
				// add setting require if defined
3538
				echo $element_require;
3539
				echo "el('div', {style: {'marginBottom': '8px'}}, '".addslashes( $args['title'] )."'),";
3540
			}
3541
3542
			// add show only if advanced
3543
			echo $require_advanced;
3544
			// add setting require if defined
3545
			echo $element_require;
3546
            echo $device_type_require;
3547
3548
			// icon
3549
			echo $icon;
3550
			?>
3551
			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...
3552
			label: <?php
3553
			if(empty($args['title'])){
3554
                echo "''";
3555
			}elseif(empty($args['row']) && !empty($args['device_type'])){
3556
                ?>el('label', {
3557
									className: 'components-base-control__label',
3558
									style: {width:"100%"}
3559
								},
3560
								el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['title'] ) ?>'}}),
3561
								<?php if($device_type_icon){ ?>
3562
                                    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)"}})
3563
								<?php
3564
                                }
3565
                                ?>
3566
3567
3568
							)<?php
3569
3570
			}else{
3571
                 ?>'<?php echo addslashes( $args['title'] ); ?>'<?php
3572
3573
			}
3574
3575
			?>,
3576
			help: <?php if ( isset( $args['desc'] ) ) {
3577
				echo "el('span',{dangerouslySetInnerHTML: {__html: '".wp_kses_post( addslashes($args['desc']) )."'}})";
3578
			}else{ echo "''"; } ?>,
3579
			value: <?php echo $value; ?>,
3580
			<?php if ( $type == 'TextControl' && $args['type'] != 'text' ) {
3581
				echo "type: '" . addslashes( $args['type'] ) . "',";
3582
			} ?>
3583
			<?php if ( ! empty( $args['placeholder'] ) ) {
3584
				echo "placeholder: '" . addslashes( $args['placeholder'] ) . "',";
3585
			} ?>
3586
			<?php echo $options; ?>
3587
			<?php echo $extra; ?>
3588
			<?php echo $custom_attributes; ?>
3589
			<?php echo $onchangecomplete;
3590
            if($onchange){
3591
            ?>
3592
			onChange: function ( <?php echo $key; ?> ) {
3593
			<?php echo $onchange; ?>
3594
			}
3595
			<?php }?>
3596
			} <?php echo $inside_elements; ?> ),
3597
			<?php
3598
			echo $after_elements;
3599
3600
		}
3601
3602
		/**
3603
		 * Convert an array of attributes to block string.
3604
		 *
3605
		 * @param $custom_attributes
3606
		 *
3607
		 * @return string
3608
		 *@todo there is prob a faster way to do this, also we could add some validation here.
3609
		 *
3610
		 */
3611
		public function array_to_attributes( $custom_attributes, $html = false ) {
3612
			$attributes = '';
3613
			if ( ! empty( $custom_attributes ) ) {
3614
3615
				foreach ( $custom_attributes as $key => $val ) {
3616
					if(is_array($val)){
3617
						$attributes .= $key.': {'.$this->array_to_attributes( $val, $html ).'},';
3618
					}else{
3619
						$attributes .= $html ?  " $key='$val' " : "'$key': '$val',";
3620
					}
3621
				}
3622
3623
			}
3624
3625
			return $attributes;
3626
		}
3627
3628
3629
3630
		/**
3631
		 * A self looping function to create the output for JS block elements.
3632
		 *
3633
		 * This is what is output in the WP Editor visual view.
3634
		 *
3635
		 * @param $args
3636
		 */
3637
		public function block_element( $args, $save = false ) {
3638
3639
3640
			if ( ! empty( $args ) ) {
3641
				foreach ( $args as $element => $new_args ) {
3642
3643
					if ( is_array( $new_args ) ) { // its an element
3644
3645
3646
						if ( isset( $new_args['element'] ) ) {
3647
3648
							if ( isset( $new_args['element_require'] ) ) {
3649
								echo str_replace( array(
3650
										"'+",
3651
										"+'"
3652
									), '', $this->block_props_replace( $new_args['element_require'] ) ) . " &&  ";
3653
								unset( $new_args['element_require'] );
3654
							}
3655
3656
                            if($new_args['element']=='InnerBlocks'){
3657
                                echo "\n el( InnerBlocks, {";
3658
                            }elseif($new_args['element']=='innerBlocksProps'){
3659
                                $element = isset($new_args['inner_element']) ? esc_attr($new_args['inner_element']) : 'div';
3660
                              //  echo "\n el( 'section', wp.blockEditor.useInnerBlocksProps( blockProps, {";
3661
//                                echo $save ? "\n el( '$element', wp.blockEditor.useInnerBlocksProps.save( " : "\n el( '$element', wp.blockEditor.useInnerBlocksProps( ";
3662
                                echo $save ? "\n el( '$element', wp.blockEditor.useInnerBlocksProps.save( " : "\n el( '$element', wp.blockEditor.useInnerBlocksProps( ";
3663
                                echo $save ? "wp.blockEditor.useBlockProps.save( {" : "wp.blockEditor.useBlockProps( {";
3664
                                echo !empty($new_args['blockProps']) ? $this->block_element( $new_args['blockProps'],$save ) : '';
3665
3666
                                echo "} ), {";
3667
                                echo !empty($new_args['innerBlocksProps']) && !$save ? $this->block_element( $new_args['innerBlocksProps'],$save ) : '';
3668
                            //    echo '###';
3669
3670
                              //  echo '###';
3671
                            }elseif($new_args['element']=='BlocksProps'){
3672
3673
								if ( isset($new_args['if_inner_element']) ) {
3674
									$element = $new_args['if_inner_element'];
3675
								}else {
3676
									$element = isset($new_args['inner_element']) ? "'".esc_attr($new_args['inner_element'])."'" : "'div'";
3677
								}
3678
3679
								unset($new_args['inner_element']);
3680
                                echo $save ? "\n el( $element, wp.blockEditor.useBlockProps.save( {" : "\n el( $element, wp.blockEditor.useBlockProps( {";
3681
                                echo !empty($new_args['blockProps']) ? $this->block_element( $new_args['blockProps'],$save ) : '';
3682
3683
3684
                               // echo "} ),";
3685
3686
                            }else{
3687
                                echo "\n el( '" . $new_args['element'] . "', {";
3688
                            }
3689
3690
3691
							// get the attributes
3692
							foreach ( $new_args as $new_key => $new_value ) {
3693
3694
3695
								if ( $new_key == 'element' || $new_key == 'content'|| $new_key == 'if_content' || $new_key == 'element_require' || $new_key == 'element_repeat' || is_array( $new_value ) ) {
3696
									// do nothing
3697
								} else {
3698
									echo $this->block_element( array( $new_key => $new_value ),$save );
3699
								}
3700
							}
3701
3702
							echo $new_args['element']=='BlocksProps' ? '} ),' : "},";// end attributes
3703
3704
							// get the content
3705
							$first_item = 0;
3706
							foreach ( $new_args as $new_key => $new_value ) {
3707
								if ( $new_key === 'content' || $new_key === 'if_content' || is_array( $new_value ) ) {
3708
3709
									if ( $new_key === 'content' ) {
3710
										echo "'" . $this->block_props_replace( wp_slash( $new_value ) ) . "'";
3711
									}else if ( $new_key === 'if_content' ) {
3712
										echo  $this->block_props_replace(  $new_value  );
3713
									}
3714
3715
									if ( is_array( $new_value ) ) {
3716
3717
										if ( isset( $new_value['element_require'] ) ) {
3718
											echo str_replace( array(
3719
													"'+",
3720
													"+'"
3721
												), '', $this->block_props_replace( $new_value['element_require'] ) ) . " &&  ";
3722
											unset( $new_value['element_require'] );
3723
										}
3724
3725
										if ( isset( $new_value['element_repeat'] ) ) {
3726
											$x = 1;
3727
											while ( $x <= absint( $new_value['element_repeat'] ) ) {
3728
												$this->block_element( array( '' => $new_value ),$save );
3729
												$x ++;
3730
											}
3731
										} else {
3732
											$this->block_element( array( '' => $new_value ),$save );
3733
										}
3734
									}
3735
									$first_item ++;
3736
								}
3737
							}
3738
3739
                            if($new_args['element']=='innerBlocksProps' || $new_args['element']=='xBlocksProps'){
3740
                                echo "))";// end content
3741
                            }else{
3742
                                echo ")";// end content
3743
                            }
3744
3745
3746
							echo ", \n";
3747
3748
						}
3749
					} else {
3750
3751
						if ( substr( $element, 0, 3 ) === "if_" ) {
3752
							$extra = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $extra is dead and can be removed.
Loading history...
3753
							if( strpos($new_args, '[%WrapClass%]') !== false ){
3754
								$new_args = str_replace('[%WrapClass%]"','" + sd_build_aui_class(props.attributes)',$new_args);
3755
								$new_args = str_replace('[%WrapClass%]','+ sd_build_aui_class(props.attributes)',$new_args);
3756
							}
3757
							echo str_replace( "if_", "", $element ) . ": " . $this->block_props_replace( $new_args, true ) . ",";
3758
						} elseif ( $element == 'style' &&  strpos($new_args, '[%WrapStyle%]') !== false ) {
3759
                            $new_args = str_replace('[%WrapStyle%]','',$new_args);
3760
                            echo $element . ": {..." . $this->block_props_replace( $new_args ) . " , ...sd_build_aui_styles(props.attributes) },";
3761
//                            echo $element . ": " . $this->block_props_replace( $new_args ) . ",";
3762
						} elseif ( $element == 'style' ) {
3763
							echo $element . ": " . $this->block_props_replace( $new_args ) . ",";
3764
						} elseif ( ( $element == 'class' || $element == 'className'  ) &&  strpos($new_args, '[%WrapClass%]') !== false ) {
3765
                            $new_args = str_replace('[%WrapClass%]','',$new_args);
3766
                            echo $element . ": '" . $this->block_props_replace( $new_args ) . "' + sd_build_aui_class(props.attributes),";
3767
						} elseif ( $element == 'template' && $new_args ) {
3768
							echo $element . ": $new_args,";
3769
						} else {
3770
							echo $element . ": '" . $this->block_props_replace( $new_args ) . "',";
3771
						}
3772
3773
					}
3774
				}
3775
			}
3776
		}
3777
3778
		/**
3779
		 * Replace block attributes placeholders with the proper naming.
3780
		 *
3781
		 * @param $string
3782
		 *
3783
		 * @return mixed
3784
		 */
3785
		public function block_props_replace( $string, $no_wrap = false ) {
3786
3787
			if ( $no_wrap ) {
3788
				$string = str_replace( array( "[%", "%]" ), array( "props.attributes.", "" ), $string );
3789
			} else {
3790
				$string = str_replace( array( "[%", "%]" ), array( "'+props.attributes.", "+'" ), $string );
3791
			}
3792
3793
			return $string;
3794
		}
3795
3796
		/**
3797
		 * Outputs the content of the widget
3798
		 *
3799
		 * @param array $args
3800
		 * @param array $instance
3801
		 */
3802
		public function widget( $args, $instance ) {
3803
3804
			// get the filtered values
3805
			$argument_values = $this->argument_values( $instance );
3806
			$argument_values = $this->string_to_bool( $argument_values );
3807
			$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...
3808
3809
			$no_wrap = false;
3810
			if ( isset( $argument_values['no_wrap'] ) && $argument_values['no_wrap'] ) {
3811
				$no_wrap = true;
3812
			}
3813
3814
			ob_start();
3815
			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...
3816
3817
				$class_original = $this->options['widget_ops']['classname'];
3818
				$class = $this->options['widget_ops']['classname']." sdel-".$this->get_instance_hash();
3819
3820
				// Before widget
3821
				$before_widget = ! empty( $args['before_widget'] ) ? $args['before_widget'] : '';
3822
				$before_widget = $before_widget ? str_replace( $class_original, $class, $before_widget ) : $before_widget;
3823
				$before_widget = apply_filters( 'wp_super_duper_before_widget', $before_widget, $args, $instance, $this );
3824
				$before_widget = apply_filters( 'wp_super_duper_before_widget_' . $this->base_id, $before_widget, $args, $instance, $this );
3825
3826
				// After widget
3827
				$after_widget = ! empty( $args['after_widget'] ) ? $args['after_widget'] : '';
3828
				$after_widget = apply_filters( 'wp_super_duper_after_widget', $after_widget, $args, $instance, $this );
3829
				$after_widget = apply_filters( 'wp_super_duper_after_widget_' . $this->base_id, $after_widget, $args, $instance, $this );
3830
3831
				echo $before_widget;
3832
				// elementor strips the widget wrapping div so we check for and add it back if needed
3833
				if ( $this->is_elementor_widget_output() ) {
3834
					// Filter class & attrs for elementor widget output.
3835
					$class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this );
3836
					$class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this );
3837
3838
					$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...
3839
					$attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this );
3840
3841
					echo "<span class='" . esc_attr( $class  ) . "' " . $attrs . ">";
3842
				}
3843
				echo $this->output_title( $args, $instance );
3844
				echo $output;
3845
				if ( $this->is_elementor_widget_output() ) {
3846
					echo "</span>";
3847
				}
3848
				echo $after_widget;
3849
			} elseif ( $this->is_preview() && $output == '' ) {// if preview show a placeholder if empty
3850
				$output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" );
3851
				echo $output;
3852
			} 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...
3853
				echo $output;
3854
			}
3855
			$output = ob_get_clean();
3856
3857
			$output = apply_filters( 'wp_super_duper_widget_output', $output, $instance, $args, $this );
3858
3859
			echo $output;
3860
		}
3861
3862
		/**
3863
		 * Tests if the current output is inside a elementor container.
3864
		 *
3865
		 * @return bool
3866
		 *@since 1.0.4
3867
		 */
3868
		public function is_elementor_widget_output() {
3869
			$result = false;
3870
			if ( defined( 'ELEMENTOR_VERSION' ) && isset( $this->number ) && $this->number == 'REPLACE_TO_ID' ) {
3871
				$result = true;
3872
			}
3873
3874
			return $result;
3875
		}
3876
3877
		/**
3878
		 * Tests if the current output is inside a elementor preview.
3879
		 *
3880
		 * @return bool
3881
		 *@since 1.0.4
3882
		 */
3883
		public function is_elementor_preview() {
3884
			$result = false;
3885
			if ( isset( $_REQUEST['elementor-preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) || ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor_ajax' ) ) {
3886
				$result = true;
3887
			}
3888
3889
			return $result;
3890
		}
3891
3892
		/**
3893
		 * Tests if the current output is inside a Divi preview.
3894
		 *
3895
		 * @return bool
3896
		 *@since 1.0.6
3897
		 */
3898
		public function is_divi_preview() {
3899
			$result = false;
3900
			if ( isset( $_REQUEST['et_fb'] ) || isset( $_REQUEST['et_pb_preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) ) {
3901
				$result = true;
3902
			}
3903
3904
			return $result;
3905
		}
3906
3907
		/**
3908
		 * Tests if the current output is inside a Beaver builder preview.
3909
		 *
3910
		 * @return bool
3911
		 *@since 1.0.6
3912
		 */
3913
		public function is_beaver_preview() {
3914
			$result = false;
3915
			if ( isset( $_REQUEST['fl_builder'] ) ) {
3916
				$result = true;
3917
			}
3918
3919
			return $result;
3920
		}
3921
3922
		/**
3923
		 * Tests if the current output is inside a siteorigin builder preview.
3924
		 *
3925
		 * @return bool
3926
		 *@since 1.0.6
3927
		 */
3928
		public function is_siteorigin_preview() {
3929
			$result = false;
3930
			if ( ! empty( $_REQUEST['siteorigin_panels_live_editor'] ) ) {
3931
				$result = true;
3932
			}
3933
3934
			return $result;
3935
		}
3936
3937
		/**
3938
		 * Tests if the current output is inside a cornerstone builder preview.
3939
		 *
3940
		 * @return bool
3941
		 *@since 1.0.8
3942
		 */
3943
		public function is_cornerstone_preview() {
3944
			$result = false;
3945
			if ( ! empty( $_REQUEST['cornerstone_preview'] ) || basename( $_SERVER['REQUEST_URI'] ) == 'cornerstone-endpoint' ) {
3946
				$result = true;
3947
			}
3948
3949
			return $result;
3950
		}
3951
3952
		/**
3953
		 * Tests if the current output is inside a fusion builder preview.
3954
		 *
3955
		 * @return bool
3956
		 *@since 1.1.0
3957
		 */
3958
		public function is_fusion_preview() {
3959
			$result = false;
3960
			if ( ! empty( $_REQUEST['fb-edit'] ) || ! empty( $_REQUEST['fusion_load_nonce'] ) ) {
3961
				$result = true;
3962
			}
3963
3964
			return $result;
3965
		}
3966
3967
		/**
3968
		 * Tests if the current output is inside a Oxygen builder preview.
3969
		 *
3970
		 * @return bool
3971
		 *@since 1.0.18
3972
		 */
3973
		public function is_oxygen_preview() {
3974
			$result = false;
3975
			if ( ! empty( $_REQUEST['ct_builder'] ) || ( ! empty( $_REQUEST['action'] ) && ( substr( $_REQUEST['action'], 0, 11 ) === "oxy_render_" || substr( $_REQUEST['action'], 0, 10 ) === "ct_render_" ) ) ) {
3976
				$result = true;
3977
			}
3978
3979
			return $result;
3980
		}
3981
3982
		/**
3983
		 * General function to check if we are in a preview situation.
3984
		 *
3985
		 * @return bool
3986
		 *@since 1.0.6
3987
		 */
3988
		public function is_preview() {
3989
			$preview = false;
3990
			if ( $this->is_divi_preview() ) {
3991
				$preview = true;
3992
			} elseif ( $this->is_elementor_preview() ) {
3993
				$preview = true;
3994
			} elseif ( $this->is_beaver_preview() ) {
3995
				$preview = true;
3996
			} elseif ( $this->is_siteorigin_preview() ) {
3997
				$preview = true;
3998
			} elseif ( $this->is_cornerstone_preview() ) {
3999
				$preview = true;
4000
			} elseif ( $this->is_fusion_preview() ) {
4001
				$preview = true;
4002
			} elseif ( $this->is_oxygen_preview() ) {
4003
				$preview = true;
4004
			} elseif( $this->is_block_content_call() ) {
4005
				$preview = true;
4006
			}
4007
4008
			return $preview;
4009
		}
4010
4011
		/**
4012
		 * Output the super title.
4013
		 *
4014
		 * @param $args
4015
		 * @param array $instance
4016
		 *
4017
		 * @return string
4018
		 */
4019
		public function output_title( $args, $instance = array() ) {
4020
			$output = '';
4021
			if ( ! empty( $instance['title'] ) ) {
4022
				/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
4023
				$title  = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
4024
4025
				if(empty($instance['widget_title_tag'])){
4026
					$output = $args['before_title'] . $title . $args['after_title'];
4027
				}else{
4028
					$title_tag = esc_attr( $instance['widget_title_tag'] );
4029
4030
					// classes
4031
					$title_classes = array();
4032
					$title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : '';
4033
					$title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : '';
4034
					$title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : '';
4035
					$title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : '';
4036
					$title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : '';
4037
					$title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : '';
4038
					$title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : '';
4039
					$title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : '';
4040
					$title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : '';
4041
					$title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : '';
4042
					$title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : '';
4043
					$title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : '';
4044
					$title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : '';
4045
4046
					$class = !empty( $title_classes ) ? implode(" ",$title_classes) : '';
4047
					$output = "<$title_tag class='$class' >$title</$title_tag>";
4048
				}
4049
4050
			}
4051
4052
			return $output;
4053
		}
4054
4055
		/**
4056
		 * Outputs the options form inputs for the widget.
4057
		 *
4058
		 * @param array $instance The widget options.
4059
		 */
4060
		public function form( $instance ) {
4061
4062
			// set widget instance
4063
			$this->instance = $instance;
4064
4065
			// set it as a SD widget
4066
			echo $this->widget_advanced_toggle();
4067
4068
			echo "<p>" . esc_attr( $this->options['widget_ops']['description'] ) . "</p>";
4069
			$arguments_raw = $this->get_arguments();
4070
4071
			if ( is_array( $arguments_raw ) ) {
0 ignored issues
show
introduced by
The condition is_array($arguments_raw) is always true.
Loading history...
4072
4073
				$arguments = $this->group_arguments( $arguments_raw );
4074
4075
				// Do we have sections?
4076
				$has_sections = $arguments == $arguments_raw ? false : true;
4077
4078
4079
				if ( $has_sections ) {
4080
					$panel_count = 0;
4081
					foreach ( $arguments as $key => $args ) {
4082
4083
						?>
4084
						<script>
4085
							//							jQuery(this).find("i").toggleClass("fas fa-chevron-up fas fa-chevron-down");jQuery(this).next().toggle();
4086
						</script>
4087
						<?php
4088
4089
						$hide       = $panel_count ? ' style="display:none;" ' : '';
4090
						$icon_class = $panel_count ? 'fas fa-chevron-up' : 'fas fa-chevron-down';
4091
						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>";
4092
						echo "<div class='sd-toggle-group sd-input-group-" . sanitize_title_with_dashes( $key ) . "' $hide>";
4093
4094
						foreach ( $args as $k => $a ) {
4095
4096
							$this->widget_inputs_row_start($k, $a);
4097
							$this->widget_inputs( $a, $instance );
4098
							$this->widget_inputs_row_end($k, $a);
4099
4100
						}
4101
4102
						echo "</div>";
4103
4104
						$panel_count ++;
4105
4106
					}
4107
				} else {
4108
					foreach ( $arguments as $key => $args ) {
4109
						$this->widget_inputs_row_start($key, $args);
4110
						$this->widget_inputs( $args, $instance );
4111
						$this->widget_inputs_row_end($key, $args);
4112
					}
4113
				}
4114
4115
			}
4116
		}
4117
4118
		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

4118
		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...
4119
			if(!empty($args['row'])){
4120
				// maybe open
4121
				if(!empty($args['row']['open'])){
4122
					?>
4123
					<div class='bsui sd-argument ' data-argument='<?php echo esc_attr( $args['row']['key'] ); ?>' data-element_require='<?php if ( !empty($args['row']['element_require'])) {
4124
						echo $this->convert_element_require( $args['row']['element_require'] );
4125
					} ?>'>
4126
					<?php if(!empty($args['row']['title'])){ ?>
4127
					<label class="mb-0 "><?php echo esc_attr( $args['row']['title'] ); ?><?php echo $this->widget_field_desc( $args['row'] ); ?></label>
4128
					<?php }?>
4129
					<div class='row <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>'>
4130
					<div class='col pr-2'>
4131
					<?php
4132
				}elseif(!empty($args['row']['close'])){
4133
					echo "<div class='col pl-0 ps-0'>";
4134
				}else{
4135
					echo "<div class='col pl-0 ps-0 pr-2 pe-2'>";
4136
				}
4137
			}
4138
		}
4139
4140
		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

4140
		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...
4141
4142
			if(!empty($args['row'])){
4143
				// maybe close
4144
				if(!empty($args['row']['close'])){
4145
					echo "</div></div>";
4146
				}
4147
4148
				echo "</div>";
4149
			}
4150
		}
4151
4152
		/**
4153
		 * Get the hidden input that when added makes the advanced button show on widget settings.
4154
		 *
4155
		 * @return string
4156
		 */
4157
		public function widget_advanced_toggle() {
4158
4159
			$output = '';
4160
			if ( $this->block_show_advanced() ) {
4161
				$val = 1;
4162
			} else {
4163
				$val = 0;
4164
			}
4165
4166
			$output .= "<input type='hidden'  class='sd-show-advanced' value='$val' />";
4167
4168
			return $output;
4169
		}
4170
4171
		/**
4172
		 * Convert require element.
4173
		 *
4174
		 * @param string $input Input element.
4175
		 *
4176
		 * @return string $output
4177
		 *@since 1.0.0
4178
		 *
4179
		 */
4180
		public function convert_element_require( $input ) {
4181
4182
			$input = str_replace( "'", '"', $input );// we only want double quotes
4183
4184
			$output = esc_attr( str_replace( array( "[%", "%]" ), array(
4185
				"jQuery(form).find('[data-argument=\"",
4186
				"\"]').find('input,select,textarea').val()"
4187
			), $input ) );
4188
4189
			return $output;
4190
		}
4191
4192
		/**
4193
		 * Builds the inputs for the widget options.
4194
		 *
4195
		 * @param $args
4196
		 * @param $instance
4197
		 */
4198
		public function widget_inputs( $args, $instance ) {
4199
4200
			$class             = "";
4201
			$element_require   = "";
4202
			$custom_attributes = "";
4203
4204
			// get value
4205
			if ( isset( $instance[ $args['name'] ] ) ) {
4206
				$value = $instance[ $args['name'] ];
4207
			} elseif ( ! isset( $instance[ $args['name'] ] ) && ! empty( $args['default'] ) ) {
4208
				$value = is_array( $args['default'] ) ? array_map( "esc_html", $args['default'] ) : esc_html( $args['default'] );
4209
			} else {
4210
				$value = '';
4211
			}
4212
4213
			// get placeholder
4214
			if ( ! empty( $args['placeholder'] ) ) {
4215
				$placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'";
4216
			} else {
4217
				$placeholder = '';
4218
			}
4219
4220
			// get if advanced
4221
			if ( isset( $args['advanced'] ) && $args['advanced'] ) {
4222
				$class .= " sd-advanced-setting ";
4223
			}
4224
4225
			// element_require
4226
			if ( isset( $args['element_require'] ) && $args['element_require'] ) {
4227
				$element_require = $args['element_require'];
4228
			}
4229
4230
			// custom_attributes
4231
			if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) {
4232
				$custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true );
4233
			}
4234
4235
4236
			// before wrapper
4237
			?>
4238
			<p class="sd-argument <?php echo esc_attr( $class ); ?>"
4239
			data-argument='<?php echo esc_attr( $args['name'] ); ?>'
4240
			data-element_require='<?php if ( $element_require ) {
4241
				echo $this->convert_element_require( $element_require );
4242
			} ?>'
4243
			>
4244
			<?php
4245
4246
4247
			switch ( $args['type'] ) {
4248
				//array('text','password','number','email','tel','url','color')
4249
				case "text":
4250
				case "password":
4251
				case "number":
4252
				case "email":
4253
				case "tel":
4254
				case "url":
4255
				case "color":
4256
					?>
4257
					<label
4258
						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>
4259
					<input <?php echo $placeholder; ?> class="widefat"
4260
						<?php echo $custom_attributes; ?>
4261
						                               id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
4262
						                               name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>"
4263
						                               type="<?php echo esc_attr( $args['type'] ); ?>"
4264
						                               value="<?php echo esc_attr( $value ); ?>">
4265
					<?php
4266
4267
					break;
4268
				case "select":
4269
					$multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false;
4270
					if ( $multiple ) {
4271
						if ( empty( $value ) ) {
4272
							$value = array();
4273
						}
4274
					}
4275
					?>
4276
					<label
4277
						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>
4278
					<select <?php echo $placeholder; ?> class="widefat"
4279
						<?php echo $custom_attributes; ?>
4280
						                                id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
4281
						                                name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) );
4282
						                                if ( $multiple ) {
4283
							                                echo "[]";
4284
						                                } ?>"
4285
						<?php if ( $multiple ) {
4286
							echo "multiple";
4287
						} //@todo not implemented yet due to gutenberg not supporting it
4288
						?>
4289
					>
4290
						<?php
4291
4292
						if ( ! empty( $args['options'] ) ) {
4293
							foreach ( $args['options'] as $val => $label ) {
4294
								if ( $multiple ) {
4295
									$selected = in_array( $val, $value ) ? 'selected="selected"' : '';
4296
								} else {
4297
									$selected = selected( $value, $val, false );
4298
								}
4299
								echo "<option value='$val' " . $selected . ">$label</option>";
4300
							}
4301
						}
4302
						?>
4303
					</select>
4304
					<?php
4305
					break;
4306
				case "checkbox":
4307
					?>
4308
					<input <?php echo $placeholder; ?>
4309
						<?php checked( 1, $value, true ) ?>
4310
						<?php echo $custom_attributes; ?>
4311
						class="widefat" id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
4312
						name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="checkbox"
4313
						value="1">
4314
					<label
4315
						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>
4316
					<?php
4317
					break;
4318
				case "textarea":
4319
					?>
4320
					<label
4321
						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>
4322
					<textarea <?php echo $placeholder; ?> class="widefat"
4323
						<?php echo $custom_attributes; ?>
4324
						                                  id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
4325
						                                  name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>"
4326
					><?php echo esc_attr( $value ); ?></textarea>
4327
					<?php
4328
4329
					break;
4330
				case "hidden":
4331
					?>
4332
					<input id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
4333
					       name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="hidden"
4334
					       value="<?php echo esc_attr( $value ); ?>">
4335
					<?php
4336
					break;
4337
				default:
4338
					echo "No input type found!"; // @todo we need to add more input types.
4339
			}
4340
4341
			// after wrapper
4342
			?>
4343
			</p>
4344
			<?php
4345
4346
4347
		}
4348
4349
		public function get_widget_icon($icon = 'box-top', $title = ''){
4350
			if($icon=='box-top'){
4351
				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>';
4352
			}elseif($icon=='box-right'){
4353
				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>';
4354
			}elseif($icon=='box-bottom'){
4355
				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>';
4356
			}elseif($icon=='box-left'){
4357
				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>';
4358
			}
4359
		}
4360
4361
		/**
4362
		 * Get the widget input description html.
4363
		 *
4364
		 * @param $args
4365
		 *
4366
		 * @return string
4367
		 * @todo, need to make its own tooltip script
4368
		 */
4369
		public function widget_field_desc( $args ) {
4370
4371
			$description = '';
4372
			if ( isset( $args['desc'] ) && $args['desc'] ) {
4373
				if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) {
4374
					$description = $this->desc_tip( $args['desc'] );
4375
				} else {
4376
					$description = '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>';
4377
				}
4378
			}
4379
4380
			return $description;
4381
		}
4382
4383
		/**
4384
		 * Get the widget input title html.
4385
		 *
4386
		 * @param $args
4387
		 *
4388
		 * @return string
4389
		 */
4390
		public function widget_field_title( $args ) {
4391
4392
			$title = '';
4393
			if ( isset( $args['title'] ) && $args['title'] ) {
4394
				if ( isset( $args['icon'] ) && $args['icon'] ) {
4395
					$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

4395
					/** @scrutinizer ignore-call */ 
4396
     $title = self::get_widget_icon( $args['icon'], $args['title']  );
Loading history...
4396
				} else {
4397
					$title = esc_attr($args['title']);
4398
				}
4399
			}
4400
4401
			return $title;
4402
		}
4403
4404
		/**
4405
		 * Get the tool tip html.
4406
		 *
4407
		 * @param $tip
4408
		 * @param bool $allow_html
4409
		 *
4410
		 * @return string
4411
		 */
4412
		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...
4413
			if ( $allow_html ) {
4414
				$tip = $this->sanitize_tooltip( $tip );
4415
			} else {
4416
				$tip = esc_attr( $tip );
4417
			}
4418
4419
			return '<span class="gd-help-tip dashicons dashicons-editor-help" title="' . $tip . '"></span>';
4420
		}
4421
4422
		/**
4423
		 * Sanitize a string destined to be a tooltip.
4424
		 *
4425
		 * @param string $var
4426
		 *
4427
		 * @return string
4428
		 */
4429
		public function sanitize_tooltip( $var ) {
4430
			return htmlspecialchars( wp_kses( html_entity_decode( $var ), array(
4431
				'br'     => array(),
4432
				'em'     => array(),
4433
				'strong' => array(),
4434
				'small'  => array(),
4435
				'span'   => array(),
4436
				'ul'     => array(),
4437
				'li'     => array(),
4438
				'ol'     => array(),
4439
				'p'      => array(),
4440
			) ) );
4441
		}
4442
4443
		/**
4444
		 * Processing widget options on save
4445
		 *
4446
		 * @param array $new_instance The new options
4447
		 * @param array $old_instance The previous options
4448
		 *
4449
		 * @return array
4450
		 * @todo we should add some sanitation here.
4451
		 */
4452
		public function update( $new_instance, $old_instance ) {
4453
4454
			//save the widget
4455
			$instance = array_merge( (array) $old_instance, (array) $new_instance );
4456
4457
			// set widget instance
4458
			$this->instance = $instance;
4459
4460
			if ( empty( $this->arguments ) ) {
4461
				$this->get_arguments();
4462
			}
4463
4464
			// check for checkboxes
4465
			if ( ! empty( $this->arguments ) ) {
4466
				foreach ( $this->arguments as $argument ) {
4467
					if ( isset( $argument['type'] ) && $argument['type'] == 'checkbox' && ! isset( $new_instance[ $argument['name'] ] ) ) {
4468
						$instance[ $argument['name'] ] = '0';
4469
					}
4470
				}
4471
			}
4472
4473
			return $instance;
4474
		}
4475
4476
		/**
4477
		 * Checks if the current call is a ajax call to get the block content.
4478
		 *
4479
		 * This can be used in your widget to return different content as the block content.
4480
		 *
4481
		 * @return bool
4482
		 *@since 1.0.3
4483
		 */
4484
		public function is_block_content_call() {
4485
			$result = false;
4486
			if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'super_duper_output_shortcode' ) {
4487
				$result = true;
4488
			}
4489
4490
			return $result;
4491
		}
4492
4493
		/**
4494
		 * Get an instance hash that will be unique to the type and settings.
4495
		 *
4496
		 * @return string
4497
		 *@since 1.0.20
4498
		 */
4499
		public function get_instance_hash(){
4500
			$instance_string = $this->base_id.serialize($this->instance);
4501
			return hash('crc32b',$instance_string);
4502
		}
4503
4504
		/**
4505
		 * Generate and return inline styles from CSS rules that will match the unique class of the instance.
4506
		 *
4507
		 * @param array $rules
4508
		 *
4509
		 * @return string
4510
		 *@since 1.0.20
4511
		 */
4512
		public function get_instance_style($rules = array()){
4513
			$css = '';
4514
4515
			if(!empty($rules)){
4516
				$rules = array_unique($rules);
4517
				$instance_hash = $this->get_instance_hash();
4518
				$css .= "<style>";
4519
				foreach($rules as $rule){
4520
					$css .= ".sdel-$instance_hash $rule";
4521
				}
4522
				$css .= "</style>";
4523
			}
4524
4525
			return $css;
4526
		}
4527
4528
		/**
4529
		 * Encode shortcodes tags.
4530
		 *
4531
		 * @param string $content Content to search for shortcode tags.
4532
		 *
4533
*@return string Content with shortcode tags removed.
4534
		 *@since 1.0.28
4535
		 *
4536
		 */
4537
		public function encode_shortcodes( $content ) {
4538
			// Avoids existing encoded tags.
4539
			$trans   = array(
4540
				'&#91;' => '&#091;',
4541
				'&#93;' => '&#093;',
4542
				'&amp;#91;' => '&#091;',
4543
				'&amp;#93;' => '&#093;',
4544
				'&lt;' => '&0lt;',
4545
				'&gt;' => '&0gt;',
4546
				'&amp;lt;' => '&0lt;',
4547
				'&amp;gt;' => '&0gt;',
4548
			);
4549
4550
			$content = strtr( $content, $trans );
4551
4552
			$trans   = array(
4553
				'[' => '&#91;',
4554
				']' => '&#93;',
4555
				'<' => '&lt;',
4556
				'>' => '&gt;',
4557
				'"' => '&quot;',
4558
				"'" => '&#39;',
4559
			);
4560
4561
			$content = strtr( $content, $trans );
4562
4563
			return $content;
4564
		}
4565
4566
		/**
4567
		 * Remove encoded shortcod tags.
4568
		 *
4569
		 * @param string $content Content to search for shortcode tags.
4570
		 *
4571
*@return string Content with decoded shortcode tags.
4572
		 *@since 1.0.28
4573
		 *
4574
		 */
4575
		public function decode_shortcodes( $content ) {
4576
			$trans   = array(
4577
				'&#91;' => '[',
4578
				'&#93;' => ']',
4579
				'&amp;#91;' => '[',
4580
				'&amp;#93;' => ']',
4581
				'&lt;' => '<',
4582
				'&gt;' => '>',
4583
				'&amp;lt;' => '<',
4584
				'&amp;gt;' => '>',
4585
				'&quot;' => '"',
4586
				'&apos;' => "'",
4587
			);
4588
4589
			$content = strtr( $content, $trans );
4590
4591
			$trans   = array(
4592
				'&#091;' => '&#91;',
4593
				'&#093;' => '&#93;',
4594
				'&amp;#091;' => '&#91;',
4595
				'&amp;#093;' => '&#93;',
4596
				'&0lt;' => '&lt;',
4597
				'&0gt;' => '&gt;',
4598
				'&amp;0lt;' => '&lt;',
4599
				'&amp;0gt;' => '&gt;',
4600
			);
4601
4602
			$content = strtr( $content, $trans );
4603
4604
			return $content;
4605
		}
4606
	}
4607
}
4608