Passed
Pull Request — master (#817)
by Kiran
05:40
created

WP_Super_Duper::get_url()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

2538
						$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...
2539
						if( isset( $this->options['example'] ) && $this->options['example'] === false ){
2540
							// no preview if set to false
2541
						}elseif( !empty( $example_args ) ){
2542
							echo "example : {attributes:{".$this->array_to_attributes( $example_args )."},$viewport_width},";
2543
						}elseif( !empty( $this->options['example'] ) ){
2544
							unset($this->options['example']['viewportWidth']);
2545
							unset($this->options['example']['innerBlocks']);
2546
							$example_atts = $this->array_to_attributes( $this->options['example'] );
2547
							$example_parts = array();
2548
							if($example_atts){
2549
								$example_parts[] = rtrim($example_atts,",");
2550
							}
2551
							if($viewport_width){
2552
								$example_parts[] = $viewport_width;
2553
							}
2554
							if($example_inner_blocks){
2555
								$example_parts[] = $example_inner_blocks;
2556
							}
2557
							if(!empty($example_parts)){
2558
								echo "example : {".implode(',', $example_parts)."},";
2559
							}
2560
						}else{
2561
							echo 'example : {viewportWidth: 500},';
2562
						}
2563
2564
2565
2566
						// limit to parent
2567
						if( !empty( $this->options['parent'] ) ){
2568
							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

2568
							echo "parent : " . /** @scrutinizer ignore-type */ wp_json_encode( $this->options['parent'] ) . ",";
Loading history...
2569
						}
2570
2571
						// limit allowed blocks
2572
						if( !empty( $this->options['allowed-blocks'] ) ){
2573
							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

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

3393
		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...
3394
3395
			// check for row
3396
			if(!empty($args['row'])){
3397
3398
				if(!empty($args['row']['open'])){
3399
3400
				// element require
3401
				$element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3402
				$device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3403
				$device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3404
				$device_type_icon = '';
3405
				if($device_type=='Desktop'){
3406
					$device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3407
				}elseif($device_type=='Tablet'){
3408
					$device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3409
				}elseif($device_type=='Mobile'){
3410
					$device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3411
				}
3412
				echo $element_require;
3413
				echo $device_type_require;
3414
3415
					if(false){?><script><?php }?>
3416
						el('div', {
3417
								className: 'bsui components-base-control',
3418
							},
3419
							<?php if(!empty($args['row']['title'])){ ?>
3420
							el('label', {
3421
									className: 'components-base-control__label position-relative',
3422
									style: {width:"100%"}
3423
								},
3424
								el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['row']['title'] ) ?>'}}),
3425
								<?php if($device_type_icon){ ?>
3426
									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)"}})
3427
								<?php
3428
								}
3429
								?>
3430
3431
3432
							),
3433
							<?php }?>
3434
							<?php if(!empty($args['row']['desc'])){ ?>
3435
							el('p', {
3436
									className: 'components-base-control__help mb-0',
3437
								},
3438
								'<?php echo addslashes( $args['row']['desc'] ); ?>'
3439
							),
3440
							<?php }?>
3441
							el(
3442
								'div',
3443
								{
3444
									className: 'row mb-n2 <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>',
3445
								},
3446
								el(
3447
									'div',
3448
									{
3449
										className: 'col pr-2 pe-2',
3450
									},
3451
3452
					<?php
3453
					if(false){?></script><?php }
3454
				}elseif(!empty($args['row']['close'])){
3455
					if(false){?><script><?php }?>
3456
						el(
3457
							'div',
3458
							{
3459
								className: 'col pl-0 ps-0',
3460
							},
3461
					<?php
3462
					if(false){?></script><?php }
3463
				}else{
3464
					if(false){?><script><?php }?>
3465
						el(
3466
							'div',
3467
							{
3468
								className: 'col pl-0 ps-0 pr-2 pe-2',
3469
							},
3470
					<?php
3471
					if(false){?></script><?php }
3472
				}
3473
3474
			}
3475
3476
		}
3477
3478
		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

3478
		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...
3479
3480
			if(!empty($args['row'])){
3481
				// maybe close
3482
				if(!empty($args['row']['close'])){
3483
					echo "))";
3484
				}
3485
3486
				echo "),";
3487
			}
3488
		}
3489
3490
		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

3490
		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...
3491
3492
			// check for row
3493
			if(!empty($args['tab'])){
3494
3495
				if(!empty($args['tab']['tabs_open'])){
3496
3497
					if(false){?><script><?php }?>
3498
3499
el('div',{className: 'bsui'},
3500
3501
						el('hr', {className: 'm-0'}), el(
3502
									wp.components.TabPanel,
3503
									{
3504
										activeClass: 'is-active',
3505
										className: 'btn-groupx',
3506
										initialTabName: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3507
										tabs: [
3508
3509
					<?php
3510
					if(false){?></script><?php }
3511
				}
3512
3513
				if(!empty($args['tab']['open'])){
3514
3515
					if(false){?><script><?php }?>
3516
							{
3517
												name: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3518
												title: el('div', {dangerouslySetInnerHTML: {__html: '<?php echo addslashes( esc_attr( $args['tab']['title']) ); ?>'}}),
3519
												className: '<?php echo addslashes( esc_attr( $args['tab']['class']) ); ?>',
3520
												content: el('div',{}, <?php if(!empty($args['tab']['desc'])){ ?>el('p', {
3521
									className: 'components-base-control__help mb-0',
3522
									dangerouslySetInnerHTML: {__html:'<?php echo addslashes( $args['tab']['desc'] ); ?>'}
3523
								}),<?php }
3524
					if(false){?></script><?php }
3525
				}
3526
3527
			}
3528
3529
		}
3530
3531
		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

3531
		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...
3532
3533
			if(!empty($args['tab'])){
3534
				// maybe close
3535
				if(!empty($args['tab']['close'])){
3536
					echo ")}, /* tab close */";
3537
				}
3538
3539
				if(!empty($args['tab']['tabs_close'])){
3540
					if(false){?><script><?php }?>
3541
						]}, ( tab ) => {
3542
								return tab.content;
3543
							}
3544
						)), /* tabs close */
3545
					<?php if(false){ ?></script><?php }
3546
				}
3547
			}
3548
		}
3549
3550
		public function build_block_arguments( $key, $args ) {
3551
			$custom_attributes = ! empty( $args['custom_attributes'] ) ? $this->array_to_attributes( $args['custom_attributes'] ) : '';
3552
			$options           = '';
3553
			$extra             = '';
3554
			$require           = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $require is dead and can be removed.
Loading history...
3555
			$inside_elements   = '';
3556
			$after_elements	   = '';
3557
3558
			// `content` is a protected and special argument
3559
			if ( $key == 'content' ) {
3560
				return;
3561
			}
3562
3563
			$device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3564
			$device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3565
			$device_type_icon = '';
3566
			if($device_type=='Desktop'){
3567
				$device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3568
			}elseif($device_type=='Tablet'){
3569
				$device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3570
			}elseif($device_type=='Mobile'){
3571
				$device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3572
			}
3573
3574
			// icon
3575
			$icon = '';
3576
			if( !empty( $args['icon'] ) ){
3577
				$icon .= "el('div', {";
3578
									$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

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

4457
			if ( function_exists( 'bricks_is_builder' ) && ( bricks_is_builder() || /** @scrutinizer ignore-call */ bricks_is_builder_call() ) ) {
Loading history...
4458
				$result = true;
4459
			}
4460
4461
			return $result;
4462
		}
4463
4464
		/**
4465
		 * General function to check if we are in a preview situation.
4466
		 *
4467
		 * @return bool
4468
		 *@since 1.0.6
4469
		 */
4470
		public function is_preview() {
4471
			$preview = false;
4472
			if ( $this->is_divi_preview() ) {
4473
				$preview = true;
4474
			} elseif ( $this->is_elementor_preview() ) {
4475
				$preview = true;
4476
			} elseif ( $this->is_beaver_preview() ) {
4477
				$preview = true;
4478
			} elseif ( $this->is_siteorigin_preview() ) {
4479
				$preview = true;
4480
			} elseif ( $this->is_cornerstone_preview() ) {
4481
				$preview = true;
4482
			} elseif ( $this->is_fusion_preview() ) {
4483
				$preview = true;
4484
			} elseif ( $this->is_oxygen_preview() ) {
4485
				$preview = true;
4486
			} elseif( $this->is_kallyas_zion_preview() ) {
4487
				$preview = true;
4488
			} elseif( $this->is_block_content_call() ) {
4489
				$preview = true;
4490
			} elseif( $this->is_bricks_preview() ) {
4491
				$preview = true;
4492
			}
4493
4494
			return $preview;
4495
		}
4496
4497
		/**
4498
		 * Output the super title.
4499
		 *
4500
		 * @param $args
4501
		 * @param array $instance
4502
		 *
4503
		 * @return string
4504
		 */
4505
		public function output_title( $args, $instance = array() ) {
4506
			$output = '';
4507
			if ( ! empty( $instance['title'] ) ) {
4508
				/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
4509
				$title  = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
4510
4511
				if ( empty( $instance['widget_title_tag'] ) ) {
4512
					if ( ! isset( $args['before_title'] ) ) {
4513
						$args['before_title'] = '';
4514
					}
4515
4516
					if ( ! isset( $args['after_title'] ) ) {
4517
						$args['after_title'] = '';
4518
					}
4519
4520
					$output = $args['before_title'] . $title . $args['after_title'];
4521
				} else {
4522
					$tag 			= esc_attr( $instance['widget_title_tag'] );
4523
					$allowed_tags 	= array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'div', 'p' );
4524
					$title_tag      = in_array( $tag, $allowed_tags, true ) ? esc_attr( $tag ) : 'h2';
4525
4526
					// classes
4527
					$title_classes = array();
4528
					$title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : '';
4529
					$title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : '';
4530
					$title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : '';
4531
					$title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : '';
4532
					$title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : '';
4533
					$title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : '';
4534
					$title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : '';
4535
					$title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : '';
4536
					$title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : '';
4537
					$title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : '';
4538
					$title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : '';
4539
					$title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : '';
4540
					$title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : '';
4541
4542
					$class = !empty( $title_classes ) ? implode(" ",$title_classes) : '';
4543
					$output = "<$title_tag class='$class' >$title</$title_tag>";
4544
				}
4545
4546
			}
4547
4548
			return $output;
4549
		}
4550
4551
		/**
4552
		 * Outputs the options form inputs for the widget.
4553
		 *
4554
		 * @param array $instance The widget options.
4555
		 */
4556
		public function form( $instance ) {
4557
4558
			// set widget instance
4559
			$this->instance = $instance;
4560
4561
			// set it as a SD widget
4562
			echo $this->widget_advanced_toggle();
4563
4564
			echo "<p>" . esc_attr( $this->options['widget_ops']['description'] ) . "</p>";
4565
			$arguments_raw = $this->get_arguments();
4566
4567
			if ( is_array( $arguments_raw ) ) {
0 ignored issues
show
introduced by
The condition is_array($arguments_raw) is always true.
Loading history...
4568
4569
				$arguments = $this->group_arguments( $arguments_raw );
4570
4571
				// Do we have sections?
4572
				$has_sections = $arguments == $arguments_raw ? false : true;
4573
4574
4575
				if ( $has_sections ) {
4576
					$panel_count = 0;
4577
					foreach ( $arguments as $key => $args ) {
4578
4579
						?>
4580
						<script>
4581
							//							jQuery(this).find("i").toggleClass("fas fa-chevron-up fas fa-chevron-down");jQuery(this).next().toggle();
4582
						</script>
4583
						<?php
4584
4585
						$hide       = $panel_count ? ' style="display:none;" ' : '';
4586
						$icon_class = $panel_count ? 'fas fa-chevron-up' : 'fas fa-chevron-down';
4587
						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>";
4588
						echo "<div class='sd-toggle-group sd-input-group-" . sanitize_title_with_dashes( $key ) . "' $hide>";
4589
4590
						foreach ( $args as $k => $a ) {
4591
4592
							$this->widget_inputs_row_start($k, $a);
4593
							$this->widget_inputs( $a, $instance );
4594
							$this->widget_inputs_row_end($k, $a);
4595
4596
						}
4597
4598
						echo "</div>";
4599
4600
						$panel_count ++;
4601
4602
					}
4603
				} else {
4604
					foreach ( $arguments as $key => $args ) {
4605
						$this->widget_inputs_row_start($key, $args);
4606
						$this->widget_inputs( $args, $instance );
4607
						$this->widget_inputs_row_end($key, $args);
4608
					}
4609
				}
4610
4611
			}
4612
		}
4613
4614
		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

4614
		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...
4615
			if ( ! empty( $args['row'] ) ) {
4616
				// Maybe open
4617
				if ( ! empty( $args['row']['open'] ) ) {
4618
					?>
4619
					<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'] ) : '' ); ?>'>
4620
					<?php if ( ! empty( $args['row']['title'] ) ) { ?>
4621
					<?php
4622
						if ( isset( $args['row']['icon'] ) ) {
4623
							$args['row']['icon'] = '';
4624
						}
4625
4626
						if ( ! isset( $args['row']['device_type'] ) && isset( $args['device_type'] ) ) {
4627
							$args['row']['device_type'] = $args['device_type'];
4628
						}
4629
					?>
4630
					<label class="mb-0"><?php echo $this->widget_field_title( $args['row'] ); ?><?php echo $this->widget_field_desc( $args['row'] ); ?></label>
4631
					<?php } ?>
4632
					<div class='row<?php echo ( ! empty( $args['row']['class'] ) ? ' ' . esc_attr( $args['row']['class'] ) : '' ); ?>'>
4633
					<div class='col pr-2'>
4634
					<?php
4635
				} else if ( ! empty( $args['row']['close'] ) ) {
4636
					echo "<div class='col pl-0 ps-0'>";
4637
				} else {
4638
					echo "<div class='col pl-0 ps-0 pr-2 pe-2'>";
4639
				}
4640
			}
4641
		}
4642
4643
		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

4643
		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...
4644
			if ( ! empty( $args['row'] ) ) {
4645
				// Maybe close
4646
				if ( ! empty( $args['row']['close'] ) ) {
4647
					echo "</div></div>";
4648
				}
4649
				echo "</div>";
4650
			}
4651
		}
4652
4653
		/**
4654
		 * Get the hidden input that when added makes the advanced button show on widget settings.
4655
		 *
4656
		 * @return string
4657
		 */
4658
		public function widget_advanced_toggle() {
4659
4660
			$output = '';
4661
			if ( $this->block_show_advanced() ) {
4662
				$val = 1;
4663
			} else {
4664
				$val = 0;
4665
			}
4666
4667
			$output .= "<input type='hidden'  class='sd-show-advanced' value='$val' />";
4668
4669
			return $output;
4670
		}
4671
4672
		/**
4673
		 * Convert require element.
4674
		 *
4675
		 * @param string $input Input element.
4676
		 *
4677
		 * @return string $output
4678
		 *@since 1.0.0
4679
		 *
4680
		 */
4681
		public function convert_element_require( $input ) {
4682
			$input = str_replace( "'", '"', $input );// we only want double quotes
4683
4684
			$output = esc_attr( str_replace( array( "[%", "%]", "%:checked]" ), array(
4685
				"jQuery(form).find('[data-argument=\"",
4686
				"\"]').find('input,select,textarea').val()",
4687
				"\"]').find('input:checked').val()"
4688
			), $input ) );
4689
4690
			return $output;
4691
		}
4692
4693
		/**
4694
		 * Builds the inputs for the widget options.
4695
		 *
4696
		 * @param $args
4697
		 * @param $instance
4698
		 */
4699
		public function widget_inputs( $args, $instance ) {
4700
4701
			$class             = "";
4702
			$element_require   = "";
4703
			$custom_attributes = "";
4704
4705
			// get value
4706
			if ( isset( $instance[ $args['name'] ] ) ) {
4707
				$value = $instance[ $args['name'] ];
4708
			} elseif ( ! isset( $instance[ $args['name'] ] ) && ! empty( $args['default'] ) ) {
4709
				$value = is_array( $args['default'] ) ? array_map( "esc_html", $args['default'] ) : esc_html( $args['default'] );
4710
			} else {
4711
				$value = '';
4712
			}
4713
4714
			// get placeholder
4715
			if ( ! empty( $args['placeholder'] ) ) {
4716
				$placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'";
4717
			} else {
4718
				$placeholder = '';
4719
			}
4720
4721
			// get if advanced
4722
			if ( isset( $args['advanced'] ) && $args['advanced'] ) {
4723
				$class .= " sd-advanced-setting ";
4724
			}
4725
4726
			// element_require
4727
			if ( isset( $args['element_require'] ) && $args['element_require'] ) {
4728
				$element_require = $args['element_require'];
4729
			}
4730
4731
			// custom_attributes
4732
			if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) {
4733
				$custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true );
4734
			}
