Passed
Push — master ( 30e673...96cf3c )
by Brian
06:42 queued 01:20
created

AyeCode_UI_Settings::customizer_settings()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 23
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 33
rs 9.552
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.45';
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
471
					var templates = {
472
						prefix: "",
473
						suffix: " ago",
474
						seconds: "less than a minute",
475
						minute: "about a minute",
476
						minutes: "%d minutes",
477
						hour: "about an hour",
478
						hours: "about %d hours",
479
						day: "a day",
480
						days: "%d days",
481
						month: "about a month",
482
						months: "%d months",
483
						year: "about a year",
484
						years: "%d years"
485
					};
486
					var template = function (t, n) {
487
						return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n)));
488
					};
489
490
					var timer = function (time) {
491
						if (!time)
492
							return;
493
						time = time.replace(/\.\d+/, ""); // remove milliseconds
494
						time = time.replace(/-/, "/").replace(/-/, "/");
495
						time = time.replace(/T/, " ").replace(/Z/, " UTC");
496
						time = time.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2"); // -04:00 -> -0400
497
						time = new Date(time * 1000 || time);
498
499
						var now = new Date();
500
						var seconds = ((now.getTime() - time) * .001) >> 0;
501
						var minutes = seconds / 60;
502
						var hours = minutes / 60;
503
						var days = hours / 24;
504
						var years = days / 365;
505
506
						return templates.prefix + (
507
								seconds < 45 && template('seconds', seconds) ||
508
								seconds < 90 && template('minute', 1) ||
509
								minutes < 45 && template('minutes', minutes) ||
510
								minutes < 90 && template('hour', 1) ||
511
								hours < 24 && template('hours', hours) ||
512
								hours < 42 && template('day', 1) ||
513
								days < 30 && template('days', days) ||
514
								days < 45 && template('month', 1) ||
515
								days < 365 && template('months', days / 30) ||
516
								years < 1.5 && template('year', 1) ||
517
								template('years', years)
518
							) + templates.suffix;
519
					};
520
521
					var elements = document.getElementsByClassName(selector);
522
					if (selector && elements && elements.length) {
523
						for (var i in elements) {
524
							var $el = elements[i];
525
							if (typeof $el === 'object') {
526
								$el.innerHTML = '<i class="far fa-clock"></i> ' + timer($el.getAttribute('title') || $el.getAttribute('datetime'));
527
							}
528
						}
529
					}
530
531
					// update time every minute
532
					setTimeout(function() {
533
						aui_time_ago(selector);
534
					}, 60000);
535
536
				}
537
538
				/**
539
				 * Initiate tooltips on the page.
540
				 */
541
				function aui_init_tooltips(){
542
					jQuery('[data-toggle="tooltip"]').tooltip();
543
					jQuery('[data-toggle="popover"]').popover();
544
					jQuery('[data-toggle="popover-html"]').popover({
545
						html: true
546
					});
547
548
					// fix popover container compatibility
549
					jQuery('[data-toggle="popover"],[data-toggle="popover-html"]').on('inserted.bs.popover', function () {
550
						jQuery('body > .popover').wrapAll("<div class='bsui' />");
551
					});
552
				}
553
554
				/**
555
				 * Initiate flatpickrs on the page.
556
				 */
557
				$aui_doing_init_flatpickr = false;
558
				function aui_init_flatpickr(){
559
					if ( typeof jQuery.fn.flatpickr === "function" && !$aui_doing_init_flatpickr) {
560
						$aui_doing_init_flatpickr = true;
561
						<?php if ( ! empty( $flatpickr_locale ) ) { ?>try{flatpickr.localize(<?php echo $flatpickr_locale; ?>);}catch(err){console.log(err.message);}<?php } ?>
562
						jQuery('input[data-aui-init="flatpickr"]:not(.flatpickr-input)').flatpickr();
563
					}
564
					$aui_doing_init_flatpickr = false;
565
				}
566
567
				function aui_modal($title,$body,$footer,$dismissible,$class,$dialog_class) {
568
					if(!$class){$class = '';}
569
					if(!$dialog_class){$dialog_class = '';}
570
					if(!$body){$body = '<div class="text-center"><div class="spinner-border" role="status"></div></div>';}
571
					// remove it first
572
					jQuery('.aui-modal').modal('hide').modal('dispose').remove();
573
					jQuery('.modal-backdrop').remove();
574
575
					var $modal = '';
576
577
					$modal += '<div class="modal aui-modal fade shadow bsui '+$class+'" tabindex="-1">'+
578
						'<div class="modal-dialog modal-dialog-centered '+$dialog_class+'">'+
579
							'<div class="modal-content">';
580
581
					if($title) {
582
						$modal += '<div class="modal-header">' +
583
						'<h5 class="modal-title">' + $title + '</h5>';
584
585
						if ($dismissible) {
586
							$modal += '<button type="button" class="close" data-dismiss="modal" aria-label="Close">' +
587
								'<span aria-hidden="true">&times;</span>' +
588
								'</button>';
589
						}
590
591
						$modal += '</div>';
592
					}
593
					$modal += '<div class="modal-body">'+
594
									$body+
595
								'</div>';
596
597
					if($footer){
598
						$modal += '<div class="modal-footer">'+
599
							$footer +
600
							'</div>';
601
					}
602
603
					$modal +='</div>'+
604
						'</div>'+
605
					'</div>';
606
607
					jQuery('body').append($modal);
608
609
					jQuery('.aui-modal').modal('hide').modal({
610
						//backdrop: 'static'
611
					});
612
				}
613
614
				/**
615
				 * Show / hide fields depending on conditions.
616
				 */
617
				function aui_conditional_fields(form){
618
					jQuery(form).find(".aui-conditional-field").each(function () {
619
620
						var $element_require = jQuery(this).data('element-require');
621
622
						if ($element_require) {
623
624
							$element_require = $element_require.replace("&#039;", "'"); // replace single quotes
625
							$element_require = $element_require.replace("&quot;", '"'); // replace double quotes
626
627
							if (aui_check_form_condition($element_require,form)) {
628
								jQuery(this).removeClass('d-none');
629
							} else {
630
								jQuery(this).addClass('d-none');
631
							}
632
						}
633
					});
634
				}
635
636
				/**
637
				 * Check form condition
638
				 */
639
				function aui_check_form_condition(condition,form) {
640
					if (form) {
641
						condition = condition.replace(/\(form\)/g, "('"+form+"')");
642
					}
643
					return new Function("return " + condition+";")();
644
				}
645
646
				/**
647
				 * A function to determine if a element is on screen.
648
				 */
649
				jQuery.fn.aui_isOnScreen = function(){
650
651
					var win = jQuery(window);
652
653
					var viewport = {
654
						top : win.scrollTop(),
655
						left : win.scrollLeft()
656
					};
657
					viewport.right = viewport.left + win.width();
658
					viewport.bottom = viewport.top + win.height();
659
660
					var bounds = this.offset();
661
					bounds.right = bounds.left + this.outerWidth();
662
					bounds.bottom = bounds.top + this.outerHeight();
663
664
					return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
665
666
				};
667
668
				/**
669
				 * Maybe show multiple carousel items if set to do so.
670
				 */ 
