Passed
Push — master ( 32890d...b6d11a )
by Brian
13:10
created

AyeCode_UI_Settings::bs3_compat_css()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 32
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 31
nc 4
nop 0
dl 0
loc 32
rs 9.424
c 0
b 0
f 0
1
<?php
2
/**
3
 * A class for adjusting AyeCode UI settings on WordPress
4
 *
5
 * This class can be added to any plugin or theme and will add a settings screen to WordPress to control Bootstrap settings.
6
 *
7
 * @link https://github.com/AyeCode/wp-ayecode-ui
8
 *
9
 * @internal This file should not be edited directly but pulled from the github repo above.
10
 */
11
12
/**
13
 * Bail if we are not in WP.
14
 */
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
/**
20
 * Only add if the class does not already exist.
21
 */
22
if ( ! class_exists( 'AyeCode_UI_Settings' ) ) {
23
24
	/**
25
	 * A Class to be able to change settings for Font Awesome.
26
	 *
27
	 * Class AyeCode_UI_Settings
28
	 * @ver 1.0.0
29
	 * @todo decide how to implement textdomain
30
	 */
31
	class AyeCode_UI_Settings {
32
33
		/**
34
		 * Class version version.
35
		 *
36
		 * @var string
37
		 */
38
		public $version = '0.1.59';
39
40
		/**
41
		 * Class textdomain.
42
		 *
43
		 * @var string
44
		 */
45
		public $textdomain = 'aui';
46
47
		/**
48
		 * Latest version of Bootstrap at time of publish published.
49
		 *
50
		 * @var string
51
		 */
52
		public $latest = "4.5.3";
53
54
		/**
55
		 * Current version of select2 being used.
56
		 *
57
		 * @var string
58
		 */
59
		public $select2_version = "4.0.11";
60
61
		/**
62
		 * The title.
63
		 *
64
		 * @var string
65
		 */
66
		public $name = 'AyeCode UI';
67
68
		/**
69
		 * The relative url to the assets.
70
		 *
71
		 * @var string
72
		 */
73
		public $url = '';
74
75
		/**
76
		 * Holds the settings values.
77
		 *
78
		 * @var array
79
		 */
80
		private $settings;
81
82
		/**
83
		 * AyeCode_UI_Settings instance.
84
		 *
85
		 * @access private
86
		 * @since  1.0.0
87
		 * @var    AyeCode_UI_Settings There can be only one!
88
		 */
89
		private static $instance = null;
90
91
		/**
92
		 * Main AyeCode_UI_Settings Instance.
93
		 *
94
		 * Ensures only one instance of AyeCode_UI_Settings is loaded or can be loaded.
95
		 *
96
		 * @since 1.0.0
97
		 * @static
98
		 * @return AyeCode_UI_Settings - Main instance.
99
		 */
100
		public static function instance() {
101
			if ( ! isset( self::$instance ) && ! ( self::$instance instanceof AyeCode_UI_Settings ) ) {
102
103
				self::$instance = new AyeCode_UI_Settings;
104
105
				add_action( 'init', array( self::$instance, 'init' ) ); // set settings
106
107
				if ( is_admin() ) {
108
					add_action( 'admin_menu', array( self::$instance, 'menu_item' ) );
109
					add_action( 'admin_init', array( self::$instance, 'register_settings' ) );
110
111
					// Maybe show example page
112
					add_action( 'template_redirect', array( self::$instance,'maybe_show_examples' ) );
113
				}
114
115
				add_action( 'customize_register', array( self::$instance, 'customizer_settings' ));
116
117
				do_action( 'ayecode_ui_settings_loaded' );
118
			}
119
120
			return self::$instance;
121
		}
122
123
		/**
124
		 * Setup some constants.
125
		 */
126
		public function constants(){
127
			define('AUI_PRIMARY_COLOR_ORIGINAL', "#1e73be");
128
			define('AUI_SECONDARY_COLOR_ORIGINAL', '#6c757d');
129
			if (!defined('AUI_PRIMARY_COLOR')) define('AUI_PRIMARY_COLOR', AUI_PRIMARY_COLOR_ORIGINAL);
130
			if (!defined('AUI_SECONDARY_COLOR')) define('AUI_SECONDARY_COLOR', AUI_SECONDARY_COLOR_ORIGINAL);
131
		}
132
133
		/**
134
		 * Initiate the settings and add the required action hooks.
135
		 */
136
		public function init() {
137
			$this->constants();
138
			$this->settings = $this->get_settings();
139
			$this->url = $this->get_url();
140
141
			/**
142
			 * Maybe load CSS
143
			 *
144
			 * We load super early in case there is a theme version that might change the colors
145
			 */
146
			if ( $this->settings['css'] ) {
147
				add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ), 1 );
148
			}
149
			if ( $this->settings['css_backend'] && $this->load_admin_scripts() ) {
150
				add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_style' ), 1 );
151
			}
152
153
			// maybe load JS
154
			if ( $this->settings['js'] ) {
155
				$priority = $this->is_bs3_compat() ? 100 : 1;
156
				add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), $priority );
157
			}
158
			if ( $this->settings['js_backend'] && $this->load_admin_scripts() ) {
159
				add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ), 1 );
160
			}
161
162
			// Maybe set the HTML font size
163
			if ( $this->settings['html_font_size'] ) {
164
				add_action( 'wp_footer', array( $this, 'html_font_size' ), 10 );
165
			}
166
167
168
		}
169
170
		/**
171
		 * Check if we should load the admin scripts or not.
172
		 *
173
		 * @return bool
174
		 */
175
		public function load_admin_scripts(){
176
			$result = true;
177
178
			// check if specifically disabled
179
			if(!empty($this->settings['disable_admin'])){
180
				$url_parts = explode("\n",$this->settings['disable_admin']);
181
				foreach($url_parts as $part){
182
					if( strpos($_SERVER['REQUEST_URI'], trim($part)) !== false ){
183
						return false; // return early, no point checking further
184
					}
185
				}
186
			}
187
188
			return $result;
189
		}
190
191
		/**
192
		 * Add a html font size to the footer.
193
		 */
194
		public function html_font_size(){
195
			$this->settings = $this->get_settings();
196
			echo "<style>html{font-size:".absint($this->settings['html_font_size'])."px;}</style>";
197
		}
198
199
		/**
200
		 * Check if the current admin screen should load scripts.
201
		 * 
202
		 * @return bool
203
		 */
204
		public function is_aui_screen(){
205
			$load = false;
206
			// check if we should load or not
207
			if ( is_admin() ) {
208
				// Only enable on set pages
209
				$aui_screens = array(
210
					'page',
211
					'post',
212
					'settings_page_ayecode-ui-settings',
213
					'appearance_page_gutenberg-widgets',
214
					'widgets'
215
				);
216
				$screen_ids = apply_filters( 'aui_screen_ids', $aui_screens );
217
218
				$screen = get_current_screen();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $screen is correct as get_current_screen() 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...
219
220
//				echo '###'.$screen->id;
221
222
				// check if we are on a AUI screen
223
				if ( $screen && in_array( $screen->id, $screen_ids ) ) {
0 ignored issues
show
introduced by
$screen is of type null, thus it always evaluated to false.
Loading history...
224
					$load = true;
225
				}
226
227
				//load for widget previews in WP 5.8
228
				if( !empty($_REQUEST['legacy-widget-preview'])){
229
					$load = true;
230
				}
231
			}
232
233
			return apply_filters( 'aui_load_on_admin' , $load );
234
		}
235
236
		/**
237
		 * Adds the styles.
238
		 */
239
		public function enqueue_style() {
240
241
			if( is_admin() && !$this->is_aui_screen()){
242
				// don't add wp-admin scripts if not requested to
243
			}else{
244
				$css_setting = current_action() == 'wp_enqueue_scripts' ? 'css' : 'css_backend';
245
246
				$rtl = is_rtl() ? '-rtl' : '';
247
248
				if($this->settings[$css_setting]){
249
					$compatibility = $this->settings[$css_setting]=='core' ? false : true;
250
					$url = $this->settings[$css_setting]=='core' ? $this->url.'assets/css/ayecode-ui'.$rtl.'.css' : $this->url.'assets/css/ayecode-ui-compatibility'.$rtl.'.css';
251
					wp_register_style( 'ayecode-ui', $url, array(), $this->latest );
252
					wp_enqueue_style( 'ayecode-ui' );
253
254
					// flatpickr
255
					wp_register_style( 'flatpickr', $this->url.'assets/css/flatpickr.min.css', array(), $this->latest );
256
257
258
					// fix some wp-admin issues
259
					if(is_admin()){
260
						$custom_css = "
261
                body{
262
                    background-color: #f1f1f1;
263
                    font-family: -apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen-Sans,Ubuntu,Cantarell,\"Helvetica Neue\",sans-serif;
264
                    font-size:13px;
265
                }
266
                a {
267
				    color: #0073aa;
268
				    text-decoration: underline;
269
				}
270
                label {
271
				    display: initial;
272
				    margin-bottom: 0;
273
				}
274
				input, select {
275
				    margin: 1px;
276
				    line-height: initial;
277
				}
278
				th, td, div, h2 {
279
				    box-sizing: content-box;
280
				}
281
				p {
282
				    font-size: 13px;
283
				    line-height: 1.5;
284
				    margin: 1em 0;
285
				}
286
				h1, h2, h3, h4, h5, h6 {
287
				    display: block;
288
				    font-weight: 600;
289
				}
290
				h2,h3 {
291
				    font-size: 1.3em;
292
				    margin: 1em 0
293
				}
294
				.blocks-widgets-container .bsui *{
295
					box-sizing: border-box;
296
				}
297
				.bs-tooltip-top .arrow{
298
					margin-left:0px;
299
				}
300
                ";
301
302
						// @todo, remove once fixed :: fix for this bug https://github.com/WordPress/gutenberg/issues/14377
303
						$custom_css .= "
304
						.edit-post-sidebar input[type=color].components-text-control__input{
305
						    padding: 0;
306
						}
307
					";
308
						wp_add_inline_style( 'ayecode-ui', $custom_css );
309
					}
310
311
					// custom changes
312
					wp_add_inline_style( 'ayecode-ui', self::custom_css($compatibility) );
313
314
				}
315
			}
316
317
318
		}
319
320
		/**
321
		 * Get inline script used if bootstrap enqueued
322
		 *
323
		 * If this remains small then its best to use this than to add another JS file.
324
		 */
325
		public function inline_script() {
326
			// Flatpickr calendar locale
327
			$flatpickr_locale = self::flatpickr_locale();
328
329
			ob_start();
330
			?>
331
			<script>
332
				/**
333
				 * An AUI bootstrap adaptation of GreedyNav.js ( by Luke Jackson ).
334
				 *
335
				 * Simply add the class `greedy` to any <nav> menu and it will do the rest.
336
				 * Licensed under the MIT license - http://opensource.org/licenses/MIT
337
				 * @ver 0.0.1
338
				 */
339
				function aui_init_greedy_nav(){
340
					jQuery('nav.greedy').each(function(i, obj) {
341
342
						// Check if already initialized, if so continue.
343
						if(jQuery(this).hasClass("being-greedy")){return true;}
344
345
						// Make sure its always expanded
346
						jQuery(this).addClass('navbar-expand');
347
348
						// vars
349
						var $vlinks = '';
350
						var $dDownClass = '';
351
						if(jQuery(this).find('.navbar-nav').length){
352
							if(jQuery(this).find('.navbar-nav').hasClass("being-greedy")){return true;}
353
							$vlinks = jQuery(this).find('.navbar-nav').addClass("being-greedy w-100").removeClass('overflow-hidden');
354
						}else if(jQuery(this).find('.nav').length){
355
							if(jQuery(this).find('.nav').hasClass("being-greedy")){return true;}
356
							$vlinks = jQuery(this).find('.nav').addClass("being-greedy w-100").removeClass('overflow-hidden');
357
							$dDownClass = ' mt-2 ';
358
						}else{
359
							return false;
360
						}
361
362
						jQuery($vlinks).append('<li class="nav-item list-unstyled ml-auto greedy-btn d-none dropdown ">' +
363
							'<a href="javascript:void(0)" data-toggle="dropdown" class="nav-link"><i class="fas fa-ellipsis-h"></i> <span class="greedy-count badge badge-dark badge-pill"></span></a>' +
364
							'<ul class="greedy-links dropdown-menu  dropdown-menu-right '+$dDownClass+'"></ul>' +
365
							'</li>');
366
367
						var $hlinks = jQuery(this).find('.greedy-links');
368
						var $btn = jQuery(this).find('.greedy-btn');
369
370
						var numOfItems = 0;
371
						var totalSpace = 0;
372
						var closingTime = 1000;
373
						var breakWidths = [];
374
375
						// Get initial state
376
						$vlinks.children().outerWidth(function(i, w) {
377
							totalSpace += w;
378
							numOfItems += 1;
379
							breakWidths.push(totalSpace);
380
						});
381
382
						var availableSpace, numOfVisibleItems, requiredSpace, buttonSpace ,timer;
383
384
						/*
385
						 The check function.
386
						 */
387
						function check() {
388
389
							// Get instant state
390
							buttonSpace = $btn.width();
391
							availableSpace = $vlinks.width() - 10;
392
							numOfVisibleItems = $vlinks.children().length;
393
							requiredSpace = breakWidths[numOfVisibleItems - 1];
394
395
							// There is not enough space
396
							if (numOfVisibleItems > 1 && requiredSpace > availableSpace) {
397
								$vlinks.children().last().prev().prependTo($hlinks);
398
								numOfVisibleItems -= 1;
399
								check();
400
								// There is more than enough space
401
							} else if (availableSpace > breakWidths[numOfVisibleItems]) {
402
								$hlinks.children().first().insertBefore($btn);
403
								numOfVisibleItems += 1;
404
								check();
405
							}
406
							// Update the button accordingly
407
							jQuery($btn).find(".greedy-count").html( numOfItems - numOfVisibleItems);
408
							if (numOfVisibleItems === numOfItems) {
409
								$btn.addClass('d-none');
410
							} else $btn.removeClass('d-none');
411
						}
412
413
						// Window listeners
414
						jQuery(window).on("resize",function() {
415
							check();
416
						});
417
418
						// do initial check
419
						check();
420
					});
421
				}
422
423
				function aui_select2_locale() {
424
					var aui_select2_params = <?php echo self::select2_locale(); ?>;
425
426
					return {
427
						'language': {
428
							errorLoading: function() {
429
								// Workaround for https://github.com/select2/select2/issues/4355 instead of i18n_ajax_error.
430
								return aui_select2_params.i18n_searching;
431
							},
432
							inputTooLong: function(args) {
433
								var overChars = args.input.length - args.maximum;
434
								if (1 === overChars) {
435
									return aui_select2_params.i18n_input_too_long_1;
436
								}
437
								return aui_select2_params.i18n_input_too_long_n.replace('%item%', overChars);
438
							},
439
							inputTooShort: function(args) {
440
								var remainingChars = args.minimum - args.input.length;
441
								if (1 === remainingChars) {
442
									return aui_select2_params.i18n_input_too_short_1;
443
								}
444
								return aui_select2_params.i18n_input_too_short_n.replace('%item%', remainingChars);
445
							},
446
							loadingMore: function() {
447
								return aui_select2_params.i18n_load_more;
448
							},
449
							maximumSelected: function(args) {
450
								if (args.maximum === 1) {
451
									return aui_select2_params.i18n_selection_too_long_1;
452
								}
453
								return aui_select2_params.i18n_selection_too_long_n.replace('%item%', args.maximum);
454
							},
455
							noResults: function() {
456
								return aui_select2_params.i18n_no_matches;
457
							},
458
							searching: function() {
459
								return aui_select2_params.i18n_searching;
460
							}
461
						}
462
					};
463
				}
464
465
				/**
466
				 * Initiate Select2 items.
467
				 */
468
				function aui_init_select2(){
469
					var select2_args = jQuery.extend({}, aui_select2_locale());
470
471
					jQuery("select.aui-select2").select2(select2_args);
472
				}
473
474
				/**
475
				 * A function to convert a time value to a "ago" time text.
476
				 *
477
				 * @param selector string The .class selector
478
				 */
479
				function aui_time_ago(selector) {
480
					var aui_timeago_params = <?php echo self::timeago_locale(); ?>;
481
482
					var templates = {
483
						prefix: aui_timeago_params.prefix_ago,
484
						suffix: aui_timeago_params.suffix_ago,
485
						seconds: aui_timeago_params.seconds,
486
						minute: aui_timeago_params.minute,
487
						minutes: aui_timeago_params.minutes,
488
						hour: aui_timeago_params.hour,
489
						hours: aui_timeago_params.hours,
490
						day: aui_timeago_params.day,
491
						days: aui_timeago_params.days,
492
						month: aui_timeago_params.month,
493
						months: aui_timeago_params.months,
494
						year: aui_timeago_params.year,
495
						years: aui_timeago_params.years
496
					};
497
					var template = function (t, n) {
498
						return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n)));
