Passed
Push — master ( 991cb4...4e36e9 )
by Stiofan
03:52
created

WP_Super_Duper::_set()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 0
dl 0
loc 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Contains the main class.
4
 *
5
 * @since 1.0.0
6
 */
7
8
defined( 'ABSPATH' ) || exit;
9
10
// Ensure the class is only loaded once.
11
if ( ! class_exists( 'WP_Super_Duper' ) ) {
12
13
	/**
14
	 *
15
	 * A Class to be able to create a Widget, Shortcode or Block to be able to output content for WordPress.
16
	 *
17
	 * View hello-world.php for example usage
18
	 *
19
	 * @since 1.0.0
20
	 * @since 1.0.16 change log moved to file change-log.txt - CHANGED
21
	 * @since 2.0.0 shortcode, widget and blocks moved into separate files - CHANGED
22
	 * @version 2.0.0
23
	 */
24
	abstract class WP_Super_Duper {
25
	
26
		public $version = "2.0.2";
27
		public $font_awesome_icon_version = "5.11.2";
28
		public $block_code;
29
		public $options;
30
		public $base_id;
31
		public $number;
32
		public $settings_hash;
33
		public $arguments = array();
34
		public $instance = array();
35
	
36
		// prevent SDv1 errors if register_widget() function used
37
		public $id_base;
38
	
39
		/**
40
		 * @var array Contains an array of output types instances.
41
		 */
42
		public $output_types = array();
43
	
44
		/**
45
		 * The relative url to the current folder.
46
		 *
47
		 * @var string
48
		 */
49
		public $url = '';
50
	
51
		/**
52
		 * Take the array options and use them to build.
53
		 */
54
		public function __construct( $options ) {
55
			global $sd_widgets;
56
	
57
			$sd_widgets[ $options['base_id'] ] = array(
58
				'name'       => $options['name'],
59
				'class_name' => $options['class_name']
60
			);
61
			$this->base_id   = $options['base_id'];
62
	
63
			// Lets filter the options before we do anything.
64
			$options = apply_filters( 'wp_super_duper_options', $options, $this );
65
			$options = apply_filters( "wp_super_duper_options_{$this->base_id}", $options, $this );
66
			$options = $this->add_name_from_key( $options );
67
	
68
			// Set args.
69
			$this->options   = $options;
70
			$this->base_id   = $options['base_id'];
71
			$this->arguments = isset( $options['arguments'] ) ? $options['arguments'] : array();
72
	
73
			// Load output types.
74
			$this->load_output_types();
75
	
76
			// add generator text to admin head
77
			add_action( 'admin_head', array( $this, 'generator' ) );
78
	
79
			add_action( 'admin_init', array( __CLASS__, 'load_widgets_setting' ) );
80
	
81
			add_action( 'wp_ajax_super_duper_get_picker', array( __CLASS__, 'get_picker' ) );
82
	
83
			do_action( 'wp_super_duper_widget_init', $options, $this );
84
	
85
		}
86
	
87
		/**
88
		 * Set the name from the argument key.
89
		 *
90
		 * @param array $options
91
		 * @param bool $arguments
92
		 *
93
		 * @return mixed
94
		 */
95
		protected function add_name_from_key( $options, $arguments = false ) {
96
			if ( ! empty( $options['arguments'] ) ) {
97
				foreach ( $options['arguments'] as $key => $val ) {
98
					$options['arguments'][ $key ]['name'] = $key;
99
				}
100
			} elseif ( $arguments && is_array( $options ) && ! empty( $options ) ) {
101
				foreach ( $options as $key => $val ) {
102
					$options[ $key ]['name'] = $key;
103
				}
104
			}
105
	
106
			return $options;
107
		}
108
	
109
		/**
110
		 * Output the version in the admin header.
111
		 */
112
		public function load_output_types() {
113
	
114
			$allowed_types = $this->get_output_types();
115
			$output_types  = array( 'block', 'shortcode', 'widget' );
116
	
117
			// Check if this is being overidden by the widget.
118
			$args = $this->get_arguments();
119
			if ( isset( $args['output_types'] ) && is_array( $args['output_types'] ) ) {
120
				$output_types  = $args['output_types'] ;
121
			}
122
	
123
			if ( isset( $this->options['output_types'] ) && is_array( $this->options['output_types'] ) ) {
124
				$output_types  = $this->options['output_types'] ;
125
			}
126
	
127
			// Load each output type.
128
			foreach ( $output_types as $output_type ) {
129
	
130
				// Ensure this is an allowed type.
131
				if ( ! isset( $allowed_types[ $output_type ] ) ) {
132
					continue;
133
				}
134
	
135
				// If the class does not exist, try loading it.
136
				if ( ! class_exists( $allowed_types[ $output_type ] ) ) {
137
	
138
					if ( file_exists( plugin_dir_path( __FILE__ ) . "type/$output_type.php" ) ) {
139
						require_once( plugin_dir_path( __FILE__ ) . "type/$output_type.php" );
140
					} else {
141
						continue;
142
					}
143
	
144
				}
145
	
146
				$output_class                       = $allowed_types[ $output_type ];
147
				$this->output_types[ $output_type ] = new $output_class( $this );
148
			}
149
	
150
		}
151
	
152
		/**
153
		 * Retrieves an array of available SD types.
154
		 *
155
		 * @return array
156
		 */
157
		protected function get_output_types() {
158
	
159
			// Output type id and class.
160
			$types = array(
161
				'block'     => 'WP_Super_Duper_Block',
162
				'shortcode' => 'WP_Super_Duper_Shortcode',
163
				'widget'    => 'WP_Super_Duper_Widget',
164
			);
165
	
166
			// Maybe disable widgets.
167
			$disable_widget   = get_option( 'sd_load_widgets', 'auto' );
168
	
169
			if ( 'auto' === $disable_widget ) {
170
				if ( !$this->widgets_required() ) {
171
					unset( $types['widget'] );
172
				}
173
			}
174
	
175
			if ( 'no' === $disable_widget ) {
176
				unset( $types['widget'] );
177
			}
178
	
179
			return apply_filters( 'super_duper_types', $types, $this );
180
		}
181
	
182
		/**
183
		 * Check if we are required to load widgets.
184
		 *
185
		 * @return mixed|void
186
		 */
187
		protected function widgets_required(){
188
			global $wp_version;
189
	
190
			$required = false;
191
	
192
	
193
			// check wp version
194
			if( version_compare( $wp_version, '5.8', '<' ) ){
195
				$required = true;
196
			}
197
	
198
			// Page builders that require widgets
199
			if(
200
			!$required && (
201
			defined( 'ELEMENTOR_VERSION' ) // elementor
202
			|| class_exists( 'Fusion_Element' ) // Fusion Builder (avada)
203
			|| class_exists( 'SiteOrigin_Panels' ) // SiteOrigin Page builder
204
			|| defined( 'WPB_VC_VERSION' ) // WPBakery page builder
205
			|| defined( 'CT_VERSION' ) // Oxygen Builder
206
			|| defined( 'FL_BUILDER_VERSION' ) // Beaver Builder
207
			|| defined( 'FL_THEME_BUILDER_VERSION' ) // Beaver Themer
208
			)
209
			){
210
				$required = true;
211
			}
212
	
213
			// Theme has active widgets
214
			if( !$required && !empty( $this->has_active_widgets() )  ){
215
				$required = true;
216
			}
217
	
218
	
219
			return apply_filters( 'sd_widgets_required' , $required );
220
		}
221
	
222
		/**
223
		 * Check if the current site has any active old style widgets.
224
		 *
225
		 * @return bool
226
		 */
227
		protected function has_active_widgets(){
228
			global $sd_has_active_widgets;
229
	
230
			// have we already done this?
231
			if(!is_null($sd_has_active_widgets)){
232
				return $sd_has_active_widgets;
233
			}
234
	
235
			$result = false;
236
			$sidebars_widgets = get_option('sidebars_widgets');
237
	
238
			if(is_array($sidebars_widgets)){
239
	
240
				foreach ($sidebars_widgets as $key => $value) {
241
	
242
	
243
	
244
					if( $key != 'wp_inactive_widgets' ) {
245
	
246
						if(!empty($value) && is_array($value)){
247
							foreach($value as $widget){
248
								if($widget && substr( $widget, 0, 6 ) !== "block-"){
249
									$result = true;
250
								}
251
							}
252
						}
253
	
254
					}
255
				}
256
			}
257
	
258
			$sd_has_active_widgets = $result;
259
	
260
			return $result;
261
		}
262
	
263
		/**
264
		 * Get arguments in super duper.
265
		 *
266
		 * @since 1.0.0
267
		 *
268
		 * @return array Get arguments.
269
		 */
270
		public function get_arguments() {
271
			if ( empty( $this->arguments ) ) {
272
				$this->arguments = $this->set_arguments();
273
			}
274
	
275
			$this->arguments = apply_filters( 'wp_super_duper_arguments', $this->arguments, $this->options, $this->instance );
276
			$this->arguments = $this->add_name_from_key( $this->arguments, true );
277
	
278
			return $this->arguments;
279
		}
280
	
281
		/**
282
		 * Set arguments in super duper.
283
		 *
284
		 * @since 1.0.0
285
		 *
286
		 * @return array Set arguments.
287
		 */
288
		public function set_arguments() {
289
			return $this->arguments;
290
		}
291
	
292
		/**
293
		 * Makes SD work with the siteOrigin page builder.
294
		 *
295
		 * @since 1.0.6
296
		 * @return mixed
297
		 */
298
		public static function siteorigin_js() {
299
			ob_start();
300
			?>
301
			<script>
302
				/**
303
				 * Check a form to see what items should be shown or hidden.
304
				 */
305
				function sd_so_show_hide(form) {
306
					jQuery(form).find(".sd-argument").each(function () {
307
	
308
						var $element_require = jQuery(this).data('element_require');
309
	
310
						if ($element_require) {
311
	
312
							$element_require = $element_require.replace("&#039;", "'"); // replace single quotes
313
							$element_require = $element_require.replace("&quot;", '"'); // replace double quotes
314
	
315
							if (eval($element_require)) {
316
								jQuery(this).removeClass('sd-require-hide');
317
							} else {
318
								jQuery(this).addClass('sd-require-hide');
319
							}
320
						}
321
					});
322
				}
323
	
324
				/**
325
				 * Toggle advanced settings visibility.
326
				 */
327
				function sd_so_toggle_advanced($this) {
328
					var form = jQuery($this).parents('form,.form,.so-content');
329
					form.find('.sd-advanced-setting').toggleClass('sd-adv-show');
330
					return false;// prevent form submit
331
				}
332
	
333
				/**
334
				 * Initialise a individual widget.
335
				 */
336
				function sd_so_init_widget($this, $selector) {
337
					if (!$selector) {
338
						$selector = 'form';
339
					}
340
					// only run once.
341
					if (jQuery($this).data('sd-widget-enabled')) {
342
						return;
343
					} else {
344
						jQuery($this).data('sd-widget-enabled', true);
345
					}
346
	
347
					var $button = '<button title="<?php _e( 'Advanced Settings' );?>" class="button button-primary right sd-advanced-button" onclick="sd_so_toggle_advanced(this);return false;"><i class="fas fa-sliders-h" aria-hidden="true"></i></button>';
348
					var form = jQuery($this).parents('' + $selector + '');
349
	
350
					if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) {
351
						jQuery(form).append($button);
352
					}
353
	
354
					// show hide on form change
355
					jQuery(form).on("change", function () {
356
						sd_so_show_hide(form);
357
					});
358
	
359
					// show hide on load
360
					sd_so_show_hide(form);
361
				}
362
	
363
				jQuery(function () {
364
					jQuery(document).on('open_dialog', function (w, e) {
365
						setTimeout(function () {
366
							if (jQuery('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced').length) {
367
								console.log('exists');
368
								if (jQuery('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced').val() == '1') {
369
									console.log('true');
370
									sd_so_init_widget('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced', 'div');
371
								}
372
							}
373
						}, 200);
374
					});
375
				});
376
			</script>
377
			<?php
378
			$output = ob_get_clean();
379
	
380
			/*
381
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
382
			 */
383
			return str_replace( array(
384
				'<script>',
385
				'</script>'
386
			), '', $output );
387
		}
388
	
389
		/**
390
		 * A function to ge the shortcode builder picker html.
391
		 *
392
		 * @param string $editor_id
393
		 *
394
		 * @return string
395
		 */
396
		public static function get_picker( $editor_id = '' ) {
397
	
398
			ob_start();
399
			if ( isset( $_POST['editor_id'] ) ) {
400
				$editor_id = esc_attr( $_POST['editor_id'] );
401
			} elseif ( isset( $_REQUEST['et_fb'] ) ) {
402
				$editor_id = 'main_content_content_vb_tiny_mce';
403
			}
404
	
405
			global $sd_widgets;
406
			?>
407
	
408
			<div class="sd-shortcode-left-wrap">
409
				<?php
410
				ksort( $sd_widgets );
411
				//				print_r($sd_widgets);exit;
412
				if ( ! empty( $sd_widgets ) ) {
413
					echo '<select class="widefat" onchange="sd_get_shortcode_options(this);">';
414
					echo "<option>" . __( 'Select shortcode' ) . "</option>";
415
					foreach ( $sd_widgets as $shortcode => $class ) {
416
						echo "<option value='" . esc_attr( $shortcode ) . "'>" . esc_attr( $shortcode ) . " (" . esc_attr( $class['name'] ) . ")</option>";
417
					}
418
					echo "</select>";
419
	
420
				}
421
				?>
422
				<div class="sd-shortcode-settings"></div>
423
	
424
			</div>
425
	
426
			<div class="sd-shortcode-right-wrap">
427
				<textarea id='sd-shortcode-output' disabled></textarea>
428
				<div id='sd-shortcode-output-actions'>
429
					<?php if ( $editor_id != '' ) { ?>
430
						<button class="button sd-insert-shortcode-button"
431
								onclick="sd_insert_shortcode(<?php if ( ! empty( $editor_id ) ) {
432
									echo "'" . $editor_id . "'";
433
								} ?>)"><?php _e( 'Insert shortcode' ); ?></button>
434
					<?php } ?>