671
				function aui_carousel_maybe_show_multiple_items($carousel){
672
					var $items = {};
673
					var $item_count = 0;
674
675
					// maybe backup
676
					if(!jQuery($carousel).find('.carousel-inner-original').length){
677
						jQuery($carousel).append('<div class="carousel-inner-original d-none">'+jQuery($carousel).find('.carousel-inner').html()+'</div>');
678
					}
679
680
					// Get the original items html
681
					jQuery($carousel).find('.carousel-inner-original .carousel-item').each(function () {
682
						$items[$item_count] = jQuery(this).html();
683
						$item_count++;
684
					});
685
686
					// bail if no items
687
					if(!$item_count){return;}
688
689
					if(jQuery(window).width() <= 576){
690
						// maybe restore original
691
						if(jQuery($carousel).find('.carousel-inner').hasClass('aui-multiple-items') && jQuery($carousel).find('.carousel-inner-original').length){
692
							jQuery($carousel).find('.carousel-inner').removeClass('aui-multiple-items').html(jQuery($carousel).find('.carousel-inner-original').html());
693
							jQuery($carousel).find(".carousel-indicators li").removeClass("d-none");
694
						}
695
696
					}else{
697
						// new items
698
						var $md_count = jQuery($carousel).data('limit_show');
699
						var $new_items = '';
700
						var $new_items_count = 0;
701
						var $new_item_count = 0;
702
						var $closed = true;
703
						Object.keys($items).forEach(function(key,index) {
704
705
							// close
706
							if(index != 0 && Number.isInteger(index/$md_count) ){
707
								$new_items += '</div></div>';
708
								$closed = true;
709
							}
710
711
							// open
712
							if(index == 0 || Number.isInteger(index/$md_count) ){
713
								$active = index == 0 ? 'active' : '';
714
								$new_items += '<div class="carousel-item '+$active+'"><div class="row m-0">';
715
								$closed = false;
716
								$new_items_count++;
717
								$new_item_count = 0;
718
							}
719
720
							// content
721
							$new_items += '<div class="col pr-1 pl-0">'+$items[index]+'</div>';
722
							$new_item_count++;
723
724
725
						});
726
727
						// close if not closed in the loop
728
						if(!$closed){
729
							// check for spares
730
							if($md_count-$new_item_count > 0){
731
								$placeholder_count = $md_count-$new_item_count;
732
								while($placeholder_count > 0){
733
									$new_items += '<div class="col pr-1 pl-0"></div>';
734
									$placeholder_count--;
735
								}
736
737
							}
738
739
							$new_items += '</div></div>';
740
						}
741
742
						// insert the new items
743
						jQuery($carousel).find('.carousel-inner').addClass('aui-multiple-items').html($new_items);
744
745
						// fix any lazyload images in the active slider
746
						jQuery($carousel).find('.carousel-item.active img').each(function () {
747
							// fix the srcset
748
							if(real_srcset = jQuery(this).attr("data-srcset")){
749
								if(!jQuery(this).attr("srcset")) jQuery(this).attr("srcset",real_srcset);
750
							}
751
							// fix the src
752
							if(real_src = jQuery(this).attr("data-src")){
753
								if(!jQuery(this).attr("srcset"))  jQuery(this).attr("src",real_src);
754
							}
755
						});
756
757
						// maybe fix carousel indicators
758
						$hide_count = $new_items_count-1;
759
						jQuery($carousel).find(".carousel-indicators li:gt("+$hide_count+")").addClass("d-none");
760
					}
761
762
					// trigger a global action to say we have
763
					jQuery( window ).trigger( "aui_carousel_multiple" );
764
				}
765
766
				/**
767
				 * Init Multiple item carousels.
768
				 */ 
769
				function aui_init_carousel_multiple_items(){
770
					jQuery(window).on("resize",function(){
771
						jQuery('.carousel-multiple-items').each(function () {
772
							aui_carousel_maybe_show_multiple_items(this);
773
						});
774
					});
775
776
					// run now
777
					jQuery('.carousel-multiple-items').each(function () {
778
						aui_carousel_maybe_show_multiple_items(this);
779
					});
780
				}
781
782
				/**
783
				 * Allow navs to use multiple sub menus.
784
				 */
785
				function init_nav_sub_menus(){
786
787
					jQuery('.navbar-multi-sub-menus').each(function(i, obj) {
788
						// Check if already initialized, if so continue.
789
						if(jQuery(this).hasClass("has-sub-sub-menus")){return true;}
790
791
						// Make sure its always expanded
792
						jQuery(this).addClass('has-sub-sub-menus');
793
794
						jQuery(this).find( '.dropdown-menu a.dropdown-toggle' ).on( 'click', function ( e ) {
795
							var $el = jQuery( this );
796
							$el.toggleClass('active-dropdown');
797
							var $parent = jQuery( this ).offsetParent( ".dropdown-menu" );
798
							if ( !jQuery( this ).next().hasClass( 'show' ) ) {
799
								jQuery( this ).parents( '.dropdown-menu' ).first().find( '.show' ).removeClass( "show" );
800
							}
801
							var $subMenu = jQuery( this ).next( ".dropdown-menu" );
802
							$subMenu.toggleClass( 'show' );
803
804
							jQuery( this ).parent( "li" ).toggleClass( 'show' );
805
806
							jQuery( this ).parents( 'li.nav-item.dropdown.show' ).on( 'hidden.bs.dropdown', function ( e ) {
807
								jQuery( '.dropdown-menu .show' ).removeClass( "show" );
808
								$el.removeClass('active-dropdown');
809
							} );
810
811
							if ( !$parent.parent().hasClass( 'navbar-nav' ) ) {
812
								$el.next().addClass('position-relative border-top border-bottom');
813
							}
814
815
							return false;
816
						} );
817
818
					});
819
820
				}
821
				
822
823
				/**
824
				 * Initiate all AUI JS.
825
				 */
826
				function aui_init(){
827
					// nav menu submenus
828
					init_nav_sub_menus();
829
					
830
					// init tooltips
831
					aui_init_tooltips();
832
833
					// init select2
834
					aui_init_select2();
835
836
					// init flatpickr
837
					aui_init_flatpickr();
838
839
					// init Greedy nav
840
					aui_init_greedy_nav();
841
842
					// Set times to time ago
843
					aui_time_ago('timeago');
844
					
845
					// init multiple item carousels
846
					aui_init_carousel_multiple_items();
847
				}
848
849
				// run on window loaded
850
				jQuery(window).on("load",function() {
851
					aui_init();
852
				});
853
854
			</script>
855
			<?php
856
			$output = ob_get_clean();
857
858
			/*
859
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
860
			 */
861
			return str_replace( array(
862
				'<script>',
863
				'</script>'
864
			), '', $output );
865
		}
866
867
868
		/**
869
		 * JS to help with conflict issues with other plugins and themes using bootstrap v3.
870
		 *
871
		 * @TODO we may need this when other conflicts arrise.
872
		 * @return mixed
873
		 */
874
		public static function bs3_compat_js() {
875
			ob_start();
876
			?>
877
			<script>
878
				<?php if( defined( 'FUSION_BUILDER_VERSION' ) ){ ?>
879
				/* With Avada builder */
880
881
				<?php } ?>
882
			</script>
883
			<?php
884
			return str_replace( array(
885
				'<script>',
886
				'</script>'
887
			), '', ob_get_clean());
888
		}
889
890
		/**
891
		 * Get inline script used if bootstrap file browser enqueued.
892
		 *
893
		 * If this remains small then its best to use this than to add another JS file.
894
		 */
895
		public function inline_script_file_browser(){
896
			ob_start();
897
			?>
898
			<script>
899
				// run on doc ready
900
				jQuery(document).ready(function () {
901
					bsCustomFileInput.init();
902
				});
903
			</script>
904
			<?php
905
			$output = ob_get_clean();
906
907
			/*
908
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
909
			 */
910
			return str_replace( array(
911
				'<script>',
912
				'</script>'
913
			), '', $output );
914
		}
