Passed
Push — master ( e67cdc...5aad15 )
by Stiofan
10:57
created

WP_Super_Duper::wp_media_buttons()   A

Complexity

Conditions 4

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 3
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
if ( ! class_exists( 'WP_Super_Duper' ) ) {
7
8
	define( 'SUPER_DUPER_VER', '1.2.9' );
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, 'wp_media_buttons' ), 1 );
108
				add_action( 'media_buttons', array( $this, 'shortcode_insert_button' ) );
109
				// generatepress theme sections compatibility
110
				if ( function_exists( 'generate_sections_sections_metabox' ) ) {
111
					add_action( 'generate_sections_metabox', array( $this, 'shortcode_insert_button_script' ) );
112
				}
113
				/* Load script on Divi theme builder page */
114
				if ( function_exists( 'et_builder_is_tb_admin_screen' ) && et_builder_is_tb_admin_screen() ) {
115
					add_thickbox();
116
					add_action( 'admin_footer', array( $this, 'shortcode_insert_button_script' ) );
117
				}
118
119
				if ( $this->is_preview() ) {
120
					add_action( 'wp_footer', array( $this, 'shortcode_insert_button_script' ) );
121
					// this makes the insert button work for elementor
122
					add_action( 'elementor/editor/after_enqueue_scripts', array(
123
						$this,
124
						'shortcode_insert_button_script'
125
					) ); // for elementor
126
				}
127
				// this makes the insert button work for cornerstone
128
				add_action( 'wp_print_footer_scripts', array( __CLASS__, 'maybe_cornerstone_builder' ) );
129
130
				add_action( 'wp_ajax_super_duper_get_widget_settings', array( __CLASS__, 'get_widget_settings' ) );
131
				add_action( 'wp_ajax_super_duper_get_picker', array( __CLASS__, 'get_picker' ) );
132
133
				// add generator text to head
134
				add_action( 'admin_head', array( $this, 'generator' ), 99 );
135
				add_action( 'wp_head', array( $this, 'generator' ), 99 );
136
			}
137
138
			do_action( 'wp_super_duper_widget_init', $options, $this );
139
		}
140
141
		/**
142
		 * The register widget function
143
		 * @return void
144
		 */
145
		public function _register() {
146
			if(empty($this->options['output_types']) || in_array('widget',$this->options['output_types'])){
147
				parent::_register();
148
			}
149
		}
150
151
		/**
152
		 * Add our widget CSS to elementor editor.
153
		 */
154
		public function elementor_editor_styles() {
155
			wp_add_inline_style( 'elementor-editor', $this->widget_css( false ) );
156
		}