435
					<button class="button"
436
							onclick="sd_copy_to_clipboard()"><?php _e( 'Copy shortcode' ); ?></button>
437
				</div>
438
			</div>
439
			<?php
440
	
441
			$html = ob_get_clean();
442
	
443
			if ( wp_doing_ajax() ) {
444
				echo $html;
445
				$should_die = true;
446
	
447
				// some builder get the editor via ajax so we should not die on those occasions
448
				$dont_die = array(
449
					'parent_tag',// WP Bakery
450
					'avia_request' // enfold
451
				);
452
	
453
				foreach ( $dont_die as $request ) {
454
					if ( isset( $_REQUEST[ $request ] ) ) {
455
						$should_die = false;
456
					}
457
				}
458
	
459
				if ( $should_die ) {
460
					wp_die();
461
				}
462
	
463
			} else {
464
				return $html;
465
			}
466
	
467
			return '';
468
	
469
		}
470
	
471
		/**
472
		 * Returns the JS used to render the widget/shortcode settings form.
473
		 *
474
		 * @return string
475
		 */
476
		public static function widget_js() {
477
			ob_start();
478
			?>
479
			<script>
480
	
481
				/**
482
				 * Toggle advanced settings visibility.
483
				 */
484
				function sd_toggle_advanced($this) {
485
					var form = jQuery($this).parents('form,.form');
486
						form.find('.sd-advanced-setting').toggleClass('sd-adv-show');
487
						return false;// prevent form submit
488
				}
489
	
490
				/**
491
				 * Check a form to see what items should be shown or hidden.
492
				 */
493
				function sd_show_hide(form) {
494
					console.log('show/hide');
495
					jQuery(form).find(".sd-argument").each(function () {
496
	
497
						var $element_require = jQuery(this).data('element_require');
498
	
499
						if ($element_require) {
500
	
501
							$element_require = $element_require.replace("&#039;", "'"); // replace single quotes
502
							$element_require = $element_require.replace("&quot;", '"'); // replace double quotes
503
	
504
							if (eval($element_require)) {
505
								jQuery(this).removeClass('sd-require-hide');
506
							} else {
507
								jQuery(this).addClass('sd-require-hide');
508
							}
509
						}
510
					});
511
				}
512
	
513
				/**
514
				 * Initialise widgets from the widgets screen.
515
				 */
516
				function sd_init_widgets($selector) {
517
					jQuery(".sd-show-advanced").each(function (index) {
518
						sd_init_widget(this, $selector);
519
					});
520
				}
521
	
522
				/**
523
				 * Initialise a individual widget.
524
				 */
525
				function sd_init_widget($this, $selector) {
526
					console.log($selector);
527
	
528
					if (!$selector) {
529
						$selector = 'form';
530
					}
531
					// only run once.
532
					if (jQuery($this).data('sd-widget-enabled')) {
533
						return;
534
					} else {
535
						jQuery($this).data('sd-widget-enabled', true);
536
					}
537
	
538
					var $button = '<button title="<?php _e( 'Advanced Settings' );?>" style="line-height: 28px;" class="button button-primary right sd-advanced-button" onclick="sd_toggle_advanced(this);return false;"><span class="dashicons dashicons-admin-settings" style="width: 28px;font-size: 28px;"></span></button>';
539
					var form = jQuery($this).parents('' + $selector + '');
540
	
541
					if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) {
542
						console.log('add advanced button');
543
						if(jQuery(form).find('.widget-control-save').length > 0){
544
							jQuery(form).find('.widget-control-save').after($button);
545
						}else{
546
							jQuery(form).find('.sd-show-advanced').after($button);
547
						}
548
					} else {
549
						console.log('no advanced button');
550
						console.log(jQuery($this).val());
551
						console.log(jQuery(form).find('.sd-advanced-button').length);
552
					}
553
	
554
					// show hide on form change
555
					jQuery(form).on("change", function () {
556
						sd_show_hide(form);
557
					});
558
	
559
					// show hide on load
560
					sd_show_hide(form);
561
					}
562
	
563
					/**
564
					 * Init a customizer widget.
565
					 */
566
					function sd_init_customizer_widget(section) {
567
						if (section.expanded) {
568
							section.expanded.bind(function (isExpanding) {
569
								if (isExpanding) {
570
									// is it a SD widget?
571
									if (jQuery(section.container).find('.sd-show-advanced').length) {
572
										// init the widget
573
										sd_init_widget(jQuery(section.container).find('.sd-show-advanced'), ".form");
574
									}
575
								}
576
							});
577
						}
578
					}