915
916
		/**
917
		 * Adds the Font Awesome JS.
918
		 */
919
		public function enqueue_scripts() {
920
921
			if( is_admin() && !$this->is_aui_screen()){
922
				// don't add wp-admin scripts if not requested to
923
			}else {
924
925
				$js_setting = current_action() == 'wp_enqueue_scripts' ? 'js' : 'js_backend';
926
927
				// select2
928
				wp_register_script( 'select2', $this->url . 'assets/js/select2.min.js', array( 'jquery' ), $this->select2_version );
929
930
				// flatpickr
931
				wp_register_script( 'flatpickr', $this->url . 'assets/js/flatpickr.min.js', array(), $this->latest );
932
933
				// Bootstrap file browser
934
				wp_register_script( 'aui-custom-file-input', $url = $this->url . 'assets/js/bs-custom-file-input.min.js', array( 'jquery' ), $this->select2_version );
935
				wp_add_inline_script( 'aui-custom-file-input', $this->inline_script_file_browser() );
936
937
				$load_inline = false;
938
939
				if ( $this->settings[ $js_setting ] == 'core-popper' ) {
940
					// Bootstrap bundle
941
					$url = $this->url . 'assets/js/bootstrap.bundle.min.js';
942
					wp_register_script( 'bootstrap-js-bundle', $url, array(
943
						'select2',
944
						'jquery'
945
					), $this->latest, $this->is_bs3_compat() );
946
					// if in admin then add to footer for compatibility.
947
					is_admin() ? wp_enqueue_script( 'bootstrap-js-bundle', '', null, null, true ) : wp_enqueue_script( 'bootstrap-js-bundle' );
948
					$script = $this->inline_script();
949
					wp_add_inline_script( 'bootstrap-js-bundle', $script );
950
				} elseif ( $this->settings[ $js_setting ] == 'popper' ) {
951
					$url = $this->url . 'assets/js/popper.min.js';
952
					wp_register_script( 'bootstrap-js-popper', $url, array( 'select2', 'jquery' ), $this->latest );
953
					wp_enqueue_script( 'bootstrap-js-popper' );
954
					$load_inline = true;
955
				} else {
956
					$load_inline = true;
957
				}
958
959
				// Load needed inline scripts by faking the loading of a script if the main script is not being loaded
960
				if ( $load_inline ) {
961
					wp_register_script( 'bootstrap-dummy', '', array( 'select2', 'jquery' ) );
962
					wp_enqueue_script( 'bootstrap-dummy' );
963
					$script = $this->inline_script();
964
					wp_add_inline_script( 'bootstrap-dummy', $script );
965
				}
966
			}
967
968
		}
969
970
		/**
971
		 * Enqueue flatpickr if called.
972
		 */
973
		public function enqueue_flatpickr(){
974
			wp_enqueue_style( 'flatpickr' );
975
			wp_enqueue_script( 'flatpickr' );
976
		}
977
978
		/**
979
		 * Get the url path to the current folder.
980
		 *
981
		 * @return string
982
		 */
983
		public function get_url() {
984
985
			$url = '';
986
			// check if we are inside a plugin
987
			$file_dir = str_replace( "/includes","", wp_normalize_path( dirname( __FILE__ ) ) );
988
989
			// add check in-case user has changed wp-content dir name.
990
			$wp_content_folder_name = basename(WP_CONTENT_DIR);
991
			$dir_parts = explode("/$wp_content_folder_name/",$file_dir);
992
			$url_parts = explode("/$wp_content_folder_name/",plugins_url());
993
994
			if(!empty($url_parts[0]) && !empty($dir_parts[1])){
995
				$url = trailingslashit( $url_parts[0]."/$wp_content_folder_name/".$dir_parts[1] );
996
			}
997
998
			return $url;
999
		}
1000
1001
		/**
1002
		 * Register the database settings with WordPress.
1003
		 */
1004
		public function register_settings() {
1005
			register_setting( 'ayecode-ui-settings', 'ayecode-ui-settings' );
1006
		}
1007
1008
		/**
1009
		 * Add the WordPress settings menu item.
1010
		 * @since 1.0.10 Calling function name direct will fail theme check so we don't.
1011
		 */
1012
		public function menu_item() {
1013
			$menu_function = 'add' . '_' . 'options' . '_' . 'page'; // won't pass theme check if function name present in theme
1014
			call_user_func( $menu_function, $this->name, $this->name, 'manage_options', 'ayecode-ui-settings', array(
1015
				$this,
1016
				'settings_page'
1017
			) );
1018
		}
1019
1020
		/**
1021
		 * Get a list of themes and their default JS settings.
1022
		 *
1023
		 * @return array
1024
		 */
1025
		public function theme_js_settings(){
1026
			return array(
1027
				'ayetheme' => 'popper',
1028
				'listimia' => 'required',
1029
				'listimia_backend' => 'core-popper',
1030
				//'avada'    => 'required', // removed as we now add compatibility
1031
			);
1032
		}
1033
1034
		/**
1035
		 * Get the current Font Awesome output settings.
1036
		 *
1037
		 * @return array The array of settings.
1038
		 */
1039
		public function get_settings() {
1040
1041
			$db_settings = get_option( 'ayecode-ui-settings' );
1042
			$js_default = 'core-popper';
1043
			$js_default_backend = $js_default;
1044
1045
			// maybe set defaults (if no settings set)
1046
			if(empty($db_settings)){
1047
				$active_theme = strtolower( get_template() ); // active parent theme.
1048
				$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

1048
				/** @scrutinizer ignore-call */ 
1049
    $theme_js_settings = self::theme_js_settings();
Loading history...
1049
				if(isset($theme_js_settings[$active_theme])){
1050
					$js_default = $theme_js_settings[$active_theme];
1051
					$js_default_backend = isset($theme_js_settings[$active_theme."_backend"]) ? $theme_js_settings[$active_theme."_backend"] : $js_default;
1052
				}
1053
			}
1054
1055
			$defaults = array(
1056
				'css'       => 'compatibility', // core, compatibility
1057
				'js'        => $js_default, // js to load, core-popper, popper
1058
				'html_font_size'        => '16', // js to load, core-popper, popper
1059
				'css_backend'       => 'compatibility', // core, compatibility
1060
				'js_backend'        => $js_default_backend, // js to load, core-popper, popper
1061
				'disable_admin'     =>  '', // URL snippets to disable loading on admin
1062
			);
1063
1064
			$settings = wp_parse_args( $db_settings, $defaults );
1065
1066
			/**
1067
			 * Filter the Bootstrap settings.
1068
			 *
1069
			 * @todo if we add this filer people might use it and then it defeates the purpose of this class :/
1070
			 */
1071
			return $this->settings = apply_filters( 'ayecode-ui-settings', $settings, $db_settings, $defaults );
1072
		}
1073
1074
1075
		/**
1076
		 * The settings page html output.
1077
		 */
