Passed
Push — master ( 18efaa...a86e69 )
by Brian
12:41
created

AyeCode_UI_Settings::get_url()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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

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

1546
			$darker_075 = self::css_hex_lighten_darken($color_code,/** @scrutinizer ignore-type */ "-0.075");
Loading history...
1547
			$darker_10 = self::css_hex_lighten_darken($color_code,"-0.10");
1548
			$darker_125 = self::css_hex_lighten_darken($color_code,"-0.125");
1549
1550
			// lighten
1551
			$lighten_25 = self::css_hex_lighten_darken($color_code,"0.25");
1552
1553
			// opacity see https://css-tricks.com/8-digit-hex-codes/
1554
			$op_25 = $color_code."40"; // 25% opacity
1555
1556
1557
			// button states
1558
			$output .= $prefix ." .btn-primary:hover{background-color: ".$darker_075.";    border-color: ".$darker_10.";} ";
1559
			$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;} ";
1560
			$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.";} ";
1561
			$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;} ";
1562
1563
1564
			// dropdown's
1565
			$output .= $prefix ." .dropdown-item.active, $prefix .dropdown-item:active{background-color: $color_code;} ";
1566
1567
1568
			// input states
1569
			$output .= $prefix ." .form-control:focus{border-color: ".$lighten_25.";box-shadow: 0 0 0 0.2rem $op_25;} ";
1570
1571
			// page link
1572
			$output .= $prefix ." .page-link:focus{box-shadow: 0 0 0 0.2rem $op_25;} ";
1573
1574
			return $output;
1575
		}
1576
1577
		public static function css_secondary($color_code,$compatibility){;
1578
			$color_code = sanitize_hex_color($color_code);
1579
			if(!$color_code){return '';}
1580
			/**
1581
			 * c = color, b = background color, o = border-color, f = fill
1582
			 */
1583
			$selectors = array(
1584
				'.btn-secondary' => array('b','o'),
1585
				'.btn-secondary.disabled' => array('b','o'),
1586
				'.btn-secondary:disabled' => array('b','o'),
1587
				'.btn-outline-secondary' => array('c','o'),
1588
				'.btn-outline-secondary:hover' => array('b','o'),
1589
				'.btn-outline-secondary.disabled' => array('c'),
1590
				'.btn-outline-secondary:disabled' => array('c'),
1591
				'.btn-outline-secondary:not(:disabled):not(.disabled):active' => array('b','o'),
1592
				'.btn-outline-secondary:not(:disabled):not(.disabled).active' => array('b','o'),
1593
				'.btn-outline-secondary.dropdown-toggle' => array('b','o'),
1594
				'.badge-secondary' => array('b'),
1595
				'.alert-secondary' => array('b','o'),
1596
				'.btn-link.btn-secondary' => array('c'),
1597
			);
1598
1599
			$important_selectors = array(
1600
				'.bg-secondary' => array('b','f'),
1601
				'.border-secondary' => array('o'),
1602
				'.text-secondary' => array('c'),
1603
			);
1604
1605
			$color = array();
1606
			$color_i = array();
1607
			$background = array();
1608
			$background_i = array();
1609
			$border = array();
1610
			$border_i = array();
1611
			$fill = array();
1612
			$fill_i = array();
1613
1614
			$output = '';
1615
1616
			// build rules into each type
1617
			foreach($selectors as $selector => $types){
1618
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1619
				$types = array_combine($types,$types);
1620
				if(isset($types['c'])){$color[] = $selector;}
1621
				if(isset($types['b'])){$background[] = $selector;}
1622
				if(isset($types['o'])){$border[] = $selector;}
1623
				if(isset($types['f'])){$fill[] = $selector;}
1624
			}
1625
1626
			// build rules into each type
1627
			foreach($important_selectors as $selector => $types){
1628
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1629
				$types = array_combine($types,$types);
1630
				if(isset($types['c'])){$color_i[] = $selector;}
1631
				if(isset($types['b'])){$background_i[] = $selector;}
1632
				if(isset($types['o'])){$border_i[] = $selector;}
1633
				if(isset($types['f'])){$fill_i[] = $selector;}
1634
			}
1635
1636
			// add any color rules
1637
			if(!empty($color)){
1638
				$output .= implode(",",$color) . "{color: $color_code;} ";
1639
			}
1640
			if(!empty($color_i)){
1641
				$output .= implode(",",$color_i) . "{color: $color_code !important;} ";
1642
			}
1643
1644
			// add any background color rules
1645
			if(!empty($background)){
1646
				$output .= implode(",",$background) . "{background-color: $color_code;} ";
1647
			}
1648
			if(!empty($background_i)){
1649
				$output .= implode(",",$background_i) . "{background-color: $color_code !important;} ";
1650
			}
1651
1652
			// add any border color rules
1653
			if(!empty($border)){
1654
				$output .= implode(",",$border) . "{border-color: $color_code;} ";
1655
			}
1656
			if(!empty($border_i)){
1657
				$output .= implode(",",$border_i) . "{border-color: $color_code !important;} ";
1658
			}
1659
1660
			// add any fill color rules
1661
			if(!empty($fill)){
1662
				$output .= implode(",",$fill) . "{fill: $color_code;} ";
1663
			}
1664
			if(!empty($fill_i)){
1665
				$output .= implode(",",$fill_i) . "{fill: $color_code !important;} ";
1666
			}
1667
1668
1669
			$prefix = $compatibility ? ".bsui " : "";
1670
1671
			// darken
1672
			$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

1672
			$darker_075 = self::css_hex_lighten_darken($color_code,/** @scrutinizer ignore-type */ "-0.075");
Loading history...
1673
			$darker_10 = self::css_hex_lighten_darken($color_code,"-0.10");
1674
			$darker_125 = self::css_hex_lighten_darken($color_code,"-0.125");
1675
1676
			// lighten
1677
			$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...
1678
1679
			// opacity see https://css-tricks.com/8-digit-hex-codes/
1680
			$op_25 = $color_code."40"; // 25% opacity
1681
1682
1683
			// button states
1684
			$output .= $prefix ." .btn-secondary:hover{background-color: ".$darker_075.";    border-color: ".$darker_10.";} ";
1685
			$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;} ";