4735
4736
			// before wrapper
4737
			?>
4738
			<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 );} ?>'>
4739
			<?php
4740
			switch ( $args['type'] ) {
4741
				//array('text','password','number','email','tel','url','color')
4742
				case "text":
4743
				case "password":
4744
				case "number":
4745
				case "email":
4746
				case "tel":
4747
				case "url":
4748
				case "color":
4749
					?>
4750
					<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>
4751
					<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 ); ?>">
4752
					<?php
4753
4754
					break;
4755
				case "select":
4756
					$multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false;
4757
					if ( $multiple ) {
4758
						if ( empty( $value ) ) {
4759
							$value = array();
4760
						}
4761
					}
4762
					?>
4763
					<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>
4764
					<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 "[]"; } ?>"
4765
						<?php if ( $multiple ) {
4766
							echo "multiple";
4767
						} //@todo not implemented yet due to gutenberg not supporting it
4768
						?>>
4769
						<?php
4770
4771
						if ( ! empty( $args['options'] ) ) {
4772
							foreach ( $args['options'] as $val => $label ) {
4773
								if ( $multiple ) {
4774
									$selected = in_array( $val, $value ) ? 'selected="selected"' : '';
4775
								} else {
4776
									$selected = selected( $value, $val, false );
4777
								}
4778
								echo "<option value='$val' " . $selected . ">$label</option>";
4779
							}
4780
						}