579
	
580
					/**
581
					 * If on widgets screen.
582
					 */
583
					jQuery(function () {
584
						// if not in customizer.
585
						if (!wp.customize) {
586
							sd_init_widgets("form");
587
						}
588
	
589
						// init on widget added
590
						jQuery(document).on('widget-added', function (e, widget) {
591
							console.log('widget added');
592
							// is it a SD widget?
593
							if (jQuery(widget).find('.sd-show-advanced').length) {
594
								// init the widget
595
								sd_init_widget(jQuery(widget).find('.sd-show-advanced'), "form");
596
							}
597
						});
598
	
599
						// init on widget updated
600
						jQuery(document).on('widget-updated', function (e, widget) {
601
							console.log('widget updated');
602
	
603
							// is it a SD widget?
604
							if (jQuery(widget).find('.sd-show-advanced').length) {
605
								// init the widget
606
								sd_init_widget(jQuery(widget).find('.sd-show-advanced'), "form");
607
							}
608
						});
609
	
610
					});
611
	
612
	
613
					/**
614
					 * We need to run this before jQuery is ready
615
					 */
616
					if (wp.customize) {
617
						wp.customize.bind('ready', function () {
618
	
619
							// init widgets on load
620
							wp.customize.control.each(function (section) {
621
								sd_init_customizer_widget(section);
622
							});
623
	
624
							// init widgets on add
625
							wp.customize.control.bind('add', function (section) {
626
								sd_init_customizer_widget(section);
627
							});
628
	
629
						});
630
	
631
					}
632
					<?php do_action( 'wp_super_duper_widget_js' ); ?>
633
			</script>
634
	
635
			<?php
636
				$output = ob_get_clean();
637
	
638
				/*
639
				* We only add the <script> tags for code highlighting, so we strip them from the output.
640
				*/
641
	
642
				return str_replace( array(
643
					'<script>',
644
					'</script>'
645
				), '', $output );
646
		}
647
	
648
		/**
649
		 * Returns the CSS used to render the widget/shortcode settings form.
650
		 *
651
		 * @param bool $advanced If we should include advanced CSS.
652
		 *
653
		 * @return mixed
654
		 */
655
		public static function widget_css( $advanced = true ) {
656
			ob_start();
657
			?>
658
	
659
			<style>
660
				<?php if ( $advanced ) : ?>
661
					.sd-advanced-setting {
662
						display: none;
663
					}
664
	
665
					.sd-advanced-setting.sd-adv-show {
666
						display: block;
667
					}
668
	
669
					.sd-argument.sd-require-hide,
670
					.sd-advanced-setting.sd-require-hide {
671
						display: none;
672
					}
673
	
674
					button.sd-advanced-button {
675
						margin-right: 3px !important;
676
						font-size: 20px !important;
677
					}
678
	
679
				<?php endif; ?>
680
	
681
				button.sd-toggle-group-button {
682
					background-color: #f3f3f3;
683
					color: #23282d;
684
					cursor: pointer;
685
					padding: 10px;
686
					width: 100%;
687
					border: none;
688
					text-align: left;
689
					outline: none;
690
					font-size: 13px;
691
					font-weight: bold;
692
					margin-bottom: 1px;
693
				}
694
	
695
			</style>
696
	
697
			<?php
698
				$output = ob_get_clean();
699
	
700
				/*
701
				* We only add the <script> tags for code highlighting, so we strip them from the output.
702
				*/
703
	
704
				return str_replace( array(
705
					'<style>',
706
					'</style>'
707
				), '', $output );
708
		}
709
	
710
		/**
711
		 * Registers the widgets loading settings.
712
		 */
713
		public static function load_widgets_setting() {
714
			register_setting( 'general', 'sd_load_widgets', 'esc_attr' );
0 ignored issues
show
Bug introduced by
'esc_attr' of type string is incompatible with the type array expected by parameter $args of register_setting(). ( Ignorable by Annotation )

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

714
			register_setting( 'general', 'sd_load_widgets', /** @scrutinizer ignore-type */ 'esc_attr' );
Loading history...
715
	
716
			add_settings_field(
717
				'sd_load_widgets',
718
				'<label for="sd_load_widgets">' . __( 'Load Super Duper Widgets' ) . '</label>',
719
				'WP_Super_Duper::load_widgets_setting_html',
720
				'general'
721
			);
722
	
723
		}
724
	
725
		/**
726
		 * Displays the widgets settings HTML.
727
		 */
728
		public static function load_widgets_setting_html() {
729
			$available_options = array(
730
				'yes'  => __( 'Yes' ),
731
				'no'   => __( 'No' ),
732
				'auto' => __( 'Auto' ),
733
			);
734
			$selected_option   = get_option( 'sd_load_widgets', 'auto' );
735
	
736
			?>
737
				<select name="sd_load_widgets" id="sd_load_widgets">
738
					<?php foreach ( $available_options as $key => $label ) : ?>
739
						<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $selected_option ); ?>><?php echo esc_html( $label ); ?></option>
740
					<?php endforeach; ?>
741
				</select>
742
				<p class="description"><?php _e( 'This option allows you to disable Super Duper widgets and instead only load the blocks and shortcodes.' ); ?></p>
743
			<?php
744
		}
745
	
746
		/**
747
		 * prevent SDv1 errors if register_widget() function used
748
		 */
749
		public function _register(){
750
			// backwards compatibility
751
		}
752
753
		/**
754
		 * Prevents elementor errors if called the SDv1 way.
755
		 */
756
		public function _set(){
757
			// backwards compatibility for elementor pro
758
		}
759
	
760
		/**
761
		 * Output the version in the admin header.
762
		 */
763
		public function generator() {
764
	
765
			// We want to set this once.
766
			if ( empty( $GLOBALS['SD_SET_GENERATOR'] ) ) {
767
				echo '<meta name="generator" content="WP Super Duper v' . $this->version . '" />';
768
				$GLOBALS['SD_SET_GENERATOR'] = 1;
769
			}
770
	
771
		}
772
	
773
		/**
774
		 * This is the main output class for all 3 items, widget, shortcode and block, it is extended in the calling class.
775
		 *
776
		 * @param array $args
777
		 * @param array $widget_args
778
		 * @param string $content
779
		 */
780
		public function output( $args = array(), $widget_args = array(), $content = '' ) {
781
			echo call_user_func( $this->options['widget_ops']['output'], $args, $widget_args, $content );
782
		}
783
	
784
		/**
785
		 * Placeholder text to show if output is empty and we are on a preview/builder page.
786
		 *
787
		 * @param string $name
788
		 *
789
		 * @return string
790
		 */
791
		public function preview_placeholder_text( $name = '' ) {
792
			return "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" . sprintf( __( 'Placeholder for: %s' ), $name ) . "</div>";
793
		}
794
	
795
		/**
796
		 * Sometimes booleans values can be turned to strings, so we fix that.
797
		 *
798
		 * @param $options
799
		 *
800
		 * @return mixed
801
		 */
802
		public function string_to_bool( $options ) {
803
			// convert bool strings to booleans
804
			foreach ( $options as $key => $val ) {
805
				if ( $val == 'false' ) {
806
					$options[ $key ] = false;
807
				} elseif ( $val == 'true' ) {
808
					$options[ $key ] = true;
809
				}
810
			}
811
	
812
			return $options;
813
		}
814
	
815
		/**
816
		 * Get the argument values that are also filterable.
817
		 *
818
		 * @param $instance
819
		 *
820
		 * @since 1.0.12 Don't set checkbox default value if the value is empty.
821
		 *
822
		 * @return array
823
		 */
824
		public function argument_values( $instance ) {
825
			$argument_values = array();
826
	
827
			// set widget instance
828
			$this->instance = $instance;
829
	
830
			if ( empty( $this->arguments ) ) {
831
				$this->arguments = $this->get_arguments();
832
			}
833
	
834
			if ( ! empty( $this->arguments ) ) {
835
				foreach ( $this->arguments as $key => $args ) {
836
					// set the input name from the key
837
					$args['name'] = $key;
838
					//
839
					$argument_values[ $key ] = isset( $instance[ $key ] ) ? $instance[ $key ] : '';
840
					if ( $args['type'] == 'checkbox' && $argument_values[ $key ] == '' ) {
841
						// don't set default for an empty checkbox
842
					} elseif ( $argument_values[ $key ] == '' && isset( $args['default'] ) ) {
843
						$argument_values[ $key ] = $args['default'];
844
					}
845
				}
846
			}
847
	
848
			return $argument_values;
849
		}
850
	
851
		/**
852
		 * Get the url path to the current folder.
853
		 *
854
		 * @return string
855
		 */
856
		public function get_url() {
857
			$url = $this->url;
858
	
859
			if ( ! $url ) {
860
				// check if we are inside a plugin
861
				$file_dir = str_replace( "/includes", "", dirname( __FILE__ ) );
862
	
863
				$dir_parts = explode( "/wp-content/", $file_dir );
864
				$url_parts = explode( "/wp-content/", plugins_url() );
865
	
866
				if ( ! empty( $url_parts[0] ) && ! empty( $dir_parts[1] ) ) {
867
					$url       = trailingslashit( $url_parts[0] . "/wp-content/" . $dir_parts[1] );
868
					$this->url = $url;
869
				}
870
			}
871
	
872
			return $url;
873
		}