157
158
		public function register_fusion_element() {
159
160
			$options = $this->options;
161
162
			if ( $this->base_id ) {
163
164
				$params = $this->get_fusion_params();
165
166
				$args = array(
167
					'name'            => $options['name'],
168
					'shortcode'       => $this->base_id,
169
					'icon'            => $options['block-icon'] ? $options['block-icon'] : 'far fa-square',
170
					'allow_generator' => true,
171
				);
172
173
				if ( ! empty( $params ) ) {
174
					$args['params'] = $params;
175
				}
176
177
				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

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

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

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

2517
						$example_inner_blocks = !empty($this->options['example']['innerBlocks']) && is_array($this->options['example']['innerBlocks']) ? 'innerBlocks: ' . /** @scrutinizer ignore-type */ wp_json_encode($this->options['example']['innerBlocks']) : '';
Loading history...
2518
						if( isset( $this->options['example'] ) && $this->options['example'] === false ){
2519
							// no preview if set to false
2520
						}elseif( !empty( $example_args ) ){
2521
							echo "example : {attributes:{".$this->array_to_attributes( $example_args )."},$viewport_width},";
2522
						}elseif( !empty( $this->options['example'] ) ){
2523
							unset($this->options['example']['viewportWidth']);
2524
							unset($this->options['example']['innerBlocks']);
2525
							$example_atts = $this->array_to_attributes( $this->options['example'] );
2526
							$example_parts = array();
2527
							if($example_atts){
2528
								$example_parts[] = rtrim($example_atts,",");
2529
							}
2530
							if($viewport_width){
2531
								$example_parts[] = $viewport_width;
2532
							}
2533
							if($example_inner_blocks){
2534
								$example_parts[] = $example_inner_blocks;
2535
							}
2536
							if(!empty($example_parts)){
2537
								echo "example : {".implode(',', $example_parts)."},";
2538
							}
2539
						}else{
2540
							echo 'example : {viewportWidth: 500},';
2541
						}
2542
2543
2544
2545
						// limit to parent
2546
						if( !empty( $this->options['parent'] ) ){
2547
							echo "parent : " . wp_json_encode( $this->options['parent'] ) . ",";
0 ignored issues
show
Bug introduced by
Are you sure wp_json_encode($this->options['parent']) of type false|string can be used in concatenation? ( Ignorable by Annotation )

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

2547
							echo "parent : " . /** @scrutinizer ignore-type */ wp_json_encode( $this->options['parent'] ) . ",";
Loading history...
2548
						}
2549
2550
						// limit allowed blocks
2551
						if( !empty( $this->options['allowed-blocks'] ) ){
2552
							echo "allowedBlocks : " . wp_json_encode( $this->options['allowed-blocks'] ) . ",";
0 ignored issues
show
Bug introduced by
Are you sure wp_json_encode($this->options['allowed-blocks']) of type false|string can be used in concatenation? ( Ignorable by Annotation )

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

2552
							echo "allowedBlocks : " . /** @scrutinizer ignore-type */ wp_json_encode( $this->options['allowed-blocks'] ) . ",";
Loading history...
2553
						}
2554
2555
						// maybe set no_wrap
2556
						$no_wrap = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false;
2557
						if ( isset( $this->arguments['no_wrap'] ) && $this->arguments['no_wrap'] ) {
2558
							$no_wrap = true;
2559
						}
2560
						if ( $no_wrap ) {
2561
							$this->options['block-wrap'] = '';
2562
						}
2563
2564
						// maybe load the drag/drop functions.
2565
						$img_drag_drop = false;
2566
2567
						$show_alignment = false;
2568
						// align feature
2569
						/*echo "supports: {";
2570
						echo "	align: true,";
2571
						echo "  html: false";
2572
						echo "},";*/
2573
2574
2575
							echo "attributes : {";
2576
2577
							if ( $show_advanced ) {
2578
								echo "show_advanced: {";
2579
								echo "	type: 'boolean',";
2580
								echo "  default: false,";
2581
								echo "},";
2582
							}
2583
2584
							// block wrap element
2585
							if ( ! empty( $this->options['block-wrap'] ) ) { //@todo we should validate this?
2586
								echo "block_wrap: {";
2587
								echo "	type: 'string',";
2588
								echo "  default: '" . esc_attr( $this->options['block-wrap'] ) . "',";
2589
								echo "},";
2590
							}
2591
2592
2593
							if ( ! empty( $this->arguments ) ) {
2594
2595
								foreach ( $this->arguments as $key => $args ) {
2596
2597
									if( $args['type'] == 'image' ||  $args['type'] == 'images' ){
2598
										$img_drag_drop = true;
2599
									}
2600
2601
									// set if we should show alignment
2602
									if ( $key == 'alignment' ) {
2603
										$show_alignment = true;
2604
									}
2605
2606
									$extra = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $extra is dead and can be removed.
Loading history...
2607
2608
									if ( $args['type'] == 'notice' ||  $args['type'] == 'tab' ) {
2609
										continue;
2610
									}
2611
									elseif ( $args['type'] == 'checkbox' ) {
2612
										$type    = 'boolean';
2613
										$default = isset( $args['default'] ) && $args['default'] ? 'true' : 'false';
2614
									} elseif ( $args['type'] == 'number' ) {
2615
										$type    = 'number';
2616
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2617
									} elseif ( $args['type'] == 'select' && ! empty( $args['multiple'] ) ) {
2618
										$type = 'array';
2619
										if ( isset( $args['default'] ) && is_array( $args['default'] ) ) {
2620
											$default = ! empty( $args['default'] ) ? "['" . implode( "','", $args['default'] ) . "']" : "[]";
2621
										} else {
2622
											$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2623
										}
2624
									} elseif ( $args['type'] == 'tagselect' ) {
2625
										$type    = 'array';
2626
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2627
									} elseif ( $args['type'] == 'multiselect' ) {
2628
										$type    = 'array';
2629
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2630
									} elseif ( $args['type'] == 'image_xy' ) {
2631
										$type    = 'object';
2632
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2633
									} elseif ( $args['type'] == 'image' ) {
2634
										$type    = 'string';
2635
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2636
2637
										// add a field for ID
2638
	//                                    echo $key . "_id : {";
2639
	//                                    echo "type : 'number',";
2640
	//                                    echo "},";
2641
	//                                    echo $key . "_xy : {";
2642
	//                                    echo "type : 'object',";
2643
	//                                    echo "},";
2644
2645
									} else {
2646
										$type    = !empty($args['hidden_type']) ? esc_attr($args['hidden_type']) : 'string';
2647
										$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''";
2648
2649
									}
2650
									echo $key . " : {";
2651
									echo "type : '$type',";
2652
									echo "default : $default,";
2653
									echo "},";
2654
								}
2655
							}
2656
2657
							echo "content : {type : 'string',default: 'Please select the attributes in the block settings'},";
2658
							echo "sd_shortcode : {type : 'string',default: ''},";
2659
2660
							if(!empty($this->options['nested-block']) || !empty($this->arguments['html']) ){
2661
								echo "sd_shortcode_close : {type : 'string',default: ''},";
2662
							}
2663
2664
							echo "className: { type: 'string', default: '' },";
2665
2666
							echo "},";
2667
2668
2669
2670
						?>
2671
2672
						// The "edit" property must be a valid function.
2673
						edit: function (props) {
2674
2675
2676
<?php
2677
// only include the drag/drop functions if required.
2678
if( $img_drag_drop ){
2679
2680
?>
2681
2682
function enableDragSort(listClass) {
2683
	setTimeout(function(){
2684
		 const sortableLists = document.getElementsByClassName(listClass);
2685
		 Array.prototype.map.call(sortableLists, (list) => {enableDragList(list)});
2686
	}, 300);
2687
}
2688
2689
function enableDragList(list) {
2690
  Array.prototype.map.call(list.children, (item) => {enableDragItem(item)});
2691
}
2692
2693
function enableDragItem(item) {
2694
  item.setAttribute('draggable', true)
2695
  item.ondrag = handleDrag;
2696
  item.ondragend = handleDrop;
2697
}
2698
2699
function handleDrag(item) {
2700
  const selectedItem = item.target,
2701
		list = selectedItem.parentNode,
2702
		x = event.clientX,
2703
		y = event.clientY;
2704
2705
  selectedItem.classList.add('drag-sort-active');
2706
  let swapItem = document.elementFromPoint(x, y) === null ? selectedItem : document.elementFromPoint(x, y);
2707
2708
  if (list === swapItem.parentNode) {
2709
	swapItem = swapItem !== selectedItem.nextSibling ? swapItem : swapItem.nextSibling;
2710
	list.insertBefore(selectedItem, swapItem);
2711
  }
2712
}
2713
2714
function handleDrop(item) {
2715
2716
	item.target.classList.remove('drag-sort-active');
2717
2718
	const newOrder = [];
2719
	let $parent = item.target.parentNode;
2720
	let $field = $parent.dataset.field;
2721
	let $imgs = JSON.parse('[' + props.attributes[$field] + ']');
2722
	item.target.parentNode.classList.add('xxx');
2723
	$children = $parent.children;
2724
2725
	Object.keys($children).forEach(function(key) {
2726
	  let $nKey = $children[key].dataset.index
2727
	  newOrder.push($imgs[$nKey]);
2728
	});
2729
2730
	// @todo find out why we need to empty the value first otherwise the order is wrong.
2731
	props.setAttributes({ [$field]: '' });
2732
	setTimeout(function(){
2733
		props.setAttributes({ [$field]: JSON.stringify(newOrder).replace('[','').replace(']','') });
2734
	}, 100);
2735
2736
}
2737
<?php } ?>
2738
2739
							if (typeof(props.attributes.styleid) !== 'undefined'){
2740
								if(props.attributes.styleid==''){ props.setAttributes({ 'styleid': 'block-'+(Math.random() + 1).toString(36).substring(2) } ); }
2741
							}
2742
2743
							<?php
2744
							if(!empty($this->options['block-edit-raw'])) {
2745
								echo $this->options['block-edit-raw']; // strings have to be in single quotes, may cause issues
2746
							}else{
2747
							?>
2748
2749
function hasSelectedInnerBlock(props) {
2750
	const select = wp.data.select('core/editor');
2751
	const selected = select.getBlockSelectionStart();
2752
	const inner = select.getBlock(props.clientId).innerBlocks;
2753
	for (let i = 0; i < inner.length; i++) {
2754
		if (inner[i].clientId === selected || inner[i].innerBlocks.length && hasSelectedInnerBlock(inner[i])) {
2755
			return true;
2756
		}
2757
	}
2758
	return false;
2759
};
2760
2761
const parentBlocksIDs = wp.data.select( 'core/block-editor' ).getBlockParents(props.clientId);
2762
const parentBlocks = wp.data.select('core/block-editor').getBlocksByClientId(parentBlocksIDs);
2763
// const isParentOfSelectedBlock = useSelect( ( select ) => wp.data.select( 'core/block-editor' ).hasSelectedInnerBlock( props.clientId, true ) ):
2764
	const block = wp.data.select('core/block-editor').getBlocksByClientId(props.clientId);//.[0].innerBlocks;
2765
	const childBlocks = block[0] == null ? '' : block[0].innerBlocks;
2766
2767
	var $value = '';
2768
	<?php
2769
	// if we have a post_type and a category then link them
2770
	if( isset($this->arguments['post_type']) && isset($this->arguments['category']) && !empty($this->arguments['category']['post_type_linked']) ){
2771
	?>
2772
	if(typeof(prev_attributes[props.clientId]) != 'undefined'){
2773
		$pt = props.attributes.post_type;
2774
		if(post_type_rest_slugs.length){
2775
			$value = post_type_rest_slugs[0][$pt];
2776
		}
2777
		var run = false;
2778
2779
		if($pt != term_query_type){
2780
			run = true;
2781
			term_query_type = $pt;
2782
		}
2783
<?php
2784
	$cat_path = '';
2785
	if ( ! empty( $this->arguments['post_type']['onchange_rest']['path'] ) ) {
2786
		$cat_path = esc_js( strip_tags( $this->arguments['post_type']['onchange_rest']['path'] ) );
2787
		$cat_path = str_replace( array( '&quot;', '&#039;' ), array( '"', "'" ), $cat_path );
2788
	}
2789
?>
2790
		/* taxonomies */
2791
		if($value && 'post_type' in prev_attributes[props.clientId] && 'category' in prev_attributes[props.clientId] && run){
2792
			if (!window.gdCPTCats) {
2793
				window.gdCPTCats = [];
2794
			}
2795
			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...
2796
			if (window.gdCPTCats[gdCatPath]) {
2797
				terms = window.gdCPTCats[gdCatPath];
2798
				while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2799
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2800
				}
2801
				taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2802
				jQuery.each( terms, function( key, val ) {
2803
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2804
				});
2805
2806
				/* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2807
				var $old_cat_value = props.attributes.category
2808
				props.setAttributes({category: [0] });
2809
				props.setAttributes({category: $old_cat_value });
2810
			} else {
2811
				wp.apiFetch({path: gdCatPath}).then(terms => {
2812
					window.gdCPTCats[gdCatPath] = terms;
2813
					while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2814
						taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2815
					}
2816
					taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2817
					jQuery.each( terms, function( key, val ) {
2818
						taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2819
					});
2820
2821
					/* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2822
					var $old_cat_value = props.attributes.category
2823
					props.setAttributes({category: [0] });
2824
					props.setAttributes({category: $old_cat_value });
2825
2826
					return taxonomies_<?php echo str_replace("-","_", $this->id);?>;
2827
				});
2828
			}
2829
		}
2830
2831
		/* sort_by */
2832
		if($value && 'post_type' in prev_attributes[props.clientId] && 'sort_by' in prev_attributes[props.clientId] && run){
2833
			if (!window.gdCPTSort) {
2834
				window.gdCPTSort = [];
2835
			}
2836
			if (window.gdCPTSort[$pt]) {
2837
				response = window.gdCPTSort[$pt];
2838
				while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2839
					sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2840
				}
2841
2842
				jQuery.each( response, function( key, val ) {
2843
					sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2844
				});
2845
2846
				// setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2847
				var $old_sort_by_value = props.attributes.sort_by
2848
				props.setAttributes({sort_by: [0] });
2849
				props.setAttributes({sort_by: $old_sort_by_value });
2850
			} else {
2851
				var data = {
2852
					'action': 'geodir_get_sort_options',
2853
					'post_type': $pt
2854
				};
2855
				jQuery.post(ajaxurl, data, function(response) {
2856
					response = JSON.parse(response);
2857
					window.gdCPTSort[$pt] = response;
2858
					while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2859
						sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2860
					}
2861
2862
					jQuery.each( response, function( key, val ) {
2863
						sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2864
					});
2865
2866
					// setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2867
					var $old_sort_by_value = props.attributes.sort_by
2868
					props.setAttributes({sort_by: [0] });
2869
					props.setAttributes({sort_by: $old_sort_by_value });
2870
2871
					return sort_by_<?php echo str_replace("-","_", $this->id);?>;
2872
				});
2873
			}
2874
		}
2875
	}
2876
	<?php } ?>
2877
<?php
2878
$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...
2879
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...
2880
	echo 'const { deviceType } = "";';
2881
}else{
2882
?>
2883
/** Get device type const. */
2884
const { deviceType } = wp.data.useSelect != 'undefined' ?  wp.data.useSelect(select => {
2885
	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
2886
	return {
2887
		deviceType: __experimentalGetPreviewDeviceType(),
2888
	}
2889
}, []) : '';
2890
<?php } ?>
2891
							var content = props.attributes.content;
2892
                            var shortcode = '';
2893
2894
							function onChangeContent($type) {
2895
// console.log(deviceType);
2896
								$refresh = false;
2897
								// Set the old content the same as the new one so we only compare all other attributes
2898
								if(typeof(prev_attributes[props.clientId]) != 'undefined'){
2899
									prev_attributes[props.clientId].content = props.attributes.content;
2900
								}else if(props.attributes.content === ""){
2901
									// if first load and content empty then refresh
2902
									$refresh = true;
2903
								}
2904
2905
								if ( ( !is_fetching &&  JSON.stringify(prev_attributes[props.clientId]) != JSON.stringify(props.attributes) ) || $refresh  ) {
2906
2907
									is_fetching = true;
2908
2909
									var data = {
2910
										'action': 'super_duper_output_shortcode',
2911
										'shortcode': '<?php echo $this->options['base_id'];?>',
2912
										'attributes': props.attributes,
2913
										'block_parent_name': parentBlocks.length ? parentBlocks[parentBlocks.length - 1].name : '',
2914
										'post_id': <?php global $post; if ( isset( $post->ID ) ) {
2915
										echo $post->ID;
2916
									}else{echo '0';}?>,
2917
										'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>'
2918
									};
2919
2920
									jQuery.post(ajaxurl, data, function (response) {
2921
										return response;
2922
									}).then(function (env) {
2923
2924
										// if the content is empty then we place some placeholder text
2925
										if (env == '') {
2926
											env = "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" + "<?php _e( 'Placeholder for:', 'ayecode-connect' );?> " + props.name + "</div>";
2927
										}
2928
2929
										 <?php
2930
										if(!empty($this->options['nested-block'])){
2931
											?>
2932
											// props.setAttributes({content: env});
2933
										is_fetching = false;
2934
										prev_attributes[props.clientId] = props.attributes;
2935
											 <?php
2936
										}else{
2937
										?>
2938
										props.setAttributes({content: env});
2939
										is_fetching = false;
2940
										prev_attributes[props.clientId] = props.attributes;
2941
										<?php
2942
										}
2943
										?>
2944
2945
2946
										// if AUI is active call the js init function
2947
										if (typeof aui_init === "function") {
2948
											aui_init();
2949
										}
2950
									});
2951
2952
2953
								}
2954
2955
2956
2957
								return props.attributes.content;
2958
2959
							}
2960
2961
							<?php
2962
							if(!empty($this->options['block-edit-js'])) {
2963
								echo  $this->options['block-edit-js'] ; // strings have to be in single quotes, may cause issues
2964
							}
2965
2966
2967
2968
2969
							if(empty($this->options['block-save-return'])){
2970
							?>
2971
								///////////////////////////////////////////////////////////////////////
2972
2973
									 // build the shortcode.
2974
								shortcode = "[<?php echo $this->options['base_id'];?>";
2975
								<?php
2976
2977
								if(! empty( $this->arguments )){
2978
2979
								foreach($this->arguments as $key => $args){
2980
								   // if($args['type']=='tabs'){continue;}
2981
2982
								   // don't add metadata arguments
2983
								   if (substr($key, 0, 9 ) === 'metadata_') {
2984
									   continue;
2985
								   }
2986
								?>
2987
								if (props.attributes.hasOwnProperty("<?php echo esc_attr( $key );?>")) {
2988
									if ('<?php echo esc_attr( $key );?>' == 'html') {
2989
									} else if ('<?php echo esc_attr( $args['type'] );?>' == 'image_xy') {
2990
										shortcode += props.attributes.<?php echo esc_attr( $key );?>.length && ( props.attributes.<?php echo esc_attr( $key );?>.x.length || props.attributes.<?php echo esc_attr( $key );?>.y.length ) ? " <?php echo esc_attr( $key );?>='{x:" + props.attributes.<?php echo esc_attr( $key );?>.x + ",y:"+props.attributes.<?php echo esc_attr( $key );?>.y +"}' " : "";
2991
									} else {
2992
										//shortcode += props.attributes.<?php echo esc_attr( $key );?>.length ? " <?php echo esc_attr( $key );?>='" + props.attributes.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' " : "";
2993
										shortcode +=  " <?php echo esc_attr( $key );?>='" + props.attributes.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' ";
2994
									}
2995
								}
2996
								<?php
2997
								}
2998
								}
2999
3000
								?>
3001
								shortcode += "]";
3002
3003
								if(shortcode){
3004
3005
									props.setAttributes({sd_shortcode: shortcode});
3006
3007
									<?php
3008
									if(!empty($this->options['nested-block']) || !empty($this->arguments['html']) ){
3009
										echo "props.setAttributes({sd_shortcode_close: '[/".esc_attr( $this->options['base_id'] )."]'});";
3010
									}
3011
									?>
3012
								}
3013
3014
3015
							///////////////////////////////////////////////////////////////////////
3016
							<?php
3017
							} // end nested block check
3018
							?>
3019
3020
							return [
3021
3022
								el(wp.blockEditor.BlockControls, {key: 'controls'},
3023
3024
									<?php if($show_alignment){?>
3025
									el(
3026
										wp.blockEditor.AlignmentToolbar,
3027
										{
3028
											value: props.attributes.alignment,
3029
											onChange: function (alignment) {
3030
												props.setAttributes({alignment: alignment})
3031
											}
3032
										}
3033
									)
3034
									<?php }?>
3035
3036
								),
3037
3038
								el(wp.blockEditor.InspectorControls, {key: 'inspector'},
3039
3040
									<?php
3041
3042
									if(! empty( $this->arguments )){
3043
3044
									if ( $show_advanced ) {
3045
									?>
3046
									el('div', {
3047
											style: {'padding-left': '16px','padding-right': '16px'}
3048
										},
3049
										el(
3050
											wp.components.ToggleControl,
3051
											{
3052
												label: 'Show Advanced Settings?',
3053
												checked: props.attributes.show_advanced,
3054
												onChange: function (show_advanced) {
3055
													props.setAttributes({show_advanced: !props.attributes.show_advanced})
3056
												}
3057
											}
3058
										)
3059
									)
3060
									,
3061
									<?php
3062
									}
3063
3064
									$arguments = $this->group_arguments( $this->arguments );
3065
									$block_group_tabs = ! empty( $this->options['block_group_tabs'] ) ? $this->group_block_tabs( $this->options['block_group_tabs'], $arguments ) : array();
3066
3067
									// Do we have sections?
3068
									$has_sections = $arguments == $this->arguments ? false : true;
3069
3070
									if($has_sections){
3071
									$panel_count = 0;
3072
									$open_tab = '';
3073
3074
									$open_tab_groups = array();
3075
									$used_tabs = array();
3076
3077
									foreach ( $arguments as $key => $args ) {
3078
										$close_tab = false;
3079
										$close_tabs = false;
3080
3081
										 if ( ! empty( $block_group_tabs ) ) {
3082
											foreach ( $block_group_tabs as $tab_name => $tab_args ) {
3083
												if ( in_array( $key, $tab_args['groups'] ) ) {
3084
													$open_tab_groups[] = $key;
3085
3086
													if ( $open_tab != $tab_name ) {
3087
														$tab_args['tab']['tabs_open'] = $open_tab == '' ? true : false;
3088
														$tab_args['tab']['open'] = true;
3089
3090
														$this->block_tab_start( '', $tab_args );
3091
														$open_tab = $tab_name;
3092
														$used_tabs[] = $tab_name;
3093
													}
3094
3095
													if ( $open_tab_groups == $tab_args['groups'] ) {
3096
														$close_tab = true;
3097
														$open_tab_groups = array();
3098
3099
														if ( $used_tabs == array_keys( $block_group_tabs ) ) {
3100
															$close_tabs = true;
3101
														}
3102
													}
3103
												}
3104
											}
3105
										}
3106
										?>
3107
										el(wp.components.PanelBody, {
3108
												title: '<?php esc_attr_e( $key ); ?>',
3109
												initialOpen: <?php if ( $panel_count ) {
3110
												echo "false";
3111
											} else {
3112
												echo "true";
3113
											}?>
3114
											},
3115
											<?php
3116
											foreach ( $args as $k => $a ) {
3117
												$this->block_tab_start( $k, $a );
3118
												$this->block_row_start( $k, $a );
3119
												$this->build_block_arguments( $k, $a );
3120
												$this->block_row_end( $k, $a );
3121
												$this->block_tab_end( $k, $a );
3122
											}
3123
											?>
3124
										),
3125
										<?php
3126
										$panel_count ++;
3127
3128
										if($close_tab || $close_tabs){
3129
											$tab_args = array(
3130
												'tab'	=> array(
3131
													'tabs_close' => $close_tabs,
3132
												'close' => true,
3133
												)
3134
3135
											);
3136
											$this->block_tab_end( '', $tab_args );
3137
//											echo '###close'; print_r($tab_args);
3138
											$panel_count = 0;
3139
										}
3140
//
3141
3142
									}
3143
									}else {
3144
									?>
3145
									el(wp.components.PanelBody, {
3146
											title: '<?php esc_attr_e( "Settings", 'ayecode-connect' ); ?>',
3147
											initialOpen: true
3148
										},
3149
										<?php
3150
										foreach ( $this->arguments as $key => $args ) {
3151
											$this->block_row_start( $key, $args );
3152
											$this->build_block_arguments( $key, $args );
3153
											$this->block_row_end( $key, $args );
3154
										}
3155
										?>
3156
									),
3157
									<?php
3158
									}
3159
3160
									}
3161
									?>
3162
3163
								),
3164
3165
								<?php
3166
								// If the user sets block-output array then build it
3167
								if ( ! empty( $this->options['block-output'] ) ) {
3168
								$this->block_element( $this->options['block-output'] );
3169
							}elseif(!empty($this->options['block-edit-return'])){
3170
								   echo $this->options['block-edit-return'];
3171
							}else{
3172
								// if no block-output is set then we try and get the shortcode html output via ajax.
3173
								$block_edit_wrap_tag = !empty($this->options['block_edit_wrap_tag']) ? esc_attr($this->options['block_edit_wrap_tag']) : 'div';
3174
								?>
3175
								el('<?php echo esc_attr($block_edit_wrap_tag); ?>', wp.blockEditor.useBlockProps({
3176
									dangerouslySetInnerHTML: {__html: onChangeContent()},
3177
									className: props.className,
3178
									<?php //if(isset($this->arguments['visibility_conditions'])){ echo 'dataVisibilityConditionSD: props.visibility_conditions ? true : false,';} //@todo we need to implement this in the other outputs also ?>
3179
									style: {'minHeight': '30px'}
3180
								}))
3181
								<?php
3182
								}
3183
								?>
3184
							]; // end return
3185
3186
							<?php
3187
							} // end block-edit-raw else
3188
							?>
3189
						},