1078
		public function settings_page() {
1079
			if ( ! current_user_can( 'manage_options' ) ) {
1080
				wp_die( __( 'You do not have sufficient permissions to access this page.', 'aui' ) );
1081
			}
1082
			?>
1083
			<div class="wrap">
1084
				<h1><?php echo $this->name; ?></h1>
1085
				<p><?php _e("Here you can adjust settings if you are having compatibility issues.",'aui');?></p>
1086
				<form method="post" action="options.php">
1087
					<?php
1088
					settings_fields( 'ayecode-ui-settings' );
1089
					do_settings_sections( 'ayecode-ui-settings' );
1090
					?>
1091
1092
					<h2><?php _e( 'Frontend', 'aui' ); ?></h2>
1093
					<table class="form-table wpbs-table-settings">
1094
						<tr valign="top">
1095
							<th scope="row"><label
1096
									for="wpbs-css"><?php _e( 'Load CSS', 'aui' ); ?></label></th>
1097
							<td>
1098
								<select name="ayecode-ui-settings[css]" id="wpbs-css">
1099
									<option	value="compatibility" <?php selected( $this->settings['css'], 'compatibility' ); ?>><?php _e( 'Compatibility Mode (default)', 'aui' ); ?></option>
1100
									<option value="core" <?php selected( $this->settings['css'], 'core' ); ?>><?php _e( 'Full Mode', 'aui' ); ?></option>
1101
									<option	value="" <?php selected( $this->settings['css'], '' ); ?>><?php _e( 'Disabled', 'aui' ); ?></option>
1102
								</select>
1103
							</td>
1104
						</tr>
1105
1106
						<tr valign="top">
1107
							<th scope="row"><label
1108
									for="wpbs-js"><?php _e( 'Load JS', 'aui' ); ?></label></th>
1109
							<td>
1110
								<select name="ayecode-ui-settings[js]" id="wpbs-js">
1111
									<option	value="core-popper" <?php selected( $this->settings['js'], 'core-popper' ); ?>><?php _e( 'Core + Popper (default)', 'aui' ); ?></option>
1112
									<option value="popper" <?php selected( $this->settings['js'], 'popper' ); ?>><?php _e( 'Popper', 'aui' ); ?></option>
1113
									<option value="required" <?php selected( $this->settings['js'], 'required' ); ?>><?php _e( 'Required functions only', 'aui' ); ?></option>
1114
									<option	value="" <?php selected( $this->settings['js'], '' ); ?>><?php _e( 'Disabled (not recommended)', 'aui' ); ?></option>
1115
								</select>
1116
							</td>
1117
						</tr>
1118
1119
						<tr valign="top">
1120
							<th scope="row"><label
1121
									for="wpbs-font_size"><?php _e( 'HTML Font Size (px)', 'aui' ); ?></label></th>
1122
							<td>
1123
								<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" />
1124
								<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>
1125
							</td>
1126
						</tr>
1127
1128
					</table>
1129
1130
					<h2><?php _e( 'Backend', 'aui' ); ?> (wp-admin)</h2>
1131
					<table class="form-table wpbs-table-settings">
1132
						<tr valign="top">
1133
							<th scope="row"><label
1134
									for="wpbs-css-admin"><?php _e( 'Load CSS', 'aui' ); ?></label></th>
1135
							<td>
1136
								<select name="ayecode-ui-settings[css_backend]" id="wpbs-css-admin">
1137
									<option	value="compatibility" <?php selected( $this->settings['css_backend'], 'compatibility' ); ?>><?php _e( 'Compatibility Mode (default)', 'aui' ); ?></option>
1138
									<option value="core" <?php selected( $this->settings['css_backend'], 'core' ); ?>><?php _e( 'Full Mode (will cause style issues)', 'aui' ); ?></option>
1139
									<option	value="" <?php selected( $this->settings['css_backend'], '' ); ?>><?php _e( 'Disabled', 'aui' ); ?></option>
1140
								</select>
1141
							</td>
1142
						</tr>
1143
1144
						<tr valign="top">
1145
							<th scope="row"><label
1146
									for="wpbs-js-admin"><?php _e( 'Load JS', 'aui' ); ?></label></th>
1147
							<td>
1148
								<select name="ayecode-ui-settings[js_backend]" id="wpbs-js-admin">
1149
									<option	value="core-popper" <?php selected( $this->settings['js_backend'], 'core-popper' ); ?>><?php _e( 'Core + Popper (default)', 'aui' ); ?></option>
1150
									<option value="popper" <?php selected( $this->settings['js_backend'], 'popper' ); ?>><?php _e( 'Popper', 'aui' ); ?></option>
1151
									<option value="required" <?php selected( $this->settings['js_backend'], 'required' ); ?>><?php _e( 'Required functions only', 'aui' ); ?></option>
1152
									<option	value="" <?php selected( $this->settings['js_backend'], '' ); ?>><?php _e( 'Disabled (not recommended)', 'aui' ); ?></option>
1153
								</select>
1154
							</td>
1155
						</tr>
1156
1157
						<tr valign="top">
1158
							<th scope="row"><label
1159
									for="wpbs-disable-admin"><?php _e( 'Disable load on URL', 'aui' ); ?></label></th>
1160
							<td>
1161
								<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>
1162
								<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>
1163
1164
							</td>
1165
						</tr>
1166
1167
					</table>
1168
1169
					<?php
1170
					submit_button();
1171
					?>
1172
				</form>
1173
1174
				<div id="wpbs-version"><?php echo $this->version; ?></div>
1175
			</div>
1176
1177
			<?php
1178
		}
1179
1180
		public function customizer_settings($wp_customize){
1181
			$wp_customize->add_section('aui_settings', array(
1182
				'title'    => __('AyeCode UI','aui'),
1183
				'priority' => 120,
1184
			));
1185
1186
			//  =============================
1187
			//  = Color Picker              =
1188
			//  =============================
1189
			$wp_customize->add_setting('aui_options[color_primary]', array(
1190
				'default'           => AUI_PRIMARY_COLOR,
1191
				'sanitize_callback' => 'sanitize_hex_color',
1192
				'capability'        => 'edit_theme_options',
1193
				'type'              => 'option',
1194
				'transport'         => 'refresh',
1195
			));
1196
			$wp_customize->add_control( new WP_Customize_Color_Control($wp_customize, 'color_primary', array(
1197
				'label'    => __('Primary Color','aui'),
1198
				'section'  => 'aui_settings',
1199
				'settings' => 'aui_options[color_primary]',
1200
			)));
1201
1202
			$wp_customize->add_setting('aui_options[color_secondary]', array(
1203
				'default'           => '#6c757d',
1204
				'sanitize_callback' => 'sanitize_hex_color',
1205
				'capability'        => 'edit_theme_options',
1206
				'type'              => 'option',
1207
				'transport'         => 'refresh',
1208
			));
1209
			$wp_customize->add_control( new WP_Customize_Color_Control($wp_customize, 'color_secondary', array(
1210
				'label'    => __('Secondary Color','aui'),
1211
				'section'  => 'aui_settings',
1212
				'settings' => 'aui_options[color_secondary]',
1213
			)));
1214
		}
1215
1216
		/**
1217
		 * CSS to help with conflict issues with other plugins and themes using bootstrap v3.
1218
		 *
1219
		 * @return mixed
1220
		 */
1221
		public static function bs3_compat_css() {
1222
			ob_start();
1223
			?>
1224
			<style>
1225
			/* Bootstrap 3 compatibility */
1226
			body.modal-open .modal-backdrop.show:not(.in) {opacity:0.5;}
1227
			body.modal-open .modal.show:not(.in)  {opacity:1;z-index: 99999}
1228
			body.modal-open .modal.show:not(.in) .modal-content  {box-shadow: none;}
1229
			body.modal-open .modal.show:not(.in)  .modal-dialog {transform: initial;}
1230
1231
			body.modal-open .modal.bsui .modal-dialog{left: auto;}
1232
1233
			.collapse.show:not(.in){display: inherit;}
1234
			.fade.show{opacity: 1;}
1235
1236
			<?php if( defined( 'SVQ_THEME_VERSION' ) ){ ?>
1237
			/* KLEO theme specific */
1238
			.kleo-main-header .navbar-collapse.collapse.show:not(.in){display: inherit !important;}
1239
			<?php } ?>
1240
1241
			<?php if( defined( 'FUSION_BUILDER_VERSION' ) ){ ?>
1242
			/* With Avada builder */
1243
			body.modal-open .modal.in  {opacity:1;z-index: 99999}
1244
			body.modal-open .modal.bsui.in .modal-content  {box-shadow: none;}
1245
			.bsui .collapse.in{display: inherit;}
1246
			<?php } ?>
1247
			</style>
1248
			<?php
1249
			return str_replace( array(
1250
				'<style>',
1251
				'</style>'
1252
			), '', ob_get_clean());
1253
		}