499
					};
500
501
					var timer = function (time) {
502
						if (!time)
503
							return;
504
						time = time.replace(/\.\d+/, ""); // remove milliseconds
505
						time = time.replace(/-/, "/").replace(/-/, "/");
506
						time = time.replace(/T/, " ").replace(/Z/, " UTC");
507
						time = time.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2"); // -04:00 -> -0400
508
						time = new Date(time * 1000 || time);
509
510
						var now = new Date();
511
						var seconds = ((now.getTime() - time) * .001) >> 0;
512
						var minutes = seconds / 60;
513
						var hours = minutes / 60;
514
						var days = hours / 24;
515
						var years = days / 365;
516
517
						return templates.prefix + (
518
								seconds < 45 && template('seconds', seconds) ||
519
								seconds < 90 && template('minute', 1) ||
520
								minutes < 45 && template('minutes', minutes) ||
521
								minutes < 90 && template('hour', 1) ||
522
								hours < 24 && template('hours', hours) ||
523
								hours < 42 && template('day', 1) ||
524
								days < 30 && template('days', days) ||
525
								days < 45 && template('month', 1) ||
526
								days < 365 && template('months', days / 30) ||
527
								years < 1.5 && template('year', 1) ||
528
								template('years', years)
529
							) + templates.suffix;
530
					};
531
532
					var elements = document.getElementsByClassName(selector);
533
					if (selector && elements && elements.length) {
534
						for (var i in elements) {
535
							var $el = elements[i];
536
							if (typeof $el === 'object') {
537
								$el.innerHTML = '<i class="far fa-clock"></i> ' + timer($el.getAttribute('title') || $el.getAttribute('datetime'));
538
							}
539
						}
540
					}
541
542
					// update time every minute
543
					setTimeout(function() {
544
						aui_time_ago(selector);
545
					}, 60000);
546
547
				}
548
549
				/**
550
				 * Initiate tooltips on the page.
551
				 */
552
				function aui_init_tooltips(){
553
					jQuery('[data-toggle="tooltip"]').tooltip();
554
					jQuery('[data-toggle="popover"]').popover();
555
					jQuery('[data-toggle="popover-html"]').popover({
556
						html: true
557
					});
558
559
					// fix popover container compatibility
560
					jQuery('[data-toggle="popover"],[data-toggle="popover-html"]').on('inserted.bs.popover', function () {
561
						jQuery('body > .popover').wrapAll("<div class='bsui' />");
562
					});
563
				}
564
565
				/**
566
				 * Initiate flatpickrs on the page.
567
				 */
568
				$aui_doing_init_flatpickr = false;
569
				function aui_init_flatpickr(){
570
					if ( typeof jQuery.fn.flatpickr === "function" && !$aui_doing_init_flatpickr) {
571
						$aui_doing_init_flatpickr = true;
572
						<?php if ( ! empty( $flatpickr_locale ) ) { ?>try{flatpickr.localize(<?php echo $flatpickr_locale; ?>);}catch(err){console.log(err.message);}<?php } ?>
573
						jQuery('input[data-aui-init="flatpickr"]:not(.flatpickr-input)').flatpickr();
574
					}
575
					$aui_doing_init_flatpickr = false;
576
				}
577
578
				function aui_modal($title,$body,$footer,$dismissible,$class,$dialog_class) {
579
					if(!$class){$class = '';}
580
					if(!$dialog_class){$dialog_class = '';}
581
					if(!$body){$body = '<div class="text-center"><div class="spinner-border" role="status"></div></div>';}
582
					// remove it first
583
					jQuery('.aui-modal').modal('hide').modal('dispose').remove();
584
					jQuery('.modal-backdrop').remove();
585
586
					var $modal = '';
587
588
					$modal += '<div class="modal aui-modal fade shadow bsui '+$class+'" tabindex="-1">'+
589
						'<div class="modal-dialog modal-dialog-centered '+$dialog_class+'">'+
590
							'<div class="modal-content">';
591
592
					if($title) {
593
						$modal += '<div class="modal-header">' +
594
						'<h5 class="modal-title">' + $title + '</h5>';
595
596
						if ($dismissible) {
597
							$modal += '<button type="button" class="close" data-dismiss="modal" aria-label="Close">' +
598
								'<span aria-hidden="true">&times;</span>' +
599
								'</button>';
600
						}
601
602
						$modal += '</div>';
603
					}
604
					$modal += '<div class="modal-body">'+
605
									$body+
606
								'</div>';
607
608
					if($footer){
609
						$modal += '<div class="modal-footer">'+
610
							$footer +
611
							'</div>';
612
					}
613
614
					$modal +='</div>'+
615
						'</div>'+
616
					'</div>';
617
618
					jQuery('body').append($modal);
619
620
					jQuery('.aui-modal').modal('hide').modal({
621
						//backdrop: 'static'
622
					});
623
				}
624
625
				/**
626
				 * Show / hide fields depending on conditions.
627
				 */
628
				function aui_conditional_fields(form){
629
					jQuery(form).find(".aui-conditional-field").each(function () {
630
631
						var $element_require = jQuery(this).data('element-require');
632
633
						if ($element_require) {
634
635
							$element_require = $element_require.replace("&#039;", "'"); // replace single quotes
636
							$element_require = $element_require.replace("&quot;", '"'); // replace double quotes
637
638
							if (aui_check_form_condition($element_require,form)) {
639
								jQuery(this).removeClass('d-none');
640
							} else {
641
								jQuery(this).addClass('d-none');
642
							}
643
						}
644
					});
645
				}
646
647
				/**
648
				 * Check form condition
649
				 */
650
				function aui_check_form_condition(condition,form) {
651
					if (form) {
652
						condition = condition.replace(/\(form\)/g, "('"+form+"')");
653
					}
654
					return new Function("return " + condition+";")();
655
				}
656
657
				/**
658
				 * A function to determine if a element is on screen.
659
				 */
660
				jQuery.fn.aui_isOnScreen = function(){
661
662
					var win = jQuery(window);
663
664
					var viewport = {
665
						top : win.scrollTop(),
666
						left : win.scrollLeft()
667
					};
668
					viewport.right = viewport.left + win.width();
669
					viewport.bottom = viewport.top + win.height();
670
671
					var bounds = this.offset();
672
					bounds.right = bounds.left + this.outerWidth();
673
					bounds.bottom = bounds.top + this.outerHeight();
674
675
					return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
676
677
				};
678
679
				/**
680
				 * Maybe show multiple carousel items if set to do so.
681
				 */ 
682
				function aui_carousel_maybe_show_multiple_items($carousel){
683
					var $items = {};
684
					var $item_count = 0;
685
686
					// maybe backup
687
					if(!jQuery($carousel).find('.carousel-inner-original').length){
688
						jQuery($carousel).append('<div class="carousel-inner-original d-none">'+jQuery($carousel).find('.carousel-inner').html()+'</div>');
689
					}
690
691
					// Get the original items html
692
					jQuery($carousel).find('.carousel-inner-original .carousel-item').each(function () {
693
						$items[$item_count] = jQuery(this).html();
694
						$item_count++;
695
					});
696
697
					// bail if no items
698
					if(!$item_count){return;}
699
700
					if(jQuery(window).width() <= 576){
701
						// maybe restore original
702
						if(jQuery($carousel).find('.carousel-inner').hasClass('aui-multiple-items') && jQuery($carousel).find('.carousel-inner-original').length){
703
							jQuery($carousel).find('.carousel-inner').removeClass('aui-multiple-items').html(jQuery($carousel).find('.carousel-inner-original').html());
704
							jQuery($carousel).find(".carousel-indicators li").removeClass("d-none");
705
						}
706
707
					}else{
708
						// new items
709
						var $md_count = jQuery($carousel).data('limit_show');
710
						var $new_items = '';
711
						var $new_items_count = 0;
712
						var $new_item_count = 0;
713
						var $closed = true;
714
						Object.keys($items).forEach(function(key,index) {
715
716
							// close
717
							if(index != 0 && Number.isInteger(index/$md_count) ){
718
								$new_items += '</div></div>';
719
								$closed = true;
720
							}
721
722
							// open
723
							if(index == 0 || Number.isInteger(index/$md_count) ){
724
								$active = index == 0 ? 'active' : '';
725
								$new_items += '<div class="carousel-item '+$active+'"><div class="row m-0">';
726
								$closed = false;
727
								$new_items_count++;
728
								$new_item_count = 0;
729
							}
730
731
							// content
732
							$new_items += '<div class="col pr-1 pl-0">'+$items[index]+'</div>';
733
							$new_item_count++;
734
735
736
						});
737
738
						// close if not closed in the loop
739
						if(!$closed){
740
							// check for spares
741
							if($md_count-$new_item_count > 0){
742
								$placeholder_count = $md_count-$new_item_count;
743
								while($placeholder_count > 0){
744
									$new_items += '<div class="col pr-1 pl-0"></div>';
745
									$placeholder_count--;
746
								}
747
748
							}
749
750
							$new_items += '</div></div>';
751
						}
752
753
						// insert the new items
754
						jQuery($carousel).find('.carousel-inner').addClass('aui-multiple-items').html($new_items);
755
756
						// fix any lazyload images in the active slider
757
						jQuery($carousel).find('.carousel-item.active img').each(function () {
758
							// fix the srcset
759
							if(real_srcset = jQuery(this).attr("data-srcset")){
760
								if(!jQuery(this).attr("srcset")) jQuery(this).attr("srcset",real_srcset);
761
							}
762
							// fix the src
763
							if(real_src = jQuery(this).attr("data-src")){
764
								if(!jQuery(this).attr("srcset"))  jQuery(this).attr("src",real_src);
765
							}
766
						});
767
768
						// maybe fix carousel indicators
769
						$hide_count = $new_items_count-1;
770
						jQuery($carousel).find(".carousel-indicators li:gt("+$hide_count+")").addClass("d-none");
771
					}
772
773
					// trigger a global action to say we have
774
					jQuery( window ).trigger( "aui_carousel_multiple" );
775
				}
776
777
				/**
778
				 * Init Multiple item carousels.
779
				 */ 
780
				function aui_init_carousel_multiple_items(){
781
					jQuery(window).on("resize",function(){
782
						jQuery('.carousel-multiple-items').each(function () {
783
							aui_carousel_maybe_show_multiple_items(this);
784
						});
785
					});
786
787
					// run now
788
					jQuery('.carousel-multiple-items').each(function () {
789
						aui_carousel_maybe_show_multiple_items(this);
790
					});
791
				}
792
793
				/**
794
				 * Allow navs to use multiple sub menus.
795
				 */