3190
3191
						// The "save" property must be specified and must be a valid function.
3192
						save: function (props) {
3193
3194
							var attr = props.attributes;
3195
							var align = '';
3196
3197
							// build the shortcode.
3198
							var content = "[<?php echo $this->options['base_id'];?>";
3199
							$html = '';
3200
							<?php
3201
3202
							if(! empty( $this->arguments )){
3203
3204
							foreach($this->arguments as $key => $args){
3205
							   // if($args['type']=='tabs'){continue;}
3206
3207
							   // don't add metadata arguments
3208
							   if (substr($key, 0, 9 ) === 'metadata_') {
3209
								   continue;
3210
							   }
3211
							?>
3212
							if (attr.hasOwnProperty("<?php echo esc_attr( $key );?>")) {
3213
								if ('<?php echo esc_attr( $key );?>' == 'html') {
3214
									$html = attr.<?php echo esc_attr( $key );?>;
3215
								} else if ('<?php echo esc_attr( $args['type'] );?>' == 'image_xy') {
3216
									content += " <?php echo esc_attr( $key );?>='{x:" + attr.<?php echo esc_attr( $key );?>.x + ",y:"+attr.<?php echo esc_attr( $key );?>.y +"}' ";
3217
								} else {
3218
									content += " <?php echo esc_attr( $key );?>='" + attr.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' ";
3219
								}
3220
							}
3221
							<?php
3222
							}
3223
							}
3224
3225
							?>
3226
							content += "]";
3227
							 content = '';
3228
3229
							<?php
3230
//                            if(!empty($this->options['nested-block'])){
3231
//                                ?>
3232
//                                $html = 'el( InnerBlocks.Content )';
3233
//                                <?php
3234
//                            }
3235
							?>
3236
							// if has html element
3237
							if ($html) {
3238
								//content += $html + "[/<?php echo $this->options['base_id'];?>]";
3239
							}
3240
3241
							// @todo should we add inline style here or just css classes?
3242
							if (attr.alignment) {
3243
								if (attr.alignment == 'left') {
3244
									align = 'alignleft';
3245
								}
3246
								if (attr.alignment == 'center') {
3247
									align = 'aligncenter';
3248
								}
3249
								if (attr.alignment == 'right') {
3250
									align = 'alignright';
3251
								}
3252
							}
3253
3254
							<?php
3255
//							if(!empty($this->options['nested-block'])){
3256
//                                ?x>
3257
//                              return el(
3258
//                                    'div',
3259
//                                    { className: props.className,
3260
//                                        style: {'minHeight': '300px','position':'relative','overflow':'hidden','backgroundImage': 'url(https://s.w.org/images/core/5.5/don-quixote-06.jpg)'}
3261
//                                    },
3262
//                                    el( InnerBlocks.Content ),
3263
//                                    el('div', {dangerouslySetInnerHTML: {__html: content}, className: align})
3264
//                                );
3265
//                                <x?php
3266
//							}else
3267
3268
							if(!empty($this->options['block-output'])){
3269
//                               echo "return";
3270
//                               $this->block_element( $this->options['block-output'], true );
3271
//                               echo ";";
3272
3273
							   ?>
3274
							  return el(
3275
								   '',
3276
								   {},
3277
								  // el('', {dangerouslySetInnerHTML: {__html: content}}),
3278
								   <?php $this->block_element( $this->options['block-output'], true ); ?>
3279
								  // el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
3280
							   );
3281
								<?php
3282
3283
							}elseif(!empty($this->options['block-save-return'])){
3284
								   echo 'return ' . $this->options['block-save-return'];
3285
							}elseif(!empty($this->options['nested-block'])){
3286
								?>
3287
							  return el(
3288
								   '',
3289
								   {},
3290
								   el('', {dangerouslySetInnerHTML: {__html: content+"\n"}}),
3291
								   InnerBlocks.Content ? el( InnerBlocks.Content ) : '', // @todo i think we need a comma here
3292
								 //  el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
3293
							   );
3294
								<?php
3295
							}elseif(!empty( $this->options['block-save-return'] ) ){
3296
								echo "return ". $this->options['block-edit-return'].";";
3297
							}elseif(isset( $this->options['block-wrap'] ) && $this->options['block-wrap'] == ''){
3298
							?>
3299
							return content;
3300
							<?php
3301
							}else{
3302
							?>
3303
							var block_wrap = 'div';
3304
							if (attr.hasOwnProperty("block_wrap")) {
3305
								block_wrap = attr.block_wrap;
3306
							}
3307
							return el(block_wrap, wp.blockEditor.useBlockProps.save( {dangerouslySetInnerHTML: {__html: content}, className: align} ));
3308
							<?php
3309
							}
3310
							?>
3311
3312
3313
						}