874
	
875
		/**
876
		 * General function to check if we are in a preview situation.
877
		 *
878
		 * @since 1.0.6
879
		 * @return bool
880
		 */
881
		public function is_preview() {
882
			return $this->is_divi_preview() || $this->is_elementor_preview() || $this->is_beaver_preview() || $this->is_siteorigin_preview() || $this->is_cornerstone_preview() || $this->is_fusion_preview() || $this->is_oxygen_preview() || $this->is_block_content_call();
883
		}
884
	
885
		/**
886
		 * Tests if the current output is inside a Divi preview.
887
		 *
888
		 * @since 1.0.6
889
		 * @return bool
890
		 */
891
		public function is_divi_preview() {
892
			$result = false;
893
			if ( isset( $_REQUEST['et_fb'] ) || isset( $_REQUEST['et_pb_preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) ) {
894
				$result = true;
895
			}
896
	
897
			return $result;
898
		}
899
	
900
		/**
901
		 * Tests if the current output is inside a elementor preview.
902
		 *
903
		 * @since 1.0.4
904
		 * @return bool
905
		 */
906
		public function is_elementor_preview() {
907
			$result = false;
908
			if ( isset( $_REQUEST['elementor-preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) || ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor_ajax' ) ) {
909
				$result = true;
910
			}
911
	
912
			return $result;
913
		}
914
	
915
		/**
916
		 * Tests if the current output is inside a Beaver builder preview.
917
		 *
918
		 * @since 1.0.6
919
		 * @return bool
920
		 */
921
		public function is_beaver_preview() {
922
			$result = false;
923
			if ( isset( $_REQUEST['fl_builder'] ) ) {
924
				$result = true;
925
			}
926
	
927
			return $result;
928
		}
929
	
930
		/**
931
		 * Tests if the current output is inside a siteorigin builder preview.
932
		 *
933
		 * @since 1.0.6
934
		 * @return bool
935
		 */
936
		public function is_siteorigin_preview() {
937
			$result = false;
938
			if ( ! empty( $_REQUEST['siteorigin_panels_live_editor'] ) ) {
939
				$result = true;
940
			}
941
	
942
			return $result;
943
		}
944
	
945
		/**
946
		 * Tests if the current output is inside a cornerstone builder preview.
947
		 *
948
		 * @since 1.0.8
949
		 * @return bool
950
		 */
951
		public function is_cornerstone_preview() {
952
			$result = false;
953
			if ( ! empty( $_REQUEST['cornerstone_preview'] ) || basename( $_SERVER['REQUEST_URI'] ) == 'cornerstone-endpoint' ) {
954
				$result = true;
955
			}
956
	
957
			return $result;
958
		}
959
	
960
		/**
961
		 * Tests if the current output is inside a fusion builder preview.
962
		 *
963
		 * @since 1.1.0
964
		 * @return bool
965
		 */
966
		public function is_fusion_preview() {
967
			$result = false;
968
			if ( ! empty( $_REQUEST['fb-edit'] ) || ! empty( $_REQUEST['fusion_load_nonce'] ) ) {
969
				$result = true;
970
			}
971
	
972
			return $result;
973
		}
974
	
975
		/**
976
		 * Tests if the current output is inside a Oxygen builder preview.
977
		 *
978
		 * @since 1.0.18
979
		 * @return bool
980
		 */
981
		public function is_oxygen_preview() {
982
			$result = false;
983
			if ( ! empty( $_REQUEST['ct_builder'] ) || ( ! empty( $_REQUEST['action'] ) && ( substr( $_REQUEST['action'], 0, 11 ) === "oxy_render_" || substr( $_REQUEST['action'], 0, 10 ) === "ct_render_" ) ) ) {
984
				$result = true;
985
			}
986
	
987
			return $result;
988
		}
989
	
990
		/**
991
		* Checks if the current call is a ajax call to get the block content.
992
		*
993
		* This can be used in your widget to return different content as the block content.
994
		*
995
		* @since 1.0.3
996
		* @return bool
997
		*/
998
		public function is_block_content_call() {
999
			$result = false;
1000
			if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'super_duper_output_shortcode' ) {
1001
				$result = true;
1002
			}
1003
	
1004
			return $result;
1005
		}
1006
	
1007
		/**
1008
		 * Outputs the options form inputs for the widget/shortcode.
1009
		 *
1010
		 * @param array $instance The widget options.
1011
		 */
1012
		public function form( $instance ) {
1013
	
1014
			// Set widget instance.
1015
			$this->instance = $instance;
1016
	
1017
			// Set it as a SD widget.
1018
			echo $this->widget_advanced_toggle();
1019
	
1020
			// Display description.
1021
			printf( '<p>%s</p>', esc_html( $this->options['widget_ops']['description'] ) );
1022
	
1023
			// Prepare arguments.
1024
			$arguments_raw = $this->get_arguments();
1025
	
1026
		if ( is_array( $arguments_raw ) ) {
0 ignored issues
show
introduced by
The condition is_array($arguments_raw) is always true.
Loading history...
1027
	
1028
			$arguments = $this->group_arguments( $arguments_raw );
1029
	
1030
			// Do we have sections?
1031
			if ( $arguments != $arguments_raw ) {
1032
	
1033
					$panel_count = 0;
1034
					foreach ( $arguments as $key => $args ) {
1035
	
1036
						$hide       = $panel_count ? ' style="display:none;" ' : '';
1037
						$icon_class = $panel_count ? 'fas fa-chevron-up' : 'fas fa-chevron-down';
1038
						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='" . esc_attr( $icon_class ) . "'></i></button>";
1039
						echo "<div class='sd-toggle-group sd-input-group-" . sanitize_title_with_dashes( $key ) . "' $hide>";
1040
	
1041
						foreach ( $args as $k => $a ) {
1042
	
1043
							$this->widget_inputs_row_start($k, $a);
1044
							$this->widget_inputs( $a, $instance );
1045
							$this->widget_inputs_row_end($k, $a);
1046
	
1047
						}
1048
	
1049
						echo "</div>";
1050
	
1051
						$panel_count ++;
1052
	
1053
					}
1054
	
1055
				} else {
1056
	
1057
					foreach ( $arguments as $key => $args ) {
1058
						$this->widget_inputs_row_start($key, $args);
1059
						$this->widget_inputs( $args, $instance );
1060
						$this->widget_inputs_row_end($key, $args);
1061
					}
1062
	
1063
				}
1064
	
1065
			}
1066
		}
1067
	
1068
		/**
1069
		 * Get the hidden input that when added makes the advanced button show on widget settings.
1070
		 *
1071
		 * @return string
1072
		 */
1073
		public function widget_advanced_toggle() {
1074
	
1075
			return sprintf(
1076
				'<input type="hidden"  class="sd-show-advanced" value="%s" />',
1077
				(int) $this->block_show_advanced()
1078
			);
1079
	
1080
		}
1081
	
1082
		/**
1083
		 * Check if we need to show advanced options.
1084
		 *
1085
		 * @return bool
1086
		 */
1087
		public function block_show_advanced() {
1088
			$show      = false;
1089
			$arguments = $this->get_arguments();
1090
	
1091
			if ( ! empty( $arguments ) ) {
1092
				foreach ( $arguments as $argument ) {
1093
					if ( isset( $argument['advanced'] ) && $argument['advanced'] ) {
1094
						$show = true;
1095
						break; // no need to continue if we know we have it
1096
					}
1097
				}
1098
			}
1099
	
1100
			return $show;
1101
		}
1102
	
1103
		/**
1104
		 * Groups widget arguments.
1105
		 *
1106
		 * @param array $arguments
1107
		 *
1108
		 * @return array
1109
		 */
1110
		public function group_arguments( $arguments ) {
1111
	
1112
			if ( ! empty( $arguments ) ) {
1113
				$temp_arguments = array();
1114
				$general        = __( "General" );
1115
				$add_sections   = false;
1116
				foreach ( $arguments as $key => $args ) {
1117
					if ( isset( $args['group'] ) ) {
1118
						$temp_arguments[ $args['group'] ][ $key ] = $args;
1119
						$add_sections                             = true;
1120
					} else {
1121
						$temp_arguments[ $general ][ $key ] = $args;
1122
					}
1123
				}
1124
	
1125
				// only add sections if more than one
1126
				if ( $add_sections ) {
1127
					$arguments = $temp_arguments;
1128
				}
1129
			}
1130
	
1131
			return $arguments;
1132
		}
1133
	
1134
		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

1134
		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...
1135
			if(!empty($args['row'])){
1136
				// maybe open
1137
				if(!empty($args['row']['open'])){
1138
					?>
1139
					<div class='bsui sd-argument ' data-argument='<?php echo esc_attr( $args['row']['key'] ); ?>' data-element_require='<?php if ( !empty($args['row']['element_require'])) {
1140
						echo $this->convert_element_require( $args['row']['element_require'] );
1141
					} ?>'>
1142
					<?php if(!empty($args['row']['title'])){ ?>
1143
					<label class="mb-0 "><?php echo esc_attr( $args['row']['title'] ); ?><?php echo $this->widget_field_desc( $args['row'] ); ?></label>
1144
					<?php }?>
1145
					<div class='row <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>'>
1146
					<div class='col pr-2'>
1147
					<?php
1148
				}elseif(!empty($args['row']['close'])){
1149
					echo "<div class='col pl-0'>";
1150
				}else{
1151
					echo "<div class='col pl-0 pr-2'>";
1152
				}
1153
			}
1154
		}