796
				function init_nav_sub_menus(){
797
798
					jQuery('.navbar-multi-sub-menus').each(function(i, obj) {
799
						// Check if already initialized, if so continue.
800
						if(jQuery(this).hasClass("has-sub-sub-menus")){return true;}
801
802
						// Make sure its always expanded
803
						jQuery(this).addClass('has-sub-sub-menus');
804
805
						jQuery(this).find( '.dropdown-menu a.dropdown-toggle' ).on( 'click', function ( e ) {
806
							var $el = jQuery( this );
807
							$el.toggleClass('active-dropdown');
808
							var $parent = jQuery( this ).offsetParent( ".dropdown-menu" );
809
							if ( !jQuery( this ).next().hasClass( 'show' ) ) {
810
								jQuery( this ).parents( '.dropdown-menu' ).first().find( '.show' ).removeClass( "show" );
811
							}
812
							var $subMenu = jQuery( this ).next( ".dropdown-menu" );
813
							$subMenu.toggleClass( 'show' );
814
815
							jQuery( this ).parent( "li" ).toggleClass( 'show' );
816
817
							jQuery( this ).parents( 'li.nav-item.dropdown.show' ).on( 'hidden.bs.dropdown', function ( e ) {
818
								jQuery( '.dropdown-menu .show' ).removeClass( "show" );
819
								$el.removeClass('active-dropdown');
820
							} );
821
822
							if ( !$parent.parent().hasClass( 'navbar-nav' ) ) {
823
								$el.next().addClass('position-relative border-top border-bottom');
824
							}
825
826
							return false;
827
						} );
828
829
					});
830
831
				}
832
833
834
				/**
835
				 * Open a lightbox when an embed item is clicked.
836
				 */
837
				function aui_lightbox_embed($link,ele){
838
					ele.preventDefault();
839
840
					// remove it first
841
					jQuery('.aui-carousel-modal').remove();
842
843
					var $modal = '<div class="modal fade aui-carousel-modal bsui" tabindex="-1" role="dialog" aria-labelledby="aui-modal-title" aria-hidden="true"><div class="modal-dialog modal-dialog-centered modal-xl mw-100"><div class="modal-content bg-transparent border-0"><div class="modal-header"><h5 class="modal-title" id="aui-modal-title"></h5></div><div class="modal-body text-center"><i class="fas fa-circle-notch fa-spin fa-3x"></i></div></div></div></div>';
844
					jQuery('body').append($modal);
845
846
					jQuery('.aui-carousel-modal').modal({
847
						//backdrop: 'static'
848
					});
849
					jQuery('.aui-carousel-modal').on('hidden.bs.modal', function (e) {
850
						jQuery("iframe").attr('src', '');
851
					});
852
853
					$container = jQuery($link).closest('.aui-gallery');
854
855
					$clicked_href = jQuery($link).attr('href');
856
					$images = [];
857
					$container.find('.aui-lightbox-image').each(function() {
858
						var a = this;
859
						var href = jQuery(a).attr('href');
860
						if (href) {
861
							$images.push(href);
862
						}
863
					});
864
865
					if( $images.length ){
866
						var $carousel = '<div id="aui-embed-slider-modal" class="carousel slide" >';
867
868
						// indicators
869
						if($images.length > 1){
870
							$i = 0;
871
							$carousel  += '<ol class="carousel-indicators position-fixed">';
872
							$container.find('.aui-lightbox-image').each(function() {
873
								$active = $clicked_href == jQuery(this).attr('href') ? 'active' : '';
874
								$carousel  += '<li data-target="#aui-embed-slider-modal" data-slide-to="'+$i+'" class="'+$active+'"></li>';
875
								$i++;
876
877
							});
878
							$carousel  += '</ol>';
879
						}
880
881
882
883
						// items
884
						$i = 0;
885
						$carousel  += '<div class="carousel-inner">';
886
						$container.find('.aui-lightbox-image').each(function() {
887
							var a = this;
888
889
							$active = $clicked_href == jQuery(this).attr('href') ? 'active' : '';
890
							$carousel  += '<div class="carousel-item '+ $active+'"><div>';
891
892
893
							// image
894
							var css_height = window.innerWidth > window.innerHeight ? '90vh' : 'auto';
895
							var img = jQuery(a).find('img').clone().removeClass().addClass('mx-auto d-block w-auto mw-100 rounded').css('height',css_height).get(0).outerHTML;
896
							$carousel  += img;
897
							// captions
898
							if(jQuery(a).parent().find('.carousel-caption').length ){
899
								$carousel  += jQuery(a).parent().find('.carousel-caption').clone().removeClass('sr-only').get(0).outerHTML;
900
							}
901
							$carousel  += '</div></div>';
902
							$i++;
903
904
						});
905
						$container.find('.aui-lightbox-iframe').each(function() {
906
							var a = this;
907
908
							$active = $clicked_href == jQuery(this).attr('href') ? 'active' : '';
909
							$carousel  += '<div class="carousel-item '+ $active+'"><div class="modal-xl mx-auto embed-responsive embed-responsive-16by9">';
910
911
912
							// iframe
913
							var css_height = window.innerWidth > window.innerHeight ? '95vh' : 'auto';
914
							var url = jQuery(a).attr('href');
915
							var iframe = '<iframe class="embed-responsive-item" style="height:'+css_height +'" src="'+url+'?rel=0&amp;showinfo=0&amp;modestbranding=1&amp;autoplay=1" id="video" allow="autoplay"></iframe>';
916
							var img = iframe ;//.css('height',css_height).get(0).outerHTML;
917
							$carousel  += img;
918
919
							$carousel  += '</div></div>';
920
							$i++;
921
922
						});
923
						$carousel  += '</div>';
924
925
926
						// next/prev indicators
927
						if($images.length > 1) {
928
							$carousel += '<a class="carousel-control-prev" href="#aui-embed-slider-modal" role="button" data-slide="prev">';
929
							$carousel += '<span class="carousel-control-prev-icon" aria-hidden="true"></span>';
930
							$carousel += ' <a class="carousel-control-next" href="#aui-embed-slider-modal" role="button" data-slide="next">';
931
							$carousel += '<span class="carousel-control-next-icon" aria-hidden="true"></span>';
932
							$carousel += '</a>';
933
						}
934
935
936
						$carousel  += '</div>';
937
938
						var $close = '<button type="button" class="close text-white text-right position-fixed" style="font-size: 2.5em;right: 20px;top: 10px; z-index: 1055;" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
939
940
						jQuery('.aui-carousel-modal .modal-content').html($carousel).prepend($close);
941
942
						// enable ajax load
943
						//gd_init_carousel_ajax();
944
					}
945
946
				}
947
948
				/**
949
				 * Init lightbox embed.
950
				 */
951
				function aui_init_lightbox_embed(){
952
					// Open a lightbox for embeded items
953
					jQuery('.aui-lightbox-image, .aui-lightbox-iframe').off('click').on("click",function(ele) {
954
						aui_lightbox_embed(this,ele);
955
					});
956
				}
957
				
958
959
				/**
960
				 * Initiate all AUI JS.
961
				 */
962
				function aui_init(){
963
					// nav menu submenus
964
					init_nav_sub_menus();
965
					
966
					// init tooltips
967
					aui_init_tooltips();
968
969
					// init select2
970
					aui_init_select2();
971
972
					// init flatpickr
973
					aui_init_flatpickr();
974
975
					// init Greedy nav
976
					aui_init_greedy_nav();
977
978
					// Set times to time ago
979
					aui_time_ago('timeago');
980
					
981
					// init multiple item carousels
982
					aui_init_carousel_multiple_items();
983
					
984
					// init lightbox embeds
985
					aui_init_lightbox_embed();
986
				}
987
988
				// run on window loaded
989
				jQuery(window).on("load",function() {
990
					aui_init();
991
				});
992
993
				/* Fix modal background scroll on iOS mobile device */
994
				jQuery(function($) {
995
					var ua = navigator.userAgent.toLowerCase();
996
					var isiOS = ua.match(/(iphone|ipod|ipad)/);
997
					if (isiOS) {
998
						var pS = 0; pM = parseFloat($('body').css('marginTop'));
999
1000
						$(document).on('show.bs.modal', function() {
1001
							pS = window.scrollY;
1002
							$('body').css({
1003
								marginTop: -pS,
1004
								overflow: 'hidden',
1005
								position: 'fixed',
1006
							});
1007
						}).on('hidden.bs.modal', function() {
1008
							$('body').css({
1009
								marginTop: pM,
1010
								overflow: 'visible',
1011
								position: 'inherit',
1012
							});
1013
							window.scrollTo(0, pS);
1014
						});
1015
					}
1016
				});
1017
			</script>
1018
			<?php
1019
			$output = ob_get_clean();
1020
1021
1022
1023
			/*
1024
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
1025
			 */
1026
			return str_replace( array(
1027
				'<script>',
1028
				'</script>'
1029
			), '', self::minify_js($output) );
1030
		}
1031
1032
1033
		/**
1034
		 * JS to help with conflict issues with other plugins and themes using bootstrap v3.
1035
		 *
1036
		 * @TODO we may need this when other conflicts arrise.
1037
		 * @return mixed
1038
		 */
1039
		public static function bs3_compat_js() {
1040
			ob_start();
1041
			?>
1042
			<script>
1043
				<?php if( defined( 'FUSION_BUILDER_VERSION' ) ){ ?>
1044
				/* With Avada builder */
1045
1046
				<?php } ?>
1047
			</script>
1048
			<?php
1049
			return str_replace( array(
1050
				'<script>',
1051
				'</script>'
1052
			), '', ob_get_clean());
1053
		}
1054
1055
		/**
1056
		 * Get inline script used if bootstrap file browser enqueued.
1057
		 *
1058
		 * If this remains small then its best to use this than to add another JS file.
1059
		 */
1060
		public function inline_script_file_browser(){
1061
			ob_start();
1062
			?>
1063
			<script>
1064
				// run on doc ready
1065
				jQuery(document).ready(function () {
1066
					bsCustomFileInput.init();
1067
				});
1068
			</script>
1069
			<?php
1070
			$output = ob_get_clean();
1071
1072
			/*
1073
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
1074
			 */
1075
			return str_replace( array(
1076
				'<script>',
1077
				'</script>'
1078
			), '', $output );
1079
		}
1080
1081
		/**
1082
		 * Adds the Font Awesome JS.
1083
		 */
1084
		public function enqueue_scripts() {
1085
1086
			if( is_admin() && !$this->is_aui_screen()){
1087
				// don't add wp-admin scripts if not requested to
1088
			}else {
1089
1090
				$js_setting = current_action() == 'wp_enqueue_scripts' ? 'js' : 'js_backend';
1091
1092
				// select2
1093
				wp_register_script( 'select2', $this->url . 'assets/js/select2.min.js', array( 'jquery' ), $this->select2_version );
1094
1095
				// flatpickr
1096
				wp_register_script( 'flatpickr', $this->url . 'assets/js/flatpickr.min.js', array(), $this->latest );
1097
1098
				// Bootstrap file browser
1099
				wp_register_script( 'aui-custom-file-input', $url = $this->url . 'assets/js/bs-custom-file-input.min.js', array( 'jquery' ), $this->select2_version );
1100
				wp_add_inline_script( 'aui-custom-file-input', $this->inline_script_file_browser() );
1101
1102
				$load_inline = false;
1103
1104
				if ( $this->settings[ $js_setting ] == 'core-popper' ) {
1105
					// Bootstrap bundle
1106
					$url = $this->url . 'assets/js/bootstrap.bundle.min.js';
1107
					wp_register_script( 'bootstrap-js-bundle', $url, array(
1108
						'select2',
1109
						'jquery'
1110
					), $this->latest, $this->is_bs3_compat() );
1111
					// if in admin then add to footer for compatibility.
1112
					is_admin() ? wp_enqueue_script( 'bootstrap-js-bundle', '', null, null, true ) : wp_enqueue_script( 'bootstrap-js-bundle' );
1113
					$script = $this->inline_script();
1114
					wp_add_inline_script( 'bootstrap-js-bundle', $script );
1115
				} elseif ( $this->settings[ $js_setting ] == 'popper' ) {
1116
					$url = $this->url . 'assets/js/popper.min.js';
1117
					wp_register_script( 'bootstrap-js-popper', $url, array( 'select2', 'jquery' ), $this->latest );
1118
					wp_enqueue_script( 'bootstrap-js-popper' );
1119
					$load_inline = true;
1120
				} else {
1121
					$load_inline = true;
1122
				}
1123
1124
				// Load needed inline scripts by faking the loading of a script if the main script is not being loaded
1125
				if ( $load_inline ) {
1126
					wp_register_script( 'bootstrap-dummy', '', array( 'select2', 'jquery' ) );
1127
					wp_enqueue_script( 'bootstrap-dummy' );
1128
					$script = $this->inline_script();
1129
					wp_add_inline_script( 'bootstrap-dummy', $script );
1130
				}
1131
			}
1132
1133
		}
1134
1135
		/**
1136
		 * Enqueue flatpickr if called.
1137
		 */
1138
		public function enqueue_flatpickr(){
1139
			wp_enqueue_style( 'flatpickr' );
1140
			wp_enqueue_script( 'flatpickr' );
1141
		}
1142
1143
		/**
1144
		 * Get the url path to the current folder.
1145
		 *
1146
		 * @return string
1147
		 */
1148
		public function get_url() {
1149
1150
			$url = '';
1151
			// check if we are inside a plugin
1152
			$file_dir = str_replace( "/includes","", wp_normalize_path( dirname( __FILE__ ) ) );
1153
1154
			// add check in-case user has changed wp-content dir name.
1155
			$wp_content_folder_name = basename(WP_CONTENT_DIR);
1156
			$dir_parts = explode("/$wp_content_folder_name/",$file_dir);
1157
			$url_parts = explode("/$wp_content_folder_name/",plugins_url());
1158
1159
			if(!empty($url_parts[0]) && !empty($dir_parts[1])){
1160
				$url = trailingslashit( $url_parts[0]."/$wp_content_folder_name/".$dir_parts[1] );
1161
			}
1162
1163
			return $url;
1164
		}
1165
1166
		/**
1167
		 * Register the database settings with WordPress.
1168
		 */