1254
1255
1256
		public static function custom_css($compatibility = true) {
1257
			$settings = get_option('aui_options');
1258
1259
			ob_start();
1260
1261
			$primary_color = !empty($settings['color_primary']) ? $settings['color_primary'] : AUI_PRIMARY_COLOR;
1262
			$secondary_color = !empty($settings['color_secondary']) ? $settings['color_secondary'] : AUI_SECONDARY_COLOR;
1263
				//AUI_PRIMARY_COLOR_ORIGINAL
1264
			?>
1265
			<style>
1266
				<?php
1267
1268
					// BS v3 compat
1269
					if( self::is_bs3_compat() ){
1270
					    echo self::bs3_compat_css();
1271
					}
1272
1273
					if(!is_admin() && $primary_color != AUI_PRIMARY_COLOR_ORIGINAL){
1274
						echo self::css_primary($primary_color,$compatibility);
1275
					}
1276
1277
					if(!is_admin() && $secondary_color != AUI_SECONDARY_COLOR_ORIGINAL){
1278
						echo self::css_secondary($settings['color_secondary'],$compatibility);
1279
					}
1280
1281
					// Set admin bar z-index lower when modal is open.
1282
					echo ' body.modal-open #wpadminbar{z-index:999}';
1283
                ?>
1284
			</style>
1285
			<?php
1286
1287
1288
			/*
1289
			 * We only add the <script> tags for code highlighting, so we strip them from the output.
1290
			 */
1291
			return str_replace( array(
1292
				'<style>',
1293
				'</style>'
1294
			), '', ob_get_clean());
1295
		}
1296
1297
		/**
1298
		 * Check if we should add booststrap 3 compatibility changes.
1299
		 *
1300
		 * @return bool
1301
		 */
1302
		public static function is_bs3_compat(){
1303
			return defined('AYECODE_UI_BS3_COMPAT') || defined('SVQ_THEME_VERSION') || defined('FUSION_BUILDER_VERSION');
1304
		}
1305
1306
		public static function css_primary($color_code,$compatibility){;
1307
			$color_code = sanitize_hex_color($color_code);
1308
			if(!$color_code){return '';}
1309
			/**
1310
			 * c = color, b = background color, o = border-color, f = fill
1311
			 */
1312
			$selectors = array(
1313
				'a' => array('c'),
1314
				'.btn-primary' => array('b','o'),
1315
				'.btn-primary.disabled' => array('b','o'),
1316
				'.btn-primary:disabled' => array('b','o'),
1317
				'.btn-outline-primary' => array('c','o'),
1318
				'.btn-outline-primary:hover' => array('b','o'),
1319
				'.btn-outline-primary:not(:disabled):not(.disabled).active' => array('b','o'),
1320
				'.btn-outline-primary:not(:disabled):not(.disabled):active' => array('b','o'),
1321
				'.show>.btn-outline-primary.dropdown-toggle' => array('b','o'),
1322
				'.btn-link' => array('c'),
1323
				'.dropdown-item.active' => array('b'),
1324
				'.custom-control-input:checked~.custom-control-label::before' => array('b','o'),
1325
				'.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before' => array('b','o'),
1326
//				'.custom-range::-webkit-slider-thumb' => array('b'), // these break the inline rules...
1327
//				'.custom-range::-moz-range-thumb' => array('b'),
1328
//				'.custom-range::-ms-thumb' => array('b'),
1329
				'.nav-pills .nav-link.active' => array('b'),
1330
				'.nav-pills .show>.nav-link' => array('b'),
1331
				'.page-link' => array('c'),
1332
				'.page-item.active .page-link' => array('b','o'),
1333
				'.badge-primary' => array('b'),
1334
				'.alert-primary' => array('b','o'),
1335
				'.progress-bar' => array('b'),
1336
				'.list-group-item.active' => array('b','o'),
1337
				'.bg-primary' => array('b','f'),
1338
				'.btn-link.btn-primary' => array('c'),
1339
				'.select2-container .select2-results__option--highlighted.select2-results__option[aria-selected=true]' => array('b'),
1340
			);
1341
1342
			$important_selectors = array(
1343
				'.bg-primary' => array('b','f'),
1344
				'.border-primary' => array('o'),
1345
				'.text-primary' => array('c'),
1346
			);
1347
1348
			$color = array();
1349
			$color_i = array();
1350
			$background = array();
1351
			$background_i = array();
1352
			$border = array();
1353
			$border_i = array();
1354
			$fill = array();
1355
			$fill_i = array();
1356
1357
			$output = '';
1358
1359
			// build rules into each type
1360
			foreach($selectors as $selector => $types){
1361
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1362
				$types = array_combine($types,$types);
1363
				if(isset($types['c'])){$color[] = $selector;}
1364
				if(isset($types['b'])){$background[] = $selector;}
1365
				if(isset($types['o'])){$border[] = $selector;}
1366
				if(isset($types['f'])){$fill[] = $selector;}
1367
			}
1368
1369
			// build rules into each type
1370
			foreach($important_selectors as $selector => $types){
1371
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1372
				$types = array_combine($types,$types);
1373
				if(isset($types['c'])){$color_i[] = $selector;}
1374
				if(isset($types['b'])){$background_i[] = $selector;}
1375
				if(isset($types['o'])){$border_i[] = $selector;}
1376
				if(isset($types['f'])){$fill_i[] = $selector;}
1377
			}
1378
1379
			// add any color rules
1380
			if(!empty($color)){
1381
				$output .= implode(",",$color) . "{color: $color_code;} ";
1382
			}
1383
			if(!empty($color_i)){
1384
				$output .= implode(",",$color_i) . "{color: $color_code !important;} ";
1385
			}
1386
1387
			// add any background color rules
1388
			if(!empty($background)){
1389
				$output .= implode(",",$background) . "{background-color: $color_code;} ";
1390
			}
1391
			if(!empty($background_i)){
1392
				$output .= implode(",",$background_i) . "{background-color: $color_code !important;} ";
1393
			}
1394
1395
			// add any border color rules
1396
			if(!empty($border)){
1397
				$output .= implode(",",$border) . "{border-color: $color_code;} ";
1398
			}
1399
			if(!empty($border_i)){
1400
				$output .= implode(",",$border_i) . "{border-color: $color_code !important;} ";
1401
			}
1402
1403
			// add any fill color rules
1404
			if(!empty($fill)){
1405
				$output .= implode(",",$fill) . "{fill: $color_code;} ";
1406
			}
1407
			if(!empty($fill_i)){
1408
				$output .= implode(",",$fill_i) . "{fill: $color_code !important;} ";
1409
			}
1410
1411
1412
			$prefix = $compatibility ? ".bsui " : "";
1413
1414
			// darken
1415
			$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

1415
			$darker_075 = self::css_hex_lighten_darken($color_code,/** @scrutinizer ignore-type */ "-0.075");
Loading history...
1416
			$darker_10 = self::css_hex_lighten_darken($color_code,"-0.10");
1417
			$darker_125 = self::css_hex_lighten_darken($color_code,"-0.125");
1418
1419
			// lighten
1420
			$lighten_25 = self::css_hex_lighten_darken($color_code,"0.25");
1421
1422
			// opacity see https://css-tricks.com/8-digit-hex-codes/
1423
			$op_25 = $color_code."40"; // 25% opacity
1424
1425
1426
			// button states
1427
			$output .= $prefix ." .btn-primary:hover{background-color: ".$darker_075.";    border-color: ".$darker_10.";} ";
1428
			$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;} ";