1686
			$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.";} ";
1687
			$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;} ";
1688
1689
1690
			return $output;
1691
		}
1692
1693
		/**
1694
		 * Increases or decreases the brightness of a color by a percentage of the current brightness.
1695
		 *
1696
		 * @param   string  $hexCode        Supported formats: `#FFF`, `#FFFFFF`, `FFF`, `FFFFFF`
1697
		 * @param   float   $adjustPercent  A number between -1 and 1. E.g. 0.3 = 30% lighter; -0.4 = 40% darker.
1698
		 *
1699
		 * @return  string
1700
		 */
1701
		public static function css_hex_lighten_darken($hexCode, $adjustPercent) {
1702
			$hexCode = ltrim($hexCode, '#');
1703
1704
			if (strlen($hexCode) == 3) {
1705
				$hexCode = $hexCode[0] . $hexCode[0] . $hexCode[1] . $hexCode[1] . $hexCode[2] . $hexCode[2];
1706
			}
1707
1708
			$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

1708
			$hexCode = array_map('hexdec', /** @scrutinizer ignore-type */ str_split($hexCode, 2));
Loading history...
1709
1710
			foreach ($hexCode as & $color) {
1711
				$adjustableLimit = $adjustPercent < 0 ? $color : 255 - $color;
1712
				$adjustAmount = ceil($adjustableLimit * $adjustPercent);
1713
1714
				$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

1714
				$color = str_pad(dechex(/** @scrutinizer ignore-type */ $color + $adjustAmount), 2, '0', STR_PAD_LEFT);
Loading history...
1715
			}
1716
1717
			return '#' . implode($hexCode);
1718
		}
1719
1720
		/**
1721
		 * Check if we should display examples.
1722
		 */
1723
		public function maybe_show_examples(){
1724
			if(current_user_can('manage_options') && isset($_REQUEST['preview-aui'])){
1725
				echo "<head>";
1726
				wp_head();
1727
				echo "</head>";
1728
				echo "<body>";
1729
				echo $this->get_examples();
1730
				echo "</body>";
1731
				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...
1732
			}
1733
		}
1734
1735
		/**
1736
		 * Get developer examples.
1737
		 *
1738
		 * @return string
1739
		 */