1169
		public function register_settings() {
1170
			register_setting( 'ayecode-ui-settings', 'ayecode-ui-settings' );
1171
		}
1172
1173
		/**
1174
		 * Add the WordPress settings menu item.
1175
		 * @since 1.0.10 Calling function name direct will fail theme check so we don't.
1176
		 */
1177
		public function menu_item() {
1178
			$menu_function = 'add' . '_' . 'options' . '_' . 'page'; // won't pass theme check if function name present in theme
1179
			call_user_func( $menu_function, $this->name, $this->name, 'manage_options', 'ayecode-ui-settings', array(
1180
				$this,
1181
				'settings_page'
1182
			) );
1183
		}
1184
1185
		/**
1186
		 * Get a list of themes and their default JS settings.
1187
		 *
1188
		 * @return array
1189
		 */
1190
		public function theme_js_settings(){
1191
			return array(
1192
				'ayetheme' => 'popper',
1193
				'listimia' => 'required',
1194
				'listimia_backend' => 'core-popper',
1195
				//'avada'    => 'required', // removed as we now add compatibility
1196
			);
1197
		}
1198
1199
		/**
1200
		 * Get the current Font Awesome output settings.
1201
		 *
1202
		 * @return array The array of settings.
1203
		 */
1204
		public function get_settings() {
1205
1206
			$db_settings = get_option( 'ayecode-ui-settings' );
1207
			$js_default = 'core-popper';
1208
			$js_default_backend = $js_default;
1209
1210
			// maybe set defaults (if no settings set)
1211
			if(empty($db_settings)){
1212
				$active_theme = strtolower( get_template() ); // active parent theme.
1213
				$theme_js_settings = self::theme_js_settings();
0 ignored issues
show
Bug Best Practice introduced by
The method AyeCode_UI_Settings::theme_js_settings() 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

1213
				/** @scrutinizer ignore-call */ 
1214
    $theme_js_settings = self::theme_js_settings();
Loading history...
1214
				if(isset($theme_js_settings[$active_theme])){
1215
					$js_default = $theme_js_settings[$active_theme];
1216
					$js_default_backend = isset($theme_js_settings[$active_theme."_backend"]) ? $theme_js_settings[$active_theme."_backend"] : $js_default;
1217
				}
1218
			}
1219
1220
			$defaults = array(
1221
				'css'       => 'compatibility', // core, compatibility
1222
				'js'        => $js_default, // js to load, core-popper, popper
1223
				'html_font_size'        => '16', // js to load, core-popper, popper
1224
				'css_backend'       => 'compatibility', // core, compatibility
1225
				'js_backend'        => $js_default_backend, // js to load, core-popper, popper
1226
				'disable_admin'     =>  '', // URL snippets to disable loading on admin
1227
			);
1228
1229
			$settings = wp_parse_args( $db_settings, $defaults );
1230
1231
			/**
1232
			 * Filter the Bootstrap settings.
1233
			 *
1234
			 * @todo if we add this filer people might use it and then it defeates the purpose of this class :/
1235
			 */
1236
			return $this->settings = apply_filters( 'ayecode-ui-settings', $settings, $db_settings, $defaults );
1237
		}
1238
1239
1240
		/**
1241
		 * The settings page html output.
1242
		 */
1243
		public function settings_page() {
1244
			if ( ! current_user_can( 'manage_options' ) ) {
1245
				wp_die( __( 'You do not have sufficient permissions to access this page.', 'aui' ) );
1246
			}
1247
			?>
1248
			<div class="wrap">
1249
				<h1><?php echo $this->name; ?></h1>
1250
				<p><?php _e("Here you can adjust settings if you are having compatibility issues.",'aui');?></p>
1251
				<form method="post" action="options.php">
1252
					<?php
1253
					settings_fields( 'ayecode-ui-settings' );
1254
					do_settings_sections( 'ayecode-ui-settings' );
1255
					?>
1256
1257
					<h2><?php _e( 'Frontend', 'aui' ); ?></h2>
1258
					<table class="form-table wpbs-table-settings">
1259
						<tr valign="top">
1260
							<th scope="row"><label
1261
									for="wpbs-css"><?php _e( 'Load CSS', 'aui' ); ?></label></th>
1262
							<td>
1263
								<select name="ayecode-ui-settings[css]" id="wpbs-css">
1264
									<option	value="compatibility" <?php selected( $this->settings['css'], 'compatibility' ); ?>><?php _e( 'Compatibility Mode (default)', 'aui' ); ?></option>
1265
									<option value="core" <?php selected( $this->settings['css'], 'core' ); ?>><?php _e( 'Full Mode', 'aui' ); ?></option>
1266
									<option	value="" <?php selected( $this->settings['css'], '' ); ?>><?php _e( 'Disabled', 'aui' ); ?></option>
1267
								</select>
1268
							</td>
1269
						</tr>
1270
1271
						<tr valign="top">
1272
							<th scope="row"><label
1273
									for="wpbs-js"><?php _e( 'Load JS', 'aui' ); ?></label></th>
1274
							<td>
1275
								<select name="ayecode-ui-settings[js]" id="wpbs-js">
1276
									<option	value="core-popper" <?php selected( $this->settings['js'], 'core-popper' ); ?>><?php _e( 'Core + Popper (default)', 'aui' ); ?></option>
1277
									<option value="popper" <?php selected( $this->settings['js'], 'popper' ); ?>><?php _e( 'Popper', 'aui' ); ?></option>
1278
									<option value="required" <?php selected( $this->settings['js'], 'required' ); ?>><?php _e( 'Required functions only', 'aui' ); ?></option>
1279
									<option	value="" <?php selected( $this->settings['js'], '' ); ?>><?php _e( 'Disabled (not recommended)', 'aui' ); ?></option>
1280
								</select>
1281
							</td>
1282
						</tr>
1283
1284
						<tr valign="top">
1285
							<th scope="row"><label
1286
									for="wpbs-font_size"><?php _e( 'HTML Font Size (px)', 'aui' ); ?></label></th>
1287
							<td>
1288
								<input type="number" name="ayecode-ui-settings[html_font_size]" id="wpbs-font_size" value="<?php echo absint( $this->settings['html_font_size']); ?>" placeholder="16" />
1289
								<p class="description" ><?php _e("Our font sizing is rem (responsive based) here you can set the html font size in-case your theme is setting it too low.",'aui');?></p>
1290
							</td>
1291
						</tr>
1292
1293
					</table>
1294
1295
					<h2><?php _e( 'Backend', 'aui' ); ?> (wp-admin)</h2>
1296
					<table class="form-table wpbs-table-settings">
1297
						<tr valign="top">
1298
							<th scope="row"><label
1299
									for="wpbs-css-admin"><?php _e( 'Load CSS', 'aui' ); ?></label></th>
1300
							<td>
1301
								<select name="ayecode-ui-settings[css_backend]" id="wpbs-css-admin">
1302
									<option	value="compatibility" <?php selected( $this->settings['css_backend'], 'compatibility' ); ?>><?php _e( 'Compatibility Mode (default)', 'aui' ); ?></option>
1303
									<option value="core" <?php selected( $this->settings['css_backend'], 'core' ); ?>><?php _e( 'Full Mode (will cause style issues)', 'aui' ); ?></option>
1304
									<option	value="" <?php selected( $this->settings['css_backend'], '' ); ?>><?php _e( 'Disabled', 'aui' ); ?></option>
1305
								</select>
1306
							</td>
1307
						</tr>
1308
1309
						<tr valign="top">
1310
							<th scope="row"><label
1311
									for="wpbs-js-admin"><?php _e( 'Load JS', 'aui' ); ?></label></th>
1312
							<td>
1313
								<select name="ayecode-ui-settings[js_backend]" id="wpbs-js-admin">
1314
									<option	value="core-popper" <?php selected( $this->settings['js_backend'], 'core-popper' ); ?>><?php _e( 'Core + Popper (default)', 'aui' ); ?></option>
1315
									<option value="popper" <?php selected( $this->settings['js_backend'], 'popper' ); ?>><?php _e( 'Popper', 'aui' ); ?></option>
1316
									<option value="required" <?php selected( $this->settings['js_backend'], 'required' ); ?>><?php _e( 'Required functions only', 'aui' ); ?></option>
1317
									<option	value="" <?php selected( $this->settings['js_backend'], '' ); ?>><?php _e( 'Disabled (not recommended)', 'aui' ); ?></option>
1318
								</select>
1319
							</td>
1320
						</tr>
1321
1322
						<tr valign="top">
1323
							<th scope="row"><label
1324
									for="wpbs-disable-admin"><?php _e( 'Disable load on URL', 'aui' ); ?></label></th>
1325
							<td>
1326
								<p><?php _e( 'If you have backend conflict you can enter a partial URL argument that will disable the loading of AUI on those pages. Add each argument on a new line.', 'aui' ); ?></p>
1327
								<textarea name="ayecode-ui-settings[disable_admin]" rows="10" cols="50" id="wpbs-disable-admin" class="large-text code" spellcheck="false" placeholder="myplugin.php &#10;action=go"><?php echo $this->settings['disable_admin'];?></textarea>
1328
1329
							</td>
1330
						</tr>
1331
1332
					</table>
1333
1334
					<?php
1335
					submit_button();
1336
					?>
1337
				</form>
1338
1339
				<div id="wpbs-version"><?php echo $this->version; ?></div>
1340
			</div>
1341
1342
			<?php
1343
		}
1344
1345
		public function customizer_settings($wp_customize){
1346
			$wp_customize->add_section('aui_settings', array(
1347
				'title'    => __('AyeCode UI','aui'),
1348
				'priority' => 120,
1349
			));
1350
1351
			//  =============================
1352
			//  = Color Picker              =
1353
			//  =============================
1354
			$wp_customize->add_setting('aui_options[color_primary]', array(
1355
				'default'           => AUI_PRIMARY_COLOR,
1356
				'sanitize_callback' => 'sanitize_hex_color',
1357
				'capability'        => 'edit_theme_options',
1358
				'type'              => 'option',
1359
				'transport'         => 'refresh',
1360
			));
1361
			$wp_customize->add_control( new WP_Customize_Color_Control($wp_customize, 'color_primary', array(
1362
				'label'    => __('Primary Color','aui'),
1363
				'section'  => 'aui_settings',
1364
				'settings' => 'aui_options[color_primary]',
1365
			)));
1366
1367
			$wp_customize->add_setting('aui_options[color_secondary]', array(
1368
				'default'           => '#6c757d',
1369
				'sanitize_callback' => 'sanitize_hex_color',
1370
				'capability'        => 'edit_theme_options',
1371
				'type'              => 'option',
1372
				'transport'         => 'refresh',
1373
			));
1374
			$wp_customize->add_control( new WP_Customize_Color_Control($wp_customize, 'color_secondary', array(
1375
				'label'    => __('Secondary Color','aui'),
1376
				'section'  => 'aui_settings',
1377
				'settings' => 'aui_options[color_secondary]',
1378
			)));
1379
		}
1380
1381
		/**
1382
		 * CSS to help with conflict issues with other plugins and themes using bootstrap v3.
1383
		 *
1384
		 * @return mixed
1385
		 */
1386
		public static function bs3_compat_css() {
1387
			ob_start();
1388
			?>
1389
			<style>
1390
			/* Bootstrap 3 compatibility */
1391
			body.modal-open .modal-backdrop.show:not(.in) {opacity:0.5;}
1392
			body.modal-open .modal.show:not(.in)  {opacity:1;z-index: 99999}
1393
			body.modal-open .modal.show:not(.in) .modal-content  {box-shadow: none;}
1394
			body.modal-open .modal.show:not(.in)  .modal-dialog {transform: initial;}
1395
1396
			body.modal-open .modal.bsui .modal-dialog{left: auto;}
1397
1398
			.collapse.show:not(.in){display: inherit;}
1399
			.fade.show{opacity: 1;}
1400
1401
			<?php if( defined( 'SVQ_THEME_VERSION' ) ){ ?>
1402
			/* KLEO theme specific */
1403
			.kleo-main-header .navbar-collapse.collapse.show:not(.in){display: block !important;}
1404
			<?php } ?>
1405
1406
			<?php if( defined( 'FUSION_BUILDER_VERSION' ) ){ ?>
1407
			/* With Avada builder */
1408
			body.modal-open .modal.in  {opacity:1;z-index: 99999}
1409
			body.modal-open .modal.bsui.in .modal-content  {box-shadow: none;}
1410
			.bsui .collapse.in{display: inherit;}
1411
			<?php } ?>
1412
			</style>
1413
			<?php
1414
			return str_replace( array(
1415
				'<style>',
1416
				'</style>'
1417
			), '', self::minify_css( ob_get_clean() ) );
1418
		}
1419
1420
1421
		public static function custom_css($compatibility = true) {
1422
			$settings = get_option('aui_options');
1423
1424
			ob_start();
1425
1426
			$primary_color = !empty($settings['color_primary']) ? $settings['color_primary'] : AUI_PRIMARY_COLOR;
1427
			$secondary_color = !empty($settings['color_secondary']) ? $settings['color_secondary'] : AUI_SECONDARY_COLOR;
1428
				//AUI_PRIMARY_COLOR_ORIGINAL
1429
			?>
1430
			<style>
1431
				<?php
1432
1433
					// BS v3 compat
1434
					if( self::is_bs3_compat() ){
1435
					    echo self::bs3_compat_css();
1436
					}
1437
1438
					if(!is_admin() && $primary_color != AUI_PRIMARY_COLOR_ORIGINAL){
1439
						echo self::css_primary($primary_color,$compatibility);
1440
					}
1441
1442
					if(!is_admin() && $secondary_color != AUI_SECONDARY_COLOR_ORIGINAL){
1443
						echo self::css_secondary($settings['color_secondary'],$compatibility);
1444
					}
1445
1446
					// Set admin bar z-index lower when modal is open.
1447
					echo ' body.modal-open #wpadminbar{z-index:999}.embed-responsive-16by9 .fluid-width-video-wrapper{padding:0 !important;position:initial}';
1448
                ?>
1449
			</style>
1450
			<?php
1451
1452
1453
			/*
1454
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
1455
			 */
1456
			return str_replace( array(
1457
				'<style>',
1458
				'</style>'
1459
			), '', self::minify_css( ob_get_clean() ) );
1460
		}