3314
					});
3315
				})(
3316
					window.wp.blocks,
3317
	window.wp.element,
3318
	window.wp.blockEditor
3319
				);
3320
3321
				});
3322
			</script>
3323
			<?php
3324
			$output = ob_get_clean();
3325
3326
			/*
3327
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
3328
			 */
3329
3330
			return str_replace( array(
3331
				'<script>',
3332
				'</script>'
3333
			), '', $output );
3334
		}
3335
3336
3337
3338
		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

3338
		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...
3339
3340
			// check for row
3341
			if(!empty($args['row'])){
3342
3343
				if(!empty($args['row']['open'])){
3344
3345
				// element require
3346
				$element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3347
				$device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3348
				$device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3349
				$device_type_icon = '';
3350
				if($device_type=='Desktop'){
3351
					$device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3352
				}elseif($device_type=='Tablet'){
3353
					$device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3354
				}elseif($device_type=='Mobile'){
3355
					$device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3356
				}
3357
				echo $element_require;
3358
				echo $device_type_require;
3359
3360
					if(false){?><script><?php }?>
3361
						el('div', {
3362
								className: 'bsui components-base-control',
3363
							},
3364
							<?php if(!empty($args['row']['title'])){ ?>
3365
							el('label', {
3366
									className: 'components-base-control__label position-relative',
3367
									style: {width:"100%"}
3368
								},
3369
								el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['row']['title'] ) ?>'}}),
3370
								<?php if($device_type_icon){ ?>
3371
									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)"}})
3372
								<?php
3373
								}
3374
								?>
3375
3376
3377
							),
3378
							<?php }?>
3379
							<?php if(!empty($args['row']['desc'])){ ?>
3380
							el('p', {
3381
									className: 'components-base-control__help mb-0',
3382
								},
3383
								'<?php echo addslashes( $args['row']['desc'] ); ?>'
3384
							),
3385
							<?php }?>
3386
							el(
3387
								'div',
3388
								{
3389
									className: 'row mb-n2 <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>',
3390
								},
3391
								el(
3392
									'div',
3393
									{
3394
										className: 'col pr-2 pe-2',
3395
									},
3396
3397
					<?php
3398
					if(false){?></script><?php }
3399
				}elseif(!empty($args['row']['close'])){
3400
					if(false){?><script><?php }?>
3401
						el(
3402
							'div',
3403
							{
3404
								className: 'col pl-0 ps-0',
3405
							},
3406
					<?php
3407
					if(false){?></script><?php }
3408
				}else{
3409
					if(false){?><script><?php }?>
3410
						el(
3411
							'div',
3412
							{
3413
								className: 'col pl-0 ps-0 pr-2 pe-2',
3414
							},
3415
					<?php
3416
					if(false){?></script><?php }
3417
				}
3418
3419
			}
3420
3421
		}
3422
3423
		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

3423
		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...
3424
3425
			if(!empty($args['row'])){
3426
				// maybe close
3427
				if(!empty($args['row']['close'])){
3428
					echo "))";
3429
				}
3430
3431
				echo "),";
3432
			}
3433
		}
3434
3435
		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

3435
		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...
3436
3437
			// check for row
3438
			if(!empty($args['tab'])){
3439
3440
				if(!empty($args['tab']['tabs_open'])){
3441
3442
					if(false){?><script><?php }?>
3443
3444
el('div',{className: 'bsui'},
3445
3446
						el('hr', {className: 'm-0'}), el(
3447
									wp.components.TabPanel,
3448
									{
3449
										activeClass: 'is-active',
3450
										className: 'btn-groupx',
3451
										initialTabName: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3452
										tabs: [
3453
3454
					<?php
3455
					if(false){?></script><?php }
3456
				}
3457
3458
				if(!empty($args['tab']['open'])){
3459
3460
					if(false){?><script><?php }?>
3461
							{
3462
												name: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3463
												title: el('div', {dangerouslySetInnerHTML: {__html: '<?php echo addslashes( esc_attr( $args['tab']['title']) ); ?>'}}),
3464
												className: '<?php echo addslashes( esc_attr( $args['tab']['class']) ); ?>',
3465
												content: el('div',{}, <?php if(!empty($args['tab']['desc'])){ ?>el('p', {
3466
									className: 'components-base-control__help mb-0',
3467
									dangerouslySetInnerHTML: {__html:'<?php echo addslashes( $args['tab']['desc'] ); ?>'}
3468
								}),<?php }
3469
					if(false){?></script><?php }
3470
				}
3471
3472
			}
3473
3474
		}
3475
3476
		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

3476
		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...
3477
3478
			if(!empty($args['tab'])){
3479
				// maybe close
3480
				if(!empty($args['tab']['close'])){
3481
					echo ")}, /* tab close */";
3482
				}
3483
3484
				if(!empty($args['tab']['tabs_close'])){
3485
					if(false){?><script><?php }?>
3486
						]}, ( tab ) => {
3487
								return tab.content;
3488
							}
3489
						)), /* tabs close */
3490
					<?php if(false){ ?></script><?php }
3491
				}
3492
			}
3493
		}
3494
3495
		public function build_block_arguments( $key, $args ) {
3496
			$custom_attributes = ! empty( $args['custom_attributes'] ) ? $this->array_to_attributes( $args['custom_attributes'] ) : '';
3497
			$options           = '';
3498
			$extra             = '';
3499
			$require           = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $require is dead and can be removed.
Loading history...
3500
			$inside_elements   = '';
3501
			$after_elements	   = '';
3502
3503
			// `content` is a protected and special argument
3504
			if ( $key == 'content' ) {
3505
				return;
3506
			}
3507
3508
			$device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3509
			$device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3510
			$device_type_icon = '';
3511
			if($device_type=='Desktop'){
3512
				$device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3513
			}elseif($device_type=='Tablet'){
3514
				$device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3515
			}elseif($device_type=='Mobile'){
3516
				$device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3517
			}
3518
3519
			// icon
3520
			$icon = '';
3521
			if( !empty( $args['icon'] ) ){
3522
				$icon .= "el('div', {";
3523
									$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

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

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

4402
			if ( function_exists( 'bricks_is_builder' ) && ( bricks_is_builder() || /** @scrutinizer ignore-call */ bricks_is_builder_call() ) ) {
Loading history...
4403
				$result = true;
4404
			}
4405
4406
			return $result;
4407
		}
4408
4409
		/**
4410
		 * General function to check if we are in a preview situation.
4411
		 *
4412
		 * @return bool
4413
		 *@since 1.0.6
4414
		 */
4415
		public function is_preview() {
4416
			$preview = false;
4417
			if ( $this->is_divi_preview() ) {
4418
				$preview = true;
4419
			} elseif ( $this->is_elementor_preview() ) {
4420
				$preview = true;
4421
			} elseif ( $this->is_beaver_preview() ) {
4422
				$preview = true;
4423
			} elseif ( $this->is_siteorigin_preview() ) {
4424
				$preview = true;
4425
			} elseif ( $this->is_cornerstone_preview() ) {
4426
				$preview = true;
4427
			} elseif ( $this->is_fusion_preview() ) {
4428
				$preview = true;
4429
			} elseif ( $this->is_oxygen_preview() ) {
4430
				$preview = true;
4431
			} elseif( $this->is_kallyas_zion_preview() ) {
4432
				$preview = true;
4433
			} elseif( $this->is_block_content_call() ) {
4434
				$preview = true;
4435
			} elseif( $this->is_bricks_preview() ) {
4436
				$preview = true;
4437
			}
4438
4439
			return $preview;
4440
		}
4441
4442
		/**
4443
		 * Output the super title.
4444
		 *
4445
		 * @param $args
4446
		 * @param array $instance
4447
		 *
4448
		 * @return string
4449
		 */
4450
		public function output_title( $args, $instance = array() ) {
4451
			$output = '';
4452
			if ( ! empty( $instance['title'] ) ) {
4453
				/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
4454
				$title  = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
4455
4456
				if ( empty( $instance['widget_title_tag'] ) ) {
4457
					if ( ! isset( $args['before_title'] ) ) {
4458
						$args['before_title'] = '';
4459
					}
4460
4461
					if ( ! isset( $args['after_title'] ) ) {
4462
						$args['after_title'] = '';
4463
					}
4464
4465
					$output = $args['before_title'] . $title . $args['after_title'];
4466
				} else {
4467
					$title_tag = esc_attr( $instance['widget_title_tag'] );
4468
4469
					// classes
4470
					$title_classes = array();
4471
					$title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : '';
4472
					$title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : '';
4473
					$title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : '';
4474
					$title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : '';
4475
					$title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : '';
4476
					$title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : '';
4477
					$title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : '';
4478
					$title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : '';
4479
					$title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : '';
4480
					$title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : '';
4481
					$title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : '';
4482
					$title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : '';
4483
					$title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : '';
4484
4485
					$class = !empty( $title_classes ) ? implode(" ",$title_classes) : '';
4486
					$output = "<$title_tag class='$class' >$title</$title_tag>";
4487
				}
4488
4489
			}
4490
4491
			return $output;
4492
		}
4493
4494
		/**
4495
		 * Outputs the options form inputs for the widget.
4496
		 *
4497
		 * @param array $instance The widget options.
4498
		 */
4499
		public function form( $instance ) {
4500
4501
			// set widget instance
4502
			$this->instance = $instance;
4503
4504
			// set it as a SD widget
4505
			echo $this->widget_advanced_toggle();
4506
4507
			echo "<p>" . esc_attr( $this->options['widget_ops']['description'] ) . "</p>";
4508
			$arguments_raw = $this->get_arguments();
4509
4510
			if ( is_array( $arguments_raw ) ) {
0 ignored issues
show
introduced by
The condition is_array($arguments_raw) is always true.
Loading history...
4511
4512
				$arguments = $this->group_arguments( $arguments_raw );
4513
4514
				// Do we have sections?
4515
				$has_sections = $arguments == $arguments_raw ? false : true;
4516
4517
4518
				if ( $has_sections ) {
4519
					$panel_count = 0;
4520
					foreach ( $arguments as $key => $args ) {
4521
4522
						?>
4523
						<script>
4524
							//							jQuery(this).find("i").toggleClass("fas fa-chevron-up fas fa-chevron-down");jQuery(this).next().toggle();
4525
						</script>
4526
						<?php
4527
4528
						$hide       = $panel_count ? ' style="display:none;" ' : '';
4529
						$icon_class = $panel_count ? 'fas fa-chevron-up' : 'fas fa-chevron-down';
4530
						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>";
4531
						echo "<div class='sd-toggle-group sd-input-group-" . sanitize_title_with_dashes( $key ) . "' $hide>";
4532
4533
						foreach ( $args as $k => $a ) {
4534
4535
							$this->widget_inputs_row_start($k, $a);
4536
							$this->widget_inputs( $a, $instance );
4537
							$this->widget_inputs_row_end($k, $a);
4538
4539
						}
4540
4541
						echo "</div>";
4542
4543
						$panel_count ++;
4544
4545
					}
4546
				} else {
4547
					foreach ( $arguments as $key => $args ) {
4548
						$this->widget_inputs_row_start($key, $args);
4549
						$this->widget_inputs( $args, $instance );
4550
						$this->widget_inputs_row_end($key, $args);
4551
					}
4552
				}
4553
4554
			}
4555
		}
4556
4557
		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

4557
		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...
4558
			if ( ! empty( $args['row'] ) ) {
4559
				// Maybe open
4560
				if ( ! empty( $args['row']['open'] ) ) {
4561
					?>
4562
					<div class='bsui sd-argument' data-argument='<?php echo esc_attr( $args['row']['key'] ); ?>' data-element_require='<?php echo ( ! empty( $args['row']['element_require'] ) ? $this->convert_element_require( $args['row']['element_require'] ) : '' ); ?>'>
4563
					<?php if ( ! empty( $args['row']['title'] ) ) { ?>
4564
					<?php
4565
						if ( isset( $args['row']['icon'] ) ) {
4566
							$args['row']['icon'] = '';
4567
						}
4568
4569
						if ( ! isset( $args['row']['device_type'] ) && isset( $args['device_type'] ) ) {
4570
							$args['row']['device_type'] = $args['device_type'];
4571
						}
4572
					?>
4573
					<label class="mb-0"><?php echo $this->widget_field_title( $args['row'] ); ?><?php echo $this->widget_field_desc( $args['row'] ); ?></label>
4574
					<?php } ?>
4575
					<div class='row<?php echo ( ! empty( $args['row']['class'] ) ? ' ' . esc_attr( $args['row']['class'] ) : '' ); ?>'>
4576
					<div class='col pr-2'>
4577
					<?php
4578
				} else if ( ! empty( $args['row']['close'] ) ) {
4579
					echo "<div class='col pl-0 ps-0'>";
4580
				} else {
4581
					echo "<div class='col pl-0 ps-0 pr-2 pe-2'>";
4582
				}
4583
			}
4584
		}
4585
4586
		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

4586
		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...
4587
			if ( ! empty( $args['row'] ) ) {
4588
				// Maybe close
4589
				if ( ! empty( $args['row']['close'] ) ) {
4590
					echo "</div></div>";
4591
				}
4592
				echo "</div>";
4593
			}
4594
		}