1740
		public function get_examples(){
1741
			$output = '';
1742
1743
1744
			// open form
1745
			$output .= "<form class='p-5 m-5 border rounded'>";
1746
1747
			// input example
1748
			$output .= aui()->input(array(
1749
				'type'  =>  'text',
1750
				'id'    =>  'text-example',
1751
				'name'    =>  'text-example',
1752
				'placeholder'   => 'text placeholder',
1753
				'title'   => 'Text input example',
1754
				'value' =>  '',
1755
				'required'  => false,
1756
				'help_text' => 'help text',
1757
				'label' => 'Text input example label'
1758
			));
1759
1760
			// input example
1761
			$output .= aui()->input(array(
1762
				'type'  =>  'url',
1763
				'id'    =>  'text-example2',
1764
				'name'    =>  'text-example',
1765
				'placeholder'   => 'url placeholder',
1766
				'title'   => 'Text input example',
1767
				'value' =>  '',
1768
				'required'  => false,
1769
				'help_text' => 'help text',
1770
				'label' => 'Text input example label'
1771
			));
1772
1773
			// checkbox example
1774
			$output .= aui()->input(array(
1775
				'type'  =>  'checkbox',
1776
				'id'    =>  'checkbox-example',
1777
				'name'    =>  'checkbox-example',
1778
				'placeholder'   => 'checkbox-example',
1779
				'title'   => 'Checkbox example',
1780
				'value' =>  '1',
1781
				'checked'   => true,
1782
				'required'  => false,
1783
				'help_text' => 'help text',
1784
				'label' => 'Checkbox checked'
1785
			));
1786
1787
			// checkbox example
1788
			$output .= aui()->input(array(
1789
				'type'  =>  'checkbox',
1790
				'id'    =>  'checkbox-example2',
1791
				'name'    =>  'checkbox-example2',
1792
				'placeholder'   => 'checkbox-example',
1793
				'title'   => 'Checkbox example',
1794
				'value' =>  '1',
1795
				'checked'   => false,
1796
				'required'  => false,
1797
				'help_text' => 'help text',
1798
				'label' => 'Checkbox un-checked'
1799
			));
1800
1801
			// switch example
1802
			$output .= aui()->input(array(
1803
				'type'  =>  'checkbox',
1804
				'id'    =>  'switch-example',
1805
				'name'    =>  'switch-example',
1806
				'placeholder'   => 'checkbox-example',
1807
				'title'   => 'Switch example',
1808
				'value' =>  '1',
1809
				'checked'   => true,
1810
				'switch'    => true,
1811
				'required'  => false,
1812
				'help_text' => 'help text',
1813
				'label' => 'Switch on'
1814
			));
1815
1816
			// switch example
1817
			$output .= aui()->input(array(
1818
				'type'  =>  'checkbox',
1819
				'id'    =>  'switch-example2',
1820
				'name'    =>  'switch-example2',
1821
				'placeholder'   => 'checkbox-example',
1822
				'title'   => 'Switch example',
1823
				'value' =>  '1',
1824
				'checked'   => false,
1825
				'switch'    => true,
1826
				'required'  => false,
1827
				'help_text' => 'help text',
1828
				'label' => 'Switch off'
1829
			));
1830
1831
			// close form
1832
			$output .= "</form>";
1833
1834
			return $output;
1835
		}
1836
1837
		/**
1838
		 * Calendar params.
1839
		 *
1840
		 * @since 0.1.44
1841
		 *
1842
		 * @return array Calendar params.
1843
		 */