1429
			$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.";} ";
1430
			$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;} ";
1431
1432
1433
			// dropdown's
1434
			$output .= $prefix ." .dropdown-item.active, $prefix .dropdown-item:active{background-color: $color_code;} ";
1435
1436
1437
			// input states
1438
			$output .= $prefix ." .form-control:focus{border-color: ".$lighten_25.";box-shadow: 0 0 0 0.2rem $op_25;} ";
1439
1440
			// page link
1441
			$output .= $prefix ." .page-link:focus{box-shadow: 0 0 0 0.2rem $op_25;} ";
1442
1443
			return $output;
1444
		}
1445
1446
		public static function css_secondary($color_code,$compatibility){;
1447
			$color_code = sanitize_hex_color($color_code);
1448
			if(!$color_code){return '';}
1449
			/**
1450
			 * c = color, b = background color, o = border-color, f = fill
1451
			 */
1452
			$selectors = array(
1453
				'.btn-secondary' => array('b','o'),
1454
				'.btn-secondary.disabled' => array('b','o'),
1455
				'.btn-secondary:disabled' => array('b','o'),
1456
				'.btn-outline-secondary' => array('c','o'),
1457
				'.btn-outline-secondary:hover' => array('b','o'),
1458
				'.btn-outline-secondary.disabled' => array('c'),
1459
				'.btn-outline-secondary:disabled' => array('c'),
1460
				'.btn-outline-secondary:not(:disabled):not(.disabled):active' => array('b','o'),
1461
				'.btn-outline-secondary:not(:disabled):not(.disabled).active' => array('b','o'),
1462
				'.btn-outline-secondary.dropdown-toggle' => array('b','o'),
1463
				'.badge-secondary' => array('b'),
1464
				'.alert-secondary' => array('b','o'),
1465
				'.btn-link.btn-secondary' => array('c'),
1466
			);
1467
1468
			$important_selectors = array(
1469
				'.bg-secondary' => array('b','f'),
1470
				'.border-secondary' => array('o'),
1471
				'.text-secondary' => array('c'),
1472
			);
1473
1474
			$color = array();
1475
			$color_i = array();
1476
			$background = array();
1477
			$background_i = array();
1478
			$border = array();
1479
			$border_i = array();
1480
			$fill = array();
1481
			$fill_i = array();
1482
1483
			$output = '';
1484
1485
			// build rules into each type
1486
			foreach($selectors as $selector => $types){
1487
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1488
				$types = array_combine($types,$types);
1489
				if(isset($types['c'])){$color[] = $selector;}
1490
				if(isset($types['b'])){$background[] = $selector;}
1491
				if(isset($types['o'])){$border[] = $selector;}
1492
				if(isset($types['f'])){$fill[] = $selector;}
1493
			}
1494
1495
			// build rules into each type
1496
			foreach($important_selectors as $selector => $types){
1497
				$selector = $compatibility ? ".bsui ".$selector : $selector;
1498
				$types = array_combine($types,$types);
1499
				if(isset($types['c'])){$color_i[] = $selector;}
1500
				if(isset($types['b'])){$background_i[] = $selector;}
1501
				if(isset($types['o'])){$border_i[] = $selector;}
1502
				if(isset($types['f'])){$fill_i[] = $selector;}
1503
			}
1504
1505
			// add any color rules
1506
			if(!empty($color)){
1507
				$output .= implode(",",$color) . "{color: $color_code;} ";
1508
			}
1509
			if(!empty($color_i)){
1510
				$output .= implode(",",$color_i) . "{color: $color_code !important;} ";
1511
			}
1512
1513
			// add any background color rules
1514
			if(!empty($background)){
1515
				$output .= implode(",",$background) . "{background-color: $color_code;} ";
1516
			}
1517
			if(!empty($background_i)){
1518
				$output .= implode(",",$background_i) . "{background-color: $color_code !important;} ";
1519
			}
1520
1521
			// add any border color rules
1522
			if(!empty($border)){
1523
				$output .= implode(",",$border) . "{border-color: $color_code;} ";
1524
			}
1525
			if(!empty($border_i)){
1526
				$output .= implode(",",$border_i) . "{border-color: $color_code !important;} ";
1527
			}
1528
1529
			// add any fill color rules
1530
			if(!empty($fill)){
1531
				$output .= implode(",",$fill) . "{fill: $color_code;} ";
1532
			}
1533
			if(!empty($fill_i)){
1534
				$output .= implode(",",$fill_i) . "{fill: $color_code !important;} ";
1535
			}
1536
1537
1538
			$prefix = $compatibility ? ".bsui " : "";
1539
1540
			// darken
1541
			$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

1541
			$darker_075 = self::css_hex_lighten_darken($color_code,/** @scrutinizer ignore-type */ "-0.075");
Loading history...
1542
			$darker_10 = self::css_hex_lighten_darken($color_code,"-0.10");
1543
			$darker_125 = self::css_hex_lighten_darken($color_code,"-0.125");
1544
1545
			// lighten
1546
			$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...
1547
1548
			// opacity see https://css-tricks.com/8-digit-hex-codes/
1549
			$op_25 = $color_code."40"; // 25% opacity
1550
1551
1552
			// button states
1553
			$output .= $prefix ." .btn-secondary:hover{background-color: ".$darker_075.";    border-color: ".$darker_10.";} ";
1554
			$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;} ";
1555
			$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.";} ";
1556
			$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;} ";
1557
1558
1559
			return $output;
1560
		}
1561
1562
		/**
1563
		 * Increases or decreases the brightness of a color by a percentage of the current brightness.
1564
		 *
1565
		 * @param   string  $hexCode        Supported formats: `#FFF`, `#FFFFFF`, `FFF`, `FFFFFF`
1566
		 * @param   float   $adjustPercent  A number between -1 and 1. E.g. 0.3 = 30% lighter; -0.4 = 40% darker.
1567
		 *
1568
		 * @return  string
1569
		 */
1570
		public static function css_hex_lighten_darken($hexCode, $adjustPercent) {
1571
			$hexCode = ltrim($hexCode, '#');
1572
1573
			if (strlen($hexCode) == 3) {
1574
				$hexCode = $hexCode[0] . $hexCode[0] . $hexCode[1] . $hexCode[1] . $hexCode[2] . $hexCode[2];
1575
			}
1576
1577
			$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

1577
			$hexCode = array_map('hexdec', /** @scrutinizer ignore-type */ str_split($hexCode, 2));
Loading history...
1578
1579
			foreach ($hexCode as & $color) {
1580
				$adjustableLimit = $adjustPercent < 0 ? $color : 255 - $color;
1581
				$adjustAmount = ceil($adjustableLimit * $adjustPercent);
1582
1583
				$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

1583
				$color = str_pad(dechex(/** @scrutinizer ignore-type */ $color + $adjustAmount), 2, '0', STR_PAD_LEFT);
Loading history...
1584
			}
1585
1586
			return '#' . implode($hexCode);
1587
		}
1588
1589
		/**
1590
		 * Check if we should display examples.
1591
		 */