1155
	
1156
		/**
1157
		 * Convert require element.
1158
		 *
1159
		 * @since 1.0.0
1160
		 *
1161
		 * @param string $input Input element.
1162
		 *
1163
		 * @return string $output
1164
		 */
1165
		public function convert_element_require( $input ) {
1166
	
1167
			$input = str_replace( "'", '"', $input );// we only want double quotes
1168
	
1169
			$output = esc_attr( str_replace( array( "[%", "%]" ), array(
1170
				"jQuery(form).find('[data-argument=\"",
1171
				"\"]').find('input,select,textarea').val()"
1172
			), $input ) );
1173
	
1174
			return $output;
1175
		}
1176
	
1177
		/**
1178
		 * Get the widget input description html.
1179
		 *
1180
		 * @param $args
1181
		 *
1182
		 * @return string
1183
		 * @todo, need to make its own tooltip script
1184
		 */
1185
		public function widget_field_desc( $args ) {
1186
	
1187
			$description = '';
1188
			if ( isset( $args['desc'] ) && $args['desc'] ) {
1189
				if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) {
1190
					$description = $this->desc_tip( $args['desc'] );
1191
				} else {
1192
					$description = '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>';
1193
				}
1194
			}
1195
	
1196
			return $description;
1197
		}
1198
	
1199
		/**
1200
		 * Get the tool tip html.
1201
		 *
1202
		 * @param $tip
1203
		 * @param bool $allow_html
1204
		 *
1205
		 * @return string
1206
		 */
1207
		public function desc_tip( $tip, $allow_html = false ) {
1208
			if ( $allow_html ) {
1209
				$tip = $this->sanitize_tooltip( $tip );
1210
			} else {
1211
				$tip = esc_attr( $tip );
1212
			}
1213
	
1214
			return '<span class="gd-help-tip dashicons dashicons-editor-help" title="' . $tip . '"></span>';
1215
		}
1216
	
1217
		/**
1218
		 * Sanitize a string destined to be a tooltip.
1219
		 *
1220
		 * @param string $var
1221
		 *
1222
		 * @return string
1223
		 */
1224
		public function sanitize_tooltip( $var ) {
1225
			return htmlspecialchars( wp_kses( html_entity_decode( $var ), array(
1226
				'br'     => array(),
1227
				'em'     => array(),
1228
				'strong' => array(),
1229
				'small'  => array(),
1230
				'span'   => array(),
1231
				'ul'     => array(),
1232
				'li'     => array(),
1233
				'ol'     => array(),
1234
				'p'      => array(),
1235
			) ) );
1236
		}
1237
	
1238
		/**
1239
		 * Builds the inputs for the widget options.
1240
		 *
1241
		 * @param $args
1242
		 * @param $instance
1243
		 */
1244
		public function widget_inputs( $args, $instance ) {
1245
	
1246
			$class             = "";
1247
			$element_require   = "";
1248
			$custom_attributes = "";
1249
	
1250
			// get value
1251
			if ( isset( $instance[ $args['name'] ] ) ) {
1252
				$value = $instance[ $args['name'] ];
1253
			} elseif ( ! isset( $instance[ $args['name'] ] ) && ! empty( $args['default'] ) ) {
1254
				$value = is_array( $args['default'] ) ? array_map( "esc_html", $args['default'] ) : esc_html( $args['default'] );
1255
			} else {
1256
				$value = '';
1257
			}
1258
	
1259
			// get placeholder
1260
			if ( ! empty( $args['placeholder'] ) ) {
1261
				$placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'";
1262
			} else {
1263
				$placeholder = '';
1264
			}
1265
	
1266
			// get if advanced
1267
			if ( isset( $args['advanced'] ) && $args['advanced'] ) {
1268
				$class .= " sd-advanced-setting ";
1269
			}
1270
	
1271
			// element_require
1272
			if ( isset( $args['element_require'] ) && $args['element_require'] ) {
1273
				$element_require = $args['element_require'];
1274
			}
1275
	
1276
			// custom_attributes
1277
			if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) {
1278
				$custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true );
1279
			}
1280
	
1281
	
1282
			// before wrapper
1283
			?>
1284
			<p class="sd-argument <?php echo esc_attr( $class ); ?>"
1285
			data-argument='<?php echo esc_attr( $args['name'] ); ?>'
1286
			data-element_require='<?php if ( $element_require ) {
1287
				echo $this->convert_element_require( $element_require );
1288
			} ?>'
1289
			>
1290
			<?php
1291
	
1292
	
1293
			switch ( $args['type'] ) {
1294
				//array('text','password','number','email','tel','url','color')
1295
				case "text":
1296
				case "password":
1297
				case "number":
1298
				case "email":
1299
				case "tel":
1300
				case "url":
1301
				case "color":
1302
					?>
1303
					<label
1304
						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>
1305
					<input <?php echo $placeholder; ?> class="widefat"
1306
						<?php echo $custom_attributes; ?>
1307
													   id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
1308
													   name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>"
1309
													   type="<?php echo esc_attr( $args['type'] ); ?>"
1310
													   value="<?php echo esc_attr( $value ); ?>">
1311
					<?php
1312
	
1313
					break;
1314
				case "select":
1315
					$multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false;
1316
					if ( $multiple ) {
1317
						if ( empty( $value ) ) {
1318
							$value = array();
1319
						}
1320
					}
1321
					?>
1322
					<label
1323
						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>
1324
					<select <?php echo $placeholder; ?> class="widefat"
1325
						<?php echo $custom_attributes; ?>
1326
														id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
1327
														name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) );
1328
														if ( $multiple ) {
1329
															echo "[]";
1330
														} ?>"
1331
						<?php if ( $multiple ) {
1332
							echo "multiple";
1333
						} //@todo not implemented yet due to gutenberg not supporting it
1334
						?>
1335
					>
1336
						<?php
1337
	
1338
						if ( ! empty( $args['options'] ) ) {
1339
							foreach ( $args['options'] as $val => $label ) {
1340
								if ( $multiple ) {
1341
									$selected = in_array( $val, $value ) ? 'selected="selected"' : '';
1342
								} else {
1343
									$selected = selected( $value, $val, false );
1344
								}
1345
								echo "<option value='$val' " . $selected . ">$label</option>";
1346
							}
1347
						}
1348
						?>
1349
					</select>
1350
					<?php
1351
					break;
1352
				case "checkbox":
1353
					?>
1354
					<input <?php echo $placeholder; ?>
1355
						<?php checked( 1, $value, true ) ?>
1356
						<?php echo $custom_attributes; ?>
1357
						class="widefat" id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
1358
						name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="checkbox"
1359
						value="1">
1360
					<label
1361
						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>
1362
					<?php
1363
					break;
1364
				case "textarea":
1365
					?>
1366
					<label
1367
						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>
1368
					<textarea <?php echo $placeholder; ?> class="widefat"
1369
						<?php echo $custom_attributes; ?>
1370
														  id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
1371
														  name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>"
1372
					><?php echo esc_attr( $value ); ?></textarea>
1373
					<?php
1374
	
1375
					break;
1376
				case "hidden":
1377
					?>
1378
					<input id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"
1379
						   name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="hidden"
1380
						   value="<?php echo esc_attr( $value ); ?>">
1381
					<?php
1382
					break;
1383
				default:
1384
					echo "No input type found!"; // @todo we need to add more input types.
1385
			}
1386
	
1387
			// after wrapper
1388
			?>
1389
			</p>
1390
			<?php
1391
		}
1392
	
1393
		/**
1394
		 * Convert an array of attributes to JS object or HTML attributes string.
1395
		 *
1396
		 * @todo there is prob a faster way to do this, also we could add some validation here.
1397
		 *
1398
		 * @param $attributes
1399
		 *
1400
		 * @return string
1401
		 */
1402
		public function array_to_attributes( $attributes, $html = false ) {
1403
	
1404
			if ( ! is_array( $attributes ) ) {
1405
				return '';
1406
			}
1407
	
1408
			$output = '';
1409
			foreach ( $attributes as $name => $value ) {
1410
	
1411
				if ( $html ) {
1412
	
1413
					if ( true === $value ) {
1414
						$output .= esc_html( $name ) . ' ';
1415
					} else if ( false !== $value ) {
1416
						$output .= sprintf( '%s="%s" ', esc_html( $name ), trim( esc_attr( $value ) ) );
1417
					}
1418
	
1419
				} else {
1420
					$output .= sprintf( "'%s': '%s',", esc_js( $name ), is_bool( $value ) ? $value : trim( esc_js( $value ) ) );
1421
				}
1422
	
1423
			}
1424
	
1425
			return $output;
1426
		}
1427
	
1428
		/**
1429
		 * Constructs id attributes for use in WP_Widget::form() fields.
1430
		 *
1431
		 * This function should be used in form() methods to create id attributes
1432
		 * for fields to be saved by WP_Widget::update().
1433
		 *
1434
		 * @since 2.8.0
1435
		 * @since 4.4.0 Array format field IDs are now accepted.
1436
		 *
1437
		 * @param string $field_name Field name.
1438
		 *
1439
		 * @return string ID attribute for `$field_name`.
1440
		 */