1844
		public static function calendar_params() {
1845
			$params = array(
1846
				'month_long_1' => __( 'January', 'aui' ),
1847
				'month_long_2' => __( 'February', 'aui' ),
1848
				'month_long_3' => __( 'March', 'aui' ),
1849
				'month_long_4' => __( 'April', 'aui' ),
1850
				'month_long_5' => __( 'May', 'aui' ),
1851
				'month_long_6' => __( 'June', 'aui' ),
1852
				'month_long_7' => __( 'July', 'aui' ),
1853
				'month_long_8' => __( 'August', 'aui' ),
1854
				'month_long_9' => __( 'September', 'aui' ),
1855
				'month_long_10' => __( 'October', 'aui' ),
1856
				'month_long_11' => __( 'November', 'aui' ),
1857
				'month_long_12' => __( 'December', 'aui' ),
1858
				'month_s_1' => _x( 'Jan', 'January abbreviation', 'aui' ),
1859
				'month_s_2' => _x( 'Feb', 'February abbreviation', 'aui' ),
1860
				'month_s_3' => _x( 'Mar', 'March abbreviation', 'aui' ),
1861
				'month_s_4' => _x( 'Apr', 'April abbreviation', 'aui' ),
1862
				'month_s_5' => _x( 'May', 'May abbreviation', 'aui' ),
1863
				'month_s_6' => _x( 'Jun', 'June abbreviation', 'aui' ),
1864
				'month_s_7' => _x( 'Jul', 'July abbreviation', 'aui' ),
1865
				'month_s_8' => _x( 'Aug', 'August abbreviation', 'aui' ),
1866
				'month_s_9' => _x( 'Sep', 'September abbreviation', 'aui' ),
1867
				'month_s_10' => _x( 'Oct', 'October abbreviation', 'aui' ),
1868
				'month_s_11' => _x( 'Nov', 'November abbreviation', 'aui' ),
1869
				'month_s_12' => _x( 'Dec', 'December abbreviation', 'aui' ),
1870
				'day_s1_1' => _x( 'S', 'Sunday initial', 'aui' ),
1871
				'day_s1_2' => _x( 'M', 'Monday initial', 'aui' ),
1872
				'day_s1_3' => _x( 'T', 'Tuesday initial', 'aui' ),
1873
				'day_s1_4' => _x( 'W', 'Wednesday initial', 'aui' ),
1874
				'day_s1_5' => _x( 'T', 'Friday initial', 'aui' ),
1875
				'day_s1_6' => _x( 'F', 'Thursday initial', 'aui' ),
1876
				'day_s1_7' => _x( 'S', 'Saturday initial', 'aui' ),
1877
				'day_s2_1' => __( 'Su', 'aui' ),
1878
				'day_s2_2' => __( 'Mo', 'aui' ),
1879
				'day_s2_3' => __( 'Tu', 'aui' ),
1880
				'day_s2_4' => __( 'We', 'aui' ),
1881
				'day_s2_5' => __( 'Th', 'aui' ),
1882
				'day_s2_6' => __( 'Fr', 'aui' ),
1883
				'day_s2_7' => __( 'Sa', 'aui' ),
1884
				'day_s3_1' => __( 'Sun', 'aui' ),
1885
				'day_s3_2' => __( 'Mon', 'aui' ),
1886
				'day_s3_3' => __( 'Tue', 'aui' ),
1887
				'day_s3_4' => __( 'Wed', 'aui' ),
1888
				'day_s3_5' => __( 'Thu', 'aui' ),
1889
				'day_s3_6' => __( 'Fri', 'aui' ),
1890
				'day_s3_7' => __( 'Sat', 'aui' ),
1891
				'day_s5_1' => __( 'Sunday', 'aui' ),
1892
				'day_s5_2' => __( 'Monday', 'aui' ),
1893
				'day_s5_3' => __( 'Tuesday', 'aui' ),
1894
				'day_s5_4' => __( 'Wednesday', 'aui' ),
1895
				'day_s5_5' => __( 'Thursday', 'aui' ),
1896
				'day_s5_6' => __( 'Friday', 'aui' ),
1897
				'day_s5_7' => __( 'Saturday', 'aui' ),
1898
				'am_lower' => __( 'am', 'aui' ),
1899
				'pm_lower' => __( 'pm', 'aui' ),
1900
				'am_upper' => __( 'AM', 'aui' ),
1901
				'pm_upper' => __( 'PM', 'aui' ),
1902
				'firstDayOfWeek' => (int) get_option( 'start_of_week' ),
1903
				'time_24hr' => false,
1904
				'year' => __( 'Year', 'aui' ),
1905
				'hour' => __( 'Hour', 'aui' ),
1906
				'minute' => __( 'Minute', 'aui' ),
1907
				'weekAbbreviation' => __( 'Wk', 'aui' ),
1908
				'rangeSeparator' => __( ' to ', 'aui' ),
1909
				'scrollTitle' => __( 'Scroll to increment', 'aui' ),
1910
				'toggleTitle' => __( 'Click to toggle', 'aui' )
1911
			);
1912
1913
			return apply_filters( 'ayecode_ui_calendar_params', $params );
1914
		}