1461
1462
		/**
1463
		 * Check if we should add booststrap 3 compatibility changes.
1464
		 *
1465
		 * @return bool
1466
		 */
1467
		public static function is_bs3_compat(){
1468
			return defined('AYECODE_UI_BS3_COMPAT') || defined('SVQ_THEME_VERSION') || defined('FUSION_BUILDER_VERSION');
1469
		}
1470
1471
		public static function css_primary($color_code,$compatibility){;
1472
			$color_code = sanitize_hex_color($color_code);
1473
			if(!$color_code){return '';}
1474
			/**
1475
			 * c = color, b = background color, o = border-color, f = fill
1476
			 */
1477
			$selectors = array(
1478
				'a' => array('c'),
1479
				'.btn-primary' => array('b','o'),
1480
				'.btn-primary.disabled' => array('b','o'),
1481
				'.btn-primary:disabled' => array('b','o'),
1482
				'.btn-outline-primary' => array('c','o'),
1483
				'.btn-outline-primary:hover' => array('b','o'),
1484
				'.btn-outline-primary:not(:disabled):not(.disabled).active' => array('b','o'),
1485
				'.btn-outline-primary:not(:disabled):not(.disabled):active' => array('b','o'),
1486
				'.show>.btn-outline-primary.dropdown-toggle' => array('b','o'),
1487
				'.btn-link' => array('c'),
1488
				'.dropdown-item.active' => array('b'),
1489
				'.custom-control-input:checked~.custom-control-label::before' => array('b','o'),
1490
				'.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before' => array('b','o'),
1491
//				'.custom-range::-webkit-slider-thumb' => array('b'), // these break the inline rules...
1492
//				'.custom-range::-moz-range-thumb' => array('b'),
1493
//				'.custom-range::-ms-thumb' => array('b'),
1494
				'.nav-pills .nav-link.active' => array('b'),
1495
				'.nav-pills .show>.nav-link' => array('b'),
1496
				'.page-link' => array('c'),
1497
				'.page-item.active .page-link' => array('b','o'),
1498
				'.badge-primary' => array('b'),
1499
				'.alert-primary' => array('b','o'),
1500
				'.progress-bar' => array('b'),
1501
				'.list-group-item.active' => array('b','o'),
1502
				'.bg-primary' => array('b','f'),
1503
				'.btn-link.btn-primary' => array('c'),
1504
				'.select2-container .select2-results__option--highlighted.select2-results__option[aria-selected=true]' => array('b'),
1505
			);
1506
1507
			$important_selectors = array(
1508
				'.bg-primary' => array('b','f'),
1509
				'.border-primary' => array('o'),
1510
				'.text-primary' => array('c'),
1511
			);
1512
1513
			$color = array();
1514
			$color_i = array();
1515
			$background = array();
1516
			$background_i = array();
1517
			$border = array();
1518
			$border_i = array();
1519
			$fill = array();
1520
			$fill_i = array();
1521
1522
			$output = '';
1523
1524
			// build rules into each type
1525
			foreach($selectors as $selector => $types){
1526
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1527
				$types = array_combine($types,$types);
1528
				if(isset($types['c'])){$color[] = $selector;}
1529
				if(isset($types['b'])){$background[] = $selector;}
1530
				if(isset($types['o'])){$border[] = $selector;}
1531
				if(isset($types['f'])){$fill[] = $selector;}
1532
			}
1533
1534
			// build rules into each type
1535
			foreach($important_selectors as $selector => $types){
1536
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1537
				$types = array_combine($types,$types);
1538
				if(isset($types['c'])){$color_i[] = $selector;}
1539
				if(isset($types['b'])){$background_i[] = $selector;}
1540
				if(isset($types['o'])){$border_i[] = $selector;}
1541
				if(isset($types['f'])){$fill_i[] = $selector;}
1542
			}
1543
1544
			// add any color rules
1545
			if(!empty($color)){
1546
				$output .= implode(",",$color) . "{color: $color_code;} ";
1547
			}
1548
			if(!empty($color_i)){
1549
				$output .= implode(",",$color_i) . "{color: $color_code !important;} ";
1550
			}
1551
1552
			// add any background color rules
1553
			if(!empty($background)){
1554
				$output .= implode(",",$background) . "{background-color: $color_code;} ";
1555
			}
1556
			if(!empty($background_i)){
1557
				$output .= implode(",",$background_i) . "{background-color: $color_code !important;} ";
1558
			}
1559
1560
			// add any border color rules
1561
			if(!empty($border)){
1562
				$output .= implode(",",$border) . "{border-color: $color_code;} ";
1563
			}
1564
			if(!empty($border_i)){
1565
				$output .= implode(",",$border_i) . "{border-color: $color_code !important;} ";
1566
			}
1567
1568
			// add any fill color rules
1569
			if(!empty($fill)){
1570
				$output .= implode(",",$fill) . "{fill: $color_code;} ";
1571
			}
1572
			if(!empty($fill_i)){
1573
				$output .= implode(",",$fill_i) . "{fill: $color_code !important;} ";
1574
			}
1575
1576
1577
			$prefix = $compatibility ? ".bsui " : "";
1578
1579
			// darken
1580
			$darker_075 = self::css_hex_lighten_darken($color_code,"-0.075");
0 ignored issues
show
Bug introduced by
'-0.075' of type string is incompatible with the type double expected by parameter $adjustPercent of AyeCode_UI_Settings::css_hex_lighten_darken(). ( Ignorable by Annotation )

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

1580
			$darker_075 = self::css_hex_lighten_darken($color_code,/** @scrutinizer ignore-type */ "-0.075");
Loading history...
1581
			$darker_10 = self::css_hex_lighten_darken($color_code,"-0.10");
1582
			$darker_125 = self::css_hex_lighten_darken($color_code,"-0.125");
1583
1584
			// lighten
1585
			$lighten_25 = self::css_hex_lighten_darken($color_code,"0.25");
1586
1587
			// opacity see https://css-tricks.com/8-digit-hex-codes/
1588
			$op_25 = $color_code."40"; // 25% opacity
1589
1590
1591
			// button states
1592
			$output .= $prefix ." .btn-primary:hover, $prefix .btn-primary:focus, $prefix .btn-primary.focus{background-color: ".$darker_075.";    border-color: ".$darker_10.";} ";
1593
			$output .= $prefix ." .btn-outline-primary:not(:disabled):not(.disabled):active:focus, $prefix .btn-outline-primary:not(:disabled):not(.disabled).active:focus, .show>$prefix .btn-outline-primary.dropdown-toggle:focus{box-shadow: 0 0 0 0.2rem $op_25;} ";
1594
			$output .= $prefix ." .btn-primary:not(:disabled):not(.disabled):active, $prefix .btn-primary:not(:disabled):not(.disabled).active, .show>$prefix .btn-primary.dropdown-toggle{background-color: ".$darker_10.";    border-color: ".$darker_125.";} ";
1595
			$output .= $prefix ." .btn-primary:not(:disabled):not(.disabled):active:focus, $prefix .btn-primary:not(:disabled):not(.disabled).active:focus, .show>$prefix .btn-primary.dropdown-toggle:focus {box-shadow: 0 0 0 0.2rem $op_25;} ";
1596
1597
1598
			// dropdown's
1599
			$output .= $prefix ." .dropdown-item.active, $prefix .dropdown-item:active{background-color: $color_code;} ";
1600
1601
1602
			// input states
1603
			$output .= $prefix ." .form-control:focus{border-color: ".$lighten_25.";box-shadow: 0 0 0 0.2rem $op_25;} ";
1604
1605
			// page link
1606
			$output .= $prefix ." .page-link:focus{box-shadow: 0 0 0 0.2rem $op_25;} ";
1607
1608
			return $output;
1609
		}
1610
1611
		public static function css_secondary($color_code,$compatibility){;
1612
			$color_code = sanitize_hex_color($color_code);
1613
			if(!$color_code){return '';}
1614
			/**
1615
			 * c = color, b = background color, o = border-color, f = fill
1616
			 */
1617
			$selectors = array(
1618
				'.btn-secondary' => array('b','o'),
1619
				'.btn-secondary.disabled' => array('b','o'),
1620
				'.btn-secondary:disabled' => array('b','o'),
1621
				'.btn-outline-secondary' => array('c','o'),
1622
				'.btn-outline-secondary:hover' => array('b','o'),
1623
				'.btn-outline-secondary.disabled' => array('c'),
1624
				'.btn-outline-secondary:disabled' => array('c'),
1625
				'.btn-outline-secondary:not(:disabled):not(.disabled):active' => array('b','o'),
1626
				'.btn-outline-secondary:not(:disabled):not(.disabled).active' => array('b','o'),
1627
				'.btn-outline-secondary.dropdown-toggle' => array('b','o'),
1628
				'.badge-secondary' => array('b'),
1629
				'.alert-secondary' => array('b','o'),
1630
				'.btn-link.btn-secondary' => array('c'),
1631
			);
1632
1633
			$important_selectors = array(
1634
				'.bg-secondary' => array('b','f'),
1635
				'.border-secondary' => array('o'),
1636
				'.text-secondary' => array('c'),
1637
			);
1638
1639
			$color = array();
1640
			$color_i = array();
1641
			$background = array();
1642
			$background_i = array();
1643
			$border = array();
1644
			$border_i = array();
1645
			$fill = array();
1646
			$fill_i = array();
1647
1648
			$output = '';
1649
1650
			// build rules into each type
1651
			foreach($selectors as $selector => $types){
1652
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1653
				$types = array_combine($types,$types);
1654
				if(isset($types['c'])){$color[] = $selector;}
1655
				if(isset($types['b'])){$background[] = $selector;}
1656
				if(isset($types['o'])){$border[] = $selector;}
1657
				if(isset($types['f'])){$fill[] = $selector;}
1658
			}
1659
1660
			// build rules into each type
1661
			foreach($important_selectors as $selector => $types){
1662
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1663
				$types = array_combine($types,$types);
1664
				if(isset($types['c'])){$color_i[] = $selector;}
1665
				if(isset($types['b'])){$background_i[] = $selector;}
1666
				if(isset($types['o'])){$border_i[] = $selector;}
1667
				if(isset($types['f'])){$fill_i[] = $selector;}
1668
			}
1669
1670
			// add any color rules
1671
			if(!empty($color)){
1672
				$output .= implode(",",$color) . "{color: $color_code;} ";
1673
			}
1674
			if(!empty($color_i)){
1675
				$output .= implode(",",$color_i) . "{color: $color_code !important;} ";
1676
			}
1677
1678
			// add any background color rules
1679
			if(!empty($background)){
1680
				$output .= implode(",",$background) . "{background-color: $color_code;} ";
1681
			}
1682
			if(!empty($background_i)){
1683
				$output .= implode(",",$background_i) . "{background-color: $color_code !important;} ";
1684
			}
1685
1686
			// add any border color rules
1687
			if(!empty($border)){
1688
				$output .= implode(",",$border) . "{border-color: $color_code;} ";
1689
			}
1690
			if(!empty($border_i)){
1691
				$output .= implode(",",$border_i) . "{border-color: $color_code !important;} ";
1692
			}
1693
1694
			// add any fill color rules
1695
			if(!empty($fill)){
1696
				$output .= implode(",",$fill) . "{fill: $color_code;} ";
1697
			}
1698
			if(!empty($fill_i)){
1699
				$output .= implode(",",$fill_i) . "{fill: $color_code !important;} ";
1700
			}
1701
1702
1703
			$prefix = $compatibility ? ".bsui " : "";
1704
1705
			// darken
1706
			$darker_075 = self::css_hex_lighten_darken($color_code,"-0.075");
0 ignored issues
show
Bug introduced by
'-0.075' of type string is incompatible with the type double expected by parameter $adjustPercent of AyeCode_UI_Settings::css_hex_lighten_darken(). ( Ignorable by Annotation )

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

1706
			$darker_075 = self::css_hex_lighten_darken($color_code,/** @scrutinizer ignore-type */ "-0.075");
Loading history...
1707
			$darker_10 = self::css_hex_lighten_darken($color_code,"-0.10");
1708
			$darker_125 = self::css_hex_lighten_darken($color_code,"-0.125");
1709
1710
			// lighten
1711
			$lighten_25 = self::css_hex_lighten_darken($color_code,"0.25");
0 ignored issues
show
Unused Code introduced by
The assignment to $lighten_25 is dead and can be removed.
Loading history...
1712
1713
			// opacity see https://css-tricks.com/8-digit-hex-codes/
1714
			$op_25 = $color_code."40"; // 25% opacity
1715
1716
1717
			// button states
1718
			$output .= $prefix ." .btn-secondary:hover{background-color: ".$darker_075.";    border-color: ".$darker_10.";} ";
1719
			$output .= $prefix ." .btn-outline-secondary:not(:disabled):not(.disabled):active:focus, $prefix .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, .show>$prefix .btn-outline-secondary.dropdown-toggle:focus{box-shadow: 0 0 0 0.2rem $op_25;} ";
1720
			$output .= $prefix ." .btn-secondary:not(:disabled):not(.disabled):active, $prefix .btn-secondary:not(:disabled):not(.disabled).active, .show>$prefix .btn-secondary.dropdown-toggle{background-color: ".$darker_10.";    border-color: ".$darker_125.";} ";
1721
			$output .= $prefix ." .btn-secondary:not(:disabled):not(.disabled):active:focus, $prefix .btn-secondary:not(:disabled):not(.disabled).active:focus, .show>$prefix .btn-secondary.dropdown-toggle:focus {box-shadow: 0 0 0 0.2rem $op_25;} ";
1722
1723
1724
			return $output;
1725
		}