4595
4596
		/**
4597
		 * Get the hidden input that when added makes the advanced button show on widget settings.
4598
		 *
4599
		 * @return string
4600
		 */
4601
		public function widget_advanced_toggle() {
4602
4603
			$output = '';
4604
			if ( $this->block_show_advanced() ) {
4605
				$val = 1;
4606
			} else {
4607
				$val = 0;
4608
			}
4609
4610
			$output .= "<input type='hidden'  class='sd-show-advanced' value='$val' />";
4611
4612
			return $output;
4613
		}
4614
4615
		/**
4616
		 * Convert require element.
4617
		 *
4618
		 * @param string $input Input element.
4619
		 *
4620
		 * @return string $output
4621
		 *@since 1.0.0
4622
		 *
4623
		 */
4624
		public function convert_element_require( $input ) {
4625
			$input = str_replace( "'", '"', $input );// we only want double quotes
4626
4627
			$output = esc_attr( str_replace( array( "[%", "%]", "%:checked]" ), array(
4628
				"jQuery(form).find('[data-argument=\"",
4629
				"\"]').find('input,select,textarea').val()",
4630
				"\"]').find('input:checked').val()"
4631
			), $input ) );
4632
4633
			return $output;
4634
		}
4635
4636
		/**
4637
		 * Builds the inputs for the widget options.
4638
		 *
4639
		 * @param $args
4640
		 * @param $instance
4641
		 */