1441
		public function get_field_id( $field_name ) {
1442
	
1443
			$field_name = str_replace( array( '[]', '[', ']' ), array( '', '-', '' ), $field_name );
1444
			$field_name = trim( $field_name, '-' );
1445
	
1446
			return 'widget-' . $this->base_id . '-' . $this->get_number() . '-' . $field_name;
1447
		}
1448
	
1449
		/**
1450
		 * Returns the instance number.
1451
		 *
1452
		 * @return int
1453
		 */
1454
		public function get_number() {
1455
			static $number = 1;
1456
	
1457
			if ( isset( $this->output_types['widget'] ) ) {
1458
				return $this->output_types['widget']->number;
1459
			}
1460
	
1461
			if ( empty( $this->number ) ) {
1462
				$this->number = $number;
1463
				$number ++;
1464
			}
1465
	
1466
			return $this->number;
1467
		}
1468
	
1469
		/**
1470
		 * Get the widget input title html.
1471
		 *
1472
		 * @param $args
1473
		 *
1474
		 * @return string
1475
		 */
1476
		public function widget_field_title( $args ) {
1477
	
1478
			$title = '';
1479
			if ( isset( $args['title'] ) && $args['title'] ) {
1480
				if ( isset( $args['icon'] ) && $args['icon'] ) {
1481
					$title = $this->get_widget_icon( $args['icon'], $args['title']  );
1482
				} else {
1483
					$title = esc_attr($args['title']);
1484
				}
1485
			}
1486
	
1487
			return $title;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $title also could return the type array which is incompatible with the documented return type string.
Loading history...
1488
		}
1489
	
1490
		/**
1491
		 * Retrieves the icon to use for widgets / blocks.
1492
		 *
1493
		 * @return array
1494
		 */
1495
		public function get_widget_icon( $icon = 'box-top', $title = '' ) {
1496
			if($icon=='box-top'){
1497
				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>';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '<svg title="' . ...#555D66"></rect></svg>' returns the type string which is incompatible with the documented return type array.
Loading history...
1498
			}elseif($icon=='box-right'){
1499
				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>';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '<svg title="' . ...#555D66"></rect></svg>' returns the type string which is incompatible with the documented return type array.
Loading history...
1500
			}elseif($icon=='box-bottom'){
1501
				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>';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '<svg title="' . ...#272B2F"></rect></svg>' returns the type string which is incompatible with the documented return type array.
Loading history...
1502
			}elseif($icon=='box-left'){
1503
				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>';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '<svg title="' . ...#555D66"></rect></svg>' returns the type string which is incompatible with the documented return type array.
Loading history...
1504
			}
1505
		}
1506
	
1507
		/**
1508
		 * Constructs name attributes for use in form() fields
1509
		 *
1510
		 * This function should be used in form() methods to create name attributes for fields
1511
		 * to be saved by update()
1512
		 *
1513
		 * @since 2.8.0
1514
		 * @since 4.4.0 Array format field names are now accepted.
1515
		 *
1516
		 * @param string $field_name Field name.
1517
		 *
1518
		 * @return string Name attribute for `$field_name`.
1519
		 */