1726
1727
		/**
1728
		 * Increases or decreases the brightness of a color by a percentage of the current brightness.
1729
		 *
1730
		 * @param   string  $hexCode        Supported formats: `#FFF`, `#FFFFFF`, `FFF`, `FFFFFF`
1731
		 * @param   float   $adjustPercent  A number between -1 and 1. E.g. 0.3 = 30% lighter; -0.4 = 40% darker.
1732
		 *
1733
		 * @return  string
1734
		 */
1735
		public static function css_hex_lighten_darken($hexCode, $adjustPercent) {
1736
			$hexCode = ltrim($hexCode, '#');
1737
1738
			if (strlen($hexCode) == 3) {
1739
				$hexCode = $hexCode[0] . $hexCode[0] . $hexCode[1] . $hexCode[1] . $hexCode[2] . $hexCode[2];
1740
			}
1741
1742
			$hexCode = array_map('hexdec', str_split($hexCode, 2));
0 ignored issues
show
Bug introduced by
It seems like str_split($hexCode, 2) can also be of type true; however, parameter $array of array_map() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

1742
			$hexCode = array_map('hexdec', /** @scrutinizer ignore-type */ str_split($hexCode, 2));
Loading history...
1743
1744
			foreach ($hexCode as & $color) {
1745
				$adjustableLimit = $adjustPercent < 0 ? $color : 255 - $color;
1746
				$adjustAmount = ceil($adjustableLimit * $adjustPercent);
1747
1748
				$color = str_pad(dechex($color + $adjustAmount), 2, '0', STR_PAD_LEFT);
0 ignored issues
show
Bug introduced by
$color + $adjustAmount of type double is incompatible with the type integer expected by parameter $num of dechex(). ( Ignorable by Annotation )

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

1748
				$color = str_pad(dechex(/** @scrutinizer ignore-type */ $color + $adjustAmount), 2, '0', STR_PAD_LEFT);
Loading history...
1749
			}
1750
1751
			return '#' . implode($hexCode);
1752
		}
1753
1754
		/**
1755
		 * Check if we should display examples.
1756
		 */
1757
		public function maybe_show_examples(){
1758
			if(current_user_can('manage_options') && isset($_REQUEST['preview-aui'])){
1759
				echo "<head>";
1760
				wp_head();
1761
				echo "</head>";
1762
				echo "<body>";
1763
				echo $this->get_examples();
1764
				echo "</body>";
1765
				exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1766
			}
1767
		}
1768
1769
		/**
1770
		 * Get developer examples.
1771
		 *
1772
		 * @return string
1773
		 */
1774
		public function get_examples(){
1775
			$output = '';
1776
1777
1778
			// open form
1779
			$output .= "<form class='p-5 m-5 border rounded'>";
1780
1781
			// input example
1782
			$output .= aui()->input(array(
1783
				'type'  =>  'text',
1784
				'id'    =>  'text-example',
1785
				'name'    =>  'text-example',
1786
				'placeholder'   => 'text placeholder',
1787
				'title'   => 'Text input example',
1788
				'value' =>  '',
1789
				'required'  => false,
1790
				'help_text' => 'help text',
1791
				'label' => 'Text input example label'
1792
			));
1793
1794
			// input example
1795
			$output .= aui()->input(array(
1796
				'type'  =>  'url',
1797
				'id'    =>  'text-example2',
1798
				'name'    =>  'text-example',
1799
				'placeholder'   => 'url placeholder',
1800
				'title'   => 'Text input example',
1801
				'value' =>  '',
1802
				'required'  => false,
1803
				'help_text' => 'help text',
1804
				'label' => 'Text input example label'
1805
			));
1806
1807
			// checkbox example
1808
			$output .= aui()->input(array(
1809
				'type'  =>  'checkbox',
1810
				'id'    =>  'checkbox-example',
1811
				'name'    =>  'checkbox-example',
1812
				'placeholder'   => 'checkbox-example',
1813
				'title'   => 'Checkbox example',
1814
				'value' =>  '1',
1815
				'checked'   => true,
1816
				'required'  => false,
1817
				'help_text' => 'help text',
1818
				'label' => 'Checkbox checked'
1819
			));
1820
1821
			// checkbox example
1822
			$output .= aui()->input(array(
1823
				'type'  =>  'checkbox',
1824
				'id'    =>  'checkbox-example2',
1825
				'name'    =>  'checkbox-example2',
1826
				'placeholder'   => 'checkbox-example',
1827
				'title'   => 'Checkbox example',
1828
				'value' =>  '1',
1829
				'checked'   => false,
1830
				'required'  => false,
1831
				'help_text' => 'help text',
1832
				'label' => 'Checkbox un-checked'
1833
			));
1834
1835
			// switch example
1836
			$output .= aui()->input(array(
1837
				'type'  =>  'checkbox',
1838
				'id'    =>  'switch-example',
1839
				'name'    =>  'switch-example',
1840
				'placeholder'   => 'checkbox-example',
1841
				'title'   => 'Switch example',
1842
				'value' =>  '1',
1843
				'checked'   => true,
1844
				'switch'    => true,
1845
				'required'  => false,
1846
				'help_text' => 'help text',
1847
				'label' => 'Switch on'
1848
			));
1849
1850
			// switch example
1851
			$output .= aui()->input(array(
1852
				'type'  =>  'checkbox',
1853
				'id'    =>  'switch-example2',
1854
				'name'    =>  'switch-example2',
1855
				'placeholder'   => 'checkbox-example',
1856
				'title'   => 'Switch example',
1857
				'value' =>  '1',
1858
				'checked'   => false,
1859
				'switch'    => true,
1860
				'required'  => false,
1861
				'help_text' => 'help text',
1862
				'label' => 'Switch off'
1863
			));
1864
1865
			// close form
1866
			$output .= "</form>";
1867
1868
			return $output;
1869
		}
1870
1871
		/**
1872
		 * Calendar params.
1873
		 *
1874
		 * @since 0.1.44
1875
		 *
1876
		 * @return array Calendar params.
1877
		 */
1878
		public static function calendar_params() {
1879
			$params = array(
1880
				'month_long_1' => __( 'January', 'aui' ),
1881
				'month_long_2' => __( 'February', 'aui' ),
1882
				'month_long_3' => __( 'March', 'aui' ),
1883
				'month_long_4' => __( 'April', 'aui' ),
1884
				'month_long_5' => __( 'May', 'aui' ),
1885
				'month_long_6' => __( 'June', 'aui' ),
1886
				'month_long_7' => __( 'July', 'aui' ),
1887
				'month_long_8' => __( 'August', 'aui' ),
1888
				'month_long_9' => __( 'September', 'aui' ),
1889
				'month_long_10' => __( 'October', 'aui' ),
1890
				'month_long_11' => __( 'November', 'aui' ),
1891
				'month_long_12' => __( 'December', 'aui' ),
1892
				'month_s_1' => _x( 'Jan', 'January abbreviation', 'aui' ),
1893
				'month_s_2' => _x( 'Feb', 'February abbreviation', 'aui' ),
1894
				'month_s_3' => _x( 'Mar', 'March abbreviation', 'aui' ),
1895
				'month_s_4' => _x( 'Apr', 'April abbreviation', 'aui' ),
1896
				'month_s_5' => _x( 'May', 'May abbreviation', 'aui' ),
1897
				'month_s_6' => _x( 'Jun', 'June abbreviation', 'aui' ),
1898
				'month_s_7' => _x( 'Jul', 'July abbreviation', 'aui' ),
1899
				'month_s_8' => _x( 'Aug', 'August abbreviation', 'aui' ),
1900
				'month_s_9' => _x( 'Sep', 'September abbreviation', 'aui' ),
1901
				'month_s_10' => _x( 'Oct', 'October abbreviation', 'aui' ),
1902
				'month_s_11' => _x( 'Nov', 'November abbreviation', 'aui' ),
1903
				'month_s_12' => _x( 'Dec', 'December abbreviation', 'aui' ),
1904
				'day_s1_1' => _x( 'S', 'Sunday initial', 'aui' ),
1905
				'day_s1_2' => _x( 'M', 'Monday initial', 'aui' ),
1906
				'day_s1_3' => _x( 'T', 'Tuesday initial', 'aui' ),
1907
				'day_s1_4' => _x( 'W', 'Wednesday initial', 'aui' ),
1908
				'day_s1_5' => _x( 'T', 'Friday initial', 'aui' ),
1909
				'day_s1_6' => _x( 'F', 'Thursday initial', 'aui' ),
1910
				'day_s1_7' => _x( 'S', 'Saturday initial', 'aui' ),
1911
				'day_s2_1' => __( 'Su', 'aui' ),
1912
				'day_s2_2' => __( 'Mo', 'aui' ),
1913
				'day_s2_3' => __( 'Tu', 'aui' ),
1914
				'day_s2_4' => __( 'We', 'aui' ),
1915
				'day_s2_5' => __( 'Th', 'aui' ),
1916
				'day_s2_6' => __( 'Fr', 'aui' ),
1917
				'day_s2_7' => __( 'Sa', 'aui' ),
1918
				'day_s3_1' => __( 'Sun', 'aui' ),
1919
				'day_s3_2' => __( 'Mon', 'aui' ),
1920
				'day_s3_3' => __( 'Tue', 'aui' ),
1921
				'day_s3_4' => __( 'Wed', 'aui' ),
1922
				'day_s3_5' => __( 'Thu', 'aui' ),
1923
				'day_s3_6' => __( 'Fri', 'aui' ),
1924
				'day_s3_7' => __( 'Sat', 'aui' ),
1925
				'day_s5_1' => __( 'Sunday', 'aui' ),
1926
				'day_s5_2' => __( 'Monday', 'aui' ),
1927
				'day_s5_3' => __( 'Tuesday', 'aui' ),
1928
				'day_s5_4' => __( 'Wednesday', 'aui' ),
1929
				'day_s5_5' => __( 'Thursday', 'aui' ),
1930
				'day_s5_6' => __( 'Friday', 'aui' ),
1931
				'day_s5_7' => __( 'Saturday', 'aui' ),
1932
				'am_lower' => __( 'am', 'aui' ),
1933
				'pm_lower' => __( 'pm', 'aui' ),
1934
				'am_upper' => __( 'AM', 'aui' ),
1935
				'pm_upper' => __( 'PM', 'aui' ),
1936
				'firstDayOfWeek' => (int) get_option( 'start_of_week' ),
1937
				'time_24hr' => false,
1938
				'year' => __( 'Year', 'aui' ),
1939
				'hour' => __( 'Hour', 'aui' ),
1940
				'minute' => __( 'Minute', 'aui' ),
1941
				'weekAbbreviation' => __( 'Wk', 'aui' ),
1942
				'rangeSeparator' => __( ' to ', 'aui' ),
1943
				'scrollTitle' => __( 'Scroll to increment', 'aui' ),
1944
				'toggleTitle' => __( 'Click to toggle', 'aui' )
1945
			);
1946
1947
			return apply_filters( 'ayecode_ui_calendar_params', $params );
1948
		}
1949
1950
		/**
1951
		 * Flatpickr calendar localize.
1952
		 *
1953
		 * @since 0.1.44
1954
		 *
1955
		 * @return string Calendar locale.
1956
		 */