1592
		public function maybe_show_examples(){
1593
			if(current_user_can('manage_options') && isset($_REQUEST['preview-aui'])){
1594
				echo "<head>";
1595
				wp_head();
1596
				echo "</head>";
1597
				echo "<body>";
1598
				echo $this->get_examples();
1599
				echo "</body>";
1600
				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...
1601
			}
1602
		}
1603
1604
		/**
1605
		 * Get developer examples.
1606
		 *
1607
		 * @return string
1608
		 */
1609
		public function get_examples(){
1610
			$output = '';
1611
1612
1613
			// open form
1614
			$output .= "<form class='p-5 m-5 border rounded'>";
1615
1616
			// input example
1617
			$output .= aui()->input(array(
1618
				'type'  =>  'text',
1619
				'id'    =>  'text-example',
1620
				'name'    =>  'text-example',
1621
				'placeholder'   => 'text placeholder',
1622
				'title'   => 'Text input example',
1623
				'value' =>  '',
1624
				'required'  => false,
1625
				'help_text' => 'help text',
1626
				'label' => 'Text input example label'
1627
			));
1628
1629
			// input example
1630
			$output .= aui()->input(array(
1631
				'type'  =>  'url',
1632
				'id'    =>  'text-example2',
1633
				'name'    =>  'text-example',
1634
				'placeholder'   => 'url placeholder',
1635
				'title'   => 'Text input example',
1636
				'value' =>  '',
1637
				'required'  => false,
1638
				'help_text' => 'help text',
1639
				'label' => 'Text input example label'
1640
			));
1641
1642
			// checkbox example
1643
			$output .= aui()->input(array(
1644
				'type'  =>  'checkbox',
1645
				'id'    =>  'checkbox-example',
1646
				'name'    =>  'checkbox-example',
1647
				'placeholder'   => 'checkbox-example',
1648
				'title'   => 'Checkbox example',
1649
				'value' =>  '1',
1650
				'checked'   => true,
1651
				'required'  => false,
1652
				'help_text' => 'help text',
1653
				'label' => 'Checkbox checked'
1654
			));
1655
1656
			// checkbox example
1657
			$output .= aui()->input(array(
1658
				'type'  =>  'checkbox',
1659
				'id'    =>  'checkbox-example2',
1660
				'name'    =>  'checkbox-example2',
1661
				'placeholder'   => 'checkbox-example',
1662
				'title'   => 'Checkbox example',
1663
				'value' =>  '1',
1664
				'checked'   => false,
1665
				'required'  => false,
1666
				'help_text' => 'help text',
1667
				'label' => 'Checkbox un-checked'
1668
			));
1669
1670
			// switch example
1671
			$output .= aui()->input(array(
1672
				'type'  =>  'checkbox',
1673
				'id'    =>  'switch-example',
1674
				'name'    =>  'switch-example',
1675
				'placeholder'   => 'checkbox-example',
1676
				'title'   => 'Switch example',
1677
				'value' =>  '1',
1678
				'checked'   => true,
1679
				'switch'    => true,
1680
				'required'  => false,
1681
				'help_text' => 'help text',
1682
				'label' => 'Switch on'
1683
			));
1684
1685
			// switch example
1686
			$output .= aui()->input(array(
1687
				'type'  =>  'checkbox',
1688
				'id'    =>  'switch-example2',
1689
				'name'    =>  'switch-example2',
1690
				'placeholder'   => 'checkbox-example',
1691
				'title'   => 'Switch example',
1692
				'value' =>  '1',
1693
				'checked'   => false,
1694
				'switch'    => true,
1695
				'required'  => false,
1696
				'help_text' => 'help text',
1697
				'label' => 'Switch off'
1698
			));
1699
1700
			// close form
1701
			$output .= "</form>";
1702
1703
			return $output;
1704
		}
1705
1706
		/**
1707
		 * Calendar params.
1708
		 *
1709
		 * @since 0.1.44
1710
		 *
1711
		 * @return array Calendar params.
1712
		 */
1713
		public static function calendar_params() {
1714
			$params = array(
1715
				'month_long_1' => __( 'January', 'aui' ),
1716
				'month_long_2' => __( 'February', 'aui' ),
1717
				'month_long_3' => __( 'March', 'aui' ),
1718
				'month_long_4' => __( 'April', 'aui' ),
1719
				'month_long_5' => __( 'May', 'aui' ),
1720
				'month_long_6' => __( 'June', 'aui' ),
1721
				'month_long_7' => __( 'July', 'aui' ),
1722
				'month_long_8' => __( 'August', 'aui' ),
1723
				'month_long_9' => __( 'September', 'aui' ),
1724
				'month_long_10' => __( 'October', 'aui' ),
1725
				'month_long_11' => __( 'November', 'aui' ),
1726
				'month_long_12' => __( 'December', 'aui' ),
1727
				'month_s_1' => _x( 'Jan', 'January abbreviation', 'aui' ),
1728
				'month_s_2' => _x( 'Feb', 'February abbreviation', 'aui' ),
1729
				'month_s_3' => _x( 'Mar', 'March abbreviation', 'aui' ),
1730
				'month_s_4' => _x( 'Apr', 'April abbreviation', 'aui' ),
1731
				'month_s_5' => _x( 'May', 'May abbreviation', 'aui' ),
1732
				'month_s_6' => _x( 'Jun', 'June abbreviation', 'aui' ),
1733
				'month_s_7' => _x( 'Jul', 'July abbreviation', 'aui' ),
1734
				'month_s_8' => _x( 'Aug', 'August abbreviation', 'aui' ),
1735
				'month_s_9' => _x( 'Sep', 'September abbreviation', 'aui' ),
1736
				'month_s_10' => _x( 'Oct', 'October abbreviation', 'aui' ),
1737
				'month_s_11' => _x( 'Nov', 'November abbreviation', 'aui' ),
1738
				'month_s_12' => _x( 'Dec', 'December abbreviation', 'aui' ),
1739
				'day_s1_1' => _x( 'S', 'Sunday initial', 'aui' ),
1740
				'day_s1_2' => _x( 'M', 'Monday initial', 'aui' ),
1741
				'day_s1_3' => _x( 'T', 'Tuesday initial', 'aui' ),
1742
				'day_s1_4' => _x( 'W', 'Wednesday initial', 'aui' ),
1743
				'day_s1_5' => _x( 'T', 'Friday initial', 'aui' ),
1744
				'day_s1_6' => _x( 'F', 'Thursday initial', 'aui' ),
1745
				'day_s1_7' => _x( 'S', 'Saturday initial', 'aui' ),
1746
				'day_s2_1' => __( 'Su', 'aui' ),
1747
				'day_s2_2' => __( 'Mo', 'aui' ),
1748
				'day_s2_3' => __( 'Tu', 'aui' ),
1749
				'day_s2_4' => __( 'We', 'aui' ),
1750
				'day_s2_5' => __( 'Th', 'aui' ),
1751
				'day_s2_6' => __( 'Fr', 'aui' ),
1752
				'day_s2_7' => __( 'Sa', 'aui' ),
1753
				'day_s3_1' => __( 'Sun', 'aui' ),
1754
				'day_s3_2' => __( 'Mon', 'aui' ),
1755
				'day_s3_3' => __( 'Tue', 'aui' ),
1756
				'day_s3_4' => __( 'Wed', 'aui' ),
1757
				'day_s3_5' => __( 'Thu', 'aui' ),
1758
				'day_s3_6' => __( 'Fri', 'aui' ),
1759
				'day_s3_7' => __( 'Sat', 'aui' ),
1760
				'day_s5_1' => __( 'Sunday', 'aui' ),
1761
				'day_s5_2' => __( 'Monday', 'aui' ),
1762
				'day_s5_3' => __( 'Tuesday', 'aui' ),
1763
				'day_s5_4' => __( 'Wednesday', 'aui' ),
1764
				'day_s5_5' => __( 'Thursday', 'aui' ),
1765
				'day_s5_6' => __( 'Friday', 'aui' ),
1766
				'day_s5_7' => __( 'Saturday', 'aui' ),
1767
				'am_lower' => __( 'am', 'aui' ),
1768
				'pm_lower' => __( 'pm', 'aui' ),
1769
				'am_upper' => __( 'AM', 'aui' ),
1770
				'pm_upper' => __( 'PM', 'aui' ),
1771
				'firstDayOfWeek' => (int) get_option( 'start_of_week' ),
1772
				'time_24hr' => false,
1773
				'year' => __( 'Year', 'aui' ),
1774
				'hour' => __( 'Hour', 'aui' ),
1775
				'minute' => __( 'Minute', 'aui' ),
1776
				'weekAbbreviation' => __( 'Wk', 'aui' ),
1777
				'rangeSeparator' => __( ' to ', 'aui' ),
1778
				'scrollTitle' => __( 'Scroll to increment', 'aui' ),
1779
				'toggleTitle' => __( 'Click to toggle', 'aui' )
1780
			);
1781
1782
			return apply_filters( 'ayecode_ui_calendar_params', $params );
1783
		}