4642
		public function widget_inputs( $args, $instance ) {
4643
4644
			$class             = "";
4645
			$element_require   = "";
4646
			$custom_attributes = "";
4647
4648
			// get value
4649
			if ( isset( $instance[ $args['name'] ] ) ) {
4650
				$value = $instance[ $args['name'] ];
4651
			} elseif ( ! isset( $instance[ $args['name'] ] ) && ! empty( $args['default'] ) ) {
4652
				$value = is_array( $args['default'] ) ? array_map( "esc_html", $args['default'] ) : esc_html( $args['default'] );
4653
			} else {
4654
				$value = '';
4655
			}
4656
4657
			// get placeholder
4658
			if ( ! empty( $args['placeholder'] ) ) {
4659
				$placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'";
4660
			} else {
4661
				$placeholder = '';
4662
			}
4663
4664
			// get if advanced
4665
			if ( isset( $args['advanced'] ) && $args['advanced'] ) {
4666
				$class .= " sd-advanced-setting ";
4667
			}
4668
4669
			// element_require
4670
			if ( isset( $args['element_require'] ) && $args['element_require'] ) {
4671
				$element_require = $args['element_require'];
4672
			}
4673
4674
			// custom_attributes
4675
			if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) {
4676
				$custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true );
4677
			}
4678
4679
			// before wrapper
4680
			?>
4681
			<p class="sd-argument <?php echo esc_attr( $class ); ?>" data-argument='<?php echo esc_attr( $args['name'] ); ?>' data-element_require='<?php if ( $element_require ) { echo $this->convert_element_require( $element_require );} ?>'>
4682
			<?php
4683
			switch ( $args['type'] ) {
4684
				//array('text','password','number','email','tel','url','color')
4685
				case "text":
4686
				case "password":
4687
				case "number":
4688
				case "email":
4689
				case "tel":
4690
				case "url":
4691
				case "color":
4692
					?>
4693
					<label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args );?><?php echo $this->widget_field_desc( $args ); ?></label>
4694
					<input <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="<?php echo esc_attr( $args['type'] ); ?>" value="<?php echo esc_attr( $value ); ?>">
4695
					<?php
4696
4697
					break;
4698
				case "select":
4699
					$multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false;
4700
					if ( $multiple ) {
4701
						if ( empty( $value ) ) {
4702
							$value = array();
4703
						}
4704
					}
4705
					?>
4706
					<label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args ); ?><?php echo $this->widget_field_desc( $args ); ?></label>
4707
					<select <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); if ( $multiple ) { echo "[]"; } ?>"
4708
						<?php if ( $multiple ) {
4709
							echo "multiple";
4710
						} //@todo not implemented yet due to gutenberg not supporting it
4711
						?>>
4712
						<?php
4713
4714
						if ( ! empty( $args['options'] ) ) {
4715
							foreach ( $args['options'] as $val => $label ) {
4716
								if ( $multiple ) {
4717
									$selected = in_array( $val, $value ) ? 'selected="selected"' : '';
4718
								} else {
4719
									$selected = selected( $value, $val, false );
4720
								}
4721
								echo "<option value='$val' " . $selected . ">$label</option>";
4722
							}
4723
						}
4724
						?>
4725
					</select>
4726
					<?php
4727
					break;
4728
				case "checkbox":
4729
					?>
4730
					<input <?php echo $placeholder; ?> <?php checked( 1, $value, true ) ?> <?php echo $custom_attributes; ?> class="widefat" id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="checkbox" value="1">
4731
					<label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args );?><?php echo $this->widget_field_desc( $args ); ?></label>
4732
					<?php
4733
					break;
4734
				case "textarea":
4735
					?>
4736
					<label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args ); ?><?php echo $this->widget_field_desc( $args ); ?></label>
4737
					<textarea <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>"><?php echo esc_attr( $value ); ?></textarea>
4738
					<?php
4739
4740
					break;
4741
				case "hidden":
4742
					?>
4743
					<input id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="hidden" value="<?php echo esc_attr( $value ); ?>">
4744
					<?php
4745
					break;
4746
				default:
4747
					echo "No input type found!"; // @todo we need to add more input types.
4748
			}
4749
			// after wrapper
4750
			?></p><?php
4751
		}
4752
4753
		public function get_widget_icon($icon = 'box-top', $title = ''){
4754
			if($icon=='box-top'){
4755
				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>';
4756
			}elseif($icon=='box-right'){
4757
				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>';
4758
			}elseif($icon=='box-bottom'){
4759
				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>';
4760
			}elseif($icon=='box-left'){
4761
				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>';
4762
			}
4763
		}
4764
4765
		/**
4766
		 * Get the widget input description html.
4767
		 *
4768
		 * @param $args
4769
		 *
4770
		 * @return string
4771
		 * @todo, need to make its own tooltip script
4772
		 */
4773
		public function widget_field_desc( $args ) {
4774
4775
			$description = '';
4776
			if ( isset( $args['desc'] ) && $args['desc'] ) {
4777
				if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) {
4778
					$description = $this->desc_tip( $args['desc'] );
4779
				} else {
4780
					$description = '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>';
4781
				}
4782
			}
4783
4784
			return $description;
4785
		}
4786
4787
		/**
4788
		 * Get the widget input title html.
4789
		 *
4790
		 * @param $args
4791
		 *
4792
		 * @return string
4793
		 */
4794
		public function widget_field_title( $args ) {
4795
			$title = '';
4796
4797
			if ( isset( $args['title'] ) && $args['title'] ) {
4798
				if ( ! empty( $args['device_type'] ) ) {
4799
					$args['title'] .= ' (' . $args['device_type'] . ')'; // Append device type to title.
4800
				}
4801
4802
				if ( isset( $args['icon'] ) && $args['icon'] ) {
4803
					$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

4803
					/** @scrutinizer ignore-call */ 
4804
     $title = self::get_widget_icon( $args['icon'], $args['title']  );
Loading history...
4804
				} else {
4805
					$title = esc_attr( $args['title'] );
4806
				}
4807
			}
4808
4809
			return $title;
4810
		}