1957
		public static function flatpickr_locale() {
1958
			$params = self::calendar_params();
1959
1960
			if ( is_string( $params ) ) {
0 ignored issues
show
introduced by
The condition is_string($params) is always false.
Loading history...
1961
				$params = html_entity_decode( $params, ENT_QUOTES, 'UTF-8' );
1962
			} else {
1963
				foreach ( (array) $params as $key => $value ) {
1964
					if ( ! is_scalar( $value ) ) {
1965
						continue;
1966
					}
1967
1968
					$params[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
1969
				}
1970
			}
1971
1972
			$day_s3 = array();
1973
			$day_s5 = array();
1974
1975
			for ( $i = 1; $i <= 7; $i ++ ) {
1976
				$day_s3[] = addslashes( $params[ 'day_s3_' . $i ] );
1977
				$day_s5[] = addslashes( $params[ 'day_s3_' . $i ] );
1978
			}
1979
1980
			$month_s = array();
1981
			$month_long = array();
1982
1983
			for ( $i = 1; $i <= 12; $i ++ ) {
1984
				$month_s[] = addslashes( $params[ 'month_s_' . $i ] );
1985
				$month_long[] = addslashes( $params[ 'month_long_' . $i ] );
1986
			}
1987
1988
ob_start();
1989
if ( 0 ) { ?><script><?php } ?>
1990
{
1991
	weekdays: {
1992
		shorthand: ['<?php echo implode( "','", $day_s3 ); ?>'],
1993
		longhand: ['<?php echo implode( "','", $day_s5 ); ?>'],
1994
	},
1995
	months: {
1996
		shorthand: ['<?php echo implode( "','", $month_s ); ?>'],
1997
		longhand: ['<?php echo implode( "','", $month_long ); ?>'],
1998
	},
1999
	daysInMonth: [31,28,31,30,31,30,31,31,30,31,30,31],
2000
	firstDayOfWeek: <?php echo (int) $params[ 'firstDayOfWeek' ]; ?>,
2001
	ordinal: function (nth) {
2002
		var s = nth % 100;
2003
		if (s > 3 && s < 21)
2004
			return "th";
2005
		switch (s % 10) {
2006
			case 1:
2007
				return "st";
2008
			case 2:
2009
				return "nd";
2010
			case 3:
2011
				return "rd";
2012
			default:
2013
				return "th";
2014
		}
2015
	},
2016
	rangeSeparator: '<?php echo addslashes( $params[ 'rangeSeparator' ] ); ?>',
2017
	weekAbbreviation: '<?php echo addslashes( $params[ 'weekAbbreviation' ] ); ?>',
2018
	scrollTitle: '<?php echo addslashes( $params[ 'scrollTitle' ] ); ?>',
2019
	toggleTitle: '<?php echo addslashes( $params[ 'toggleTitle' ] ); ?>',
2020
	amPM: ['<?php echo addslashes( $params[ 'am_upper' ] ); ?>','<?php echo addslashes( $params[ 'pm_upper' ] ); ?>'],
2021
	yearAriaLabel: '<?php echo addslashes( $params[ 'year' ] ); ?>',
2022
	hourAriaLabel: '<?php echo addslashes( $params[ 'hour' ] ); ?>',
2023
	minuteAriaLabel: '<?php echo addslashes( $params[ 'minute' ] ); ?>',
2024
	time_24hr: <?php echo ( $params[ 'time_24hr' ] ? 'true' : 'false' ) ; ?>
2025
}
2026
<?php if ( 0 ) { ?></script><?php } ?>
2027
<?php
2028
			$locale = ob_get_clean();
2029
2030
			return apply_filters( 'ayecode_ui_flatpickr_locale', trim( $locale ) );
2031
		}
2032
2033
		/**
2034
		 * Select2 JS params.
2035
		 *
2036
		 * @since 0.1.44
2037
		 *
2038
		 * @return array Select2 JS params.
2039
		 */
2040
		public static function select2_params() {
2041
			$params = array(
2042
				'i18n_select_state_text'    => esc_attr__( 'Select an option&hellip;', 'aui' ),
2043
				'i18n_no_matches'           => _x( 'No matches found', 'enhanced select', 'aui' ),
2044
				'i18n_ajax_error'           => _x( 'Loading failed', 'enhanced select', 'aui' ),
2045
				'i18n_input_too_short_1'    => _x( 'Please enter 1 or more characters', 'enhanced select', 'aui' ),
2046
				'i18n_input_too_short_n'    => _x( 'Please enter %item% or more characters', 'enhanced select', 'aui' ),
2047
				'i18n_input_too_long_1'     => _x( 'Please delete 1 character', 'enhanced select', 'aui' ),
2048
				'i18n_input_too_long_n'     => _x( 'Please delete %item% characters', 'enhanced select', 'aui' ),
2049
				'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'aui' ),
2050
				'i18n_selection_too_long_n' => _x( 'You can only select %item% items', 'enhanced select', 'aui' ),
2051
				'i18n_load_more'            => _x( 'Loading more results&hellip;', 'enhanced select', 'aui' ),
2052
				'i18n_searching'            => _x( 'Searching&hellip;', 'enhanced select', 'aui' )
2053
			);
2054
2055
			return apply_filters( 'ayecode_ui_select2_params', $params );
2056
		}
2057
2058
		/**
2059
		 * Select2 JS localize.
2060
		 *
2061
		 * @since 0.1.44
2062
		 *
2063
		 * @return string Select2 JS locale.
2064
		 */
2065
		public static function select2_locale() {
2066
			$params = self::select2_params();
2067
2068
			foreach ( (array) $params as $key => $value ) {
2069
				if ( ! is_scalar( $value ) ) {
2070
					continue;
2071
				}
2072
2073
				$params[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
2074
			}
2075
2076
			$locale = json_encode( $params );
2077
2078
			return apply_filters( 'ayecode_ui_select2_locale', trim( $locale ) );
2079
		}
2080
2081
		/**
2082
		 * Time ago JS localize.
2083
		 *
2084
		 * @since 0.1.47
2085
		 *
2086
		 * @return string Time ago JS locale.
2087
		 */
2088
		public static function timeago_locale() {
2089
			$params = array(
2090
				'prefix_ago' => '',
2091
				'suffix_ago' => ' ' . _x( 'ago', 'time ago', 'aui' ),
2092
				'prefix_after' => _x( 'after', 'time ago', 'aui' ) . ' ',
2093
				'suffix_after' => '',
2094
				'seconds' => _x( 'less than a minute', 'time ago', 'aui' ),
2095
				'minute' => _x( 'about a minute', 'time ago', 'aui' ),
2096
				'minutes' => _x( '%d minutes', 'time ago', 'aui' ),
2097
				'hour' => _x( 'about an hour', 'time ago', 'aui' ),
2098
				'hours' => _x( 'about %d hours', 'time ago', 'aui' ),
2099
				'day' => _x( 'a day', 'time ago', 'aui' ),
2100
				'days' => _x( '%d days', 'time ago', 'aui' ),
2101
				'month' => _x( 'about a month', 'time ago', 'aui' ),
2102
				'months' => _x( '%d months', 'time ago', 'aui' ),
2103
				'year' => _x( 'about a year', 'time ago', 'aui' ),
2104
				'years' => _x( '%d years', 'time ago', 'aui' ),
2105
			);
2106
2107
			$params = apply_filters( 'ayecode_ui_timeago_params', $params );
2108
2109
			foreach ( (array) $params as $key => $value ) {
2110
				if ( ! is_scalar( $value ) ) {
2111
					continue;
2112
				}
2113
2114
				$params[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
2115
			}
2116
2117
			$locale = json_encode( $params );
2118
2119
			return apply_filters( 'ayecode_ui_timeago_locale', trim( $locale ) );
2120
		}
2121
2122
		/**
2123
		 * JavaScript Minifier
2124
		 *
2125
		 * @param $input
2126
		 *
2127
		 * @return mixed
2128
		 */
2129
		public static function minify_js($input) {
2130
			if(trim($input) === "") return $input;
2131
			return preg_replace(
2132
				array(
2133
					// Remove comment(s)
2134
					'#\s*("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')\s*|\s*\/\*(?!\!|@cc_on)(?>[\s\S]*?\*\/)\s*|\s*(?<![\:\=])\/\/.*(?=[\n\r]|$)|^\s*|\s*$#',
2135
					// Remove white-space(s) outside the string and regex
2136
					'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/)|\/(?!\/)[^\n\r]*?\/(?=[\s.,;]|[gimuy]|$))|\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#s',
2137
					// Remove the last semicolon
2138
					'#;+\}#',
2139
					// Minify object attribute(s) except JSON attribute(s). From `{'foo':'bar'}` to `{foo:'bar'}`
2140
					'#([\{,])([\'])(\d+|[a-z_][a-z0-9_]*)\2(?=\:)#i',
2141
					// --ibid. From `foo['bar']` to `foo.bar`
2142
					'#([a-z0-9_\)\]])\[([\'"])([a-z_][a-z0-9_]*)\2\]#i'
2143
				),
2144
				array(
2145
					'$1',
2146
					'$1$2',
2147
					'}',
2148
					'$1$3',
2149
					'$1.$3'
2150
				),
2151
				$input);
2152
		}
2153
2154
		/**
2155
		 * Minify CSS
2156
		 *
2157
		 * @param $input
2158
		 *
2159
		 * @return mixed
2160
		 */
2161
		public static function minify_css($input) {
2162
			if(trim($input) === "") return $input;
2163
			return preg_replace(
2164
				array(
2165
					// Remove comment(s)
2166
					'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')|\/\*(?!\!)(?>.*?\*\/)|^\s*|\s*$#s',
2167
					// Remove unused white-space(s)
2168
					'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/))|\s*+;\s*+(})\s*+|\s*+([*$~^|]?+=|[{};,>~]|\s(?![0-9\.])|!important\b)\s*+|([[(:])\s++|\s++([])])|\s++(:)\s*+(?!(?>[^{}"\']++|"(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')*+{)|^\s++|\s++\z|(\s)\s+#si',
2169
					// Replace `0(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)` with `0`
2170
					'#(?<=[\s:])(0)(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)#si',
2171
					// Replace `:0 0 0 0` with `:0`
2172
					'#:(0\s+0|0\s+0\s+0\s+0)(?=[;\}]|\!important)#i',
2173
					// Replace `background-position:0` with `background-position:0 0`
2174
					'#(background-position):0(?=[;\}])#si',
2175
					// Replace `0.6` with `.6`, but only when preceded by `:`, `,`, `-` or a white-space
2176
					'#(?<=[\s:,\-])0+\.(\d+)#s',
2177
					// Minify string value
2178
					'#(\/\*(?>.*?\*\/))|(?<!content\:)([\'"])([a-z_][a-z0-9\-_]*?)\2(?=[\s\{\}\];,])#si',
2179
					'#(\/\*(?>.*?\*\/))|(\burl\()([\'"])([^\s]+?)\3(\))#si',
2180
					// Minify HEX color code
2181
					'#(?<=[\s:,\-]\#)([a-f0-6]+)\1([a-f0-6]+)\2([a-f0-6]+)\3#i',
2182
					// Replace `(border|outline):none` with `(border|outline):0`
2183
					'#(?<=[\{;])(border|outline):none(?=[;\}\!])#',
2184
					// Remove empty selector(s)
2185
					'#(\/\*(?>.*?\*\/))|(^|[\{\}])(?:[^\s\{\}]+)\{\}#s'
2186
				),
2187
				array(
2188
					'$1',
2189
					'$1$2$3$4$5$6$7',
2190
					'$1',
2191
					':0',
2192
					'$1:0 0',
2193
					'.$1',
2194
					'$1$3',
2195
					'$1$2$4$5',
2196
					'$1$2$3',
2197
					'$1:0',
2198
					'$1$2'
2199
				),
2200
				$input);
2201
		}
2202
2203
		/**
2204
		 * Get the conditional fields JavaScript.
2205
		 *
2206
		 * @return mixed
2207
		 */