1915
1916
		/**
1917
		 * Flatpickr calendar localize.
1918
		 *
1919
		 * @since 0.1.44
1920
		 *
1921
		 * @return string Calendar locale.
1922
		 */
1923
		public static function flatpickr_locale() {
1924
			$params = self::calendar_params();
1925
1926
			if ( is_string( $params ) ) {
0 ignored issues
show
introduced by
The condition is_string($params) is always false.
Loading history...
1927
				$params = html_entity_decode( $params, ENT_QUOTES, 'UTF-8' );
1928
			} else {
1929
				foreach ( (array) $params as $key => $value ) {
1930
					if ( ! is_scalar( $value ) ) {
1931
						continue;
1932
					}
1933
1934
					$params[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
1935
				}
1936
			}
1937
1938
			$day_s3 = array();
1939
			$day_s5 = array();
1940
1941
			for ( $i = 1; $i <= 7; $i ++ ) {
1942
				$day_s3[] = addslashes( $params[ 'day_s3_' . $i ] );
1943
				$day_s5[] = addslashes( $params[ 'day_s3_' . $i ] );
1944
			}
1945
1946
			$month_s = array();
1947
			$month_long = array();
1948
1949
			for ( $i = 1; $i <= 12; $i ++ ) {
1950
				$month_s[] = addslashes( $params[ 'month_s_' . $i ] );
1951
				$month_long[] = addslashes( $params[ 'month_long_' . $i ] );
1952
			}
1953
1954
ob_start();
1955
if ( 0 ) { ?><script><?php } ?>
1956
{
1957
	weekdays: {
1958
		shorthand: ['<?php echo implode( "','", $day_s3 ); ?>'],
1959
		longhand: ['<?php echo implode( "','", $day_s5 ); ?>'],
1960
	},
1961
	months: {
1962
		shorthand: ['<?php echo implode( "','", $month_s ); ?>'],
1963
		longhand: ['<?php echo implode( "','", $month_long ); ?>'],
1964
	},
1965
	daysInMonth: [31,28,31,30,31,30,31,31,30,31,30,31],
1966
	firstDayOfWeek: <?php echo (int) $params[ 'firstDayOfWeek' ]; ?>,
1967
	ordinal: function (nth) {
1968
		var s = nth % 100;
1969
		if (s > 3 && s < 21)
1970
			return "th";
1971
		switch (s % 10) {
1972
			case 1:
1973
				return "st";
1974
			case 2:
1975
				return "nd";
1976
			case 3:
1977
				return "rd";
1978
			default:
1979
				return "th";
1980
		}
1981
	},
1982
	rangeSeparator: '<?php echo addslashes( $params[ 'rangeSeparator' ] ); ?>',
1983
	weekAbbreviation: '<?php echo addslashes( $params[ 'weekAbbreviation' ] ); ?>',
1984
	scrollTitle: '<?php echo addslashes( $params[ 'scrollTitle' ] ); ?>',
1985
	toggleTitle: '<?php echo addslashes( $params[ 'toggleTitle' ] ); ?>',
1986
	amPM: ['<?php echo addslashes( $params[ 'am_upper' ] ); ?>','<?php echo addslashes( $params[ 'pm_upper' ] ); ?>'],
1987
	yearAriaLabel: '<?php echo addslashes( $params[ 'year' ] ); ?>',
1988
	hourAriaLabel: '<?php echo addslashes( $params[ 'hour' ] ); ?>',
1989
	minuteAriaLabel: '<?php echo addslashes( $params[ 'minute' ] ); ?>',
1990
	time_24hr: <?php echo ( $params[ 'time_24hr' ] ? 'true' : 'false' ) ; ?>
1991
}
1992
<?php if ( 0 ) { ?></script><?php } ?>
1993
<?php
1994
			$locale = ob_get_clean();
1995
1996
			return apply_filters( 'ayecode_ui_flatpickr_locale', trim( $locale ) );
1997
		}
1998
1999
		/**
2000
		 * Select2 JS params.
2001
		 *
2002
		 * @since 0.1.44
2003
		 *
2004
		 * @return array Select2 JS params.
2005
		 */
2006
		public static function select2_params() {
2007
			$params = array(
2008
				'i18n_select_state_text'    => esc_attr__( 'Select an option&hellip;', 'aui' ),
2009
				'i18n_no_matches'           => _x( 'No matches found', 'enhanced select', 'aui' ),
2010
				'i18n_ajax_error'           => _x( 'Loading failed', 'enhanced select', 'aui' ),
2011
				'i18n_input_too_short_1'    => _x( 'Please enter 1 or more characters', 'enhanced select', 'aui' ),
2012
				'i18n_input_too_short_n'    => _x( 'Please enter %item% or more characters', 'enhanced select', 'aui' ),
2013
				'i18n_input_too_long_1'     => _x( 'Please delete 1 character', 'enhanced select', 'aui' ),
2014
				'i18n_input_too_long_n'     => _x( 'Please delete %item% characters', 'enhanced select', 'aui' ),
2015
				'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'aui' ),
2016
				'i18n_selection_too_long_n' => _x( 'You can only select %item% items', 'enhanced select', 'aui' ),
2017
				'i18n_load_more'            => _x( 'Loading more results&hellip;', 'enhanced select', 'aui' ),
2018
				'i18n_searching'            => _x( 'Searching&hellip;', 'enhanced select', 'aui' )
2019
			);
2020
2021
			return apply_filters( 'ayecode_ui_select2_params', $params );
2022
		}
2023
2024
		/**
2025
		 * Select2 JS localize.
2026
		 *
2027
		 * @since 0.1.44
2028
		 *
2029
		 * @return string Select2 JS locale.
2030
		 */
2031
		public static function select2_locale() {
2032
			$params = self::select2_params();
2033
2034
			foreach ( (array) $params as $key => $value ) {
2035
				if ( ! is_scalar( $value ) ) {
2036
					continue;
2037
				}
2038
2039
				$params[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
2040
			}
2041
2042
			$locale = json_encode( $params );
2043
2044
			return apply_filters( 'ayecode_ui_select2_locale', trim( $locale ) );
2045
		}
2046
2047
		/**
2048
		 * Time ago JS localize.
2049
		 *
2050
		 * @since 0.1.47
2051
		 *
2052
		 * @return string Time ago JS locale.
2053
		 */
2054
		public static function timeago_locale() {
2055
			$params = array(
2056
				'prefix_ago' => '',
2057
				'suffix_ago' => ' ' . _x( 'ago', 'time ago', 'aui' ),
2058
				'prefix_after' => _x( 'after', 'time ago', 'aui' ) . ' ',
2059
				'suffix_after' => '',
2060
				'seconds' => _x( 'less than a minute', 'time ago', 'aui' ),
2061
				'minute' => _x( 'about a minute', 'time ago', 'aui' ),
2062
				'minutes' => _x( '%d minutes', 'time ago', 'aui' ),
2063
				'hour' => _x( 'about an hour', 'time ago', 'aui' ),
2064
				'hours' => _x( 'about %d hours', 'time ago', 'aui' ),
2065
				'day' => _x( 'a day', 'time ago', 'aui' ),
2066
				'days' => _x( '%d days', 'time ago', 'aui' ),
2067
				'month' => _x( 'about a month', 'time ago', 'aui' ),
2068
				'months' => _x( '%d months', 'time ago', 'aui' ),
2069
				'year' => _x( 'about a year', 'time ago', 'aui' ),
2070
				'years' => _x( '%d years', 'time ago', 'aui' ),
2071
			);
2072
2073
			$params = apply_filters( 'ayecode_ui_timeago_params', $params );
2074
2075
			foreach ( (array) $params as $key => $value ) {
2076
				if ( ! is_scalar( $value ) ) {
2077
					continue;
2078
				}
2079
2080
				$params[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
2081
			}
2082
2083
			$locale = json_encode( $params );
2084
2085
			return apply_filters( 'ayecode_ui_timeago_locale', trim( $locale ) );
2086
		}
2087
2088
		/**
2089
		 * JavaScript Minifier
2090
		 *
2091
		 * @param $input
2092
		 *
2093
		 * @return mixed
2094
		 */
2095
		public static function minify_js($input) {
2096
			if(trim($input) === "") return $input;
2097
			return preg_replace(
2098
				array(
2099
					// Remove comment(s)
2100
					'#\s*("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')\s*|\s*\/\*(?!\!|@cc_on)(?>[\s\S]*?\*\/)\s*|\s*(?<![\:\=])\/\/.*(?=[\n\r]|$)|^\s*|\s*$#',
2101
					// Remove white-space(s) outside the string and regex
2102
					'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/)|\/(?!\/)[^\n\r]*?\/(?=[\s.,;]|[gimuy]|$))|\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#s',
2103
					// Remove the last semicolon
2104
					'#;+\}#',
2105
					// Minify object attribute(s) except JSON attribute(s). From `{'foo':'bar'}` to `{foo:'bar'}`
2106
					'#([\{,])([\'])(\d+|[a-z_][a-z0-9_]*)\2(?=\:)#i',
2107
					// --ibid. From `foo['bar']` to `foo.bar`
2108
					'#([a-z0-9_\)\]])\[([\'"])([a-z_][a-z0-9_]*)\2\]#i'
2109
				),
2110
				array(
2111
					'$1',
2112
					'$1$2',
2113
					'}',
2114
					'$1$3',
2115
					'$1.$3'
2116
				),
2117
				$input);
2118
		}
2119
2120
		/**
2121
		 * Minify CSS
2122
		 *
2123
		 * @param $input
2124
		 *
2125
		 * @return mixed
2126
		 */
2127
		public static function minify_css($input) {
2128
			if(trim($input) === "") return $input;
2129
			return preg_replace(
2130
				array(
2131
					// Remove comment(s)
2132
					'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')|\/\*(?!\!)(?>.*?\*\/)|^\s*|\s*$#s',
2133
					// Remove unused white-space(s)
2134
					'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/))|\s*+;\s*+(})\s*+|\s*+([*$~^|]?+=|[{};,>~]|\s(?![0-9\.])|!important\b)\s*+|([[(:])\s++|\s++([])])|\s++(:)\s*+(?!(?>[^{}"\']++|"(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')*+{)|^\s++|\s++\z|(\s)\s+#si',
2135
					// Replace `0(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)` with `0`
2136
					'#(?<=[\s:])(0)(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)#si',
2137
					// Replace `:0 0 0 0` with `:0`
2138
					'#:(0\s+0|0\s+0\s+0\s+0)(?=[;\}]|\!important)#i',
2139
					// Replace `background-position:0` with `background-position:0 0`
2140
					'#(background-position):0(?=[;\}])#si',
2141
					// Replace `0.6` with `.6`, but only when preceded by `:`, `,`, `-` or a white-space
2142
					'#(?<=[\s:,\-])0+\.(\d+)#s',
2143
					// Minify string value
2144
					'#(\/\*(?>.*?\*\/))|(?<!content\:)([\'"])([a-z_][a-z0-9\-_]*?)\2(?=[\s\{\}\];,])#si',
2145
					'#(\/\*(?>.*?\*\/))|(\burl\()([\'"])([^\s]+?)\3(\))#si',
2146
					// Minify HEX color code
2147
					'#(?<=[\s:,\-]\#)([a-f0-6]+)\1([a-f0-6]+)\2([a-f0-6]+)\3#i',
2148
					// Replace `(border|outline):none` with `(border|outline):0`
2149
					'#(?<=[\{;])(border|outline):none(?=[;\}\!])#',
2150
					// Remove empty selector(s)
2151
					'#(\/\*(?>.*?\*\/))|(^|[\{\}])(?:[^\s\{\}]+)\{\}#s'
2152
				),
2153
				array(
2154
					'$1',
2155
					'$1$2$3$4$5$6$7',
2156
					'$1',
2157
					':0',
2158
					'$1:0 0',
2159
					'.$1',
2160
					'$1$3',
2161
					'$1$2$4$5',
2162
					'$1$2$3',
2163
					'$1:0',
2164
					'$1$2'
2165
				),
2166
				$input);
2167
		}
2168
	}
2169
2170
	/**
2171
	 * Run the class if found.
2172
	 */
2173
	AyeCode_UI_Settings::instance();
2174
}