4811
4812
		/**
4813
		 * Get the tool tip html.
4814
		 *
4815
		 * @param $tip
4816
		 * @param bool $allow_html
4817
		 *
4818
		 * @return string
4819
		 */
4820
		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...
4821
			if ( $allow_html ) {
4822
				$tip = $this->sanitize_tooltip( $tip );
4823
			} else {
4824
				$tip = esc_attr( $tip );
4825
			}
4826
4827
			return '<span class="gd-help-tip dashicons dashicons-editor-help" title="' . $tip . '"></span>';
4828
		}
4829
4830
		/**
4831
		 * Sanitize a string destined to be a tooltip.
4832
		 *
4833
		 * @param string $var
4834
		 *
4835
		 * @return string
4836
		 */
4837
		public function sanitize_tooltip( $var ) {
4838
			return htmlspecialchars( wp_kses( html_entity_decode( $var ), array(
4839
				'br'     => array(),
4840
				'em'     => array(),
4841
				'strong' => array(),
4842
				'small'  => array(),
4843
				'span'   => array(),
4844
				'ul'     => array(),
4845
				'li'     => array(),
4846
				'ol'     => array(),
4847
				'p'      => array(),
4848
			) ) );
4849
		}
4850
4851
		/**
4852
		 * Processing widget options on save
4853
		 *
4854
		 * @param array $new_instance The new options
4855
		 * @param array $old_instance The previous options
4856
		 *
4857
		 * @return array
4858
		 * @todo we should add some sanitation here.
4859
		 */
4860
		public function update( $new_instance, $old_instance ) {
4861
4862
			//save the widget
4863
			$instance = array_merge( (array) $old_instance, (array) $new_instance );
4864
4865
			// set widget instance
4866
			$this->instance = $instance;
4867
4868
			if ( empty( $this->arguments ) ) {
4869
				$this->get_arguments();
4870
			}
4871
4872
			// check for checkboxes
4873
			if ( ! empty( $this->arguments ) ) {
4874
				foreach ( $this->arguments as $argument ) {
4875
					if ( isset( $argument['type'] ) && $argument['type'] == 'checkbox' && ! isset( $new_instance[ $argument['name'] ] ) ) {
4876
						$instance[ $argument['name'] ] = '0';
4877
					}
4878
				}
4879
			}
4880
4881
			return $instance;
4882
		}
4883
4884
		/**
4885
		 * Checks if the current call is a ajax call to get the block content.
4886
		 *
4887
		 * This can be used in your widget to return different content as the block content.
4888
		 *
4889
		 * @return bool
4890
		 *@since 1.0.3
4891
		 */
4892
		public function is_block_content_call() {
4893
			$result = false;
4894
			if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'super_duper_output_shortcode' ) {
4895
				$result = true;
4896
			}
4897
4898
			return $result;
4899
		}
4900
4901
		/**
4902
		 * Get an instance hash that will be unique to the type and settings.
4903
		 *
4904
		 * @return string
4905
		 *@since 1.0.20
4906
		 */
4907
		public function get_instance_hash(){
4908
			$instance_string = $this->base_id.serialize($this->instance);
4909
			return hash('crc32b',$instance_string);
4910
		}
4911
4912
		/**
4913
		 * Generate and return inline styles from CSS rules that will match the unique class of the instance.
4914
		 *
4915
		 * @param array $rules
4916
		 *
4917
		 * @return string
4918
		 *@since 1.0.20
4919
		 */
4920
		public function get_instance_style($rules = array()){
4921
			$css = '';
4922
4923
			if(!empty($rules)){
4924
				$rules = array_unique($rules);
4925
				$instance_hash = $this->get_instance_hash();
4926
				$css .= "<style>";
4927
				foreach($rules as $rule){
4928
					$css .= ".sdel-$instance_hash $rule";
4929
				}
4930
				$css .= "</style>";
4931
			}
4932
4933
			return $css;
4934
		}
4935
4936
		/**
4937
		 * Encode shortcodes tags.
4938
		 *
4939
		 * @param string $content Content to search for shortcode tags.
4940
		 *
4941
*@return string Content with shortcode tags removed.
4942
		 *@since 1.0.28
4943
		 *
4944
		 */
4945
		public function encode_shortcodes( $content ) {
4946
			// Avoids existing encoded tags.
4947
			$trans   = array(
4948
				'&#91;' => '&#091;',
4949
				'&#93;' => '&#093;',
4950
				'&amp;#91;' => '&#091;',
4951
				'&amp;#93;' => '&#093;',
4952
				'&lt;' => '&0lt;',
4953
				'&gt;' => '&0gt;',
4954
				'&amp;lt;' => '&0lt;',
4955
				'&amp;gt;' => '&0gt;',
4956
			);
4957
4958
			$content = strtr( $content, $trans );
4959
4960
			$trans   = array(
4961
				'[' => '&#91;',
4962
				']' => '&#93;',
4963
				'<' => '&lt;',
4964
				'>' => '&gt;',
4965
				'"' => '&quot;',
4966
				"'" => '&#39;',
4967
			);
4968
4969
			$content = strtr( $content, $trans );
4970
4971
			return $content;
4972
		}
4973
4974
		/**
4975
		 * Remove encoded shortcod tags.
4976
		 *
4977
		 * @param string $content Content to search for shortcode tags.
4978
		 *
4979
*@return string Content with decoded shortcode tags.
4980
		 *@since 1.0.28
4981
		 *
4982
		 */
4983
		public function decode_shortcodes( $content ) {
4984
			$trans   = array(
4985
				'&#91;' => '[',
4986
				'&#93;' => ']',
4987
				'&amp;#91;' => '[',
4988
				'&amp;#93;' => ']',
4989
				'&lt;' => '<',
4990
				'&gt;' => '>',
4991
				'&amp;lt;' => '<',
4992
				'&amp;gt;' => '>',
4993
				'&quot;' => '"',
4994
				'&apos;' => "'",
4995
			);
4996
4997
			$content = strtr( $content, $trans );
4998
4999
			$trans   = array(
5000
				'&#091;' => '&#91;',
5001
				'&#093;' => '&#93;',
5002
				'&amp;#091;' => '&#91;',
5003
				'&amp;#093;' => '&#93;',
5004
				'&0lt;' => '&lt;',
5005
				'&0gt;' => '&gt;',
5006
				'&amp;0lt;' => '&lt;',
5007
				'&amp;0gt;' => '&gt;',
5008
			);
5009
5010
			$content = strtr( $content, $trans );
5011
5012
			return $content;
5013
		}