2208
		public function conditional_fields_js() {
2209
			ob_start();
2210
			?>
2211
<script>
2212
/**
2213
 * Conditional Fields
2214
 */
2215
var aui_cf_field_rules = [], aui_cf_field_key_rules = {}, aui_cf_field_default_values = {};
2216
2217
jQuery(function($) {
2218
    aui_cf_field_init_rules($);
2219
});
2220
2221
/**
2222
 * Conditional fields init.
2223
 */
2224
function aui_cf_field_init_rules($) {
2225
    if (!$('[data-has-rule]').length) {
2226
        return;
2227
    }
2228
2229
    $('[data-rule-key]').on('change keypress keyup', 'input, textarea', function() {
2230
        aui_cf_field_apply_rules($(this));
2231
    });
2232
2233
    $('[data-rule-key]').on('change', 'select', function() {
2234
        aui_cf_field_apply_rules($(this));
2235
    });
2236
2237
    $('[data-rule-key]').on('change.select2', 'select', function() {
2238
        aui_cf_field_apply_rules($(this));
2239
    });
2240
2241
    aui_cf_field_setup_rules($);
2242
}
2243
2244
/**
2245
 * Setup conditional field rules.
2246
 */
2247
function aui_cf_field_setup_rules($) {
2248
    var aui_cf_field_keys = [];
2249
2250
    $('[data-rule-key]').each(function() {
2251
        var key = jQuery(this).data('rule-key'), irule = parseInt(jQuery(this).data('has-rule'));
2252
        if (key) {
2253
            aui_cf_field_keys.push(key);
2254
        }
2255
2256
        var parse_conds = {};
2257
        if ($(this).data('rule-fie-0')) {
2258
            for (var i = 0; i < irule; i++) {
2259
                var field = $(this).data('rule-fie-' + i);
2260
                if (typeof parse_conds[i] === 'undefined') {
2261
                    parse_conds[i] = {};
2262
                }
2263
                parse_conds[i]['action'] = $(this).data('rule-act-' + i);
2264
                parse_conds[i]['field'] = $(this).data('rule-fie-' + i);
2265
                parse_conds[i]['condition'] = $(this).data('rule-con-' + i);
2266
                parse_conds[i]['value'] = $(this).data('rule-val-' + i);
2267
            }
2268
2269
            jQuery.each(parse_conds, function(j, data) {
2270
                var item = {
2271
                    'field': {
2272
                        key: key,
2273
                        action: data.action,
2274
                        field: data.field,
2275
                        condition: data.condition,
2276
                        value: data.value,
2277
                        rule: {
2278
                            key: key,
2279
                            action: data.action,
2280
                            condition: data.condition,
2281
                            value: data.value
2282
                        }
2283
                    }
2284
                };
2285
                aui_cf_field_rules.push(item);
2286
            });
2287
        }
2288
        aui_cf_field_default_values[jQuery(this).data('rule-key')] = aui_cf_field_get_default_value(jQuery(this));
2289
    });
2290
2291
    jQuery.each(aui_cf_field_keys, function(i, fkey) {
2292
        aui_cf_field_key_rules[fkey] = aui_cf_field_get_children(fkey);
2293
    });
2294
2295
    jQuery('[data-rule-key]:visible').each(function() {
2296
        var conds = aui_cf_field_key_rules[jQuery(this).data('rule-key')];
2297
        if (conds && conds.length) {
2298
            var $main_el = jQuery(this), el = aui_cf_field_get_element($main_el);
2299
            if (jQuery(el).length) {
2300
                aui_cf_field_apply_rules(jQuery(el));
2301
            }
2302
        }
2303
    });
2304
}
2305
2306
/**
2307
 * Apply conditional field rules.
2308
 */
2309
function aui_cf_field_apply_rules($el) {
2310
    if (!$el.parents('[data-rule-key]').length) {
2311
        return;
2312
    }
2313
2314
    if ($el.data('no-rule')) {
2315
        return;
2316
    }
2317
2318
    var key = $el.parents('[data-rule-key]').data('rule-key');
2319
    var conditions = aui_cf_field_key_rules[key];
2320
    if (typeof conditions === 'undefined') {
2321
        return;
2322
    }
2323
    var field_type = aui_cf_field_get_type($el.parents('[data-rule-key]')), current_value = aui_cf_field_get_value($el);
2324
    var $keys = {}, $keys_values = {}, $key_rules = {};
2325
2326
    jQuery.each(conditions, function(index, condition) {
2327
        if (typeof $keys_values[condition.key] == 'undefined') {
2328
            $keys_values[condition.key] = [];
2329
            $key_rules[condition.key] = {}
2330
        }
2331
2332
        $keys_values[condition.key].push(condition.value);
2333
        $key_rules[condition.key] = condition;
2334
    });
2335
2336
    jQuery.each(conditions, function(index, condition) {
2337
        if (typeof $keys[condition.key] == 'undefined') {
2338
            $keys[condition.key] = {};
2339
        }
2340
2341
        if (condition.condition === 'empty') {
2342
            var field_value = Array.isArray(current_value) ? current_value.join('') : current_value;
2343
            if (!field_value || field_value === '') {
2344
                $keys[condition.key][index] = true;
2345
            } else {
2346
                $keys[condition.key][index] = false;
2347
            }
2348
        } else if (condition.condition === 'not empty') {
2349
            var field_value = Array.isArray(current_value) ? current_value.join('') : current_value;
2350
            if (field_value && field_value !== '') {
2351
                $keys[condition.key][index] = true;
2352
            } else {
2353
                $keys[condition.key][index] = false;
2354
            }
2355
        } else if (condition.condition === 'equals to') {
2356
            var field_value = (Array.isArray(current_value) && current_value.length === 1) ? current_value[0] : current_value;
2357
            if (((condition.value && condition.value == condition.value) || (condition.value === field_value)) && aui_cf_field_in_array(field_value, $keys_values[condition.key])) {
2358
                $keys[condition.key][index] = true;
2359
            } else {
2360
                $keys[condition.key][index] = false;
2361
            }
2362
        } else if (condition.condition === 'not equals') {
2363
            var field_value = (Array.isArray(current_value) && current_value.length === 1) ? current_value[0] : current_value;
2364
            if (jQuery.isNumeric(condition.value) && parseInt(field_value) !== parseInt(condition.value) && field_value && !aui_cf_field_in_array(field_value, $keys_values[condition.key])) {
2365
                $keys[condition.key][index] = true;
2366
            } else if (condition.value != field_value && !aui_cf_field_in_array(field_value, $keys_values[condition.key])) {
2367
                $keys[condition.key][index] = true;
2368
            } else {
2369
                $keys[condition.key][index] = false;
2370
            }
2371
        } else if (condition.condition === 'greater than') {
2372
            var field_value = (Array.isArray(current_value) && current_value.length === 1) ? current_value[0] : current_value;
2373
            if (jQuery.isNumeric(condition.value) && parseInt(field_value) > parseInt(condition.value)) {
2374
                $keys[condition.key][index] = true;
2375
            } else {
2376
                $keys[condition.key][index] = false;
2377
            }
2378
        } else if (condition.condition === 'less than') {
2379
            var field_value = (Array.isArray(current_value) && current_value.length === 1) ? current_value[0] : current_value;
2380
            if (jQuery.isNumeric(condition.value) && parseInt(field_value) < parseInt(condition.value)) {
2381
                $keys[condition.key][index] = true;
2382
            } else {
2383
                $keys[condition.key][index] = false;
2384
            }
2385
        } else if (condition.condition === 'contains') {
2386
            switch (field_type) {
2387
                case 'multiselect':
2388
                    if (current_value && ((!Array.isArray(current_value) && current_value.indexOf(condition.value) >= 0) || (Array.isArray(current_value) && aui_cf_field_in_array(condition.value, current_value)))) { //
2389
                        $keys[condition.key][index] = true;
2390
                    } else {
2391
                        $keys[condition.key][index] = false;
2392
                    }
2393
                    break;
2394
                case 'checkbox':
2395
                    if (current_value && ((!Array.isArray(current_value) && current_value.indexOf(condition.value) >= 0) || (Array.isArray(current_value) && aui_cf_field_in_array(condition.value, current_value)))) { //
2396
                        $keys[condition.key][index] = true;
2397
                    } else {
2398
                        $keys[condition.key][index] = false;
2399
                    }
2400
                    break;
2401
                default:
2402
                    if (typeof $keys[condition.key][index] === 'undefined') {
2403
                        if (current_value && current_value.indexOf(condition.value) >= 0 && aui_cf_field_in_array(current_value, $keys_values[condition.key])) {
2404
                            $keys[condition.key][index] = true;
2405
                        } else {
2406
                            $keys[condition.key][index] = false;
2407
                        }
2408
                    }
2409
                    break;
2410
            }
2411
        }
2412
    });
2413
2414
    jQuery.each($keys, function(index, field) {
2415
        if (aui_cf_field_in_array(true, field)) {
2416
            aui_cf_field_apply_action($el, $key_rules[index], true);
2417
        } else {
2418
            aui_cf_field_apply_action($el, $key_rules[index], false);
2419
        }
2420
    });
2421
2422
    /* Trigger field change */
2423
    if ($keys.length) {
2424
        $el.trigger('aui_cf_field_on_change');
2425
    }
2426
}
2427
2428
/**
2429
 * Get the field element.
2430
 */
2431
function aui_cf_field_get_element($el) {
2432
    var el = $el.find('input,textarea,select'),
2433
        type = aui_cf_field_get_type($el);
2434
    if (type && window._aui_cf_field_elements && typeof window._aui_cf_field_elements == 'object' && typeof window._aui_cf_field_elements[type] != 'undefined') {
2435
        el = window._aui_cf_field_elements[type];
2436
    }
2437
    return el;
2438
}
2439
2440
/**
2441
 * Get the field type.
2442
 */
2443
function aui_cf_field_get_type($el) {
2444
    return $el.data('rule-type');
2445
}
2446
2447
/**
2448
 * Get the field value.
2449
 */
2450
function aui_cf_field_get_value($el) {
2451
    var current_value = $el.val();
2452
2453
    if ($el.is(':checkbox')) {
2454
        current_value = '';
2455
        if ($el.parents('[data-rule-key]').find('input:checked').length > 1) {
2456
            $el.parents('[data-rule-key]').find('input:checked').each(function() {
2457
                current_value = current_value + jQuery(this).val() + ' ';
2458
            });
2459
        } else {
2460
            if ($el.parents('[data-rule-key]').find('input:checked').length >= 1) {
2461
                current_value = $el.parents('[data-rule-key]').find('input:checked').val();
2462
            }
2463
        }
2464
    }
2465
2466
    if ($el.is(':radio')) {
2467
        current_value = $el.parents('[data-rule-key]').find('input[type=radio]:checked').val();
2468
    }
2469
2470
    return current_value;
2471
}
2472
2473
/**
2474
 * Get the field default value.
2475
 */
2476
function aui_cf_field_get_default_value($el) {
2477
    var value = '', type = aui_cf_field_get_type($el);
2478
2479
    switch (type) {
2480
        case 'text':
2481
        case 'number':
2482
        case 'date':
2483
        case 'textarea':
2484
        case 'select':
2485
            value = $el.find('input:text,input[type="number"],textarea,select').val();
2486
            break;
2487
        case 'phone':
2488
        case 'email':
2489
        case 'color':
2490
        case 'url':
2491
        case 'hidden':
2492
        case 'password':
2493
        case 'file':
2494
            value = $el.find('input[type="' + type + '"]').val();
2495
            break;
2496
        case 'multiselect':
2497
            value = $el.find('select').val();
2498
            break;
2499
        case 'radio':
2500
            if ($el.find('input[type="radio"]:checked').length >= 1) {
2501
                value = $el.find('input[type="radio"]:checked').val();
2502
            }
2503
            break;
2504
        case 'checkbox':
2505
            if ($el.find('input[type="checkbox"]:checked').length >= 1) {
2506
                if ($el.find('input[type="checkbox"]:checked').length > 1) {
2507
                    var values = [];
2508
                    values.push(value);
2509
                    $el.find('input[type="checkbox"]:checked').each(function() {
2510
                        values.push(jQuery(this).val());
2511
                    });
2512
                    value = values;
2513
                } else {
2514
                    value = $el.find('input[type="checkbox"]:checked').val();
2515
                }
2516
            }
2517
            break;
2518
        default:
2519
            if (window._aui_cf_field_default_values && typeof window._aui_cf_field_default_values == 'object' && typeof window._aui_cf_field_default_values[type] != 'undefined') {
2520
                value = window._aui_cf_field_default_values[type];
2521
            }
2522
            break;
2523
    }
2524
    return {
2525
        type: type,
2526
        value: value
2527
    };
2528
}
2529
2530
/**
2531
 * Reset field default value.
2532
 */
2533
function aui_cf_field_reset_default_value($el) {
2534
    var type = aui_cf_field_get_type($el), key = $el.data('rule-key'), field = aui_cf_field_default_values[key];
2535
2536
    switch (type) {
2537
        case 'text':
2538
        case 'number':
2539
        case 'date':
2540
        case 'textarea':
2541
            $el.find('input:text,input[type="number"],textarea').val(field.value);
2542
            break;
2543
        case 'phone':
2544
        case 'email':
2545
        case 'color':
2546
        case 'url':
2547
        case 'hidden':
2548
        case 'password':
2549
        case 'file':
2550
            $el.find('input[type="' + type + '"]').val(field.value);
2551
            break;
2552
        case 'select':
2553
            $el.find('select').find('option').prop('selected', false);
2554
            $el.find('select').val(field.value);
2555
            $el.find('select').trigger('change');
2556
            break;
2557
        case 'multiselect':
2558
            $el.find('select').find('option').prop('selected', false);
2559
            if ((typeof field.value === 'object' || typeof field.value === 'array') && !field.value.length && $el.find('select option:first').text() == '') {
2560
                $el.find('select option:first').remove(); // Clear first option to show placeholder.
2561
            }
2562
            jQuery.each(field.value, function(i, v) {
2563
                $el.find('select').find('option[value="' + v + '"]').attr('selected', true);
2564
            });
2565
            $el.find('select').trigger('change');
2566
            break;
2567
        case 'checkbox':
2568
            if ($el.find('input[type="checkbox"]:checked').length >= 1) {
2569
                $el.find('input[type="checkbox"]:checked').prop('checked', false);
2570
                if (Array.isArray(field.value)) {
2571
                    jQuery.each(field.value, function(i, v) {
2572
                        $el.find('input[type="checkbox"][value="' + v + '"]').attr('checked', true);
2573
                    });
2574
                } else {
2575
                    $el.find('input[type="checkbox"][value="' + field.value + '"]').attr('checked', true);
2576
                }
2577
            }
2578
            break;
2579
        case 'radio':
2580
            if ($el.find('input[type="radio"]:checked').length >= 1) {
2581
                setTimeout(function() {
2582
                    $el.find('input[type="radio"]:checked').prop('checked', false);
2583
                    $el.find('input[type="radio"][value="' + field.value + '"]').attr('checked', true);
2584
                }, 100);
2585
            }
2586
            break;
2587
        default:
2588
            jQuery(document.body).trigger('aui_cf_field_reset_default_value', type, $el, field);
2589
            break;
2590
    }
2591
2592
    if (!$el.hasClass('aui-cf-field-has-changed')) {
2593
        var el = aui_cf_field_get_element($el);
2594
        if (type === 'radio' || type === 'checkbox') {
2595
            el = el.find(':checked');
2596
        }
2597
        if (el) {
2598
            el.trigger('change');
2599
            $el.addClass('aui-cf-field-has-changed');
2600
        }
2601
    }
2602
}
2603
2604
/**
2605
 * Get the field children.
2606
 */
2607
function aui_cf_field_get_children(field_key) {
2608
    var rules = [];
2609
    jQuery.each(aui_cf_field_rules, function(j, rule) {
2610
        if (rule.field.field === field_key) {
2611
            rules.push(rule.field.rule);
2612
        }
2613
    });
2614
    return rules;
2615
}
2616
2617
/**
2618
 * Check in array field value.
2619
 */
2620
function aui_cf_field_in_array(find, item, match) {
2621
    var found = false, key;
2622
    match = !!match;
2623
2624
    for (key in item) {
2625
        if ((match && item[key] === find) || (!match && item[key] == find)) {
2626
            found = true;
2627
            break;
2628
        }
2629
    }
2630
    return found;
2631
}
2632
2633
/**
2634
 * App the field condition action.
2635
 */
2636
function aui_cf_field_apply_action($el, rule, isTrue) {
2637
    var $destEl = jQuery('[data-rule-key="' + rule.key + '"]');
2638
2639
    if (rule.action === 'show' && isTrue) {
2640
        if ($destEl.is(':hidden')) {
2641
            aui_cf_field_reset_default_value($destEl);
2642
        }
2643
        aui_cf_field_show_element($destEl);
2644
    } else if (rule.action === 'show' && !isTrue) {
2645
        aui_cf_field_hide_element($destEl);
2646
    } else if (rule.action === 'hide' && isTrue) {
2647
        aui_cf_field_hide_element($destEl);
2648
    } else if (rule.action === 'hide' && !isTrue) {
2649
        if ($destEl.is(':hidden')) {
2650
            aui_cf_field_reset_default_value($destEl);
2651
        }
2652
        aui_cf_field_show_element($destEl);
2653
    }
2654
    return $el.removeClass('aui-cf-field-has-changed');
2655
}
2656
2657
/**
2658
 * Show field element.
2659
 */
2660
function aui_cf_field_show_element($el) {
2661
    $el.removeClass('d-none').show();
2662
2663
    if (window && window.navigator.userAgent.indexOf("MSIE") !== -1) {
2664
        $el.css({
2665
            "visibility": "visible"
2666
        });
2667
    }
2668
}
2669
2670
/**
2671
 * Hide field element.
2672
 */
2673
function aui_cf_field_hide_element($el) {
2674
    $el.addClass('d-none').hide();
2675
2676
    if (window && window.navigator.userAgent.indexOf("MSIE") !== -1) {
2677
        $el.css({
2678
            "visibility": "hidden"
2679
        });
2680
    }
2681
}
2682
<?php do_action( 'aui_conditional_fields_js', $this ); ?>
2683
</script>
2684
			<?php
2685
			$output = ob_get_clean();
2686
2687
			return str_replace( array( '<script>', '</script>' ), '', self::minify_js( $output ) );
2688
		}
2689
	}
2690
2691
	/**
2692
	 * Run the class if found.
2693
	 */
2694
	AyeCode_UI_Settings::instance();
2695
}