1520
		public function get_field_name( $field_name ) {
1521
			$pos = strpos( $field_name, '[' );
1522
	
1523
			if ( false !== $pos ) {
1524
				// Replace the first occurrence of '[' with ']['.
1525
				$field_name = '[' . substr_replace( $field_name, '][', $pos, strlen( '[' ) );
0 ignored issues
show
Bug introduced by
Are you sure substr_replace($field_na...][', $pos, strlen('[')) of type array|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

1525
				$field_name = '[' . /** @scrutinizer ignore-type */ substr_replace( $field_name, '][', $pos, strlen( '[' ) );
Loading history...
1526
			} else {
1527
				$field_name = '[' . $field_name . ']';
1528
			}
1529
	
1530
			return 'widget-' . $this->base_id . '[' . $this->get_number() . ']' . $field_name;
1531
		}
1532
	
1533
		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

1533
		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...
1534
			if(!empty($args['row'])){
1535
				// maybe close
1536
				if(!empty($args['row']['close'])){
1537
					echo "</div></div>";
1538
				}
1539
	
1540
				echo "</div>";
1541
			}
1542
		}
1543
	
1544
		/**
1545
		 * Generate and return inline styles from CSS rules that will match the unique class of the instance.
1546
		 *
1547
		 * @param array $rules
1548
		 *
1549
		 * @since 1.0.20
1550
		 * @return string
1551
		 */
1552
		public function get_instance_style($rules = array()){
1553
			$css = '';
1554
	
1555
			if(!empty($rules)){
1556
				$rules = array_unique($rules);
1557
				$instance_hash = $this->get_instance_hash();
1558
				$css .= "<style>";
1559
				foreach($rules as $rule){
1560
					$css .= ".sdel-$instance_hash $rule";
1561
				}
1562
				$css .= "</style>";
1563
			}
1564
	
1565
			return $css;
1566
		}
1567
	
1568
		/**
1569
		 * Get an instance hash that will be unique to the type and settings.
1570
		 *
1571
		 * @since 1.0.20
1572
		 * @return string
1573
		 */
1574
		public function get_instance_hash(){
1575
			$instance_string = $this->base_id . serialize( $this->instance );
1576
			return hash( 'crc32b', $instance_string );
1577
		}
1578
	
1579
		/**
1580
		 * Get the conditional fields JavaScript.
1581
		 *
1582
		 * @return mixed
1583
		 */
1584
		public function conditional_fields_js() {
1585
			ob_start();
1586
			?>
1587
			<script>
1588
			/**
1589
			* Conditional Fields
1590
			*/
1591
			var sd_cf_field_rules = [], sd_cf_field_key_rules = {}, sd_cf_field_default_values = {};
1592
	
1593
			jQuery(function($) {
1594
				/* Init conditional fields */
1595
				sd_cf_field_init_rules($);
1596
			});
1597
	
1598
			/**
1599
			* Conditional fields init.
1600
			*/
1601
			function sd_cf_field_init_rules($) {
1602
				if (!$('[data-has-rule]').length) {
1603
					return;
1604
				}
1605
	
1606
				$('[data-rule-key]').on('change keypress keyup', 'input, textarea', function() {
1607
					sd_cf_field_apply_rules($(this));
1608
				});
1609
	
1610
				$('[data-rule-key]').on('change', 'select', function() {
1611
					sd_cf_field_apply_rules($(this));
1612
				});
1613
	
1614
				$('[data-rule-key]').on('change.select2', 'select', function() {
1615
					sd_cf_field_apply_rules($(this));
1616
				});
1617
	
1618
				/*jQuery(document).on('sd_cf_field_on_change', function() {
1619
					sd_cf_field_hide_child_elements();
1620
				});*/
1621
	
1622
				sd_cf_field_setup_rules($);
1623
			}
1624
	
1625
			/**
1626
			* Setup conditional field rules.
1627
			*/
1628
			function sd_cf_field_setup_rules($) {
1629
				var sd_cf_field_keys = [];
1630
	
1631
				$('[data-rule-key]').each(function() {
1632
					var key = jQuery(this).data('rule-key'),
1633
						irule = parseInt(jQuery(this).data('has-rule'));
1634
					if (key) {
1635
						sd_cf_field_keys.push(key);
1636
					}
1637
	
1638
					var parse_conds = {};
1639
					if ($(this).data('rule-fie-0')) {
1640
						for (var i = 0; i < irule; i++) {
1641
							var field = $(this).data('rule-fie-' + i);
1642
							if (typeof parse_conds[i] === 'undefined') {
1643
								parse_conds[i] = {};
1644
							}
1645
							parse_conds[i]['action'] = $(this).data('rule-act-' + i);
1646
							parse_conds[i]['field'] = $(this).data('rule-fie-' + i);
1647
							parse_conds[i]['condition'] = $(this).data('rule-con-' + i);
1648
							parse_conds[i]['value'] = $(this).data('rule-val-' + i);
1649
						}
1650
	
1651
						jQuery.each(parse_conds, function(j, data) {
1652
							var item = {
1653
								'field': {
1654
									key: key,
1655
									action: data.action,
1656
									field: data.field,
1657
									condition: data.condition,
1658
									value: data.value,
1659
									rule: {
1660
										key: key,
1661
										action: data.action,
1662
										condition: data.condition,
1663
										value: data.value
1664
									}
1665
								}
1666
							};
1667
							sd_cf_field_rules.push(item);
1668
						});
1669
					}
1670
					sd_cf_field_default_values[jQuery(this).data('rule-key')] = sd_cf_field_get_default_value(jQuery(this));
1671
				});
1672
	
1673
				jQuery.each(sd_cf_field_keys, function(i, fkey) {
1674
					sd_cf_field_key_rules[fkey] = sd_cf_field_get_children(fkey);
1675
				});
1676
	
1677
				jQuery('[data-rule-key]:visible').each(function() {
1678
					var conds = sd_cf_field_key_rules[jQuery(this).data('rule-key')];
1679
					if (conds && conds.length) {
1680
						var $main_el = jQuery(this), el = sd_cf_field_get_element($main_el);
1681
						if (jQuery(el).length) {
1682
							sd_cf_field_apply_rules(jQuery(el));
1683
						}
1684
					}
1685
				});
1686
			}
1687
	
1688
			/**
1689
			* Apply conditional field rules.
1690
			*/
1691
			function sd_cf_field_apply_rules($el) {
1692
				if (!$el.parents('[data-rule-key]').length) {
1693
					return;
1694
				}
1695
	
1696
				if ($el.data('no-rule')) {
1697
					return;
1698
				}
1699
	
1700
				var key = $el.parents('[data-rule-key]').data('rule-key');
1701
				var conditions = sd_cf_field_key_rules[key];
1702
				if (typeof conditions === 'undefined') {
1703
					return;
1704
				}
1705
				var field_type = sd_cf_field_get_type($el.parents('[data-rule-key]')),
1706
					current_value = sd_cf_field_get_value($el);
1707
	
1708
				var $keys = {},
1709
					$keys_values = {},
1710
					$key_rules = {};
1711
	
1712
				jQuery.each(conditions, function(index, condition) {
1713
					if (typeof $keys_values[condition.key] == 'undefined') {
1714
						$keys_values[condition.key] = [];
1715
						$key_rules[condition.key] = {}
1716
					}
1717
	
1718
					$keys_values[condition.key].push(condition.value);
1719
					$key_rules[condition.key] = condition;
1720
				});
1721
	
1722
				jQuery.each(conditions, function(index, condition) {
1723
					if (typeof $keys[condition.key] == 'undefined') {
1724
						$keys[condition.key] = {};
1725
					}
1726
	
1727
					if (condition.condition === 'empty') {
1728
						var field_value = Array.isArray(current_value) ? current_value.join('') : current_value;
1729
						if (!field_value || field_value === '') {
1730
							$keys[condition.key][index] = true;
1731
						} else {
1732
							$keys[condition.key][index] = false;
1733
						}
1734
					} else if (condition.condition === 'not empty') {
1735
						var field_value = Array.isArray(current_value) ? current_value.join('') : current_value;
1736
						if (field_value && field_value !== '') {
1737
							$keys[condition.key][index] = true;
1738
						} else {
1739
							$keys[condition.key][index] = false;
1740
						}
1741
					} else if (condition.condition === 'equals to') {
1742
						var field_value = (Array.isArray(current_value) && current_value.length === 1) ? current_value[0] : current_value;
1743
						if (((condition.value && condition.value == condition.value) || (condition.value === field_value)) && sd_cf_field_in_array(field_value, $keys_values[condition.key])) {
1744
							$keys[condition.key][index] = true;
1745
						} else {
1746
							$keys[condition.key][index] = false;
1747
						}
1748
					} else if (condition.condition === 'not equals') {
1749
						var field_value = (Array.isArray(current_value) && current_value.length === 1) ? current_value[0] : current_value;
1750
						if (jQuery.isNumeric(condition.value) && parseInt(field_value) !== parseInt(condition.value) && field_value && !sd_cf_field_in_array(field_value, $keys_values[condition.key])) {
1751
							$keys[condition.key][index] = true;
1752
						} else if (condition.value != field_value && !sd_cf_field_in_array(field_value, $keys_values[condition.key])) {
1753
							$keys[condition.key][index] = true;
1754
						} else {
1755
							$keys[condition.key][index] = false;
1756
						}
1757
					} else if (condition.condition === 'greater than') {
1758
						var field_value = (Array.isArray(current_value) && current_value.length === 1) ? current_value[0] : current_value;
1759
						if (jQuery.isNumeric(condition.value) && parseInt(field_value) > parseInt(condition.value)) {
1760
							$keys[condition.key][index] = true;
1761
						} else {
1762
							$keys[condition.key][index] = false;
1763
						}
1764
					} else if (condition.condition === 'less than') {
1765
						var field_value = (Array.isArray(current_value) && current_value.length === 1) ? current_value[0] : current_value;
1766
						if (jQuery.isNumeric(condition.value) && parseInt(field_value) < parseInt(condition.value)) {
1767
							$keys[condition.key][index] = true;
1768
						} else {
1769
							$keys[condition.key][index] = false;
1770
						}
1771
					} else if (condition.condition === 'contains') {
1772
						switch (field_type) {
1773
							case 'multiselect':
1774
								if (current_value && ((!Array.isArray(current_value) && current_value.indexOf(condition.value) >= 0) || (Array.isArray(current_value) && sd_cf_field_in_array(condition.value, current_value)))) { //
1775
									$keys[condition.key][index] = true;
1776
								} else {
1777
									$keys[condition.key][index] = false;
1778
								}
1779
								break;
1780
							case 'checkbox':
1781
								if (current_value && ((!Array.isArray(current_value) && current_value.indexOf(condition.value) >= 0) || (Array.isArray(current_value) && sd_cf_field_in_array(condition.value, current_value)))) { //
1782
									$keys[condition.key][index] = true;
1783
								} else {
1784
									$keys[condition.key][index] = false;
1785
								}
1786
								break;
1787
							default:
1788
								if (typeof $keys[condition.key][index] === 'undefined') {
1789
									if (current_value && current_value.indexOf(condition.value) >= 0 && sd_cf_field_in_array(current_value, $keys_values[condition.key])) {
1790
										$keys[condition.key][index] = true;
1791
									} else {
1792
										$keys[condition.key][index] = false;
1793
									}
1794
								}
1795
								break;
1796
						}
1797
					}
1798
				});
1799
	
1800
				jQuery.each($keys, function(index, field) {
1801
					if (sd_cf_field_in_array(true, field)) {
1802
						sd_cf_field_apply_action($el, $key_rules[index], true);
1803
					} else {
1804
						sd_cf_field_apply_action($el, $key_rules[index], false);
1805
					}
1806
				});
1807
	
1808
				/* Trigger field change */
1809
				if ($keys.length) {
1810
					$el.trigger('sd_cf_field_on_change');
1811
				}
1812
			}
1813
	
1814
			/**
1815
			* Get the field element.
1816
			*/
1817
			function sd_cf_field_get_element($el) {
1818
				var el = $el.find('input,textarea,select'),
1819
					type = sd_cf_field_get_type($el);
1820
				if (type && window._sd_cf_field_elements && typeof window._sd_cf_field_elements == 'object' && typeof window._sd_cf_field_elements[type] != 'undefined') {
1821
					el = window._sd_cf_field_elements[type];
1822
				}
1823
				return el;
1824
			}
1825
	
1826
			/**
1827
			* Get the field type.
1828
			*/
1829
			function sd_cf_field_get_type($el) {
1830
				return $el.data('rule-type');
1831
			}
1832
	
1833
			/**
1834
			* Get the field value.
1835
			*/
1836
			function sd_cf_field_get_value($el) {
1837
				var current_value = $el.val();
1838
	
1839
				if ($el.is(':checkbox')) {
1840
					current_value = '';
1841
					if ($el.parents('[data-rule-key]').find('input:checked').length > 1) {
1842
						$el.parents('[data-rule-key]').find('input:checked').each(function() {
1843
							current_value = current_value + jQuery(this).val() + ' ';
1844
						});
1845
					} else {
1846
						if ($el.parents('[data-rule-key]').find('input:checked').length >= 1) {
1847
							current_value = $el.parents('[data-rule-key]').find('input:checked').val();
1848
						}
1849
					}
1850
				}
1851
	
1852
				if ($el.is(':radio')) {
1853
					current_value = $el.parents('[data-rule-key]').find('input[type=radio]:checked').val();
1854
				}
1855
	
1856
				return current_value;
1857
			}
1858
	
1859
			/**
1860
			* Get the field default value.
1861
			*/
1862
			function sd_cf_field_get_default_value($el) {
1863
				var value = '',
1864
					type = sd_cf_field_get_type($el);
1865
	
1866
				switch (type) {
1867
					case 'text':
1868
					case 'number':
1869
					case 'date':
1870
					case 'textarea':
1871
					case 'select':
1872
						value = $el.find('input:text,input[type="number"],textarea,select').val();
1873
						break;
1874
					case 'phone':
1875
					case 'email':
1876
					case 'color':
1877
					case 'url':
1878
					case 'hidden':
1879
					case 'password':
1880
					case 'file':
1881
						value = $el.find('input[type="' + type + '"]').val();
1882
						break;
1883
					case 'multiselect':
1884
						value = $el.find('select').val();
1885
						break;
1886
					case 'radio':
1887
						if ($el.find('input[type="radio"]:checked').length >= 1) {
1888
							value = $el.find('input[type="radio"]:checked').val();
1889
						}
1890
						break;
1891
					case 'checkbox':
1892
						if ($el.find('input[type="checkbox"]:checked').length >= 1) {
1893
							if ($el.find('input[type="checkbox"]:checked').length > 1) {
1894
								var values = [];
1895
								values.push(value);
1896
								$el.find('input[type="checkbox"]:checked').each(function() {
1897
									values.push(jQuery(this).val());
1898
								});
1899
								value = values;
1900
							} else {
1901
								value = $el.find('input[type="checkbox"]:checked').val();
1902
							}
1903
						}
1904
						break;
1905
					default:
1906
						if (window._sd_cf_field_default_values && typeof window._sd_cf_field_default_values == 'object' && typeof window._sd_cf_field_default_values[type] != 'undefined') {
1907
							value = window._sd_cf_field_default_values[type];
1908
						}
1909
						break;
1910
				}
1911
				return {
1912
					type: type,
1913
					value: value
1914
				};
1915
			}
1916
	
1917
			/**
1918
			* Reset field default value.
1919
			*/
1920
			function sd_cf_field_reset_default_value($el) {
1921
				var type = sd_cf_field_get_type($el),
1922
					key = $el.data('rule-key'),
1923
					field = sd_cf_field_default_values[key];
1924
	
1925
				switch (type) {
1926
					case 'text':
1927
					case 'number':
1928
					case 'date':
1929
					case 'textarea':
1930
						$el.find('input:text,input[type="number"],textarea').val(field.value);
1931
						break;
1932
					case 'phone':
1933
					case 'email':
1934
					case 'color':
1935
					case 'url':
1936
					case 'hidden':
1937
					case 'password':
1938
					case 'file':
1939
						$el.find('input[type="' + type + '"]').val(field.value);
1940
						break;
1941
					case 'select':
1942
						$el.find('select').find('option').prop('selected', false);
1943
						$el.find('select').val(field.value);
1944
						$el.find('select').trigger('change');
1945
						break;
1946
					case 'multiselect':
1947
						$el.find('select').find('option').prop('selected', false);
1948
						if ((typeof field.value === 'object' || typeof field.value === 'array') && !field.value.length && $el.find('select option:first').text() == '') {
1949
							$el.find('select option:first').remove(); // Clear first option to show placeholder.
1950
						}
1951
						jQuery.each(field.value, function(i, v) {
1952
							$el.find('select').find('option[value="' + v + '"]').attr('selected', true);
1953
						});
1954
						$el.find('select').trigger('change');
1955
						break;
1956
					case 'checkbox':
1957
						if ($el.find('input[type="checkbox"]:checked').length >= 1) {
1958
							$el.find('input[type="checkbox"]:checked').prop('checked', false);
1959
							if (Array.isArray(field.value)) {
1960
								jQuery.each(field.value, function(i, v) {
1961
									$el.find('input[type="checkbox"][value="' + v + '"]').attr('checked', true);
1962
								});
1963
							} else {
1964
								$el.find('input[type="checkbox"][value="' + field.value + '"]').attr('checked', true);
1965
							}
1966
						}
1967
						break;
1968
					case 'radio':
1969
						if ($el.find('input[type="radio"]:checked').length >= 1) {
1970
							setTimeout(function() {
1971
								$el.find('input[type="radio"]:checked').prop('checked', false);
1972
								$el.find('input[type="radio"][value="' + field.value + '"]').attr('checked', true);
1973
							}, 100);
1974
						}
1975
						break;
1976
					default:
1977
						jQuery(document.body).trigger('sd_cf_field_reset_default_value', type, $el, field);
1978
						break;
1979
				}
1980
	
1981
				if (!$el.hasClass('sd-cf-field-has-changed')) {
1982
					var el = sd_cf_field_get_element($el);
1983
					if (type === 'radio' || type === 'checkbox') {
1984
						el = el.find(':checked');
1985
					}
1986
					if (el) {
1987
						el.trigger('change');
1988
						$el.addClass('sd-cf-field-has-changed');
1989
					}
1990
				}
1991
			}
1992
	
1993
			/**
1994
			* Get the field children.
1995
			*/
1996
			function sd_cf_field_get_children(field_key) {
1997
				var rules = [];
1998
				jQuery.each(sd_cf_field_rules, function(j, rule) {
1999
					if (rule.field.field === field_key) {
2000
						rules.push(rule.field.rule);
2001
					}
2002
				});
2003
				return rules;
2004
			}
2005
	
2006
			/**
2007
			* Check in array field value.
2008
			*/
2009
			function sd_cf_field_in_array(find, item, match) {
2010
				var found = false,
2011
					key;
2012
				match = !!match;
2013
	
2014
				for (key in item) {
2015
					if ((match && item[key] === find) || (!match && item[key] == find)) {
2016
						found = true;
2017
						break;
2018
					}
2019
				}
2020
				return found;
2021
			}
2022
	
2023
			/**
2024
			* App the field condition action.
2025
			*/
2026
			function sd_cf_field_apply_action($el, rule, isTrue) {
2027
				var $destEl = jQuery('[data-rule-key="' + rule.key + '"]');
2028
	
2029
				if (rule.action === 'show' && isTrue) {
2030
					if ($destEl.is(':hidden')) {
2031
						sd_cf_field_reset_default_value($destEl);
2032
					}
2033
					sd_cf_field_show_element($destEl);
2034
				} else if (rule.action === 'show' && !isTrue) {
2035
					sd_cf_field_hide_element($destEl);
2036
				} else if (rule.action === 'hide' && isTrue) {
2037
					sd_cf_field_hide_element($destEl);
2038
				} else if (rule.action === 'hide' && !isTrue) {
2039
					if ($destEl.is(':hidden')) {
2040
						sd_cf_field_reset_default_value($destEl);
2041
					}
2042
					sd_cf_field_show_element($destEl);
2043
				}
2044
				return $el.removeClass('sd-cf-field-has-changed');
2045
			}
2046
	
2047
			/**
2048
			* Show field element.
2049
			*/
2050
			function sd_cf_field_show_element($el) {
2051
				$el.removeClass('d-none').show();
2052
	
2053
				if (window && window.navigator.userAgent.indexOf("MSIE") !== -1) {
2054
					$el.css({
2055
						"visibility": "visible"
2056
					});
2057
				}
2058
			}
2059
	
2060
			/**
2061
			* Hide field element.
2062
			*/
2063
			function sd_cf_field_hide_element($el) {
2064
				$el.addClass('d-none').hide();
2065
	
2066
				if (window && window.navigator.userAgent.indexOf("MSIE") !== -1) {
2067
					$el.css({
2068
						"visibility": "hidden"
2069
					});
2070
				}
2071
			}
2072
	
2073
			/**
2074
			* Show field child elements.
2075
			*/
2076
			function sd_cf_field_hide_child_elements() {
2077
				jQuery.each(sd_cf_field_key_rules, function(i, conds) {
2078
					if (i && conds && conds.length && (jQuery('[data-rule-key="' + i + '"]:hidden').length >= 1 || jQuery('[data-rule-key="' + i + '"]').css('display') === 'none')) {
2079
						jQuery.each(conds, function(key, cond) {
2080
							jQuery('[data-rule-key="' + cond.key + '"]').addClass('d-none').hide();
2081
						});
2082
					}
2083
				});
2084
			}
2085
			<?php do_action( 'wp_super_duper_conditional_fields_js', $this ); ?>
2086
			</script>
2087
						<?php
2088
						$output = ob_get_clean();
2089
	
2090
						return str_replace( array( '<script>', '</script>' ), '', trim( $output ) );
2091
			}
2092
	
2093
		/**
2094
		 * Output the super title.
2095
		 *
2096
		 * @param $args
2097
		 * @param array $instance
2098
		 *
2099
		 * @return string
2100
		 */
2101
		public function output_title( $args, $instance = array() ) {
2102
			$output = '';
2103
	
2104
			if ( ! empty( $instance['title'] ) ) {
2105
				/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
2106
				$title  = apply_filters( 'widget_title', $instance['title'], $instance, $this->base_id );
2107
	
2108
				if ( empty( $instance['widget_title_tag'] ) ) {
2109
					$output = $args['before_title'] . $title . $args['after_title'];
2110
				} else {
2111
					$title_tag = esc_attr( $instance['widget_title_tag'] );
2112
	
2113
					// classes
2114
					$title_classes = array();
2115
					$title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : '';
2116
					$title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : '';
2117
					$title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : '';
2118
					$title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : '';
2119
					$title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : '';
2120
					$title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : '';
2121
					$title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : '';
2122
					$title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : '';
2123
					$title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : '';
2124
					$title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : '';
2125
					$title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : '';
2126
					$title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : '';
2127
					$title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : '';
2128
					$title_classes   = array_filter( $title_classes );
2129
	
2130
					$class  = ! empty( $title_classes ) ? implode( ' ', $title_classes ) : '';
2131
					$output = "<$title_tag class='$class' >$title</$title_tag>";
2132
				}
2133
	
2134
			}
2135
	
2136
			return $output;
2137
		}
2138
2139
		/**
2140
		 * Backwards compatibility for SDv1
2141
		 * 
2142
		 * @param string $editor_id
2143
		 * @param string $insert_shortcode_function
2144
		 * 
2145
		 * @return string|void
2146
		 */
2147
		public static function shortcode_insert_button( $editor_id = '', $insert_shortcode_function = '' ) {
2148
			return class_exists('WP_Super_Duper_Shortcode') ? WP_Super_Duper_Shortcode::shortcode_insert_button( $editor_id, $insert_shortcode_function ) : '';
0 ignored issues
show
Bug introduced by
Are you sure the usage of WP_Super_Duper_Shortcode...ert_shortcode_function) targeting WP_Super_Duper_Shortcode...ortcode_insert_button() 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...
2149
		}
2150
2151
		/**
2152
		 * Backwards compatibility for SDv1
2153
		 * 
2154
		 * @param string $id
2155
		 * @param string $search_for_id
2156
		 * 
2157
		 * @return mixed|string
2158
		 */
2159
		public static function shortcode_button( $id = '', $search_for_id = '') {
2160
			return class_exists('WP_Super_Duper_Shortcode') ? WP_Super_Duper_Shortcode::shortcode_button( $id, $search_for_id ) : '';
2161
		}
2162
	
2163
	}
2164
2165
}
2166