5014
5015
		public function block_visibility_fields( $args ) {
5016
			$value = ! empty( $args['value'] ) ? esc_attr( $args['value'] ) : '';
5017
			$content = '<div class="bs-vc-rule-template d-none">';
5018
				$content .= '<div class="p-3 pb-0 mb-3 border border-1 rounded-1 position-relative bs-vc-rule" data-bs-index="BSVCINDEX" >';
5019
					$content .= '<div class="row">';
5020
						$content .= '<div class="col-sm-12">';
5021
							$content .= '<div class="bs-rule-action position-absolute top-0 end-0 p-2 zindex-5"><span class="text-danger c-pointer bs-vc-remove-rule" title="' . esc_attr__( 'Remove Rule', 'ayecode-connect' ) . '"><i class="fas fa-circle-minus fs-6"></i></span></div>';
5022
							$content .= aui()->select(
5023
								array(
5024
									'id'          => 'bsvc_rule_BSVCINDEX',
5025
									'name'        => 'bsvc_rule_BSVCINDEX',
5026
									'label'       => __( 'Rule', 'ayecode-connect' ),
5027
									'placeholder' => __( 'Select Rule...', 'ayecode-connect' ),
5028
									'class'       => 'bsvc_rule form-select-sm no-select2 mw-100',
5029
									'options'     => sd_visibility_rules_options(),
5030
									'default'     => '',
5031
									'value'       => '',
5032
									'label_type'  => '',
5033
									'select2'     => false,
5034
									'input_group_left' => __( 'Rule:', 'ayecode-connect' ),
5035
									'extra_attributes' => array(
5036
										'data-minimum-results-for-search' => '-1'
5037
									)
5038
								)
5039
							);
5040
5041
						$content .= '</div>';
5042
5043
						if ( class_exists( 'GeoDirectory' ) ) {
5044
							$content .= '<div class="col-md-7 col-sm-12">';
5045
5046
								$content .= aui()->select(
5047
									array(
5048
										'id'          => 'bsvc_gd_field_BSVCINDEX',
5049
										'name'        => 'bsvc_gd_field_BSVCINDEX',
5050
										'label'       => __( 'FIELD', 'ayecode-connect' ),
5051
										'placeholder' => __( 'FIELD', 'ayecode-connect' ),
5052
										'class'       => 'bsvc_gd_field form-select-sm no-select2 mw-100',
5053
										'options'     => sd_visibility_gd_field_options(),
5054
										'default'     => '',
5055
										'value'       => '',
5056
										'label_type'  => '',
5057
										'select2'     => false,
5058
										'element_require'  => '[%bsvc_rule_BSVCINDEX%]=="gd_field"',
5059
										'extra_attributes' => array(
5060
											'data-minimum-results-for-search' => '-1'
5061
										)
5062
									)
5063
								);
5064
5065
							$content .= '</div>';
5066
							$content .= '<div class="col-md-5 col-sm-12">';
5067
5068
								$content .= aui()->select(
5069
									array(
5070
										'id'          => 'bsvc_gd_field_condition_BSVCINDEX',
5071
										'name'        => 'bsvc_gd_field_condition_BSVCINDEX',
5072
										'label'       => __( 'CONDITION', 'ayecode-connect' ),
5073
										'placeholder' => __( 'CONDITION', 'ayecode-connect' ),
5074
										'class'       => 'bsvc_gd_field_condition form-select-sm no-select2 mw-100',
5075
										'options'     => sd_visibility_field_condition_options(),
5076
										'default'     => '',
5077
										'value'       => '',
5078
										'label_type'  => '',
5079
										'select2'     => false,
5080
										'element_require'  => '[%bsvc_rule_BSVCINDEX%]=="gd_field"',
5081
										'extra_attributes' => array(
5082
											'data-minimum-results-for-search' => '-1'
5083
										)
5084
									)
5085
								);
5086
5087
							$content .= '</div>';
5088
							$content .= '<div class="col-sm-12">';
5089
5090
								$content .= aui()->input(
5091
									array(
5092
										'type'            => 'text',
5093
										'id'              => 'bsvc_gd_field_search_BSVCINDEX',
5094
										'name'            => 'bsvc_gd_field_search_BSVCINDEX',
5095
										'label'           => __( 'VALUE TO MATCH', 'ayecode-connect' ),
5096
										'class'           => 'bsvc_gd_field_search form-control-sm',
5097
										'placeholder'     => __( 'VALUE TO MATCH', 'ayecode-connect' ),
5098
										'label_type'      => '',
5099
										'value'           => '',
5100
										'element_require' => '([%bsvc_rule_BSVCINDEX%]=="gd_field" && [%bsvc_gd_field_condition_BSVCINDEX%] && [%bsvc_gd_field_condition_BSVCINDEX%]!="is_empty" && [%bsvc_gd_field_condition_BSVCINDEX%]!="is_not_empty")'
5101
									)
5102
								);
5103
5104
							$content .= '</div>';
5105
						}
5106
5107
					$content .= '</div>';
5108
5109
					$content .= '<div class="row aui-conditional-field" data-element-require="jQuery(form).find(\'[name=bsvc_rule_BSVCINDEX]\').val()==\'user_roles\'" data-argument="bsvc_user_roles_BSVCINDEX_1"><label for="bsvc_user_roles_BSVCINDEX_1" class="form-label mb-3">' . __( 'Select User Roles:', 'ayecode-connect' ) . '</label>';
5110
						$role_options = sd_user_roles_options();
5111
5112
						$role_option_i = 0;
5113
						foreach ( $role_options as $role_option_key => $role_option_name ) {
5114
							$role_option_i++;
5115
5116
							$content .= '<div class="col-sm-6">';
5117
							$content .= aui()->input(
5118
								array(
5119
									'id'               => 'bsvc_user_roles_BSVCINDEX_' . $role_option_i,
5120
									'name'             => 'bsvc_user_roles_BSVCINDEX[]',
5121
									'type'             => 'checkbox',
5122
									'label'            => $role_option_name,
5123
									'label_type'       => 'hidden',
5124
									'class'            => 'bsvc_user_roles',
5125
									'value'            => $role_option_key,
5126
									'switch'           => 'md',
5127
									'no_wrap'          => true
5128
								)
5129
							);
5130
							$content .= '</div>';
5131
						}
5132
					$content .= '</div>';
5133
				$content .= '</div>';
5134
			$content .= '</div>';
5135
			$content .= '<form id="bs-vc-modal-form" class="bs-vc-modal-form">';
5136
			$content .= '<div class="bs-vc-rule-sets"></div>';
5137
			$content .= '<div class="row"><div class="col-sm-12 text-center pt-1 pb-4"><button type="button" class="btn btn-sm btn-primary d-block w-100 bs-vc-add-rule"><i class="fas fa-plus"></i> ' . __( 'Add Rule', 'ayecode-connect' ) . '</button></div></div>';
5138
			$content .= '<div class="row"><div class="col-md-6 col-sm-12">';
5139
			$content .= aui()->select(
5140
				array(
5141
					'id'          => 'bsvc_output',
5142
					'name'        => 'bsvc_output',
5143
					'label'       => __( 'What should happen if rules met.', 'ayecode-connect' ),
5144
					'placeholder' => __( 'Default Output', 'ayecode-connect' ),
5145
					'class'       => 'bsvc_output form-select-sm no-select2 mw-100',
5146
					'options'     => sd_visibility_output_options(),
5147
					'default'     => '',
5148
					'value'       => '',
5149
					'label_type'  => 'top',
5150
					'select2'     => false,
5151
					'extra_attributes' => array(
5152
						'data-minimum-results-for-search' => '-1'
5153
					)
5154
				)
5155
			);
5156
5157
			$content .= '</div><div class="col-md-6 col-sm-12">';
5158
5159
			$content .= aui()->select(
5160
				array(
5161
					'id'              => 'bsvc_page',
5162
					'name'            => 'bsvc_page',
5163
					'label'           => __( 'Page Content', 'ayecode-connect' ),
5164
					'placeholder'     => __( 'Select Page ID...', 'ayecode-connect' ),
5165
					'class'           => 'bsvc_page form-select-sm no-select2 mw-100',
5166
					'options'         => sd_template_page_options(),
5167
					'default'         => '',
5168
					'value'           => '',
5169
					'label_type'      => 'top',
5170
					'select2'         => false,
5171
					'element_require' => '[%bsvc_output%]=="page"'
5172
				)
5173
			);
5174
5175
			$content .= aui()->select(
5176
				array(
5177
					'id'          => 'bsvc_tmpl_part',
5178
					'name'        => 'bsvc_tmpl_part',
5179
					'label'       => __( 'Template Part', 'ayecode-connect' ),
5180
					'placeholder' => __( 'Select Template Part...', 'ayecode-connect' ),
5181
					'class'       => 'bsvc_tmpl_part form-select-sm no-select2 mw-100',
5182
					'options'     => sd_template_part_options(),
5183
					'default'     => '',
5184
					'value'       => '',
5185
					'label_type'  => 'top',
5186
					'select2'     => false,
5187
					'element_require'  => '[%bsvc_output%]=="template_part"',
5188
					'extra_attributes' => array(
5189
						'data-minimum-results-for-search' => '-1'
5190
					)
5191
				)
5192
			);
5193
5194
			$content .= aui()->select(
5195
				array(
5196
					'id'               => 'bsvc_message_type',
5197
					'name'             => 'bsvc_message_type',
5198
					'label'            => __( 'Custom Message Type', 'ayecode-connect' ),
5199
					'placeholder'      => __( 'Default (none)', 'ayecode-connect' ),
5200
					'class'            => 'bsvc_message_type form-select-sm no-select2 mw-100',
5201
					'options'          => sd_aui_colors(),
5202
					'default'          => '',
5203
					'value'            => '',
5204
					'label_type'       => 'top',
5205
					'select2'          => false,
5206
					'element_require'  => '[%bsvc_output%]=="message"',
5207
					'extra_attributes' => array(
5208
						'data-minimum-results-for-search' => '-1'
5209
					)
5210
				)
5211
			);
5212
5213
			$content .= '</div><div class="col-sm-12">';
5214
5215
			$content .= aui()->input(
5216
				array(
5217
					'type'            => 'text',
5218
					'id'              => 'bsvc_message',
5219
					'name'            => 'bsvc_message',
5220
					'label'           => '',
5221
					'class'           => 'bsvc_message form-control-sm',
5222
					'placeholder'     => __( 'CUSTOM MESSAGE TO SHOW', 'ayecode-connect' ),
5223
					'label_type'      => '',
5224
					'value'           => '',
5225
					'form_group_class' => ' ',
5226
					'element_require' => '[%bsvc_output%]=="message"',
5227
				)
5228
			);
5229
5230
			$content .= '</div></div></form><input type="hidden" id="bsvc_raw_value" name="bsvc_raw_value" value="' . $value . '">';
5231
5232
			return $content;
5233
		}
5234
5235
		/**
5236
		 * Handle media_buttons hook.
5237
		 *
5238
		 * @since 1.2.7
5239
		 */
5240
		public function wp_media_buttons() {
5241
			global $shortcode_insert_button_once;
5242
5243
			// Fix conflicts with UpSolution Core in header template edit element.
5244
			if ( defined( 'US_CORE_DIR' ) && ! empty( $_REQUEST['action'] ) && $_REQUEST['action'] == 'us_ajax_hb_get_ebuilder_html' ) {
5245
				$shortcode_insert_button_once = true;
5246
			}
5247
		}
5248
	}
5249
}
5250