4781
						?>
4782
					</select>
4783
					<?php
4784
					break;
4785
				case "checkbox":
4786
					?>
4787
					<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">
4788
					<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>
4789
					<?php
4790
					break;
4791
				case "textarea":
4792
					?>
4793
					<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>
4794
					<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>
4795
					<?php
4796
4797
					break;
4798
				case "hidden":
4799
					?>
4800
					<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 ); ?>">
4801
					<?php
4802
					break;
4803
				default:
4804
					echo "No input type found!"; // @todo we need to add more input types.
4805
			}
4806
			// after wrapper
4807
			?></p><?php
4808
		}
4809
4810
		public function get_widget_icon($icon = 'box-top', $title = ''){
4811
			if($icon=='box-top'){
4812
				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>';
4813
			}elseif($icon=='box-right'){
4814
				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>';
4815
			}elseif($icon=='box-bottom'){
4816
				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>';
4817
			}elseif($icon=='box-left'){
4818
				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>';
4819
			}
4820
		}
4821
4822
		/**
4823
		 * Get the widget input description html.
4824
		 *
4825
		 * @param $args
4826
		 *
4827
		 * @return string
4828
		 * @todo, need to make its own tooltip script
4829
		 */
4830
		public function widget_field_desc( $args ) {
4831
4832
			$description = '';
4833
			if ( isset( $args['desc'] ) && $args['desc'] ) {
4834
				if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) {
4835
					$description = $this->desc_tip( $args['desc'] );
4836
				} else {
4837
					$description = '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>';
4838
				}
4839
			}
4840
4841
			return $description;
4842
		}
4843
4844
		/**
4845
		 * Get the widget input title html.
4846
		 *
4847
		 * @param $args
4848
		 *
4849
		 * @return string
4850
		 */
4851
		public function widget_field_title( $args ) {
4852
			$title = '';
4853
4854
			if ( isset( $args['title'] ) && $args['title'] ) {
4855
				if ( ! empty( $args['device_type'] ) ) {
4856
					$args['title'] .= ' (' . $args['device_type'] . ')'; // Append device type to title.
4857
				}
4858
4859
				if ( isset( $args['icon'] ) && $args['icon'] ) {
4860
					$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

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