1784
1785
		/**
1786
		 * Flatpickr calendar localize.
1787
		 *
1788
		 * @since 0.1.44
1789
		 *
1790
		 * @return string Calendar locale.
1791
		 */
1792
		public static function flatpickr_locale() {
1793
			$params = self::calendar_params();
1794
1795
			if ( is_string( $params ) ) {
0 ignored issues
show
introduced by
The condition is_string($params) is always false.
Loading history...
1796
				$params = html_entity_decode( $params, ENT_QUOTES, 'UTF-8' );
1797
			} else {
1798
				foreach ( (array) $params as $key => $value ) {
1799
					if ( ! is_scalar( $value ) ) {
1800
						continue;
1801
					}
1802
1803
					$params[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
1804
				}
1805
			}
1806
1807
			$day_s3 = array();
1808
			$day_s5 = array();
1809
1810
			for ( $i = 1; $i <= 7; $i ++ ) {
1811
				$day_s3[] = addslashes( $params[ 'day_s3_' . $i ] );
1812
				$day_s5[] = addslashes( $params[ 'day_s3_' . $i ] );
1813
			}
1814
1815
			$month_s = array();
1816
			$month_long = array();
1817
1818
			for ( $i = 1; $i <= 12; $i ++ ) {
1819
				$month_s[] = addslashes( $params[ 'month_s_' . $i ] );
1820
				$month_long[] = addslashes( $params[ 'month_long_' . $i ] );
1821
			}
1822
1823
ob_start();
1824
if ( 0 ) { ?><script><?php } ?>
1825
{
1826
	weekdays: {
1827
		shorthand: ['<?php echo implode( "','", $day_s3 ); ?>'],
1828
		longhand: ['<?php echo implode( "','", $day_s5 ); ?>'],
1829
	},
1830
	months: {
1831
		shorthand: ['<?php echo implode( "','", $month_s ); ?>'],
1832
		longhand: ['<?php echo implode( "','", $month_long ); ?>'],
1833
	},
1834
	daysInMonth: [31,28,31,30,31,30,31,31,30,31,30,31],
1835
	firstDayOfWeek: <?php echo (int) $params[ 'firstDayOfWeek' ]; ?>,
1836
	ordinal: function (nth) {
1837
		var s = nth % 100;
1838
		if (s > 3 && s < 21)
1839
			return "th";
1840
		switch (s % 10) {
1841
			case 1:
1842
				return "st";
1843
			case 2:
1844
				return "nd";
1845
			case 3:
1846
				return "rd";
1847
			default:
1848
				return "th";
1849
		}
1850
	},
1851
	rangeSeparator: '<?php echo addslashes( $params[ 'rangeSeparator' ] ); ?>',
1852
	weekAbbreviation: '<?php echo addslashes( $params[ 'weekAbbreviation' ] ); ?>',
1853
	scrollTitle: '<?php echo addslashes( $params[ 'scrollTitle' ] ); ?>',
1854
	toggleTitle: '<?php echo addslashes( $params[ 'toggleTitle' ] ); ?>',
1855
	amPM: ['<?php echo addslashes( $params[ 'am_upper' ] ); ?>','<?php echo addslashes( $params[ 'pm_upper' ] ); ?>'],
1856
	yearAriaLabel: '<?php echo addslashes( $params[ 'year' ] ); ?>',
1857
	hourAriaLabel: '<?php echo addslashes( $params[ 'hour' ] ); ?>',
1858
	minuteAriaLabel: '<?php echo addslashes( $params[ 'minute' ] ); ?>',
1859
	time_24hr: <?php echo ( $params[ 'time_24hr' ] ? 'true' : 'false' ) ; ?>
1860
}
1861
<?php if ( 0 ) { ?></script><?php } ?>
1862
<?php
1863
			$locale = ob_get_clean();
1864
1865
			return apply_filters( 'ayecode_ui_flatpickr_locale', trim( $locale ) );
1866
		}
1867
1868
		/**
1869
		 * Select2 JS params.
1870
		 *
1871
		 * @since 0.1.44
1872
		 *
1873
		 * @return array Select2 JS params.
1874
		 */
1875
		public static function select2_params() {
1876
			$params = array(
1877
				'i18n_select_state_text'    => esc_attr__( 'Select an option&hellip;', 'aui' ),
1878
				'i18n_no_matches'           => _x( 'No matches found', 'enhanced select', 'aui' ),
1879
				'i18n_ajax_error'           => _x( 'Loading failed', 'enhanced select', 'aui' ),
1880
				'i18n_input_too_short_1'    => _x( 'Please enter 1 or more characters', 'enhanced select', 'aui' ),
1881
				'i18n_input_too_short_n'    => _x( 'Please enter %item% or more characters', 'enhanced select', 'aui' ),
1882
				'i18n_input_too_long_1'     => _x( 'Please delete 1 character', 'enhanced select', 'aui' ),
1883
				'i18n_input_too_long_n'     => _x( 'Please delete %item% characters', 'enhanced select', 'aui' ),
1884
				'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'aui' ),
1885
				'i18n_selection_too_long_n' => _x( 'You can only select %item% items', 'enhanced select', 'aui' ),
1886
				'i18n_load_more'            => _x( 'Loading more results&hellip;', 'enhanced select', 'aui' ),
1887
				'i18n_searching'            => _x( 'Searching&hellip;', 'enhanced select', 'aui' )
1888
			);
1889
1890
			return apply_filters( 'ayecode_ui_select2_params', $params );
1891
		}
1892
1893
		/**
1894
		 * Select2 JS localize.
1895
		 *
1896
		 * @since 0.1.44
1897
		 *
1898
		 * @return string Select2 JS locale.
1899
		 */
1900
		public static function select2_locale() {
1901
			$params = self::select2_params();
1902
1903
			foreach ( (array) $params as $key => $value ) {
1904
				if ( ! is_scalar( $value ) ) {
1905
					continue;
1906
				}
1907
1908
				$params[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
1909
			}
1910
1911
			$locale = json_encode( $params );
1912
1913
			return apply_filters( 'ayecode_ui_select2_locale', trim( $locale ) );
1914
		}
1915
	}
1916
1917
	/**
1918
	 * Run the class if found.
1919
	 */
1920
	AyeCode_UI_Settings::instance();
1921
}