Completed
Push — master ( d80a25...6415e4 )
by
unknown
41s
created
redux-core/inc/welcome/class-redux-welcome.php 1 patch
Indentation   +150 added lines, -150 removed lines patch added patch discarded remove patch
@@ -8,111 +8,111 @@  discard block
 block discarded – undo
8 8
  */
9 9
 
10 10
 if ( ! defined( 'ABSPATH' ) ) {
11
-	exit;
11
+    exit;
12 12
 }
13 13
 
14 14
 if ( ! class_exists( 'Redux_Welcome', false ) ) {
15 15
 
16
-	/**
17
-	 * Class Redux_Welcome
18
-	 */
19
-	class Redux_Welcome {
20
-
21
-		/**
22
-		 * Min capacity.
23
-		 *
24
-		 * @var string The capability users should have to view the page
25
-		 */
26
-		public string $minimum_capability = 'manage_options';
27
-
28
-		/**
29
-		 * Display version.
30
-		 *
31
-		 * @var string
32
-		 */
33
-		public string $display_version = '';
34
-
35
-		/**
36
-		 * Is loaded.
37
-		 *
38
-		 * @var bool
39
-		 */
40
-		public bool $redux_loaded = false;
41
-
42
-		/**
43
-		 * Get things started
44
-		 *
45
-		 * @since 1.4
46
-		 */
47
-		public function __construct() {
48
-			// Load the welcome page even if a Redux panel isn't running.
49
-			add_action( 'init', array( $this, 'init' ), 999 );
50
-		}
51
-
52
-		/**
53
-		 * Class init.
54
-		 */
55
-		public function init() {
56
-			if ( $this->redux_loaded ) {
57
-				return;
58
-			}
59
-
60
-			$this->redux_loaded = true;
61
-			add_action( 'admin_menu', array( $this, 'admin_menus' ) );
62
-
63
-			if ( isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
64
-				if ( 'redux-' === substr( sanitize_text_field( wp_unslash( $_GET['page'] ) ), 0, 6 ) ) { // phpcs:ignore WordPress.Security.NonceVerification
65
-					$version               = explode( '.', Redux_Core::$version );
66
-					$this->display_version = $version[0] . '.' . $version[1];
67
-					add_filter( 'admin_footer_text', array( $this, 'change_wp_footer' ) );
68
-					add_action( 'admin_head', array( $this, 'admin_head' ) );
69
-				}
70
-			}
71
-		}
72
-
73
-		/**
74
-		 * Do Redirect.
75
-		 */
76
-		public function do_redirect() {
77
-			if ( ! defined( 'WP_CLI' ) ) {
78
-				wp_safe_redirect( esc_url( admin_url( add_query_arg( array( 'page' => 'redux-framework' ), 'options-general.php' ) ) ) );
79
-				exit();
80
-			}
81
-		}
82
-
83
-		/**
84
-		 * Change Footer.
85
-		 */
86
-		public function change_wp_footer() {
87
-			echo esc_html__( 'If you like', 'redux-framework' ) . ' <strong>Redux</strong> ' . esc_html__( 'please leave us a', 'redux-framework' ) . ' <a href="https://wordpress.org/support/view/plugin-reviews/redux-framework?filter=5#postform" target="_blank" class="redux-rating-link" data-rated="Thanks :)">&#9733;&#9733;&#9733;&#9733;&#9733;</a> ' . esc_html__( 'rating. A huge thank you in advance!', 'redux-framework' );
88
-		}
89
-
90
-
91
-
92
-		/**
93
-		 * Register the Dashboard Pages which are later hidden but these pages
94
-		 * are used to render the What's Redux pages.
95
-		 *
96
-		 * @access public
97
-		 * @since  1.4
98
-		 * @return void
99
-		 */
100
-		public function admin_menus() {
101
-			$page = 'add_options_page';
102
-
103
-			// About Page.
104
-			$page( esc_html__( 'What is Redux Framework?', 'redux-framework' ), esc_html__( 'Redux', 'redux-framework' ), $this->minimum_capability, 'redux-framework', array( $this, 'about_screen' ) );
105
-		}
106
-
107
-		/**
108
-		 * Hide Individual Dashboard Pages
109
-		 *
110
-		 * @access public
111
-		 * @since  1.4
112
-		 * @return void
113
-		 */
114
-		public function admin_head() {
115
-			?>
16
+    /**
17
+     * Class Redux_Welcome
18
+     */
19
+    class Redux_Welcome {
20
+
21
+        /**
22
+         * Min capacity.
23
+         *
24
+         * @var string The capability users should have to view the page
25
+         */
26
+        public string $minimum_capability = 'manage_options';
27
+
28
+        /**
29
+         * Display version.
30
+         *
31
+         * @var string
32
+         */
33
+        public string $display_version = '';
34
+
35
+        /**
36
+         * Is loaded.
37
+         *
38
+         * @var bool
39
+         */
40
+        public bool $redux_loaded = false;
41
+
42
+        /**
43
+         * Get things started
44
+         *
45
+         * @since 1.4
46
+         */
47
+        public function __construct() {
48
+            // Load the welcome page even if a Redux panel isn't running.
49
+            add_action( 'init', array( $this, 'init' ), 999 );
50
+        }
51
+
52
+        /**
53
+         * Class init.
54
+         */
55
+        public function init() {
56
+            if ( $this->redux_loaded ) {
57
+                return;
58
+            }
59
+
60
+            $this->redux_loaded = true;
61
+            add_action( 'admin_menu', array( $this, 'admin_menus' ) );
62
+
63
+            if ( isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
64
+                if ( 'redux-' === substr( sanitize_text_field( wp_unslash( $_GET['page'] ) ), 0, 6 ) ) { // phpcs:ignore WordPress.Security.NonceVerification
65
+                    $version               = explode( '.', Redux_Core::$version );
66
+                    $this->display_version = $version[0] . '.' . $version[1];
67
+                    add_filter( 'admin_footer_text', array( $this, 'change_wp_footer' ) );
68
+                    add_action( 'admin_head', array( $this, 'admin_head' ) );
69
+                }
70
+            }
71
+        }
72
+
73
+        /**
74
+         * Do Redirect.
75
+         */
76
+        public function do_redirect() {
77
+            if ( ! defined( 'WP_CLI' ) ) {
78
+                wp_safe_redirect( esc_url( admin_url( add_query_arg( array( 'page' => 'redux-framework' ), 'options-general.php' ) ) ) );
79
+                exit();
80
+            }
81
+        }
82
+
83
+        /**
84
+         * Change Footer.
85
+         */
86
+        public function change_wp_footer() {
87
+            echo esc_html__( 'If you like', 'redux-framework' ) . ' <strong>Redux</strong> ' . esc_html__( 'please leave us a', 'redux-framework' ) . ' <a href="https://wordpress.org/support/view/plugin-reviews/redux-framework?filter=5#postform" target="_blank" class="redux-rating-link" data-rated="Thanks :)">&#9733;&#9733;&#9733;&#9733;&#9733;</a> ' . esc_html__( 'rating. A huge thank you in advance!', 'redux-framework' );
88
+        }
89
+
90
+
91
+
92
+        /**
93
+         * Register the Dashboard Pages which are later hidden but these pages
94
+         * are used to render the What's Redux pages.
95
+         *
96
+         * @access public
97
+         * @since  1.4
98
+         * @return void
99
+         */
100
+        public function admin_menus() {
101
+            $page = 'add_options_page';
102
+
103
+            // About Page.
104
+            $page( esc_html__( 'What is Redux Framework?', 'redux-framework' ), esc_html__( 'Redux', 'redux-framework' ), $this->minimum_capability, 'redux-framework', array( $this, 'about_screen' ) );
105
+        }
106
+
107
+        /**
108
+         * Hide Individual Dashboard Pages
109
+         *
110
+         * @access public
111
+         * @since  1.4
112
+         * @return void
113
+         */
114
+        public function admin_head() {
115
+            ?>
116 116
 			<link
117 117
 				rel='stylesheet' id='elusive-icons' <?php // phpcs:ignore WordPress.WP.EnqueuedResources ?>
118 118
 				href='<?php echo esc_url( Redux_Core::$url ); ?>assets/css/vendor/elusive-icons.css'
@@ -133,19 +133,19 @@  discard block
 block discarded – undo
133 133
 				}
134 134
 			</style>
135 135
 			<?php
136
-		}
137
-
138
-		/**
139
-		 * Navigation tabs
140
-		 *
141
-		 * @access public
142
-		 * @since  1.9
143
-		 * @return void
144
-		 */
145
-		public function tabs() {
146
-			$selected = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : 'redux-framework'; // phpcs:ignore WordPress.Security.NonceVerification
147
-
148
-			?>
136
+        }
137
+
138
+        /**
139
+         * Navigation tabs
140
+         *
141
+         * @access public
142
+         * @since  1.9
143
+         * @return void
144
+         */
145
+        public function tabs() {
146
+            $selected = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : 'redux-framework'; // phpcs:ignore WordPress.Security.NonceVerification
147
+
148
+            ?>
149 149
 			<h2 class="nav-tab-wrapper">
150 150
 				<a
151 151
 					class="nav-tab <?php echo( 'redux-framework' === $selected ? 'nav-tab-active' : '' ); ?>"
@@ -154,27 +154,27 @@  discard block
 block discarded – undo
154 154
 				</a>
155 155
 			</h2>
156 156
 			<?php
157
-		}
158
-
159
-		/**
160
-		 * Render About Screen
161
-		 *
162
-		 * @access public
163
-		 * @since  1.4
164
-		 * @return void
165
-		 */
166
-		public function about_screen() {
167
-			// Stupid hack for WordPress alerts and warnings.
168
-			echo '<div class="wrap" style="height:0;overflow:hidden;"><h2></h2></div>';
169
-
170
-			require_once 'views/about.php';
171
-		}
172
-
173
-		/**
174
-		 * Action.
175
-		 */
176
-		public function actions() {
177
-			?>
157
+        }
158
+
159
+        /**
160
+         * Render About Screen
161
+         *
162
+         * @access public
163
+         * @since  1.4
164
+         * @return void
165
+         */
166
+        public function about_screen() {
167
+            // Stupid hack for WordPress alerts and warnings.
168
+            echo '<div class="wrap" style="height:0;overflow:hidden;"><h2></h2></div>';
169
+
170
+            require_once 'views/about.php';
171
+        }
172
+
173
+        /**
174
+         * Action.
175
+         */
176
+        public function actions() {
177
+            ?>
178 178
 			<p class="redux-actions">
179 179
 				<a href="https://devs.redux.io/" class="docs button button-primary">Docs</a>
180 180
 				<a
@@ -189,30 +189,30 @@  discard block
 block discarded – undo
189 189
 					data-via="ReduxFramework" data-size="large" data-hashtags="Redux">Tweet</a>
190 190
 				<?php
191 191
 
192
-				$options = Redux_Helpers::get_plugin_options();
193
-				$nonce   = wp_create_nonce( 'redux_framework_demo' );
192
+                $options = Redux_Helpers::get_plugin_options();
193
+                $nonce   = wp_create_nonce( 'redux_framework_demo' );
194 194
 
195
-				$query_args = array(
196
-					'page'                   => 'redux-framework',
197
-					'redux-framework-plugin' => 'demo',
198
-					'nonce'                  => $nonce,
199
-				);
195
+                $query_args = array(
196
+                    'page'                   => 'redux-framework',
197
+                    'redux-framework-plugin' => 'demo',
198
+                    'nonce'                  => $nonce,
199
+                );
200 200
 
201
-				if ( $options['demo'] ) {
202
-					?>
201
+                if ( $options['demo'] ) {
202
+                    ?>
203 203
 					<a
204 204
 						href="<?php echo esc_url( admin_url( add_query_arg( $query_args, 'options-general.php' ) ) ); ?>"
205 205
 						class=" button-text button-demo"><?php echo esc_html__( 'Disable Panel Demo', 'redux-framework' ); ?></a>
206 206
 					<?php
207
-				} else {
208
-					?>
207
+                } else {
208
+                    ?>
209 209
 					<a
210 210
 						href="<?php echo esc_url( admin_url( add_query_arg( $query_args, 'options-general.php' ) ) ); ?>"
211 211
 						class=" button-text button-demo active"><?php echo esc_html__( 'Enable Panel Demo', 'redux-framework' ); ?></a>
212 212
 					<?php
213
-				}
213
+                }
214 214
 
215
-				?>
215
+                ?>
216 216
 				<script>
217 217
 					!function( d, s, id ) {
218 218
 						let js;
@@ -229,6 +229,6 @@  discard block
 block discarded – undo
229 229
 				</script>
230 230
 			</p>
231 231
 			<?php
232
-		}
233
-	}
232
+        }
233
+    }
234 234
 }
Please login to merge, or discard this patch.
redux-core/inc/lib/elusive-icons.php 1 patch
Indentation   +300 added lines, -300 removed lines patch added patch discarded remove patch
@@ -16,304 +16,304 @@
 block discarded – undo
16 16
  * @return array
17 17
  */
18 18
 function redux_get_font_icons(): array {
19
-	return array(
20
-		'el el-address-book-alt',
21
-		'el el-address-book',
22
-		'el el-adjust-alt',
23
-		'el el-adjust',
24
-		'el el-adult',
25
-		'el el-align-center',
26
-		'el el-align-justify',
27
-		'el el-align-left',
28
-		'el el-align-right',
29
-		'el el-arrow-down',
30
-		'el el-arrow-left',
31
-		'el el-arrow-right',
32
-		'el el-arrow-up',
33
-		'el el-asl',
34
-		'el el-asterisk',
35
-		'el el-backward',
36
-		'el el-ban-circle',
37
-		'el el-barcode',
38
-		'el el-behance',
39
-		'el el-bell',
40
-		'el el-blind',
41
-		'el el-blogger',
42
-		'el el-bold',
43
-		'el el-book',
44
-		'el el-bookmark-empty',
45
-		'el el-bookmark',
46
-		'el el-braille',
47
-		'el el-briefcase',
48
-		'el el-broom',
49
-		'el el-brush',
50
-		'el el-bulb',
51
-		'el el-bullhorn',
52
-		'el el-calendar-sign',
53
-		'el el-calendar',
54
-		'el el-camera',
55
-		'el el-car',
56
-		'el el-caret-down',
57
-		'el el-caret-left',
58
-		'el el-caret-right',
59
-		'el el-caret-up',
60
-		'el el-cc',
61
-		'el el-certificate',
62
-		'el el-check-empty',
63
-		'el el-check',
64
-		'el el-chevron-down',
65
-		'el el-chevron-left',
66
-		'el el-chevron-right',
67
-		'el el-chevron-up',
68
-		'el el-child',
69
-		'el el-circle-arrow-down',
70
-		'el el-circle-arrow-left',
71
-		'el el-circle-arrow-right',
72
-		'el el-circle-arrow-up',
73
-		'el el-cloud-alt',
74
-		'el el-cloud',
75
-		'el el-cog-alt',
76
-		'el el-cog',
77
-		'el el-cogs',
78
-		'el el-comment-alt',
79
-		'el el-comment',
80
-		'el el-compass-alt',
81
-		'el el-compass',
82
-		'el el-credit-card',
83
-		'el el-css',
84
-		'el el-dashboard',
85
-		'el el-delicious',
86
-		'el el-deviantart',
87
-		'el el-digg',
88
-		'el el-download-alt',
89
-		'el el-download',
90
-		'el el-dribbble',
91
-		'el el-edit',
92
-		'el el-eject',
93
-		'el el-envelope-alt',
94
-		'el el-envelope',
95
-		'el el-error-alt',
96
-		'el el-error',
97
-		'el el-eur',
98
-		'el el-exclamation-sign',
99
-		'el el-eye-close',
100
-		'el el-eye-open',
101
-		'el el-facebook',
102
-		'el el-facetime-video',
103
-		'el el-fast-backward',
104
-		'el el-fast-forward',
105
-		'el el-female',
106
-		'el el-file-alt',
107
-		'el el-file-edit-alt',
108
-		'el el-file-edit',
109
-		'el el-file-new-alt',
110
-		'el el-file-new',
111
-		'el el-file',
112
-		'el el-film',
113
-		'el el-filter',
114
-		'el el-fire',
115
-		'el el-flag-alt',
116
-		'el el-flag',
117
-		'el el-flickr',
118
-		'el el-folder-close',
119
-		'el el-folder-open',
120
-		'el el-folder-sign',
121
-		'el el-folder',
122
-		'el el-font',
123
-		'el el-fontsize',
124
-		'el el-fork',
125
-		'el el-forward-alt',
126
-		'el el-forward',
127
-		'el el-foursquare',
128
-		'el el-friendfeed-rect',
129
-		'el el-friendfeed',
130
-		'el el-fullscreen',
131
-		'el el-gbp',
132
-		'el el-gift',
133
-		'el el-github-text',
134
-		'el el-github',
135
-		'el el-glass',
136
-		'el el-glasses',
137
-		'el el-globe-alt',
138
-		'el el-globe',
139
-		'el el-googleplus',
140
-		'el el-graph-alt',
141
-		'el el-graph',
142
-		'el el-group-alt',
143
-		'el el-group',
144
-		'el el-guidedog',
145
-		'el el-hand-down',
146
-		'el el-hand-left',
147
-		'el el-hand-right',
148
-		'el el-hand-up',
149
-		'el el-hdd',
150
-		'el el-headphones',
151
-		'el el-hearing-impaired',
152
-		'el el-heart-alt',
153
-		'el el-heart-empty',
154
-		'el el-heart',
155
-		'el el-home-alt',
156
-		'el el-home',
157
-		'el el-hourglass',
158
-		'el el-idea-alt',
159
-		'el el-idea',
160
-		'el el-inbox-alt',
161
-		'el el-inbox-box',
162
-		'el el-inbox',
163
-		'el el-indent-left',
164
-		'el el-indent-right',
165
-		'el el-info-circle',
166
-		'el el-instagram',
167
-		'el el-iphone-home',
168
-		'el el-italic',
169
-		'el el-key',
170
-		'el el-laptop-alt',
171
-		'el el-laptop',
172
-		'el el-lastfm',
173
-		'el el-leaf',
174
-		'el el-lines',
175
-		'el el-link',
176
-		'el el-linkedin',
177
-		'el el-list-alt',
178
-		'el el-list',
179
-		'el el-livejournal',
180
-		'el el-lock-alt',
181
-		'el el-lock',
182
-		'el el-magic',
183
-		'el el-magnet',
184
-		'el el-male',
185
-		'el el-map-marker-alt',
186
-		'el el-map-marker',
187
-		'el el-mic-alt',
188
-		'el el-mic',
189
-		'el el-minus-sign',
190
-		'el el-minus',
191
-		'el el-move',
192
-		'el el-music',
193
-		'el el-myspace',
194
-		'el el-network',
195
-		'el el-off',
196
-		'el el-ok-circle',
197
-		'el el-ok-sign',
198
-		'el el-ok',
199
-		'el el-opensource',
200
-		'el el-paper-clip-alt',
201
-		'el el-paper-clip',
202
-		'el el-path',
203
-		'el el-pause-alt',
204
-		'el el-pause',
205
-		'el el-pencil-alt',
206
-		'el el-pencil',
207
-		'el el-person',
208
-		'el el-phone-alt',
209
-		'el el-phone',
210
-		'el el-photo-alt',
211
-		'el el-photo',
212
-		'el el-picasa',
213
-		'el el-picture',
214
-		'el el-plane',
215
-		'el el-play-alt',
216
-		'el el-play-circle',
217
-		'el el-play',
218
-		'el el-plus-sign',
219
-		'el el-plus',
220
-		'el el-podcast',
221
-		'el el-print',
222
-		'el el-puzzle',
223
-		'el el-qrcode',
224
-		'el el-question-sign',
225
-		'el el-question',
226
-		'el el-quote-alt',
227
-		'el el-quotes',
228
-		'el el-random',
229
-		'el el-record',
230
-		'el el-reddit',
231
-		'el el-refresh',
232
-		'el el-remove-circle',
233
-		'el el-remove-sign',
234
-		'el el-remove',
235
-		'el el-repeat-alt',
236
-		'el el-repeat',
237
-		'el el-resize-full',
238
-		'el el-resize-horizontal',
239
-		'el el-resize-small',
240
-		'el el-resize-vertical',
241
-		'el el-return-key',
242
-		'el el-retweet',
243
-		'el el-reverse-alt',
244
-		'el el-road',
245
-		'el el-rss',
246
-		'el el-scissors',
247
-		'el el-screen-alt',
248
-		'el el-screen',
249
-		'el el-screenshot',
250
-		'el el-search-alt',
251
-		'el el-search',
252
-		'el el-share-alt',
253
-		'el el-share',
254
-		'el el-shopping-cart-sign',
255
-		'el el-shopping-cart',
256
-		'el el-signal',
257
-		'el el-skype',
258
-		'el el-slideshare',
259
-		'el el-smiley-alt',
260
-		'el el-smiley',
261
-		'el el-soundcloud',
262
-		'el el-speaker',
263
-		'el el-spotify',
264
-		'el el-stackoverflow',
265
-		'el el-star-alt',
266
-		'el el-star-empty',
267
-		'el el-star',
268
-		'el el-step-backward',
269
-		'el el-step-forward',
270
-		'el el-stop-alt',
271
-		'el el-stop',
272
-		'el el-stumbleupon',
273
-		'el el-tag',
274
-		'el el-tags',
275
-		'el el-tasks',
276
-		'el el-text-height',
277
-		'el el-text-width',
278
-		'el el-th-large',
279
-		'el el-th-list',
280
-		'el el-th',
281
-		'el el-thumbs-down',
282
-		'el el-thumbs-up',
283
-		'el el-time-alt',
284
-		'el el-time',
285
-		'el el-tint',
286
-		'el el-torso',
287
-		'el el-trash-alt',
288
-		'el el-trash',
289
-		'el el-tumblr',
290
-		'el el-twitter',
291
-		'el el-universal-access',
292
-		'el el-unlock-alt',
293
-		'el el-unlock',
294
-		'el el-upload',
295
-		'el el-usd',
296
-		'el el-user',
297
-		'el el-viadeo',
298
-		'el el-video-alt',
299
-		'el el-video-chat',
300
-		'el el-video',
301
-		'el el-view-mode',
302
-		'el el-vimeo',
303
-		'el el-vkontakte',
304
-		'el el-volume-down',
305
-		'el el-volume-off',
306
-		'el el-volume-up',
307
-		'el el-w3c',
308
-		'el el-warning-sign',
309
-		'el el-website-alt',
310
-		'el el-website',
311
-		'el el-wheelchair',
312
-		'el el-wordpress',
313
-		'el el-wrench-alt',
314
-		'el el-wrench',
315
-		'el el-youtube',
316
-		'el el-zoom-in',
317
-		'el el-zoom-out',
318
-	);
19
+    return array(
20
+        'el el-address-book-alt',
21
+        'el el-address-book',
22
+        'el el-adjust-alt',
23
+        'el el-adjust',
24
+        'el el-adult',
25
+        'el el-align-center',
26
+        'el el-align-justify',
27
+        'el el-align-left',
28
+        'el el-align-right',
29
+        'el el-arrow-down',
30
+        'el el-arrow-left',
31
+        'el el-arrow-right',
32
+        'el el-arrow-up',
33
+        'el el-asl',
34
+        'el el-asterisk',
35
+        'el el-backward',
36
+        'el el-ban-circle',
37
+        'el el-barcode',
38
+        'el el-behance',
39
+        'el el-bell',
40
+        'el el-blind',
41
+        'el el-blogger',
42
+        'el el-bold',
43
+        'el el-book',
44
+        'el el-bookmark-empty',
45
+        'el el-bookmark',
46
+        'el el-braille',
47
+        'el el-briefcase',
48
+        'el el-broom',
49
+        'el el-brush',
50
+        'el el-bulb',
51
+        'el el-bullhorn',
52
+        'el el-calendar-sign',
53
+        'el el-calendar',
54
+        'el el-camera',
55
+        'el el-car',
56
+        'el el-caret-down',
57
+        'el el-caret-left',
58
+        'el el-caret-right',
59
+        'el el-caret-up',
60
+        'el el-cc',
61
+        'el el-certificate',
62
+        'el el-check-empty',
63
+        'el el-check',
64
+        'el el-chevron-down',
65
+        'el el-chevron-left',
66
+        'el el-chevron-right',
67
+        'el el-chevron-up',
68
+        'el el-child',
69
+        'el el-circle-arrow-down',
70
+        'el el-circle-arrow-left',
71
+        'el el-circle-arrow-right',
72
+        'el el-circle-arrow-up',
73
+        'el el-cloud-alt',
74
+        'el el-cloud',
75
+        'el el-cog-alt',
76
+        'el el-cog',
77
+        'el el-cogs',
78
+        'el el-comment-alt',
79
+        'el el-comment',
80
+        'el el-compass-alt',
81
+        'el el-compass',
82
+        'el el-credit-card',
83
+        'el el-css',
84
+        'el el-dashboard',
85
+        'el el-delicious',
86
+        'el el-deviantart',
87
+        'el el-digg',
88
+        'el el-download-alt',
89
+        'el el-download',
90
+        'el el-dribbble',
91
+        'el el-edit',
92
+        'el el-eject',
93
+        'el el-envelope-alt',
94
+        'el el-envelope',
95
+        'el el-error-alt',
96
+        'el el-error',
97
+        'el el-eur',
98
+        'el el-exclamation-sign',
99
+        'el el-eye-close',
100
+        'el el-eye-open',
101
+        'el el-facebook',
102
+        'el el-facetime-video',
103
+        'el el-fast-backward',
104
+        'el el-fast-forward',
105
+        'el el-female',
106
+        'el el-file-alt',
107
+        'el el-file-edit-alt',
108
+        'el el-file-edit',
109
+        'el el-file-new-alt',
110
+        'el el-file-new',
111
+        'el el-file',
112
+        'el el-film',
113
+        'el el-filter',
114
+        'el el-fire',
115
+        'el el-flag-alt',
116
+        'el el-flag',
117
+        'el el-flickr',
118
+        'el el-folder-close',
119
+        'el el-folder-open',
120
+        'el el-folder-sign',
121
+        'el el-folder',
122
+        'el el-font',
123
+        'el el-fontsize',
124
+        'el el-fork',
125
+        'el el-forward-alt',
126
+        'el el-forward',
127
+        'el el-foursquare',
128
+        'el el-friendfeed-rect',
129
+        'el el-friendfeed',
130
+        'el el-fullscreen',
131
+        'el el-gbp',
132
+        'el el-gift',
133
+        'el el-github-text',
134
+        'el el-github',
135
+        'el el-glass',
136
+        'el el-glasses',
137
+        'el el-globe-alt',
138
+        'el el-globe',
139
+        'el el-googleplus',
140
+        'el el-graph-alt',
141
+        'el el-graph',
142
+        'el el-group-alt',
143
+        'el el-group',
144
+        'el el-guidedog',
145
+        'el el-hand-down',
146
+        'el el-hand-left',
147
+        'el el-hand-right',
148
+        'el el-hand-up',
149
+        'el el-hdd',
150
+        'el el-headphones',
151
+        'el el-hearing-impaired',
152
+        'el el-heart-alt',
153
+        'el el-heart-empty',
154
+        'el el-heart',
155
+        'el el-home-alt',
156
+        'el el-home',
157
+        'el el-hourglass',
158
+        'el el-idea-alt',
159
+        'el el-idea',
160
+        'el el-inbox-alt',
161
+        'el el-inbox-box',
162
+        'el el-inbox',
163
+        'el el-indent-left',
164
+        'el el-indent-right',
165
+        'el el-info-circle',
166
+        'el el-instagram',
167
+        'el el-iphone-home',
168
+        'el el-italic',
169
+        'el el-key',
170
+        'el el-laptop-alt',
171
+        'el el-laptop',
172
+        'el el-lastfm',
173
+        'el el-leaf',
174
+        'el el-lines',
175
+        'el el-link',
176
+        'el el-linkedin',
177
+        'el el-list-alt',
178
+        'el el-list',
179
+        'el el-livejournal',
180
+        'el el-lock-alt',
181
+        'el el-lock',
182
+        'el el-magic',
183
+        'el el-magnet',
184
+        'el el-male',
185
+        'el el-map-marker-alt',
186
+        'el el-map-marker',
187
+        'el el-mic-alt',
188
+        'el el-mic',
189
+        'el el-minus-sign',
190
+        'el el-minus',
191
+        'el el-move',
192
+        'el el-music',
193
+        'el el-myspace',
194
+        'el el-network',
195
+        'el el-off',
196
+        'el el-ok-circle',
197
+        'el el-ok-sign',
198
+        'el el-ok',
199
+        'el el-opensource',
200
+        'el el-paper-clip-alt',
201
+        'el el-paper-clip',
202
+        'el el-path',
203
+        'el el-pause-alt',
204
+        'el el-pause',
205
+        'el el-pencil-alt',
206
+        'el el-pencil',
207
+        'el el-person',
208
+        'el el-phone-alt',
209
+        'el el-phone',
210
+        'el el-photo-alt',
211
+        'el el-photo',
212
+        'el el-picasa',
213
+        'el el-picture',
214
+        'el el-plane',
215
+        'el el-play-alt',
216
+        'el el-play-circle',
217
+        'el el-play',
218
+        'el el-plus-sign',
219
+        'el el-plus',
220
+        'el el-podcast',
221
+        'el el-print',
222
+        'el el-puzzle',
223
+        'el el-qrcode',
224
+        'el el-question-sign',
225
+        'el el-question',
226
+        'el el-quote-alt',
227
+        'el el-quotes',
228
+        'el el-random',
229
+        'el el-record',
230
+        'el el-reddit',
231
+        'el el-refresh',
232
+        'el el-remove-circle',
233
+        'el el-remove-sign',
234
+        'el el-remove',
235
+        'el el-repeat-alt',
236
+        'el el-repeat',
237
+        'el el-resize-full',
238
+        'el el-resize-horizontal',
239
+        'el el-resize-small',
240
+        'el el-resize-vertical',
241
+        'el el-return-key',
242
+        'el el-retweet',
243
+        'el el-reverse-alt',
244
+        'el el-road',
245
+        'el el-rss',
246
+        'el el-scissors',
247
+        'el el-screen-alt',
248
+        'el el-screen',
249
+        'el el-screenshot',
250
+        'el el-search-alt',
251
+        'el el-search',
252
+        'el el-share-alt',
253
+        'el el-share',
254
+        'el el-shopping-cart-sign',
255
+        'el el-shopping-cart',
256
+        'el el-signal',
257
+        'el el-skype',
258
+        'el el-slideshare',
259
+        'el el-smiley-alt',
260
+        'el el-smiley',
261
+        'el el-soundcloud',
262
+        'el el-speaker',
263
+        'el el-spotify',
264
+        'el el-stackoverflow',
265
+        'el el-star-alt',
266
+        'el el-star-empty',
267
+        'el el-star',
268
+        'el el-step-backward',
269
+        'el el-step-forward',
270
+        'el el-stop-alt',
271
+        'el el-stop',
272
+        'el el-stumbleupon',
273
+        'el el-tag',
274
+        'el el-tags',
275
+        'el el-tasks',
276
+        'el el-text-height',
277
+        'el el-text-width',
278
+        'el el-th-large',
279
+        'el el-th-list',
280
+        'el el-th',
281
+        'el el-thumbs-down',
282
+        'el el-thumbs-up',
283
+        'el el-time-alt',
284
+        'el el-time',
285
+        'el el-tint',
286
+        'el el-torso',
287
+        'el el-trash-alt',
288
+        'el el-trash',
289
+        'el el-tumblr',
290
+        'el el-twitter',
291
+        'el el-universal-access',
292
+        'el el-unlock-alt',
293
+        'el el-unlock',
294
+        'el el-upload',
295
+        'el el-usd',
296
+        'el el-user',
297
+        'el el-viadeo',
298
+        'el el-video-alt',
299
+        'el el-video-chat',
300
+        'el el-video',
301
+        'el el-view-mode',
302
+        'el el-vimeo',
303
+        'el el-vkontakte',
304
+        'el el-volume-down',
305
+        'el el-volume-off',
306
+        'el el-volume-up',
307
+        'el el-w3c',
308
+        'el el-warning-sign',
309
+        'el el-website-alt',
310
+        'el el-website',
311
+        'el el-wheelchair',
312
+        'el el-wordpress',
313
+        'el el-wrench-alt',
314
+        'el el-wrench',
315
+        'el el-youtube',
316
+        'el el-zoom-in',
317
+        'el el-zoom-out',
318
+    );
319 319
 }
Please login to merge, or discard this patch.
redux-core/inc/classes/class-redux-autoloader.php 1 patch
Indentation   +67 added lines, -67 removed lines patch added patch discarded remove patch
@@ -11,81 +11,81 @@
 block discarded – undo
11 11
  * @package altis/core
12 12
  */
13 13
 class Redux_Autoloader {
14
-	const NS_SEPARATOR = '\\';
14
+    const NS_SEPARATOR = '\\';
15 15
 
16
-	/**
17
-	 * Prefix to validate against.
18
-	 *
19
-	 * @var string
20
-	 */
21
-	protected string $prefix;
16
+    /**
17
+     * Prefix to validate against.
18
+     *
19
+     * @var string
20
+     */
21
+    protected string $prefix;
22 22
 
23
-	/**
24
-	 * String length of the prefix.
25
-	 *
26
-	 * @var int
27
-	 */
28
-	protected int $prefix_length;
23
+    /**
24
+     * String length of the prefix.
25
+     *
26
+     * @var int
27
+     */
28
+    protected int $prefix_length;
29 29
 
30
-	/**
31
-	 * Path to validate.
32
-	 *
33
-	 * @var string
34
-	 */
35
-	protected string $path;
30
+    /**
31
+     * Path to validate.
32
+     *
33
+     * @var string
34
+     */
35
+    protected string $path;
36 36
 
37
-	/**
38
-	 * Autoloader constructor.
39
-	 *
40
-	 * @param string $prefix Prefix to validate against.
41
-	 * @param string $path Path to validate.
42
-	 */
43
-	public function __construct( string $prefix, string $path ) {
44
-		$this->prefix        = $prefix;
45
-		$this->prefix_length = strlen( $prefix );
46
-		$this->path          = trailingslashit( $path );
47
-	}
37
+    /**
38
+     * Autoloader constructor.
39
+     *
40
+     * @param string $prefix Prefix to validate against.
41
+     * @param string $path Path to validate.
42
+     */
43
+    public function __construct( string $prefix, string $path ) {
44
+        $this->prefix        = $prefix;
45
+        $this->prefix_length = strlen( $prefix );
46
+        $this->path          = trailingslashit( $path );
47
+    }
48 48
 
49
-	/**
50
-	 * Load a class file if it matches our criteria.
51
-	 *
52
-	 * @param string $classname Class to test and/or load.
53
-	 */
54
-	public function load( string $classname ) {
55
-		if ( strpos( $classname, 'Redux' ) === false ) {
56
-			return;
57
-		}
49
+    /**
50
+     * Load a class file if it matches our criteria.
51
+     *
52
+     * @param string $classname Class to test and/or load.
53
+     */
54
+    public function load( string $classname ) {
55
+        if ( strpos( $classname, 'Redux' ) === false ) {
56
+            return;
57
+        }
58 58
 
59
-		// Strip prefix from the start (ala PSR-4).
60
-		$classname = substr( $classname, $this->prefix_length + 1 );
61
-		if ( function_exists( 'mb_strtolower' ) && function_exists( 'mb_detect_encoding' ) ) {
62
-			$classname = mb_strtolower( $classname, mb_detect_encoding( $classname ) );
63
-		} else {
64
-			$classname = strtolower( $classname );
65
-		}
59
+        // Strip prefix from the start (ala PSR-4).
60
+        $classname = substr( $classname, $this->prefix_length + 1 );
61
+        if ( function_exists( 'mb_strtolower' ) && function_exists( 'mb_detect_encoding' ) ) {
62
+            $classname = mb_strtolower( $classname, mb_detect_encoding( $classname ) );
63
+        } else {
64
+            $classname = strtolower( $classname );
65
+        }
66 66
 
67
-		$file = '';
68
-		// Split on namespace separator.
69
-		$last_ns_pos = strripos( $classname, self::NS_SEPARATOR );
70
-		if ( false !== $last_ns_pos ) {
71
-			$namespace = substr( $classname, 0, $last_ns_pos );
72
-			$classname = substr( $classname, $last_ns_pos + 1 );
73
-			$file      = str_replace( self::NS_SEPARATOR, DIRECTORY_SEPARATOR, $namespace ) . DIRECTORY_SEPARATOR;
74
-		}
75
-		$file_prefix = $file;
76
-		$file        = $file_prefix . 'class-' . str_replace( '_', '-', $classname ) . '.php';
67
+        $file = '';
68
+        // Split on namespace separator.
69
+        $last_ns_pos = strripos( $classname, self::NS_SEPARATOR );
70
+        if ( false !== $last_ns_pos ) {
71
+            $namespace = substr( $classname, 0, $last_ns_pos );
72
+            $classname = substr( $classname, $last_ns_pos + 1 );
73
+            $file      = str_replace( self::NS_SEPARATOR, DIRECTORY_SEPARATOR, $namespace ) . DIRECTORY_SEPARATOR;
74
+        }
75
+        $file_prefix = $file;
76
+        $file        = $file_prefix . 'class-' . str_replace( '_', '-', $classname ) . '.php';
77 77
 
78
-		$path = $this->path . $file;
78
+        $path = $this->path . $file;
79 79
 
80
-		if ( file_exists( $path ) ) {
81
-			require_once $path;
82
-		} else {
83
-			$file = $file_prefix . 'class-redux-' . str_replace( '_', '-', $classname ) . '.php';
84
-			$path = $this->path . $file;
80
+        if ( file_exists( $path ) ) {
81
+            require_once $path;
82
+        } else {
83
+            $file = $file_prefix . 'class-redux-' . str_replace( '_', '-', $classname ) . '.php';
84
+            $path = $this->path . $file;
85 85
 
86
-			if ( file_exists( $path ) ) {
87
-				require_once $path;
88
-			}
89
-		}
90
-	}
86
+            if ( file_exists( $path ) ) {
87
+                require_once $path;
88
+            }
89
+        }
90
+    }
91 91
 }
Please login to merge, or discard this patch.
inc/validation/no_special_chars/class-redux-validation-no-special-chars.php 1 patch
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -12,32 +12,32 @@
 block discarded – undo
12 12
 
13 13
 if ( ! class_exists( 'Redux_Validation_No_Special_Chars', false ) ) {
14 14
 
15
-	/**
16
-	 * Class Redux_Validation_No_Special_Chars
17
-	 */
18
-	class Redux_Validation_No_Special_Chars extends Redux_Validate {
19
-
20
-		/**
21
-		 * Field Render Function.
22
-		 * Takes the vars and validates them
23
-		 *
24
-		 * @since ReduxFramework 1.0.0
25
-		 */
26
-		public function validate() {
27
-			$this->field['msg'] = $this->field['msg'] ?? esc_html__( 'You must not enter any special characters in this field, all special characters have been removed.', 'redux-framework' );
28
-
29
-			$val = preg_match( '/[^a-zA-Z0-9_ -]/', $this->value );
30
-
31
-			if ( $val > 0 ) {
32
-				$this->field['current'] = $this->current;
33
-
34
-				$this->warning = $this->field;
35
-			}
36
-
37
-			$this->value = preg_replace( '/[^a-zA-Z0-9_ -]/', '', $this->value );
38
-
39
-			$this->field['current'] = $this->value;
40
-			$this->sanitize         = $this->field;
41
-		}
42
-	}
15
+    /**
16
+     * Class Redux_Validation_No_Special_Chars
17
+     */
18
+    class Redux_Validation_No_Special_Chars extends Redux_Validate {
19
+
20
+        /**
21
+         * Field Render Function.
22
+         * Takes the vars and validates them
23
+         *
24
+         * @since ReduxFramework 1.0.0
25
+         */
26
+        public function validate() {
27
+            $this->field['msg'] = $this->field['msg'] ?? esc_html__( 'You must not enter any special characters in this field, all special characters have been removed.', 'redux-framework' );
28
+
29
+            $val = preg_match( '/[^a-zA-Z0-9_ -]/', $this->value );
30
+
31
+            if ( $val > 0 ) {
32
+                $this->field['current'] = $this->current;
33
+
34
+                $this->warning = $this->field;
35
+            }
36
+
37
+            $this->value = preg_replace( '/[^a-zA-Z0-9_ -]/', '', $this->value );
38
+
39
+            $this->field['current'] = $this->value;
40
+            $this->sanitize         = $this->field;
41
+        }
42
+    }
43 43
 }
Please login to merge, or discard this patch.
redux-framework.php 1 patch
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -28,15 +28,15 @@
 block discarded – undo
28 28
 defined( 'ABSPATH' ) || exit;
29 29
 
30 30
 if ( ! defined( 'REDUX_PLUGIN_FILE' ) ) {
31
-	define( 'REDUX_PLUGIN_FILE', __FILE__ );
31
+    define( 'REDUX_PLUGIN_FILE', __FILE__ );
32 32
 }
33 33
 
34 34
 // This must be required before vendor/autoload.php so QM can serve its own message about PHP compatibility.
35 35
 require_once __DIR__ . '/redux-core/inc/classes/class-redux-php.php';
36 36
 
37 37
 if ( ! Redux_PHP::version_met() ) {
38
-	add_action( 'all_admin_notices', 'Redux_PHP::php_version_nope' );
39
-	return;
38
+    add_action( 'all_admin_notices', 'Redux_PHP::php_version_nope' );
39
+    return;
40 40
 }
41 41
 
42 42
 // Require the main plugin class.
Please login to merge, or discard this patch.
redux-core/inc/fields/slider/class-redux-slider.php 2 patches
Indentation   +435 added lines, -435 removed lines patch added patch discarded remove patch
@@ -13,357 +13,357 @@  discard block
 block discarded – undo
13 13
 
14 14
 if ( ! class_exists( 'Redux_Slider', false ) ) {
15 15
 
16
-	/**
17
-	 * Class Redux_Slider
18
-	 */
19
-	class Redux_Slider extends Redux_Field {
20
-
21
-		/**
22
-		 * No value readout.
23
-		 *
24
-		 * @var int
25
-		 */
26
-		private int $display_none = 0;
27
-
28
-		/**
29
-		 * Label value readout.
30
-		 *
31
-		 * @var int
32
-		 */
33
-		private int $display_label = 1;
34
-
35
-		/**
36
-		 * Text value readout.
37
-		 *
38
-		 * @var int
39
-		 */
40
-		private int $display_text = 2;
41
-
42
-		/**
43
-		 * Select box value readout.
44
-		 *
45
-		 * @var int
46
-		 */
47
-		private int $display_select = 3;
48
-
49
-		/**
50
-		 * Select2 options.
51
-		 *
52
-		 * @var string
53
-		 */
54
-		private string $select2_data = '';
55
-
56
-		/**
57
-		 * Set field and value defaults.
58
-		 */
59
-		public function set_defaults() {
60
-			$defaults = array(
61
-				'handles'       => 1,
62
-				'resolution'    => 1,
63
-				'display_value' => 'text',
64
-				'float_mark'    => '.',
65
-				'forced'        => true,
66
-				'min'           => 0,
67
-				'max'           => 1,
68
-				'step'          => 1,
69
-			);
70
-
71
-			$this->field = wp_parse_args( $this->field, $defaults );
72
-
73
-			// Sanitize float mark.
74
-			if ( ',' !== $this->field['float_mark'] && '.' !== $this->field['float_mark'] ) {
75
-				$this->field['float_mark'] = '.';
76
-			}
77
-
78
-			// Sanitize resolution value.
79
-			$this->field['resolution'] = $this->clean_val( $this->field['resolution'] );
80
-
81
-			// Sanitize handle value.
82
-			if ( 0 === $this->field['handles'] || 1 === $this->field['handles'] ) {
83
-				$this->field['handles'] = 1;
84
-			} else {
85
-				$this->field['handles'] = 2;
86
-			}
87
-
88
-			// Sanitize display value.
89
-			if ( 'label' === $this->field['display_value'] ) {
90
-				$this->field['display_value'] = $this->display_label;
91
-			} elseif ( 'select' === $this->field['display_value'] ) {
92
-				$this->field['display_value'] = $this->display_select;
93
-			} elseif ( 'none' === $this->field['display_value'] ) {
94
-				$this->field['display_value'] = $this->display_none;
95
-			} else {
96
-				$this->field['display_value'] = $this->display_text;
97
-			}
98
-		}
99
-
100
-		/**
101
-		 * Sanitize value.
102
-		 *
103
-		 * @param mixed $val Value to sanitize.
104
-		 *
105
-		 * @return float|int
106
-		 */
107
-		private function clean_val( $val ) {
108
-			if ( is_float( $val ) ) {
109
-				$clear_var = floatval( $val );
110
-			} else {
111
-				$clear_var = intval( $val );
112
-			}
113
-
114
-			return $clear_var;
115
-		}
116
-
117
-		/**
118
-		 * Clean default values.
119
-		 *
120
-		 * @param mixed $val Default values.
121
-		 *
122
-		 * @return float|int
123
-		 */
124
-		private function clean_default( $val ) {
125
-			if ( empty( $val ) && ! empty( $this->field['default'] ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
126
-				$val = $this->clean_val( $this->field['default'] );
127
-			}
128
-
129
-			if ( empty( $val ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
130
-				$val = $this->clean_val( $this->field['min'] );
131
-			}
132
-
133
-			if ( empty( $val ) ) {
134
-				$val = 0;
135
-			}
136
-
137
-			// Extra Validation.
138
-			if ( $val < $this->field['min'] ) {
139
-				$val = $this->clean_val( $this->field['min'] );
140
-			} elseif ( $val > $this->field['max'] ) {
141
-				$val = $this->clean_val( $this->field['max'] );
142
-			}
143
-
144
-			return $val;
145
-		}
146
-
147
-		/**
148
-		 * Sanitize default array.
149
-		 *
150
-		 * @param array $val Defaults.
151
-		 *
152
-		 * @return array
153
-		 */
154
-		private function clean_default_array( array $val ): array {
155
-			$one = $this->value[1];
156
-			$two = $this->value[2];
157
-
158
-			if ( empty( $one ) && ! empty( $this->field['default'][1] ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
159
-				$one = $this->clean_val( $this->field['default'][1] );
160
-			}
161
-
162
-			if ( empty( $one ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
163
-				$one = $this->clean_val( $this->field['min'] );
164
-			}
165
-
166
-			if ( empty( $one ) ) {
167
-				$one = 0;
168
-			}
169
-
170
-			if ( empty( $two ) && ! empty( $this->field['default'][2] ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
171
-				$two = $this->clean_val( $this->field['default'][1] + 1 );
172
-			}
173
-
174
-			if ( empty( $two ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
175
-				$two = $this->clean_val( $this->field['default'][1] + 1 );
176
-			}
177
-
178
-			if ( empty( $two ) ) {
179
-				$two = $this->field['default'][1] + 1;
180
-			}
181
-
182
-			$val[0] = $one;
183
-			$val[1] = $two;
184
-
185
-			return $val;
186
-		}
187
-
188
-		/**
189
-		 * Clean the field data to the fields defaults given the parameters.
190
-		 *
191
-		 * @since Redux_Framework 3.1.8
192
-		 */
193
-		private function clean() {
194
-
195
-			// Set min to 0 if no value is set.
196
-			$this->field['min'] = empty( $this->field['min'] ) ? 0 : $this->clean_val( $this->field['min'] );
197
-
198
-			// Set max to min + 1 if empty.
199
-			$this->field['max'] = empty( $this->field['max'] ) ? $this->field['min'] + 1 : $this->clean_val( $this->field['max'] );
200
-
201
-			// Set step to 1 if step is empty ot step > max.
202
-			$this->field['step'] = empty( $this->field['step'] ) || $this->field['step'] > $this->field['max'] ? 1 : $this->clean_val( $this->field['step'] );
203
-
204
-			if ( 2 === $this->field['handles'] ) {
205
-				if ( ! is_array( $this->value ) ) {
206
-					$this->value = array();
207
-
208
-					$this->value[1] = 0;
209
-					$this->value[2] = 1;
210
-				}
211
-
212
-				$this->value = $this->clean_default_array( $this->value );
213
-			} else {
214
-				if ( is_array( $this->value ) ) {
215
-					$this->value = 0;
216
-				}
217
-
218
-				$this->value = $this->clean_default( $this->value );
219
-			}
220
-
221
-			// More dummy checks.
222
-			if ( ! is_array( $this->value ) && 2 === $this->field['handles'] ) {
223
-				$this->value[0] = $this->field['min'];
224
-				$this->value[1] = $this->field['min'] + 1;
225
-			}
226
-
227
-			if ( is_array( $this->value ) && 1 === $this->field['handles'] ) {
228
-				$this->value = $this->field['min'];
229
-			}
230
-		}
231
-
232
-		/**
233
-		 * Enqueue Function.
234
-		 * If this field requires any scripts, or css define this function and register/enqueue the scripts/css
235
-		 *
236
-		 * @since ReduxFramework 3.1.8
237
-		 */
238
-		public function enqueue() {
239
-			$min = Redux_Functions::is_min();
240
-
241
-			wp_enqueue_style( 'select2-js' );
242
-
243
-			wp_enqueue_style(
244
-				'redux-nouislider',
245
-				Redux_Core::$url . "assets/css/vendor/nouislider$min.css",
246
-				array(),
247
-				'5.0.0'
248
-			);
249
-
250
-			wp_register_script(
251
-				'redux-nouislider',
252
-				Redux_Core::$url . 'assets/js/vendor/nouislider/redux.jquery.nouislider' . $min . '.js',
253
-				array( 'jquery' ),
254
-				'5.0.0',
255
-				true
256
-			);
257
-
258
-			wp_enqueue_script(
259
-				'redux-field-slider',
260
-				Redux_Core::$url . 'inc/fields/slider/redux-slider' . $min . '.js',
261
-				array( 'jquery', 'redux-nouislider', 'redux-js', 'select2-js' ),
262
-				$this->timestamp,
263
-				true
264
-			);
265
-
266
-			if ( $this->parent->args['dev_mode'] ) {
267
-				wp_enqueue_style(
268
-					'redux-field-slider',
269
-					Redux_Core::$url . 'inc/fields/slider/redux-slider.css',
270
-					array(),
271
-					$this->timestamp
272
-				);
273
-			}
274
-		}
275
-
276
-		/**
277
-		 * Field Render Function.
278
-		 * Takes the vars and outputs the HTML for the field in the settings
279
-		 *
280
-		 * @since ReduxFramework 0.0.4
281
-		 */
282
-		public function render() {
283
-			$this->clean();
284
-
285
-			$field_id   = $this->field['id'];
286
-			$field_name = $this->field['name'] . $this->field['name_suffix'];
287
-
288
-			// Set handle number variable.
289
-			$two_handles = false;
290
-			if ( 2 === $this->field['handles'] ) {
291
-				$two_handles = true;
292
-			}
293
-
294
-			// Set default values(s).
295
-			if ( true === $two_handles ) {
296
-				$val_one = $this->value[0];
297
-				$val_two = $this->value[1];
298
-
299
-				$html  = 'data-default-one=' . $val_one . ' ';
300
-				$html .= 'data-default-two=' . $val_two . ' ';
301
-
302
-				$name_one = $field_name . '[1]';
303
-				$name_two = $field_name . '[2]';
304
-
305
-				$id_one = $field_id . '[1]';
306
-				$id_two = $field_id . '[2]';
307
-			} else {
308
-				$val_one = $this->value;
309
-				$val_two = '';
310
-
311
-				$html = 'data-default-one=' . $val_one;
312
-
313
-				$name_one = $field_name;
314
-				$name_two = '';
315
-
316
-				$id_one = $field_id;
317
-				$id_two = '';
318
-			}
319
-
320
-			$show_input  = false;
321
-			$show_label  = false;
322
-			$show_select = false;
323
-
324
-			// TEXT output.
325
-			if ( $this->display_text === $this->field['display_value'] ) {
326
-				$show_input = true;
327
-				echo '<input
16
+    /**
17
+     * Class Redux_Slider
18
+     */
19
+    class Redux_Slider extends Redux_Field {
20
+
21
+        /**
22
+         * No value readout.
23
+         *
24
+         * @var int
25
+         */
26
+        private int $display_none = 0;
27
+
28
+        /**
29
+         * Label value readout.
30
+         *
31
+         * @var int
32
+         */
33
+        private int $display_label = 1;
34
+
35
+        /**
36
+         * Text value readout.
37
+         *
38
+         * @var int
39
+         */
40
+        private int $display_text = 2;
41
+
42
+        /**
43
+         * Select box value readout.
44
+         *
45
+         * @var int
46
+         */
47
+        private int $display_select = 3;
48
+
49
+        /**
50
+         * Select2 options.
51
+         *
52
+         * @var string
53
+         */
54
+        private string $select2_data = '';
55
+
56
+        /**
57
+         * Set field and value defaults.
58
+         */
59
+        public function set_defaults() {
60
+            $defaults = array(
61
+                'handles'       => 1,
62
+                'resolution'    => 1,
63
+                'display_value' => 'text',
64
+                'float_mark'    => '.',
65
+                'forced'        => true,
66
+                'min'           => 0,
67
+                'max'           => 1,
68
+                'step'          => 1,
69
+            );
70
+
71
+            $this->field = wp_parse_args( $this->field, $defaults );
72
+
73
+            // Sanitize float mark.
74
+            if ( ',' !== $this->field['float_mark'] && '.' !== $this->field['float_mark'] ) {
75
+                $this->field['float_mark'] = '.';
76
+            }
77
+
78
+            // Sanitize resolution value.
79
+            $this->field['resolution'] = $this->clean_val( $this->field['resolution'] );
80
+
81
+            // Sanitize handle value.
82
+            if ( 0 === $this->field['handles'] || 1 === $this->field['handles'] ) {
83
+                $this->field['handles'] = 1;
84
+            } else {
85
+                $this->field['handles'] = 2;
86
+            }
87
+
88
+            // Sanitize display value.
89
+            if ( 'label' === $this->field['display_value'] ) {
90
+                $this->field['display_value'] = $this->display_label;
91
+            } elseif ( 'select' === $this->field['display_value'] ) {
92
+                $this->field['display_value'] = $this->display_select;
93
+            } elseif ( 'none' === $this->field['display_value'] ) {
94
+                $this->field['display_value'] = $this->display_none;
95
+            } else {
96
+                $this->field['display_value'] = $this->display_text;
97
+            }
98
+        }
99
+
100
+        /**
101
+         * Sanitize value.
102
+         *
103
+         * @param mixed $val Value to sanitize.
104
+         *
105
+         * @return float|int
106
+         */
107
+        private function clean_val( $val ) {
108
+            if ( is_float( $val ) ) {
109
+                $clear_var = floatval( $val );
110
+            } else {
111
+                $clear_var = intval( $val );
112
+            }
113
+
114
+            return $clear_var;
115
+        }
116
+
117
+        /**
118
+         * Clean default values.
119
+         *
120
+         * @param mixed $val Default values.
121
+         *
122
+         * @return float|int
123
+         */
124
+        private function clean_default( $val ) {
125
+            if ( empty( $val ) && ! empty( $this->field['default'] ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
126
+                $val = $this->clean_val( $this->field['default'] );
127
+            }
128
+
129
+            if ( empty( $val ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
130
+                $val = $this->clean_val( $this->field['min'] );
131
+            }
132
+
133
+            if ( empty( $val ) ) {
134
+                $val = 0;
135
+            }
136
+
137
+            // Extra Validation.
138
+            if ( $val < $this->field['min'] ) {
139
+                $val = $this->clean_val( $this->field['min'] );
140
+            } elseif ( $val > $this->field['max'] ) {
141
+                $val = $this->clean_val( $this->field['max'] );
142
+            }
143
+
144
+            return $val;
145
+        }
146
+
147
+        /**
148
+         * Sanitize default array.
149
+         *
150
+         * @param array $val Defaults.
151
+         *
152
+         * @return array
153
+         */
154
+        private function clean_default_array( array $val ): array {
155
+            $one = $this->value[1];
156
+            $two = $this->value[2];
157
+
158
+            if ( empty( $one ) && ! empty( $this->field['default'][1] ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
159
+                $one = $this->clean_val( $this->field['default'][1] );
160
+            }
161
+
162
+            if ( empty( $one ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
163
+                $one = $this->clean_val( $this->field['min'] );
164
+            }
165
+
166
+            if ( empty( $one ) ) {
167
+                $one = 0;
168
+            }
169
+
170
+            if ( empty( $two ) && ! empty( $this->field['default'][2] ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
171
+                $two = $this->clean_val( $this->field['default'][1] + 1 );
172
+            }
173
+
174
+            if ( empty( $two ) && $this->clean_val( $this->field['min'] ) >= 1 ) {
175
+                $two = $this->clean_val( $this->field['default'][1] + 1 );
176
+            }
177
+
178
+            if ( empty( $two ) ) {
179
+                $two = $this->field['default'][1] + 1;
180
+            }
181
+
182
+            $val[0] = $one;
183
+            $val[1] = $two;
184
+
185
+            return $val;
186
+        }
187
+
188
+        /**
189
+         * Clean the field data to the fields defaults given the parameters.
190
+         *
191
+         * @since Redux_Framework 3.1.8
192
+         */
193
+        private function clean() {
194
+
195
+            // Set min to 0 if no value is set.
196
+            $this->field['min'] = empty( $this->field['min'] ) ? 0 : $this->clean_val( $this->field['min'] );
197
+
198
+            // Set max to min + 1 if empty.
199
+            $this->field['max'] = empty( $this->field['max'] ) ? $this->field['min'] + 1 : $this->clean_val( $this->field['max'] );
200
+
201
+            // Set step to 1 if step is empty ot step > max.
202
+            $this->field['step'] = empty( $this->field['step'] ) || $this->field['step'] > $this->field['max'] ? 1 : $this->clean_val( $this->field['step'] );
203
+
204
+            if ( 2 === $this->field['handles'] ) {
205
+                if ( ! is_array( $this->value ) ) {
206
+                    $this->value = array();
207
+
208
+                    $this->value[1] = 0;
209
+                    $this->value[2] = 1;
210
+                }
211
+
212
+                $this->value = $this->clean_default_array( $this->value );
213
+            } else {
214
+                if ( is_array( $this->value ) ) {
215
+                    $this->value = 0;
216
+                }
217
+
218
+                $this->value = $this->clean_default( $this->value );
219
+            }
220
+
221
+            // More dummy checks.
222
+            if ( ! is_array( $this->value ) && 2 === $this->field['handles'] ) {
223
+                $this->value[0] = $this->field['min'];
224
+                $this->value[1] = $this->field['min'] + 1;
225
+            }
226
+
227
+            if ( is_array( $this->value ) && 1 === $this->field['handles'] ) {
228
+                $this->value = $this->field['min'];
229
+            }
230
+        }
231
+
232
+        /**
233
+         * Enqueue Function.
234
+         * If this field requires any scripts, or css define this function and register/enqueue the scripts/css
235
+         *
236
+         * @since ReduxFramework 3.1.8
237
+         */
238
+        public function enqueue() {
239
+            $min = Redux_Functions::is_min();
240
+
241
+            wp_enqueue_style( 'select2-js' );
242
+
243
+            wp_enqueue_style(
244
+                'redux-nouislider',
245
+                Redux_Core::$url . "assets/css/vendor/nouislider$min.css",
246
+                array(),
247
+                '5.0.0'
248
+            );
249
+
250
+            wp_register_script(
251
+                'redux-nouislider',
252
+                Redux_Core::$url . 'assets/js/vendor/nouislider/redux.jquery.nouislider' . $min . '.js',
253
+                array( 'jquery' ),
254
+                '5.0.0',
255
+                true
256
+            );
257
+
258
+            wp_enqueue_script(
259
+                'redux-field-slider',
260
+                Redux_Core::$url . 'inc/fields/slider/redux-slider' . $min . '.js',
261
+                array( 'jquery', 'redux-nouislider', 'redux-js', 'select2-js' ),
262
+                $this->timestamp,
263
+                true
264
+            );
265
+
266
+            if ( $this->parent->args['dev_mode'] ) {
267
+                wp_enqueue_style(
268
+                    'redux-field-slider',
269
+                    Redux_Core::$url . 'inc/fields/slider/redux-slider.css',
270
+                    array(),
271
+                    $this->timestamp
272
+                );
273
+            }
274
+        }
275
+
276
+        /**
277
+         * Field Render Function.
278
+         * Takes the vars and outputs the HTML for the field in the settings
279
+         *
280
+         * @since ReduxFramework 0.0.4
281
+         */
282
+        public function render() {
283
+            $this->clean();
284
+
285
+            $field_id   = $this->field['id'];
286
+            $field_name = $this->field['name'] . $this->field['name_suffix'];
287
+
288
+            // Set handle number variable.
289
+            $two_handles = false;
290
+            if ( 2 === $this->field['handles'] ) {
291
+                $two_handles = true;
292
+            }
293
+
294
+            // Set default values(s).
295
+            if ( true === $two_handles ) {
296
+                $val_one = $this->value[0];
297
+                $val_two = $this->value[1];
298
+
299
+                $html  = 'data-default-one=' . $val_one . ' ';
300
+                $html .= 'data-default-two=' . $val_two . ' ';
301
+
302
+                $name_one = $field_name . '[1]';
303
+                $name_two = $field_name . '[2]';
304
+
305
+                $id_one = $field_id . '[1]';
306
+                $id_two = $field_id . '[2]';
307
+            } else {
308
+                $val_one = $this->value;
309
+                $val_two = '';
310
+
311
+                $html = 'data-default-one=' . $val_one;
312
+
313
+                $name_one = $field_name;
314
+                $name_two = '';
315
+
316
+                $id_one = $field_id;
317
+                $id_two = '';
318
+            }
319
+
320
+            $show_input  = false;
321
+            $show_label  = false;
322
+            $show_select = false;
323
+
324
+            // TEXT output.
325
+            if ( $this->display_text === $this->field['display_value'] ) {
326
+                $show_input = true;
327
+                echo '<input
328 328
 						type="text"
329 329
                         name="' . esc_attr( $name_one ) . '"
330 330
                         id="' . esc_attr( $id_one ) . '"
331 331
                         value="' . esc_attr( $val_one ) . '"
332 332
                         class="redux-slider-input redux-slider-input-one-' . esc_attr( $field_id ) . ' ' . esc_attr( $this->field['class'] ) . '"/>';
333 333
 
334
-				// LABEL output.
335
-			} elseif ( $this->display_label === $this->field['display_value'] ) {
336
-				$show_label = true;
334
+                // LABEL output.
335
+            } elseif ( $this->display_label === $this->field['display_value'] ) {
336
+                $show_label = true;
337 337
 
338
-				$label_num = $two_handles ? '-one' : '';
338
+                $label_num = $two_handles ? '-one' : '';
339 339
 
340
-				echo '<div class="redux-slider-label' . esc_attr( $label_num ) . '"
340
+                echo '<div class="redux-slider-label' . esc_attr( $label_num ) . '"
341 341
                        id="redux-slider-label-one-' . esc_attr( $field_id ) . '"
342 342
                        name="' . esc_attr( $name_one ) . '">
343 343
                   </div>';
344 344
 
345
-				// SELECT output.
346
-			} elseif ( $this->display_select === $this->field['display_value'] ) {
347
-				$show_select = true;
345
+                // SELECT output.
346
+            } elseif ( $this->display_select === $this->field['display_value'] ) {
347
+                $show_select = true;
348 348
 
349
-				if ( isset( $this->field['select2'] ) ) {
350
-					$this->field['select2'] = wp_parse_args( $this->field['select2'], $this->select2_config );
351
-				} else {
352
-					$this->field['select2'] = $this->select2_config;
353
-				}
349
+                if ( isset( $this->field['select2'] ) ) {
350
+                    $this->field['select2'] = wp_parse_args( $this->field['select2'], $this->select2_config );
351
+                } else {
352
+                    $this->field['select2'] = $this->select2_config;
353
+                }
354 354
 
355
-				$this->field['select2'] = Redux_Functions::sanitize_camel_case_array_keys( $this->field['select2'] );
355
+                $this->field['select2'] = Redux_Functions::sanitize_camel_case_array_keys( $this->field['select2'] );
356 356
 
357
-				$this->select2_data = Redux_Functions::create_data_string( $this->field['select2'] );
357
+                $this->select2_data = Redux_Functions::create_data_string( $this->field['select2'] );
358 358
 
359
-				echo '<select
359
+                echo '<select
360 360
 						class="redux-slider-select-one redux-slider-select-one-' . esc_attr( $field_id ) . ' ' . esc_attr( $this->field['class'] ) . '"
361 361
                         name="' . esc_attr( $name_one ) . '"
362 362
                         id="' . esc_attr( $id_one ) . '" ' . esc_attr( $this->select2_data ) . '></select>';
363
-			}
363
+            }
364 364
 
365
-			// DIV output.
366
-			echo '<div
365
+            // DIV output.
366
+            echo '<div
367 367
 	                class="redux-slider-container ' . esc_attr( $this->field['class'] ) . '"
368 368
 	                id="' . esc_attr( $field_id ) . '"
369 369
 	                data-id="' . esc_attr( $field_id ) . '"
@@ -377,136 +377,136 @@  discard block
 block discarded – undo
377 377
 	                data-float-mark="' . esc_attr( $this->field['float_mark'] ) . '"
378 378
 	                data-resolution="' . esc_attr( $this->field['resolution'] ) . '" ' . esc_html( $html ) . '></div>';
379 379
 
380
-			// Double slider output.
381
-			if ( true === $two_handles ) {
380
+            // Double slider output.
381
+            if ( true === $two_handles ) {
382 382
 
383
-				// TEXT.
384
-				if ( true === $show_input ) {
385
-					echo '<input
383
+                // TEXT.
384
+                if ( true === $show_input ) {
385
+                    echo '<input
386 386
 							type="text"
387 387
                             name="' . esc_attr( $name_two ) . '"
388 388
                             id="' . esc_attr( $id_two ) . '"
389 389
                             value="' . esc_attr( $val_two ) . '"
390 390
                             class="redux-slider-input redux-slider-input-two-' . esc_attr( $field_id ) . ' ' . esc_attr( $this->field['class'] ) . '"/>';
391
-				}
391
+                }
392 392
 
393
-				// LABEL.
394
-				if ( true === $show_label ) {
395
-					echo '<div
393
+                // LABEL.
394
+                if ( true === $show_label ) {
395
+                    echo '<div
396 396
 							class="redux-slider-label-two"
397 397
                             id="redux-slider-label-two-' . esc_attr( $field_id ) . '"
398 398
                             name="' . esc_attr( $name_two ) . '"></div>';
399
-				}
399
+                }
400 400
 
401
-				// SELECT.
402
-				if ( true === $show_select ) {
403
-					echo '<select
401
+                // SELECT.
402
+                if ( true === $show_select ) {
403
+                    echo '<select
404 404
 								class="redux-slider-select-two redux-slider-select-two-' . esc_attr( $field_id ) . ' ' . esc_attr( $this->field['class'] ) . '"
405 405
                                 name="' . esc_attr( $name_two ) . '"
406 406
                                 id="' . esc_attr( $id_two ) . '" ' . esc_attr( $this->select2_data ) . '></select>';
407
-				}
408
-			}
407
+                }
408
+            }
409 409
 
410
-			// NO output (input hidden).
411
-			if ( $this->display_none === $this->field['display_value'] || $this->display_label === $this->field['display_value'] ) {
412
-				echo '<input
410
+            // NO output (input hidden).
411
+            if ( $this->display_none === $this->field['display_value'] || $this->display_label === $this->field['display_value'] ) {
412
+                echo '<input
413 413
 							type="hidden"
414 414
 	                        class="redux-slider-value-one-' . esc_attr( $field_id ) . ' ' . esc_attr( $this->field['class'] ) . '"
415 415
 	                        name="' . esc_attr( $name_one ) . '"
416 416
 	                        id="' . esc_attr( $id_one ) . '"
417 417
 	                        value="' . esc_attr( $val_one ) . '"/>';
418 418
 
419
-				// double slider hidden output.
420
-				if ( true === $two_handles ) {
421
-					echo '<input
419
+                // double slider hidden output.
420
+                if ( true === $two_handles ) {
421
+                    echo '<input
422 422
 								type="hidden"
423 423
 	                            class="redux-slider-value-two-' . esc_attr( $field_id ) . ' ' . esc_attr( $this->field['class'] ) . '"
424 424
 	                            name="' . esc_attr( $name_two ) . '"
425 425
 	                            id="' . esc_attr( $id_two ) . '"
426 426
 	                            value="' . esc_attr( $val_two ) . '"/>';
427
-				}
428
-			}
429
-		}
430
-
431
-		/**
432
-		 * CSS/compiler output.
433
-		 *
434
-		 * @param string|null|array $style CSS styles.
435
-		 */
436
-		public function output( $style = '' ) {
437
-			if ( ! empty( $this->value ) ) {
438
-				if ( ! empty( $this->field['output'] ) && is_array( $this->field['output'] ) ) {
439
-					$css                      = $this->parse_css( $this->value, $this->field['output'] );
440
-					$this->parent->outputCSS .= esc_attr( $css );
441
-				}
442
-
443
-				if ( ! empty( $this->field['compiler'] ) && is_array( $this->field['compiler'] ) ) {
444
-					$css                        = $this->parse_css( $this->value, $this->field['compiler'] );
445
-					$this->parent->compilerCSS .= esc_attr( $css );
446
-				}
447
-			}
448
-		}
449
-
450
-		/**
451
-		 * Compile CSS data for output.
452
-		 *
453
-		 * @param mixed $value Value.
454
-		 * @param mixed $output .
455
-		 *
456
-		 * @return string
457
-		 */
458
-		private function parse_css( $value, $output ): string {
459
-			// No notices.
460
-			$css = '';
461
-
462
-			$unit = $this->field['output_unit'] ?? 'px';
463
-
464
-			// Must be an array.
465
-			if ( is_array( $output ) ) {
466
-				if ( is_array( $value ) ) {
467
-					foreach ( $output as $idx => $arr ) {
468
-
469
-						if ( is_array( $arr ) ) {
470
-							foreach ( $arr as $selector => $mode ) {
471
-								if ( '' !== $mode && '' !== $selector ) {
472
-									$css .= $selector . '{' . $mode . ':' . $value[ $idx ] . $unit . ';}';
473
-								}
474
-							}
475
-						}
476
-					}
477
-				} else {
478
-					foreach ( $output as $selector => $mode ) {
479
-						if ( '' !== $mode && '' !== $selector ) {
480
-							$css .= $selector . '{' . $mode . ':' . $value . $unit . ';}';
481
-						}
482
-					}
483
-				}
484
-			}
485
-
486
-			return $css;
487
-		}
488
-
489
-		/**
490
-		 * Generate CSS style (unused, but needed).
491
-		 *
492
-		 * @param string $data Field data.
493
-		 *
494
-		 * @return string
495
-		 */
496
-		public function css_style( $data ): string {
497
-			return '';
498
-		}
499
-
500
-		/**
501
-		 * Enable output_variables to be generated.
502
-		 *
503
-		 * @since       4.0.3
504
-		 * @return void
505
-		 */
506
-		public function output_variables() {
507
-			// No code needed, just defining the method is enough.
508
-		}
509
-	}
427
+                }
428
+            }
429
+        }
430
+
431
+        /**
432
+         * CSS/compiler output.
433
+         *
434
+         * @param string|null|array $style CSS styles.
435
+         */
436
+        public function output( $style = '' ) {
437
+            if ( ! empty( $this->value ) ) {
438
+                if ( ! empty( $this->field['output'] ) && is_array( $this->field['output'] ) ) {
439
+                    $css                      = $this->parse_css( $this->value, $this->field['output'] );
440
+                    $this->parent->outputCSS .= esc_attr( $css );
441
+                }
442
+
443
+                if ( ! empty( $this->field['compiler'] ) && is_array( $this->field['compiler'] ) ) {
444
+                    $css                        = $this->parse_css( $this->value, $this->field['compiler'] );
445
+                    $this->parent->compilerCSS .= esc_attr( $css );
446
+                }
447
+            }
448
+        }
449
+
450
+        /**
451
+         * Compile CSS data for output.
452
+         *
453
+         * @param mixed $value Value.
454
+         * @param mixed $output .
455
+         *
456
+         * @return string
457
+         */
458
+        private function parse_css( $value, $output ): string {
459
+            // No notices.
460
+            $css = '';
461
+
462
+            $unit = $this->field['output_unit'] ?? 'px';
463
+
464
+            // Must be an array.
465
+            if ( is_array( $output ) ) {
466
+                if ( is_array( $value ) ) {
467
+                    foreach ( $output as $idx => $arr ) {
468
+
469
+                        if ( is_array( $arr ) ) {
470
+                            foreach ( $arr as $selector => $mode ) {
471
+                                if ( '' !== $mode && '' !== $selector ) {
472
+                                    $css .= $selector . '{' . $mode . ':' . $value[ $idx ] . $unit . ';}';
473
+                                }
474
+                            }
475
+                        }
476
+                    }
477
+                } else {
478
+                    foreach ( $output as $selector => $mode ) {
479
+                        if ( '' !== $mode && '' !== $selector ) {
480
+                            $css .= $selector . '{' . $mode . ':' . $value . $unit . ';}';
481
+                        }
482
+                    }
483
+                }
484
+            }
485
+
486
+            return $css;
487
+        }
488
+
489
+        /**
490
+         * Generate CSS style (unused, but needed).
491
+         *
492
+         * @param string $data Field data.
493
+         *
494
+         * @return string
495
+         */
496
+        public function css_style( $data ): string {
497
+            return '';
498
+        }
499
+
500
+        /**
501
+         * Enable output_variables to be generated.
502
+         *
503
+         * @since       4.0.3
504
+         * @return void
505
+         */
506
+        public function output_variables() {
507
+            // No code needed, just defining the method is enough.
508
+        }
509
+    }
510 510
 }
511 511
 
512 512
 class_alias( 'Redux_Slider', 'ReduxFramework_Slider' );
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -469,7 +469,7 @@
 block discarded – undo
469 469
 						if ( is_array( $arr ) ) {
470 470
 							foreach ( $arr as $selector => $mode ) {
471 471
 								if ( '' !== $mode && '' !== $selector ) {
472
-									$css .= $selector . '{' . $mode . ':' . $value[ $idx ] . $unit . ';}';
472
+									$css .= $selector . '{' . $mode . ':' . $value[$idx] . $unit . ';}';
473 473
 								}
474 474
 							}
475 475
 						}
Please login to merge, or discard this patch.
redux-core/inc/fields/typography/class-redux-typography.php 2 patches
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -286,7 +286,7 @@  discard block
 block discarded – undo
286 286
 				}
287 287
 
288 288
 				// Is selected font a Google font.
289
-				if ( isset( Redux_Core::$fonts['google'][ $font_family[0] ] ) ) {
289
+				if ( isset( Redux_Core::$fonts['google'][$font_family[0]] ) ) {
290 290
 					$is_google_font = '1';
291 291
 				}
292 292
 
@@ -763,8 +763,8 @@  discard block
 block discarded – undo
763 763
 				$style = '';
764 764
 				if ( isset( $this->field['preview']['always_display'] ) ) {
765 765
 					if ( true === filter_var( $this->field['preview']['always_display'], FILTER_VALIDATE_BOOLEAN ) ) {
766
-						if ( true === (bool) $is_google_font ) {
767
-							$this->typography_preview[ $font_family[0] ] = array(
766
+						if ( true === ( bool ) $is_google_font ) {
767
+							$this->typography_preview[$font_family[0]] = array(
768 768
 								'font-style' => array( $this->value['font-weight'] . $this->value['font-style'] ),
769 769
 								'subset'     => array( $this->value['subsets'] ),
770 770
 							);
@@ -1220,7 +1220,7 @@  discard block
 block discarded – undo
1220 1220
 				}
1221 1221
 			}
1222 1222
 
1223
-			$this->set_google_fonts( (array) $font );
1223
+			$this->set_google_fonts( ( array ) $font );
1224 1224
 		}
1225 1225
 
1226 1226
 		/**
@@ -1249,7 +1249,7 @@  discard block
 block discarded – undo
1249 1249
 					$arr = array();
1250 1250
 					foreach ( $lc_fonts as $key => $value ) {
1251 1251
 						$key         = str_replace( ', ', ',', $key );
1252
-						$arr[ $key ] = $value;
1252
+						$arr[$key] = $value;
1253 1253
 					}
1254 1254
 
1255 1255
 					if ( is_array( $this->field['custom_fonts'] ) ) {
@@ -1257,7 +1257,7 @@  discard block
 block discarded – undo
1257 1257
 
1258 1258
 						foreach ( $lc_fonts as $font_arr ) {
1259 1259
 							foreach ( $font_arr as $key => $value ) {
1260
-								$arr[ Redux_Core::strtolower( $key ) ] = $key;
1260
+								$arr[Redux_Core::strtolower( $key )] = $key;
1261 1261
 							}
1262 1262
 						}
1263 1263
 					}
@@ -1284,16 +1284,16 @@  discard block
 block discarded – undo
1284 1284
 						$font['font-family'] = str_replace( ' ', '+', $font['font-family'] );
1285 1285
 
1286 1286
 						// Push data to parent typography variable.
1287
-						if ( empty( Redux_Core::$typography[ $font['font-family'] ] ) ) {
1288
-							Redux_Core::$typography[ $font['font-family'] ] = array();
1287
+						if ( empty( Redux_Core::$typography[$font['font-family']] ) ) {
1288
+							Redux_Core::$typography[$font['font-family']] = array();
1289 1289
 						}
1290 1290
 
1291 1291
 						if ( isset( $this->field['all-styles'] ) || isset( $this->field['all-subsets'] ) ) {
1292 1292
 							if ( empty( $font['font-options'] ) ) {
1293 1293
 								$this->get_google_array();
1294 1294
 
1295
-								if ( isset( Redux_Core::$google_array ) && ! empty( Redux_Core::$google_array ) && isset( Redux_Core::$google_array[ $family ] ) ) {
1296
-									$font['font-options'] = Redux_Core::$google_array[ $family ];
1295
+								if ( isset( Redux_Core::$google_array ) && ! empty( Redux_Core::$google_array ) && isset( Redux_Core::$google_array[$family] ) ) {
1296
+									$font['font-options'] = Redux_Core::$google_array[$family];
1297 1297
 								}
1298 1298
 							} else {
1299 1299
 								$font['font-options'] = json_decode( $font['font-options'], true );
@@ -1302,10 +1302,10 @@  discard block
 block discarded – undo
1302 1302
 
1303 1303
 						if ( isset( $font['font-options'] ) && ! empty( $font['font-options'] ) && isset( $this->field['all-styles'] ) && filter_var( $this->field['all-styles'], FILTER_VALIDATE_BOOLEAN ) ) {
1304 1304
 							if ( ! empty( $font['font-options']['variants'] ) ) {
1305
-								if ( ! isset( Redux_Core::$typography[ $font['font-family'] ]['all-styles'] ) || empty( Redux_Core::$typography[ $font['font-family'] ]['all-styles'] ) ) {
1306
-									Redux_Core::$typography[ $font['font-family'] ]['all-styles'] = array();
1305
+								if ( ! isset( Redux_Core::$typography[$font['font-family']]['all-styles'] ) || empty( Redux_Core::$typography[$font['font-family']]['all-styles'] ) ) {
1306
+									Redux_Core::$typography[$font['font-family']]['all-styles'] = array();
1307 1307
 									foreach ( $font['font-options']['variants'] as $variant ) {
1308
-										Redux_Core::$typography[ $font['font-family'] ]['all-styles'][] = $variant['id'];
1308
+										Redux_Core::$typography[$font['font-family']]['all-styles'][] = $variant['id'];
1309 1309
 									}
1310 1310
 								}
1311 1311
 							}
@@ -1313,10 +1313,10 @@  discard block
 block discarded – undo
1313 1313
 
1314 1314
 						if ( isset( $font['font-options'] ) && ! empty( $font['font-options'] ) && isset( $this->field['all-subsets'] ) && $this->field['all-styles'] ) {
1315 1315
 							if ( ! empty( $font['font-options']['subsets'] ) ) {
1316
-								if ( ! isset( Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] ) || empty( Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] ) ) {
1317
-									Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] = array();
1316
+								if ( ! isset( Redux_Core::$typography[$font['font-family']]['all-subsets'] ) || empty( Redux_Core::$typography[$font['font-family']]['all-subsets'] ) ) {
1317
+									Redux_Core::$typography[$font['font-family']]['all-subsets'] = array();
1318 1318
 									foreach ( $font['font-options']['subsets'] as $variant ) {
1319
-										Redux_Core::$typography[ $font['font-family'] ]['all-subsets'][] = $variant['id'];
1319
+										Redux_Core::$typography[$font['font-family']]['all-subsets'][] = $variant['id'];
1320 1320
 									}
1321 1321
 								}
1322 1322
 							}
@@ -1325,7 +1325,7 @@  discard block
 block discarded – undo
1325 1325
 						$style = '';
1326 1326
 
1327 1327
 						if ( ! empty( $font['font-weight'] ) ) {
1328
-							if ( empty( Redux_Core::$typography[ $font['font-family'] ]['font-weight'] ) || ! in_array( $font['font-weight'], Redux_Core::$typography[ $font['font-family'] ]['font-weight'], true ) ) {
1328
+							if ( empty( Redux_Core::$typography[$font['font-family']]['font-weight'] ) || ! in_array( $font['font-weight'], Redux_Core::$typography[$font['font-family']]['font-weight'], true ) ) {
1329 1329
 								$style = $font['font-weight'];
1330 1330
 							}
1331 1331
 
@@ -1333,14 +1333,14 @@  discard block
 block discarded – undo
1333 1333
 								$style .= $font['font-style'];
1334 1334
 							}
1335 1335
 
1336
-							if ( empty( Redux_Core::$typography[ $font['font-family'] ]['font-style'] ) || ! in_array( $style, Redux_Core::$typography[ $font['font-family'] ]['font-style'], true ) ) {
1337
-								Redux_Core::$typography[ $font['font-family'] ]['font-style'][] = $style;
1336
+							if ( empty( Redux_Core::$typography[$font['font-family']]['font-style'] ) || ! in_array( $style, Redux_Core::$typography[$font['font-family']]['font-style'], true ) ) {
1337
+								Redux_Core::$typography[$font['font-family']]['font-style'][] = $style;
1338 1338
 							}
1339 1339
 						}
1340 1340
 
1341 1341
 						if ( ! empty( $font['subsets'] ) ) {
1342
-							if ( empty( Redux_Core::$typography[ $font['font-family'] ]['subset'] ) || ! in_array( $font['subsets'], Redux_Core::$typography[ $font['font-family'] ]['subset'], true ) ) {
1343
-								Redux_Core::$typography[ $font['font-family'] ]['subset'][] = $font['subsets'];
1342
+							if ( empty( Redux_Core::$typography[$font['font-family']]['subset'] ) || ! in_array( $font['subsets'], Redux_Core::$typography[$font['font-family']]['subset'], true ) ) {
1343
+								Redux_Core::$typography[$font['font-family']]['subset'][] = $font['subsets'];
1344 1344
 							}
1345 1345
 						}
1346 1346
 					}
Please login to merge, or discard this patch.
Indentation   +1350 added lines, -1350 removed lines patch added patch discarded remove patch
@@ -12,357 +12,357 @@  discard block
 block discarded – undo
12 12
 
13 13
 if ( ! class_exists( 'Redux_Typography', false ) ) {
14 14
 
15
-	/**
16
-	 * Class Redux_Typography
17
-	 */
18
-	class Redux_Typography extends Redux_Field {
19
-
20
-		/**
21
-		 * Array of data for typography preview.
22
-		 *
23
-		 * @var array
24
-		 */
25
-		private $typography_preview = array();
26
-
27
-		/**
28
-		 *  Standard font array.
29
-		 *
30
-		 * @var array $std_fonts
31
-		 */
32
-		private $std_fonts = array(
33
-			'Arial, Helvetica, sans-serif'            => 'Arial, Helvetica, sans-serif',
34
-			'\'Arial Black\', Gadget, sans-serif'     => '\'Arial Black\', Gadget, sans-serif',
35
-			'\'Bookman Old Style\', serif'            => '\'Bookman Old Style\', serif',
36
-			'\'Comic Sans MS\', cursive'              => '\'Comic Sans MS\', cursive',
37
-			'Courier, monospace'                      => 'Courier, monospace',
38
-			'Garamond, serif'                         => 'Garamond, serif',
39
-			'Georgia, serif'                          => 'Georgia, serif',
40
-			'Impact, Charcoal, sans-serif'            => 'Impact, Charcoal, sans-serif',
41
-			'\'Lucida Console\', Monaco, monospace'   => '\'Lucida Console\', Monaco, monospace',
42
-			'\'Lucida Sans Unicode\', \'Lucida Grande\', sans-serif' => '\'Lucida Sans Unicode\', \'Lucida Grande\', sans-serif',
43
-			'\'MS Sans Serif\', Geneva, sans-serif'   => '\'MS Sans Serif\', Geneva, sans-serif',
44
-			'\'MS Serif\', \'New York\', sans-serif'  => '\'MS Serif\', \'New York\', sans-serif',
45
-			'\'Palatino Linotype\', \'Book Antiqua\', Palatino, serif' => '\'Palatino Linotype\', \'Book Antiqua\', Palatino, serif',
46
-			'Tahoma,Geneva, sans-serif'               => 'Tahoma, Geneva, sans-serif',
47
-			'\'Times New Roman\', Times,serif'        => '\'Times New Roman\', Times, serif',
48
-			'\'Trebuchet MS\', Helvetica, sans-serif' => '\'Trebuchet MS\', Helvetica, sans-serif',
49
-			'Verdana, Geneva, sans-serif'             => 'Verdana, Geneva, sans-serif',
50
-		);
51
-
52
-		/**
53
-		 * Default font weights.
54
-		 *
55
-		 * @var string[]
56
-		 */
57
-		private $default_font_weights = array(
58
-			'400'       => 'Normal 400',
59
-			'700'       => 'Bold 700',
60
-			'400italic' => 'Normal 400 Italic',
61
-			'700italic' => 'Bold 700 Italic',
62
-		);
63
-
64
-		/**
65
-		 * User font array.
66
-		 *
67
-		 * @var bool $user_fonts
68
-		 */
69
-		private $user_fonts = true;
70
-
71
-		/**
72
-		 * Redux_Field constructor.
73
-		 *
74
-		 * @param array  $field  Field array.
75
-		 * @param string $value  Field values.
76
-		 * @param null   $redux  ReduxFramework object pointer.
77
-		 *
78
-		 * @throws ReflectionException Exception.
79
-		 */
80
-		public function __construct( $field = array(), $value = null, $redux = null ) { // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod
81
-			parent::__construct( $field, $value, $redux );
82
-
83
-			$this->parent = $redux;
84
-			$this->field  = $field;
85
-			$this->value  = $value;
86
-
87
-			$this->set_defaults();
88
-
89
-			$path_info = Redux_Helpers::path_info( __FILE__ );
90
-			$this->dir = trailingslashit( dirname( $path_info['real_path'] ) );
91
-			$this->url = trailingslashit( dirname( $path_info['url'] ) );
92
-
93
-			$this->timestamp = Redux_Core::$version;
94
-			if ( $redux->args['dev_mode'] ) {
95
-				$this->timestamp .= '.' . time();
96
-			}
97
-		}
98
-
99
-		/**
100
-		 * Sets default values for field.
101
-		 */
102
-		public function set_defaults() {
103
-			// Shim out old arg to new.
104
-			if ( isset( $this->field['all_styles'] ) && ! empty( $this->field['all_styles'] ) ) {
105
-				$this->field['all-styles'] = $this->field['all_styles'];
106
-				unset( $this->field['all_styles'] );
107
-			}
108
-
109
-			$defaults = array(
110
-				'font-family'             => true,
111
-				'font-size'               => true,
112
-				'font-weight'             => true,
113
-				'font-style'              => true,
114
-				'font-backup'             => false,
115
-				'subsets'                 => true,
116
-				'custom_fonts'            => true,
117
-				'text-align'              => true,
118
-				'text-transform'          => false,
119
-				'font-variant'            => false,
120
-				'text-decoration'         => false,
121
-				'color'                   => true,
122
-				'preview'                 => true,
123
-				'line-height'             => true,
124
-				'multi'                   => array(
125
-					'subsets' => false,
126
-					'weight'  => false,
127
-				),
128
-				'word-spacing'            => false,
129
-				'letter-spacing'          => false,
130
-				'google'                  => true,
131
-				'font_family_clear'       => true,
132
-				'allow_empty_line_height' => false,
133
-				'margin-top'              => false,
134
-				'margin-bottom'           => false,
135
-				'text-shadow'             => false,
136
-				'word-spacing-unit'       => '',
137
-				'letter-spacing-unit'     => '',
138
-				'font-size-unit'          => '',
139
-				'margin-top-unit'         => '',
140
-				'margin-bottom-unit'      => '',
141
-			);
142
-
143
-			$this->field = wp_parse_args( $this->field, $defaults );
144
-
145
-			if ( isset( $this->field['color_alpha'] ) ) {
146
-				if ( is_array( $this->field['color_alpha'] ) ) {
147
-					$this->field['color_alpha']['color']        = $this->field['color_alpha']['color'] ?? false;
148
-					$this->field['color_alpha']['shadow-color'] = $this->field['color_alpha']['shadow-color'] ?? false;
149
-				} else {
150
-					$mode                                       = $this->field['color_alpha'];
151
-					$this->field['color_alpha']                 = array();
152
-					$this->field['color_alpha']['color']        = $mode;
153
-					$this->field['color_alpha']['shadow-color'] = $mode;
154
-				}
155
-			} else {
156
-				$this->field['color_alpha']['color']        = false;
157
-				$this->field['color_alpha']['shadow-color'] = false;
158
-			}
159
-
160
-			// Set value defaults.
161
-			$defaults = array(
162
-				'font-family'       => '',
163
-				'font-options'      => '',
164
-				'font-backup'       => '',
165
-				'text-align'        => '',
166
-				'text-transform'    => '',
167
-				'font-variant'      => '',
168
-				'text-decoration'   => '',
169
-				'line-height'       => '',
170
-				'word-spacing'      => '',
171
-				'letter-spacing'    => '',
172
-				'subsets'           => '',
173
-				'google'            => false,
174
-				'font-script'       => '',
175
-				'font-weight'       => '',
176
-				'font-style'        => '',
177
-				'color'             => '',
178
-				'font-size'         => '',
179
-				'margin-top'        => '',
180
-				'margin-bottom'     => '',
181
-				'shadow-color'      => '#000000',
182
-				'shadow-horizontal' => '1',
183
-				'shadow-vertical'   => '1',
184
-				'shadow-blur'       => '4',
185
-			);
186
-
187
-			$this->value = wp_parse_args( $this->value, $defaults );
188
-
189
-			if ( empty( $this->field['units'] ) || ! in_array( $this->field['units'], Redux_Helpers::$array_units, true ) ) {
190
-				$this->field['units'] = 'px';
191
-			}
192
-
193
-			// Get the Google array.
194
-			$this->get_google_array();
195
-
196
-			if ( empty( $this->field['fonts'] ) ) {
197
-				$this->user_fonts     = false;
198
-				$this->field['fonts'] = $this->std_fonts;
199
-			}
200
-
201
-			$this->field['weights'] = $this->field['weights'] ?? $this->default_font_weights;
202
-
203
-			// Localize std fonts.
204
-			$this->localize_std_fonts();
205
-		}
206
-
207
-		/**
208
-		 * Localize font array
209
-		 *
210
-		 * @param array  $field Field array.
211
-		 * @param string $value Value.
212
-		 *
213
-		 * @return array
214
-		 */
215
-		public function localize( array $field, string $value = '' ): array {
216
-			$params = array();
217
-
218
-			if ( true === $this->user_fonts && ! empty( $this->field['fonts'] ) ) {
219
-				$params['std_font'] = $this->field['fonts'];
220
-			}
221
-
222
-			return $params;
223
-		}
224
-
225
-		/**
226
-		 * Field Render Function.
227
-		 * Takes the vars and outputs the HTML for the field in the settings
228
-		 *
229
-		 * @since ReduxFramework 1.0.0
230
-		 */
231
-		public function render() {
232
-			// Since fonts declared is CSS (@font-face) are not rendered in the preview,
233
-			// they can be declared in a CSS file and passed here, so they DO display in
234
-			// font preview.  Do NOT pass style.css in your theme, as that will mess up
235
-			// admin page styling.  It's recommended to pass a CSS file with ONLY font
236
-			// declarations.
237
-			// If field is set and not blank, then enqueue field.
238
-			if ( isset( $this->field['ext-font-css'] ) && '' !== $this->field['ext-font-css'] ) {
239
-				wp_enqueue_style( 'redux-external-fonts', $this->field['ext-font-css'], array(), $this->timestamp );
240
-			}
241
-
242
-			if ( empty( $this->field['units'] ) && ! empty( $this->field['default']['units'] ) ) {
243
-				$this->field['units'] = $this->field['default']['units'];
244
-			}
245
-
246
-			$unit = $this->field['units'];
247
-
248
-			echo '<div id="' . esc_attr( $this->field['id'] ) . '" class="redux-typography-container" data-id="' . esc_attr( $this->field['id'] ) . '" data-units="' . esc_attr( $unit ) . '">';
249
-
250
-			$this->select2_config['allowClear'] = true;
251
-
252
-			if ( isset( $this->field['select2'] ) ) {
253
-				$this->field['select2'] = wp_parse_args( $this->field['select2'], $this->select2_config );
254
-			} else {
255
-				$this->field['select2'] = $this->select2_config;
256
-			}
257
-
258
-			$this->field['select2'] = Redux_Functions::sanitize_camel_case_array_keys( $this->field['select2'] );
259
-
260
-			$select2_data = Redux_Functions::create_data_string( $this->field['select2'] );
261
-
262
-			$google_set     = false;
263
-			$is_google_font = '0';
264
-
265
-			// If no fontFamily array exists, create one and set array 0
266
-			// with font value.
267
-			if ( ! isset( $font_family ) ) {
268
-				$font_family    = array();
269
-				$font_family[0] = $this->value['font-family'];
270
-				$font_family[1] = '';
271
-			}
272
-
273
-			/* Font Family */
274
-			if ( true === $this->field['font-family'] ) {
275
-				if ( filter_var( $this->value['google'], FILTER_VALIDATE_BOOLEAN ) ) {
276
-
277
-					// Divide and conquer.
278
-					$font_family = explode( ', ', $this->value['font-family'], 2 );
279
-
280
-					// If array 0 is empty and array 1 is not.
281
-					if ( empty( $font_family[0] ) && ! empty( $font_family[1] ) ) {
282
-
283
-						// Make array 0 = array 1.
284
-						$font_family[0] = $font_family[1];
285
-					}
286
-				}
287
-
288
-				// Is selected font a Google font.
289
-				if ( isset( Redux_Core::$fonts['google'][ $font_family[0] ] ) ) {
290
-					$is_google_font = '1';
291
-				}
292
-
293
-				// If not a Google font, show all font families.
294
-				if ( '1' !== $is_google_font ) {
295
-					$font_family[0] = $this->value['font-family'];
296
-				}
297
-
298
-				$user_fonts = '0';
299
-				if ( true === $this->user_fonts ) {
300
-					$user_fonts = '1';
301
-				}
302
-
303
-				echo '<input
15
+    /**
16
+     * Class Redux_Typography
17
+     */
18
+    class Redux_Typography extends Redux_Field {
19
+
20
+        /**
21
+         * Array of data for typography preview.
22
+         *
23
+         * @var array
24
+         */
25
+        private $typography_preview = array();
26
+
27
+        /**
28
+         *  Standard font array.
29
+         *
30
+         * @var array $std_fonts
31
+         */
32
+        private $std_fonts = array(
33
+            'Arial, Helvetica, sans-serif'            => 'Arial, Helvetica, sans-serif',
34
+            '\'Arial Black\', Gadget, sans-serif'     => '\'Arial Black\', Gadget, sans-serif',
35
+            '\'Bookman Old Style\', serif'            => '\'Bookman Old Style\', serif',
36
+            '\'Comic Sans MS\', cursive'              => '\'Comic Sans MS\', cursive',
37
+            'Courier, monospace'                      => 'Courier, monospace',
38
+            'Garamond, serif'                         => 'Garamond, serif',
39
+            'Georgia, serif'                          => 'Georgia, serif',
40
+            'Impact, Charcoal, sans-serif'            => 'Impact, Charcoal, sans-serif',
41
+            '\'Lucida Console\', Monaco, monospace'   => '\'Lucida Console\', Monaco, monospace',
42
+            '\'Lucida Sans Unicode\', \'Lucida Grande\', sans-serif' => '\'Lucida Sans Unicode\', \'Lucida Grande\', sans-serif',
43
+            '\'MS Sans Serif\', Geneva, sans-serif'   => '\'MS Sans Serif\', Geneva, sans-serif',
44
+            '\'MS Serif\', \'New York\', sans-serif'  => '\'MS Serif\', \'New York\', sans-serif',
45
+            '\'Palatino Linotype\', \'Book Antiqua\', Palatino, serif' => '\'Palatino Linotype\', \'Book Antiqua\', Palatino, serif',
46
+            'Tahoma,Geneva, sans-serif'               => 'Tahoma, Geneva, sans-serif',
47
+            '\'Times New Roman\', Times,serif'        => '\'Times New Roman\', Times, serif',
48
+            '\'Trebuchet MS\', Helvetica, sans-serif' => '\'Trebuchet MS\', Helvetica, sans-serif',
49
+            'Verdana, Geneva, sans-serif'             => 'Verdana, Geneva, sans-serif',
50
+        );
51
+
52
+        /**
53
+         * Default font weights.
54
+         *
55
+         * @var string[]
56
+         */
57
+        private $default_font_weights = array(
58
+            '400'       => 'Normal 400',
59
+            '700'       => 'Bold 700',
60
+            '400italic' => 'Normal 400 Italic',
61
+            '700italic' => 'Bold 700 Italic',
62
+        );
63
+
64
+        /**
65
+         * User font array.
66
+         *
67
+         * @var bool $user_fonts
68
+         */
69
+        private $user_fonts = true;
70
+
71
+        /**
72
+         * Redux_Field constructor.
73
+         *
74
+         * @param array  $field  Field array.
75
+         * @param string $value  Field values.
76
+         * @param null   $redux  ReduxFramework object pointer.
77
+         *
78
+         * @throws ReflectionException Exception.
79
+         */
80
+        public function __construct( $field = array(), $value = null, $redux = null ) { // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod
81
+            parent::__construct( $field, $value, $redux );
82
+
83
+            $this->parent = $redux;
84
+            $this->field  = $field;
85
+            $this->value  = $value;
86
+
87
+            $this->set_defaults();
88
+
89
+            $path_info = Redux_Helpers::path_info( __FILE__ );
90
+            $this->dir = trailingslashit( dirname( $path_info['real_path'] ) );
91
+            $this->url = trailingslashit( dirname( $path_info['url'] ) );
92
+
93
+            $this->timestamp = Redux_Core::$version;
94
+            if ( $redux->args['dev_mode'] ) {
95
+                $this->timestamp .= '.' . time();
96
+            }
97
+        }
98
+
99
+        /**
100
+         * Sets default values for field.
101
+         */
102
+        public function set_defaults() {
103
+            // Shim out old arg to new.
104
+            if ( isset( $this->field['all_styles'] ) && ! empty( $this->field['all_styles'] ) ) {
105
+                $this->field['all-styles'] = $this->field['all_styles'];
106
+                unset( $this->field['all_styles'] );
107
+            }
108
+
109
+            $defaults = array(
110
+                'font-family'             => true,
111
+                'font-size'               => true,
112
+                'font-weight'             => true,
113
+                'font-style'              => true,
114
+                'font-backup'             => false,
115
+                'subsets'                 => true,
116
+                'custom_fonts'            => true,
117
+                'text-align'              => true,
118
+                'text-transform'          => false,
119
+                'font-variant'            => false,
120
+                'text-decoration'         => false,
121
+                'color'                   => true,
122
+                'preview'                 => true,
123
+                'line-height'             => true,
124
+                'multi'                   => array(
125
+                    'subsets' => false,
126
+                    'weight'  => false,
127
+                ),
128
+                'word-spacing'            => false,
129
+                'letter-spacing'          => false,
130
+                'google'                  => true,
131
+                'font_family_clear'       => true,
132
+                'allow_empty_line_height' => false,
133
+                'margin-top'              => false,
134
+                'margin-bottom'           => false,
135
+                'text-shadow'             => false,
136
+                'word-spacing-unit'       => '',
137
+                'letter-spacing-unit'     => '',
138
+                'font-size-unit'          => '',
139
+                'margin-top-unit'         => '',
140
+                'margin-bottom-unit'      => '',
141
+            );
142
+
143
+            $this->field = wp_parse_args( $this->field, $defaults );
144
+
145
+            if ( isset( $this->field['color_alpha'] ) ) {
146
+                if ( is_array( $this->field['color_alpha'] ) ) {
147
+                    $this->field['color_alpha']['color']        = $this->field['color_alpha']['color'] ?? false;
148
+                    $this->field['color_alpha']['shadow-color'] = $this->field['color_alpha']['shadow-color'] ?? false;
149
+                } else {
150
+                    $mode                                       = $this->field['color_alpha'];
151
+                    $this->field['color_alpha']                 = array();
152
+                    $this->field['color_alpha']['color']        = $mode;
153
+                    $this->field['color_alpha']['shadow-color'] = $mode;
154
+                }
155
+            } else {
156
+                $this->field['color_alpha']['color']        = false;
157
+                $this->field['color_alpha']['shadow-color'] = false;
158
+            }
159
+
160
+            // Set value defaults.
161
+            $defaults = array(
162
+                'font-family'       => '',
163
+                'font-options'      => '',
164
+                'font-backup'       => '',
165
+                'text-align'        => '',
166
+                'text-transform'    => '',
167
+                'font-variant'      => '',
168
+                'text-decoration'   => '',
169
+                'line-height'       => '',
170
+                'word-spacing'      => '',
171
+                'letter-spacing'    => '',
172
+                'subsets'           => '',
173
+                'google'            => false,
174
+                'font-script'       => '',
175
+                'font-weight'       => '',
176
+                'font-style'        => '',
177
+                'color'             => '',
178
+                'font-size'         => '',
179
+                'margin-top'        => '',
180
+                'margin-bottom'     => '',
181
+                'shadow-color'      => '#000000',
182
+                'shadow-horizontal' => '1',
183
+                'shadow-vertical'   => '1',
184
+                'shadow-blur'       => '4',
185
+            );
186
+
187
+            $this->value = wp_parse_args( $this->value, $defaults );
188
+
189
+            if ( empty( $this->field['units'] ) || ! in_array( $this->field['units'], Redux_Helpers::$array_units, true ) ) {
190
+                $this->field['units'] = 'px';
191
+            }
192
+
193
+            // Get the Google array.
194
+            $this->get_google_array();
195
+
196
+            if ( empty( $this->field['fonts'] ) ) {
197
+                $this->user_fonts     = false;
198
+                $this->field['fonts'] = $this->std_fonts;
199
+            }
200
+
201
+            $this->field['weights'] = $this->field['weights'] ?? $this->default_font_weights;
202
+
203
+            // Localize std fonts.
204
+            $this->localize_std_fonts();
205
+        }
206
+
207
+        /**
208
+         * Localize font array
209
+         *
210
+         * @param array  $field Field array.
211
+         * @param string $value Value.
212
+         *
213
+         * @return array
214
+         */
215
+        public function localize( array $field, string $value = '' ): array {
216
+            $params = array();
217
+
218
+            if ( true === $this->user_fonts && ! empty( $this->field['fonts'] ) ) {
219
+                $params['std_font'] = $this->field['fonts'];
220
+            }
221
+
222
+            return $params;
223
+        }
224
+
225
+        /**
226
+         * Field Render Function.
227
+         * Takes the vars and outputs the HTML for the field in the settings
228
+         *
229
+         * @since ReduxFramework 1.0.0
230
+         */
231
+        public function render() {
232
+            // Since fonts declared is CSS (@font-face) are not rendered in the preview,
233
+            // they can be declared in a CSS file and passed here, so they DO display in
234
+            // font preview.  Do NOT pass style.css in your theme, as that will mess up
235
+            // admin page styling.  It's recommended to pass a CSS file with ONLY font
236
+            // declarations.
237
+            // If field is set and not blank, then enqueue field.
238
+            if ( isset( $this->field['ext-font-css'] ) && '' !== $this->field['ext-font-css'] ) {
239
+                wp_enqueue_style( 'redux-external-fonts', $this->field['ext-font-css'], array(), $this->timestamp );
240
+            }
241
+
242
+            if ( empty( $this->field['units'] ) && ! empty( $this->field['default']['units'] ) ) {
243
+                $this->field['units'] = $this->field['default']['units'];
244
+            }
245
+
246
+            $unit = $this->field['units'];
247
+
248
+            echo '<div id="' . esc_attr( $this->field['id'] ) . '" class="redux-typography-container" data-id="' . esc_attr( $this->field['id'] ) . '" data-units="' . esc_attr( $unit ) . '">';
249
+
250
+            $this->select2_config['allowClear'] = true;
251
+
252
+            if ( isset( $this->field['select2'] ) ) {
253
+                $this->field['select2'] = wp_parse_args( $this->field['select2'], $this->select2_config );
254
+            } else {
255
+                $this->field['select2'] = $this->select2_config;
256
+            }
257
+
258
+            $this->field['select2'] = Redux_Functions::sanitize_camel_case_array_keys( $this->field['select2'] );
259
+
260
+            $select2_data = Redux_Functions::create_data_string( $this->field['select2'] );
261
+
262
+            $google_set     = false;
263
+            $is_google_font = '0';
264
+
265
+            // If no fontFamily array exists, create one and set array 0
266
+            // with font value.
267
+            if ( ! isset( $font_family ) ) {
268
+                $font_family    = array();
269
+                $font_family[0] = $this->value['font-family'];
270
+                $font_family[1] = '';
271
+            }
272
+
273
+            /* Font Family */
274
+            if ( true === $this->field['font-family'] ) {
275
+                if ( filter_var( $this->value['google'], FILTER_VALIDATE_BOOLEAN ) ) {
276
+
277
+                    // Divide and conquer.
278
+                    $font_family = explode( ', ', $this->value['font-family'], 2 );
279
+
280
+                    // If array 0 is empty and array 1 is not.
281
+                    if ( empty( $font_family[0] ) && ! empty( $font_family[1] ) ) {
282
+
283
+                        // Make array 0 = array 1.
284
+                        $font_family[0] = $font_family[1];
285
+                    }
286
+                }
287
+
288
+                // Is selected font a Google font.
289
+                if ( isset( Redux_Core::$fonts['google'][ $font_family[0] ] ) ) {
290
+                    $is_google_font = '1';
291
+                }
292
+
293
+                // If not a Google font, show all font families.
294
+                if ( '1' !== $is_google_font ) {
295
+                    $font_family[0] = $this->value['font-family'];
296
+                }
297
+
298
+                $user_fonts = '0';
299
+                if ( true === $this->user_fonts ) {
300
+                    $user_fonts = '1';
301
+                }
302
+
303
+                echo '<input
304 304
 						type="hidden"
305 305
 						class="redux-typography-font-family ' . esc_attr( $this->field['class'] ) . '"
306 306
 						data-user-fonts="' . esc_attr( $user_fonts ) . '" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[font-family]"
307 307
 						value="' . esc_attr( $this->value['font-family'] ) . '"
308 308
 						data-id="' . esc_attr( $this->field['id'] ) . '"  />';
309 309
 
310
-				echo '<input
310
+                echo '<input
311 311
 						type="hidden"
312 312
 						class="redux-typography-font-options ' . esc_attr( $this->field['class'] ) . '"
313 313
 						name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[font-options]"
314 314
 						value="' . esc_attr( $this->value['font-options'] ) . '"
315 315
 						data-id="' . esc_attr( $this->field['id'] ) . '"  />';
316 316
 
317
-				echo '<input
317
+                echo '<input
318 318
 						type="hidden"
319 319
 						class="redux-typography-google-font" value="' . esc_attr( $is_google_font ) . '"
320 320
 						id="' . esc_attr( $this->field['id'] ) . '-google-font">';
321 321
 
322
-				echo '<div class="select_wrapper typography-family" style="width: 220px; margin-right: 5px;">';
323
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-family">' . esc_html__( 'Font Family', 'redux-framework' ) . '</label>';
322
+                echo '<div class="select_wrapper typography-family" style="width: 220px; margin-right: 5px;">';
323
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-family">' . esc_html__( 'Font Family', 'redux-framework' ) . '</label>';
324 324
 
325
-				$placeholder = esc_html__( 'Font family', 'redux-framework' );
325
+                $placeholder = esc_html__( 'Font family', 'redux-framework' );
326 326
 
327
-				$new_arr                = $this->field['select2'];
328
-				$new_arr['allow-clear'] = $this->field['font_family_clear'];
329
-				$new_data               = Redux_Functions::create_data_string( $new_arr );
327
+                $new_arr                = $this->field['select2'];
328
+                $new_arr['allow-clear'] = $this->field['font_family_clear'];
329
+                $new_data               = Redux_Functions::create_data_string( $new_arr );
330 330
 
331
-				echo '<select class=" redux-typography redux-typography-family select2-container ' . esc_attr( $this->field['class'] ) . '" id="' . esc_attr( $this->field['id'] ) . '-family" data-placeholder="' . esc_attr( $placeholder ) . '" data-id="' . esc_attr( $this->field['id'] ) . '" data-value="' . esc_attr( $font_family[0] ) . '"' . esc_html( $new_data ) . '>';
331
+                echo '<select class=" redux-typography redux-typography-family select2-container ' . esc_attr( $this->field['class'] ) . '" id="' . esc_attr( $this->field['id'] ) . '-family" data-placeholder="' . esc_attr( $placeholder ) . '" data-id="' . esc_attr( $this->field['id'] ) . '" data-value="' . esc_attr( $font_family[0] ) . '"' . esc_html( $new_data ) . '>';
332 332
 
333
-				echo '</select>';
334
-				echo '</div>';
333
+                echo '</select>';
334
+                echo '</div>';
335 335
 
336
-				if ( true === $this->field['google'] ) {
336
+                if ( true === $this->field['google'] ) {
337 337
 
338
-					// Set a flag, so we know to set a header style or not.
339
-					echo '<input
338
+                    // Set a flag, so we know to set a header style or not.
339
+                    echo '<input
340 340
 							type="hidden"
341 341
 							class="redux-typography-google ' . esc_attr( $this->field['class'] ) . '"
342 342
 							id="' . esc_attr( $this->field['id'] ) . '-google" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[google]"
343 343
 							type="text" value="' . esc_attr( $this->field['google'] ) . '"
344 344
 							data-id="' . esc_attr( $this->field['id'] ) . '" />';
345 345
 
346
-					$google_set = true;
347
-				}
348
-			}
346
+                    $google_set = true;
347
+                }
348
+            }
349 349
 
350
-			/* Backup Font */
351
-			if ( true === $this->field['font-family'] && true === $this->field['google'] ) {
352
-				if ( false === $google_set ) {
353
-					// Set a flag, so we know to set a header style or not.
354
-					echo '<input
350
+            /* Backup Font */
351
+            if ( true === $this->field['font-family'] && true === $this->field['google'] ) {
352
+                if ( false === $google_set ) {
353
+                    // Set a flag, so we know to set a header style or not.
354
+                    echo '<input
355 355
 							type="hidden"
356 356
 							class="redux-typography-google ' . esc_attr( $this->field['class'] ) . '"
357 357
 							id="' . esc_attr( $this->field['id'] ) . '-google" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[google]"
358 358
 							type="text" value="' . esc_attr( $this->field['google'] ) . '"
359 359
 							data-id="' . esc_attr( $this->field['id'] ) . '"  />';
360
-				}
360
+                }
361 361
 
362
-				if ( true === $this->field['font-backup'] ) {
363
-					echo '<div class="select_wrapper typography-family-backup" style="width: 220px; margin-right: 5px;">';
364
-					echo '<label for="' . esc_attr( $this->field['id'] ) . '-family-backup">' . esc_html__( 'Backup Font Family', 'redux-framework' ) . '</label>';
365
-					echo '<select
362
+                if ( true === $this->field['font-backup'] ) {
363
+                    echo '<div class="select_wrapper typography-family-backup" style="width: 220px; margin-right: 5px;">';
364
+                    echo '<label for="' . esc_attr( $this->field['id'] ) . '-family-backup">' . esc_html__( 'Backup Font Family', 'redux-framework' ) . '</label>';
365
+                    echo '<select
366 366
 							data-placeholder="' . esc_html__( 'Backup Font Family', 'redux-framework' ) . '"
367 367
 							name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[font-backup]"
368 368
 							class="redux-typography redux-typography-family-backup ' . esc_attr( $this->field['class'] ) . '"
@@ -370,62 +370,62 @@  discard block
 block discarded – undo
370 370
 							data-id="' . esc_attr( $this->field['id'] ) . '"
371 371
 							data-value="' . esc_attr( $this->value['font-backup'] ) . '"' . esc_attr( $select2_data ) . '>';
372 372
 
373
-					echo '<option data-google="false" data-details="" value=""></option>';
373
+                    echo '<option data-google="false" data-details="" value=""></option>';
374 374
 
375
-					foreach ( $this->field['fonts'] as $i => $family ) {
376
-						echo '<option data-google="true" value="' . esc_attr( $i ) . '" ' . selected( $this->value['font-backup'], $i, false ) . '>' . esc_html( $family ) . '</option>';
377
-					}
375
+                    foreach ( $this->field['fonts'] as $i => $family ) {
376
+                        echo '<option data-google="true" value="' . esc_attr( $i ) . '" ' . selected( $this->value['font-backup'], $i, false ) . '>' . esc_html( $family ) . '</option>';
377
+                    }
378 378
 
379
-					echo '</select></div>';
380
-				}
381
-			}
379
+                    echo '</select></div>';
380
+                }
381
+            }
382 382
 
383
-			/* Font Style/Weight */
384
-			if ( true === $this->field['font-style'] || true === $this->field['font-weight'] ) {
385
-				echo '<div data-weights="' . rawurlencode( wp_json_encode( $this->field['weights'] ) ) . '" class="select_wrapper typography-style" original-title="' . esc_html__( 'Font style', 'redux-framework' ) . '">';
386
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '_style">' . esc_html__( 'Font Weight &amp; Style', 'redux-framework' ) . '</label>';
383
+            /* Font Style/Weight */
384
+            if ( true === $this->field['font-style'] || true === $this->field['font-weight'] ) {
385
+                echo '<div data-weights="' . rawurlencode( wp_json_encode( $this->field['weights'] ) ) . '" class="select_wrapper typography-style" original-title="' . esc_html__( 'Font style', 'redux-framework' ) . '">';
386
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '_style">' . esc_html__( 'Font Weight &amp; Style', 'redux-framework' ) . '</label>';
387 387
 
388
-				$style = $this->value['font-weight'] . $this->value['font-style'];
388
+                $style = $this->value['font-weight'] . $this->value['font-style'];
389 389
 
390
-				echo '<input
390
+                echo '<input
391 391
 						type="hidden"
392 392
 						class="typography-font-weight" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[font-weight]"
393 393
 						value="' . esc_attr( $this->value['font-weight'] ) . '"
394 394
 						data-id="' . esc_attr( $this->field['id'] ) . '"  /> ';
395 395
 
396
-				echo '<input
396
+                echo '<input
397 397
 						type="hidden"
398 398
 						class="typography-font-style" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[font-style]"
399 399
 						value="' . esc_attr( $this->value['font-style'] ) . '"
400 400
 						data-id="' . esc_attr( $this->field['id'] ) . '"  /> ';
401
-				$multi = ( isset( $this->field['multi']['weight'] ) && $this->field['multi']['weight'] ) ? ' multiple="multiple"' : '';
402
-				echo '<select' . esc_html( $multi ) . '
401
+                $multi = ( isset( $this->field['multi']['weight'] ) && $this->field['multi']['weight'] ) ? ' multiple="multiple"' : '';
402
+                echo '<select' . esc_html( $multi ) . '
403 403
 				        data-placeholder="' . esc_html__( 'Style', 'redux-framework' ) . '"
404 404
 				        class="redux-typography redux-typography-style select ' . esc_attr( $this->field['class'] ) . '"
405 405
 				        original-title="' . esc_html__( 'Font style', 'redux-framework' ) . '"
406 406
 				        id="' . esc_attr( $this->field['id'] ) . '_style" data-id="' . esc_attr( $this->field['id'] ) . '"
407 407
 				        data-value="' . esc_attr( $style ) . '"' . esc_attr( $select2_data ) . '>';
408 408
 
409
-				if ( empty( $this->value['subsets'] ) || empty( $this->value['font-weight'] ) ) {
410
-					echo '<option value=""></option>';
411
-				}
409
+                if ( empty( $this->value['subsets'] ) || empty( $this->value['font-weight'] ) ) {
410
+                    echo '<option value=""></option>';
411
+                }
412 412
 
413
-				echo '</select></div>';
414
-			}
413
+                echo '</select></div>';
414
+            }
415 415
 
416
-			/* Font Script */
417
-			if ( true === $this->field['font-family'] && true === $this->field['subsets'] && true === $this->field['google'] ) {
418
-				echo '<div class="select_wrapper typography-script tooltip" original-title="' . esc_html__( 'Font subsets', 'redux-framework' ) . '">';
419
-				echo '<input
416
+            /* Font Script */
417
+            if ( true === $this->field['font-family'] && true === $this->field['subsets'] && true === $this->field['google'] ) {
418
+                echo '<div class="select_wrapper typography-script tooltip" original-title="' . esc_html__( 'Font subsets', 'redux-framework' ) . '">';
419
+                echo '<input
420 420
 						type="hidden"
421 421
 						class="typography-subsets"
422 422
 						name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[subsets]"
423 423
 						value="' . esc_attr( $this->value['subsets'] ) . '"
424 424
 						data-id="' . esc_attr( $this->field['id'] ) . '"  /> ';
425 425
 
426
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-subsets">' . esc_html__( 'Font Subsets', 'redux-framework' ) . '</label>';
427
-				$multi = ( isset( $this->field['multi']['subsets'] ) && $this->field['multi']['subsets'] ) ? ' multiple="multiple"' : '';
428
-				echo '<select' . esc_html( $multi ) . '
426
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-subsets">' . esc_html__( 'Font Subsets', 'redux-framework' ) . '</label>';
427
+                $multi = ( isset( $this->field['multi']['subsets'] ) && $this->field['multi']['subsets'] ) ? ' multiple="multiple"' : '';
428
+                echo '<select' . esc_html( $multi ) . '
429 429
 						data-placeholder="' . esc_html__( 'Subsets', 'redux-framework' ) . '"
430 430
 						class="redux-typography redux-typography-subsets ' . esc_attr( $this->field['class'] ) . '"
431 431
 						original-title="' . esc_html__( 'Font script', 'redux-framework' ) . '"
@@ -433,18 +433,18 @@  discard block
 block discarded – undo
433 433
 						data-value="' . esc_attr( $this->value['subsets'] ) . '"
434 434
 						data-id="' . esc_attr( $this->field['id'] ) . '"' . esc_attr( $select2_data ) . '>';
435 435
 
436
-				if ( empty( $this->value['subsets'] ) ) {
437
-					echo '<option value=""></option>';
438
-				}
436
+                if ( empty( $this->value['subsets'] ) ) {
437
+                    echo '<option value=""></option>';
438
+                }
439 439
 
440
-				echo '</select></div>';
441
-			}
440
+                echo '</select></div>';
441
+            }
442 442
 
443
-			/* Font Align */
444
-			if ( true === $this->field['text-align'] ) {
445
-				echo '<div class="select_wrapper typography-align tooltip" original-title="' . esc_html__( 'Text Align', 'redux-framework' ) . '">';
446
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-align">' . esc_html__( 'Text Align', 'redux-framework' ) . '</label>';
447
-				echo '<select
443
+            /* Font Align */
444
+            if ( true === $this->field['text-align'] ) {
445
+                echo '<div class="select_wrapper typography-align tooltip" original-title="' . esc_html__( 'Text Align', 'redux-framework' ) . '">';
446
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-align">' . esc_html__( 'Text Align', 'redux-framework' ) . '</label>';
447
+                echo '<select
448 448
 						data-placeholder="' . esc_html__( 'Text Align', 'redux-framework' ) . '"
449 449
 						class="redux-typography redux-typography-align ' . esc_attr( $this->field['class'] ) . '"
450 450
 						original-title="' . esc_html__( 'Text Align', 'redux-framework' ) . '"
@@ -453,29 +453,29 @@  discard block
 block discarded – undo
453 453
 						data-value="' . esc_attr( $this->value['text-align'] ) . '"
454 454
 						data-id="' . esc_attr( $this->field['id'] ) . '"' . esc_attr( $select2_data ) . '>';
455 455
 
456
-				echo '<option value=""></option>';
457
-
458
-				$align = array(
459
-					esc_html__( 'inherit', 'redux-framework' ),
460
-					esc_html__( 'left', 'redux-framework' ),
461
-					esc_html__( 'right', 'redux-framework' ),
462
-					esc_html__( 'center', 'redux-framework' ),
463
-					esc_html__( 'justify', 'redux-framework' ),
464
-					esc_html__( 'initial', 'redux-framework' ),
465
-				);
466
-
467
-				foreach ( $align as $v ) {
468
-					echo '<option value="' . esc_attr( $v ) . '" ' . selected( $this->value['text-align'], $v, false ) . '>' . esc_html( ucfirst( $v ) ) . '</option>';
469
-				}
470
-
471
-				echo '</select></div>';
472
-			}
473
-
474
-			/* Text Transform */
475
-			if ( true === $this->field['text-transform'] ) {
476
-				echo '<div class="select_wrapper typography-transform tooltip" original-title="' . esc_html__( 'Text Transform', 'redux-framework' ) . '">';
477
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-transform">' . esc_html__( 'Text Transform', 'redux-framework' ) . '</label>';
478
-				echo '<select
456
+                echo '<option value=""></option>';
457
+
458
+                $align = array(
459
+                    esc_html__( 'inherit', 'redux-framework' ),
460
+                    esc_html__( 'left', 'redux-framework' ),
461
+                    esc_html__( 'right', 'redux-framework' ),
462
+                    esc_html__( 'center', 'redux-framework' ),
463
+                    esc_html__( 'justify', 'redux-framework' ),
464
+                    esc_html__( 'initial', 'redux-framework' ),
465
+                );
466
+
467
+                foreach ( $align as $v ) {
468
+                    echo '<option value="' . esc_attr( $v ) . '" ' . selected( $this->value['text-align'], $v, false ) . '>' . esc_html( ucfirst( $v ) ) . '</option>';
469
+                }
470
+
471
+                echo '</select></div>';
472
+            }
473
+
474
+            /* Text Transform */
475
+            if ( true === $this->field['text-transform'] ) {
476
+                echo '<div class="select_wrapper typography-transform tooltip" original-title="' . esc_html__( 'Text Transform', 'redux-framework' ) . '">';
477
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-transform">' . esc_html__( 'Text Transform', 'redux-framework' ) . '</label>';
478
+                echo '<select
479 479
 						data-placeholder="' . esc_html__( 'Text Transform', 'redux-framework' ) . '"
480 480
 						class="redux-typography redux-typography-transform ' . esc_attr( $this->field['class'] ) . '"
481 481
 						original-title="' . esc_html__( 'Text Transform', 'redux-framework' ) . '"
@@ -484,29 +484,29 @@  discard block
 block discarded – undo
484 484
 						data-value="' . esc_attr( $this->value['text-transform'] ) . '"
485 485
 						data-id="' . esc_attr( $this->field['id'] ) . '"' . esc_attr( $select2_data ) . '>';
486 486
 
487
-				echo '<option value=""></option>';
488
-
489
-				$values = array(
490
-					esc_html__( 'none', 'redux-framework' ),
491
-					esc_html__( 'capitalize', 'redux-framework' ),
492
-					esc_html__( 'uppercase', 'redux-framework' ),
493
-					esc_html__( 'lowercase', 'redux-framework' ),
494
-					esc_html__( 'initial', 'redux-framework' ),
495
-					esc_html__( 'inherit', 'redux-framework' ),
496
-				);
497
-
498
-				foreach ( $values as $v ) {
499
-					echo '<option value="' . esc_attr( $v ) . '" ' . selected( $this->value['text-transform'], $v, false ) . '>' . esc_html( ucfirst( $v ) ) . '</option>';
500
-				}
501
-
502
-				echo '</select></div>';
503
-			}
504
-
505
-			/* Font Variant */
506
-			if ( true === $this->field['font-variant'] ) {
507
-				echo '<div class="select_wrapper typography-font-variant tooltip" original-title="' . esc_html__( 'Font Variant', 'redux-framework' ) . '">';
508
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-font-variant">' . esc_html__( 'Font Variant', 'redux-framework' ) . '</label>';
509
-				echo '<select
487
+                echo '<option value=""></option>';
488
+
489
+                $values = array(
490
+                    esc_html__( 'none', 'redux-framework' ),
491
+                    esc_html__( 'capitalize', 'redux-framework' ),
492
+                    esc_html__( 'uppercase', 'redux-framework' ),
493
+                    esc_html__( 'lowercase', 'redux-framework' ),
494
+                    esc_html__( 'initial', 'redux-framework' ),
495
+                    esc_html__( 'inherit', 'redux-framework' ),
496
+                );
497
+
498
+                foreach ( $values as $v ) {
499
+                    echo '<option value="' . esc_attr( $v ) . '" ' . selected( $this->value['text-transform'], $v, false ) . '>' . esc_html( ucfirst( $v ) ) . '</option>';
500
+                }
501
+
502
+                echo '</select></div>';
503
+            }
504
+
505
+            /* Font Variant */
506
+            if ( true === $this->field['font-variant'] ) {
507
+                echo '<div class="select_wrapper typography-font-variant tooltip" original-title="' . esc_html__( 'Font Variant', 'redux-framework' ) . '">';
508
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-font-variant">' . esc_html__( 'Font Variant', 'redux-framework' ) . '</label>';
509
+                echo '<select
510 510
 						data-placeholder="' . esc_html__( 'Font Variant', 'redux-framework' ) . '"
511 511
 						class="redux-typography redux-typography-font-variant ' . esc_attr( $this->field['class'] ) . '"
512 512
 						original-title="' . esc_html__( 'Font Variant', 'redux-framework' ) . '"
@@ -515,26 +515,26 @@  discard block
 block discarded – undo
515 515
 						data-value="' . esc_attr( $this->value['font-variant'] ) . '"
516 516
 						data-id="' . esc_attr( $this->field['id'] ) . '"' . esc_attr( $select2_data ) . '>';
517 517
 
518
-				echo '<option value=""></option>';
518
+                echo '<option value=""></option>';
519 519
 
520
-				$values = array(
521
-					esc_html__( 'inherit', 'redux-framework' ),
522
-					esc_html__( 'normal', 'redux-framework' ),
523
-					esc_html__( 'small-caps', 'redux-framework' ),
524
-				);
520
+                $values = array(
521
+                    esc_html__( 'inherit', 'redux-framework' ),
522
+                    esc_html__( 'normal', 'redux-framework' ),
523
+                    esc_html__( 'small-caps', 'redux-framework' ),
524
+                );
525 525
 
526
-				foreach ( $values as $v ) {
527
-					echo '<option value="' . esc_attr( $v ) . '" ' . selected( $this->value['font-variant'], $v, false ) . '>' . esc_attr( ucfirst( $v ) ) . '</option>';
528
-				}
526
+                foreach ( $values as $v ) {
527
+                    echo '<option value="' . esc_attr( $v ) . '" ' . selected( $this->value['font-variant'], $v, false ) . '>' . esc_attr( ucfirst( $v ) ) . '</option>';
528
+                }
529 529
 
530
-				echo '</select></div>';
531
-			}
530
+                echo '</select></div>';
531
+            }
532 532
 
533
-			/* Text Decoration */
534
-			if ( true === $this->field['text-decoration'] ) {
535
-				echo '<div class="select_wrapper typography-decoration tooltip" original-title="' . esc_html__( 'Text Decoration', 'redux-framework' ) . '">';
536
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-decoration">' . esc_html__( 'Text Decoration', 'redux-framework' ) . '</label>';
537
-				echo '<select
533
+            /* Text Decoration */
534
+            if ( true === $this->field['text-decoration'] ) {
535
+                echo '<div class="select_wrapper typography-decoration tooltip" original-title="' . esc_html__( 'Text Decoration', 'redux-framework' ) . '">';
536
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-decoration">' . esc_html__( 'Text Decoration', 'redux-framework' ) . '</label>';
537
+                echo '<select
538 538
 						data-placeholder="' . esc_html__( 'Text Decoration', 'redux-framework' ) . '"
539 539
 						class="redux-typography redux-typography-decoration ' . esc_attr( $this->field['class'] ) . '"
540 540
 						original-title="' . esc_html__( 'Text Decoration', 'redux-framework' ) . '"
@@ -543,32 +543,32 @@  discard block
 block discarded – undo
543 543
 						data-value="' . esc_attr( $this->value['text-decoration'] ) . '"
544 544
 						data-id="' . esc_attr( $this->field['id'] ) . '"' . esc_attr( $select2_data ) . '>';
545 545
 
546
-				echo '<option value=""></option>';
546
+                echo '<option value=""></option>';
547 547
 
548
-				$values = array(
549
-					esc_html__( 'none', 'redux-framework' ),
550
-					esc_html__( 'inherit', 'redux-framework' ),
551
-					esc_html__( 'underline', 'redux-framework' ),
552
-					esc_html__( 'overline', 'redux-framework' ),
553
-					esc_html__( 'line-through', 'redux-framework' ),
554
-					esc_html__( 'blink', 'redux-framework' ),
555
-				);
548
+                $values = array(
549
+                    esc_html__( 'none', 'redux-framework' ),
550
+                    esc_html__( 'inherit', 'redux-framework' ),
551
+                    esc_html__( 'underline', 'redux-framework' ),
552
+                    esc_html__( 'overline', 'redux-framework' ),
553
+                    esc_html__( 'line-through', 'redux-framework' ),
554
+                    esc_html__( 'blink', 'redux-framework' ),
555
+                );
556 556
 
557
-				foreach ( $values as $v ) {
558
-					echo '<option value="' . esc_attr( $v ) . '" ' . selected( $this->value['text-decoration'], $v, false ) . '>' . esc_html( ucfirst( $v ) ) . '</option>';
559
-				}
557
+                foreach ( $values as $v ) {
558
+                    echo '<option value="' . esc_attr( $v ) . '" ' . selected( $this->value['text-decoration'], $v, false ) . '>' . esc_html( ucfirst( $v ) ) . '</option>';
559
+                }
560 560
 
561
-				echo '</select></div>';
562
-			}
561
+                echo '</select></div>';
562
+            }
563 563
 
564
-			/* Font Size */
565
-			if ( true === $this->field['font-size'] ) {
566
-				$the_unit = '' !== $this->field['font-size-unit'] ? $this->field['font-size-unit'] : $unit;
564
+            /* Font Size */
565
+            if ( true === $this->field['font-size'] ) {
566
+                $the_unit = '' !== $this->field['font-size-unit'] ? $this->field['font-size-unit'] : $unit;
567 567
 
568
-				echo '<div class="input_wrapper font-size redux-container-typography">';
569
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-size">' . esc_html__( 'Font Size', 'redux-framework' ) . '</label>';
570
-				echo '<div class="input-append">';
571
-				echo '<input
568
+                echo '<div class="input_wrapper font-size redux-container-typography">';
569
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-size">' . esc_html__( 'Font Size', 'redux-framework' ) . '</label>';
570
+                echo '<div class="input-append">';
571
+                echo '<input
572 572
 						type="text"
573 573
 						class="span2 redux-typography redux-typography-size mini typography-input ' . esc_attr( $this->field['class'] ) . '"
574 574
 						title="' . esc_html__( 'Font Size', 'redux-framework' ) . '"
@@ -577,20 +577,20 @@  discard block
 block discarded – undo
577 577
 						value="' . esc_attr( str_replace( Redux_Helpers::$array_units, '', $this->value['font-size'] ) ) . '"
578 578
 						data-unit="' . esc_attr( $the_unit ) . '"
579 579
 						data-value="' . esc_attr( str_replace( Redux_Helpers::$array_units, '', $this->value['font-size'] ) ) . '">';
580
-				echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
581
-				echo '</div>';
582
-				echo '<input type="hidden" class="typography-font-size" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[font-size]" value="' . esc_attr( $this->value['font-size'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"/>';
583
-				echo '</div>';
584
-			}
585
-
586
-			/* Line Height */
587
-			if ( true === $this->field['line-height'] ) {
588
-				$the_unit = $this->field['line-height-unit'] ?? $unit;
589
-
590
-				echo '<div class="input_wrapper line-height redux-container-typography">';
591
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-height">' . esc_html__( 'Line Height', 'redux-framework' ) . '</label>';
592
-				echo '<div class="input-append">';
593
-				echo '<input
580
+                echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
581
+                echo '</div>';
582
+                echo '<input type="hidden" class="typography-font-size" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[font-size]" value="' . esc_attr( $this->value['font-size'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"/>';
583
+                echo '</div>';
584
+            }
585
+
586
+            /* Line Height */
587
+            if ( true === $this->field['line-height'] ) {
588
+                $the_unit = $this->field['line-height-unit'] ?? $unit;
589
+
590
+                echo '<div class="input_wrapper line-height redux-container-typography">';
591
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-height">' . esc_html__( 'Line Height', 'redux-framework' ) . '</label>';
592
+                echo '<div class="input-append">';
593
+                echo '<input
594 594
 						type="text"
595 595
 						class="span2 redux-typography redux-typography-height mini typography-input ' . esc_attr( $this->field['class'] ) . '"
596 596
 						title="' . esc_html__( 'Line Height', 'redux-framework' ) . '"
@@ -600,25 +600,25 @@  discard block
 block discarded – undo
600 600
 						data-allow-empty="' . esc_attr( $this->field['allow_empty_line_height'] ) . '"
601 601
 						data-unit="' . esc_attr( $the_unit ) . '"
602 602
 						data-value="' . esc_attr( str_replace( Redux_Helpers::$array_units, '', $this->value['line-height'] ) ) . '">';
603
-				echo '<span class="add-on">' . esc_html( '' === $the_unit ? '&nbsp;' : $the_unit ) . '</span>';
604
-				echo '</div>';
605
-				echo '<input
603
+                echo '<span class="add-on">' . esc_html( '' === $the_unit ? '&nbsp;' : $the_unit ) . '</span>';
604
+                echo '</div>';
605
+                echo '<input
606 606
 						type="hidden"
607 607
 						class="typography-line-height"
608 608
 						name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[line-height]"
609 609
 						value="' . esc_attr( $this->value['line-height'] ) . '"
610 610
 						data-id="' . esc_attr( $this->field['id'] ) . '"/>';
611
-				echo '</div>';
612
-			}
611
+                echo '</div>';
612
+            }
613 613
 
614
-			/* Word Spacing */
615
-			if ( true === $this->field['word-spacing'] ) {
616
-				$the_unit = '' !== $this->field['word-spacing-unit'] ? $this->field['word-spacing-unit'] : $unit;
614
+            /* Word Spacing */
615
+            if ( true === $this->field['word-spacing'] ) {
616
+                $the_unit = '' !== $this->field['word-spacing-unit'] ? $this->field['word-spacing-unit'] : $unit;
617 617
 
618
-				echo '<div class="input_wrapper word-spacing redux-container-typography">';
619
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-word">' . esc_html__( 'Word Spacing', 'redux-framework' ) . '</label>';
620
-				echo '<div class="input-append">';
621
-				echo '<input
618
+                echo '<div class="input_wrapper word-spacing redux-container-typography">';
619
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-word">' . esc_html__( 'Word Spacing', 'redux-framework' ) . '</label>';
620
+                echo '<div class="input-append">';
621
+                echo '<input
622 622
 						type="text"
623 623
 						class="span2 redux-typography redux-typography-word mini typography-input ' . esc_attr( $this->field['class'] ) . '"
624 624
 						title="' . esc_html__( 'Word Spacing', 'redux-framework' ) . '"
@@ -628,20 +628,20 @@  discard block
 block discarded – undo
628 628
 						value="' . esc_attr( str_replace( $the_unit, '', $this->value['word-spacing'] ) ) . '"
629 629
 						data-value="' . esc_attr( str_replace( $the_unit, '', $this->value['word-spacing'] ) ) . '">';
630 630
 
631
-				echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
632
-				echo '</div>';
633
-				echo '<input type="hidden" class="typography-word-spacing" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[word-spacing] " value="' . esc_attr( $this->value['word-spacing'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"/>';
634
-				echo '</div>';
635
-			}
631
+                echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
632
+                echo '</div>';
633
+                echo '<input type="hidden" class="typography-word-spacing" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[word-spacing] " value="' . esc_attr( $this->value['word-spacing'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"/>';
634
+                echo '</div>';
635
+            }
636 636
 
637
-			/* Letter Spacing */
638
-			if ( true === $this->field['letter-spacing'] ) {
639
-				$the_unit = '' !== $this->field['letter-spacing-unit'] ? $this->field['letter-spacing-unit'] : $unit;
637
+            /* Letter Spacing */
638
+            if ( true === $this->field['letter-spacing'] ) {
639
+                $the_unit = '' !== $this->field['letter-spacing-unit'] ? $this->field['letter-spacing-unit'] : $unit;
640 640
 
641
-				echo '<div class="input_wrapper letter-spacing redux-container-typography">';
642
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-letter">' . esc_html__( 'Letter Spacing', 'redux-framework' ) . '</label>';
643
-				echo '<div class="input-append">';
644
-				echo '<input
641
+                echo '<div class="input_wrapper letter-spacing redux-container-typography">';
642
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-letter">' . esc_html__( 'Letter Spacing', 'redux-framework' ) . '</label>';
643
+                echo '<div class="input-append">';
644
+                echo '<input
645 645
 						type="text"
646 646
 						class="span2 redux-typography redux-typography-letter mini typography-input ' . esc_attr( $this->field['class'] ) . '"
647 647
 						title="' . esc_html__( 'Letter Spacing', 'redux-framework' ) . '"
@@ -651,28 +651,28 @@  discard block
 block discarded – undo
651 651
 						value="' . esc_attr( str_replace( $the_unit, '', $this->value['letter-spacing'] ) ) . '"
652 652
 						data-value="' . esc_attr( str_replace( $the_unit, '', $this->value['letter-spacing'] ) ) . '">';
653 653
 
654
-				echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
655
-				echo '</div>';
656
-				echo '<input
654
+                echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
655
+                echo '</div>';
656
+                echo '<input
657 657
 						type="hidden"
658 658
 						class="typography-letter-spacing"
659 659
 						name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[letter-spacing]"
660 660
 						value="' . esc_attr( $this->value['letter-spacing'] ) . '"
661 661
 						data-id="' . esc_attr( $this->field['id'] ) . '"  />';
662 662
 
663
-				echo '</div>';
664
-			}
663
+                echo '</div>';
664
+            }
665 665
 
666
-			echo '<div class="clearfix"></div>';
666
+            echo '<div class="clearfix"></div>';
667 667
 
668
-			// Margins.
669
-			if ( $this->field['margin-top'] ) {
670
-				$the_unit = '' !== $this->field['margin-top-unit'] ? $this->field['margin-top-unit'] : $unit;
668
+            // Margins.
669
+            if ( $this->field['margin-top'] ) {
670
+                $the_unit = '' !== $this->field['margin-top-unit'] ? $this->field['margin-top-unit'] : $unit;
671 671
 
672
-				echo '<div class="input_wrapper margin-top redux-container-typography">';
673
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-margin-top">' . esc_html__( 'Margin Top', 'redux-framework' ) . '</label>';
674
-				echo '<div class="input-append">';
675
-				echo '<input
672
+                echo '<div class="input_wrapper margin-top redux-container-typography">';
673
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-margin-top">' . esc_html__( 'Margin Top', 'redux-framework' ) . '</label>';
674
+                echo '<div class="input-append">';
675
+                echo '<input
676 676
 						type="text"
677 677
 						class="span2 redux-typography redux-typography-margin-top mini typography-input ' . esc_attr( $this->field['class'] ) . '"
678 678
 						title="' . esc_html__( 'Margin Top', 'redux-framework' ) . '"
@@ -681,25 +681,25 @@  discard block
 block discarded – undo
681 681
 						data-unit="' . esc_attr( $the_unit ) . '"
682 682
 						value="' . esc_attr( str_replace( $the_unit, '', $this->value['margin-top'] ) ) . '"
683 683
 						data-value="' . esc_attr( str_replace( $the_unit, '', $this->value['margin-top'] ) ) . '">';
684
-				echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
685
-				echo '</div>';
686
-				echo '<input
684
+                echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
685
+                echo '</div>';
686
+                echo '<input
687 687
 						type="hidden"
688 688
 						class="typography-margin-top"
689 689
 						name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[margin-top]"
690 690
 						value="' . esc_attr( $this->value['margin-top'] ) . '"
691 691
 						data-id="' . esc_attr( $this->field['id'] ) . '"  />';
692
-				echo '</div>';
693
-			}
692
+                echo '</div>';
693
+            }
694 694
 
695
-			/* Bottom Margin */
696
-			if ( $this->field['margin-bottom'] ) {
697
-				$the_unit = '' !== $this->field['margin-bottom-unit'] ? $this->field['margin-bottom-unit'] : $unit;
695
+            /* Bottom Margin */
696
+            if ( $this->field['margin-bottom'] ) {
697
+                $the_unit = '' !== $this->field['margin-bottom-unit'] ? $this->field['margin-bottom-unit'] : $unit;
698 698
 
699
-				echo '<div class="input_wrapper margin-bottom redux-container-typography">';
700
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-margin-bottom">' . esc_html__( 'Margin Bottom', 'redux-framework' ) . '</label>';
701
-				echo '<div class="input-append">';
702
-				echo '<input
699
+                echo '<div class="input_wrapper margin-bottom redux-container-typography">';
700
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-margin-bottom">' . esc_html__( 'Margin Bottom', 'redux-framework' ) . '</label>';
701
+                echo '<div class="input-append">';
702
+                echo '<input
703 703
 						type="text"
704 704
 						class="span2 redux-typography redux-typography-margin-bottom mini typography-input ' . esc_attr( $this->field['class'] ) . '"
705 705
 						title="' . esc_html__( 'Margin Bottom', 'redux-framework' ) . '"
@@ -708,106 +708,106 @@  discard block
 block discarded – undo
708 708
 						data-unit="' . esc_attr( $the_unit ) . '"
709 709
 						value="' . esc_attr( str_replace( $the_unit, '', $this->value['margin-bottom'] ) ) . '"
710 710
 						data-value="' . esc_attr( str_replace( $the_unit, '', $this->value['margin-bottom'] ) ) . '">';
711
-				echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
712
-				echo '</div>';
713
-				echo '<input type="hidden" class="typography-margin-bottom" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[margin-bottom]" value="' . esc_attr( $this->value['margin-bottom'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"  />';
714
-				echo '</div>';
715
-			}
716
-
717
-			if ( $this->field['margin-top'] || $this->field['margin-bottom'] ) {
718
-				echo '<div class="clearfix"></div>';
719
-			}
720
-
721
-			/* Font Color */
722
-			if ( true === $this->field['color'] ) {
723
-				$default = '';
724
-
725
-				if ( empty( $this->field['default']['color'] ) && ! empty( $this->field['color'] ) ) {
726
-					$default = $this->value['color'];
727
-				} elseif ( ! empty( $this->field['default']['color'] ) ) {
728
-					$default = $this->field['default']['color'];
729
-				}
730
-
731
-				echo '<div class="picker-wrapper">';
732
-				echo '<label for="' . esc_attr( $this->field['id'] ) . '-color">' . esc_html__( 'Font Color', 'redux-framework' ) . '</label>';
733
-				echo '<div id="' . esc_attr( $this->field['id'] ) . '_color_picker" class="colorSelector typography-color">';
734
-				echo '<div style="background-color: ' . esc_attr( $this->value['color'] ) . '"></div>';
735
-				echo '</div>';
736
-				echo '<input ';
737
-				echo 'data-default-color="' . esc_attr( $default ) . '"';
738
-				echo 'class="color-picker redux-color redux-typography-color ' . esc_attr( $this->field['class'] ) . '"';
739
-				echo 'original-title="' . esc_html__( 'Font color', 'redux-framework' ) . '"';
740
-				echo 'id="' . esc_attr( $this->field['id'] ) . '-color"';
741
-				echo 'name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[color]"';
742
-				echo 'type="text"';
743
-				echo 'value="' . esc_attr( $this->value['color'] ) . '"';
744
-				echo 'data-id="' . esc_attr( $this->field['id'] ) . '"';
745
-
746
-				$data = array(
747
-					'field' => $this->field,
748
-					'index' => 'color',
749
-				);
750
-
751
-				echo Redux_Functions_Ex::output_alpha_data( $data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
752
-
753
-				echo '>';
754
-				echo '</div>';
755
-			}
756
-
757
-			echo '<div class="clearfix"></div>';
758
-
759
-			/* Font Preview */
760
-			if ( ! isset( $this->field['preview'] ) || false !== $this->field['preview'] ) {
761
-				$g_text = $this->field['preview']['text'] ?? '1 2 3 4 5 6 7 8 9 0 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z';
762
-
763
-				$style = '';
764
-				if ( isset( $this->field['preview']['always_display'] ) ) {
765
-					if ( true === filter_var( $this->field['preview']['always_display'], FILTER_VALIDATE_BOOLEAN ) ) {
766
-						if ( true === (bool) $is_google_font ) {
767
-							$this->typography_preview[ $font_family[0] ] = array(
768
-								'font-style' => array( $this->value['font-weight'] . $this->value['font-style'] ),
769
-								'subset'     => array( $this->value['subsets'] ),
770
-							);
771
-
772
-							wp_deregister_style( 'redux-typography-preview' );
773
-							wp_dequeue_style( 'redux-typography-preview' );
774
-
775
-							wp_enqueue_style( 'redux-typography-preview', $this->make_google_web_font_link( $this->typography_preview ), array(), $this->timestamp );
776
-						}
777
-
778
-						$style = 'display: block; font-family: ' . esc_attr( $this->value['font-family'] ) . '; font-weight: ' . esc_attr( $this->value['font-weight'] ) . ';';
779
-					}
780
-				}
781
-
782
-				if ( isset( $this->field['preview']['font-size'] ) ) {
783
-					$style .= 'font-size: ' . $this->field['preview']['font-size'] . ';';
784
-					$in_use = '1';
785
-				} else {
786
-					$in_use = '0';
787
-				}
788
-
789
-				// Filter to disable Google font updates.
790
-				if ( apply_filters( "redux/{$this->parent->args['opt_name']}/field/typography/google_font_update", true ) ) { // phpcs:ignored WordPress.NamingConventions.ValidHookName
791
-					if ( Redux_Helpers::google_fonts_update_needed() && ! get_option( 'auto_update_redux_google_fonts', false ) && $this->field['font-family'] && $this->field['google'] ) {
792
-						$nonce = wp_create_nonce( 'redux_update_google_fonts' );
793
-
794
-						echo '<div data-nonce="' . esc_attr( $nonce ) . '" class="redux-update-google-fonts update-message notice inline notice-warning notice-alt">';
795
-						echo '<p>' . esc_html__( 'Your Google Fonts are out of date. To update them, please click one of the following:', 'redux-framework' );
796
-						echo '&nbsp;<a href="#" class="update-google-fonts" data-action="automatic" aria-label="' . esc_attr__( 'Automated updates', 'redux-framework' ) . '">' . esc_html__( 'Automated updates', 'redux-framework' ) . '</a> ' . esc_html__( 'or', 'redux-framework' ) . ' <a href="#" class="update-google-fonts" data-action="manual" aria-label="' . esc_attr__( 'one-time update', 'redux-framework' ) . '">' . esc_html__( 'one-time update', 'redux-framework' ) . '</a>.';
797
-						echo '</p>';
798
-						echo '</div>';
799
-					}
800
-				}
801
-
802
-				echo '<p data-preview-size="' . esc_attr( $in_use ) . '" class="clear ' . esc_attr( $this->field['id'] ) . '_previewer typography-preview" style="' . esc_attr( $style ) . '">' . esc_html( $g_text ) . '</p>';
803
-
804
-				if ( $this->field['text-shadow'] ) {
805
-
806
-					/* Shadow Colour */
807
-					echo '<div class="picker-wrapper">';
808
-					echo '<label for="' . esc_attr( $this->field['id'] ) . '-shadow-color">' . esc_html__( 'Shadow Color', 'redux-framework' ) . '</label>';
809
-					echo '<div id="' . esc_attr( $this->field['id'] ) . '_color_picker" class="colorSelector typography-shadow-color"><div style="background-color: ' . esc_attr( $this->value['color'] ) . '"></div></div>';
810
-					echo '<input
711
+                echo '<span class="add-on">' . esc_html( $the_unit ) . '</span>';
712
+                echo '</div>';
713
+                echo '<input type="hidden" class="typography-margin-bottom" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[margin-bottom]" value="' . esc_attr( $this->value['margin-bottom'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"  />';
714
+                echo '</div>';
715
+            }
716
+
717
+            if ( $this->field['margin-top'] || $this->field['margin-bottom'] ) {
718
+                echo '<div class="clearfix"></div>';
719
+            }
720
+
721
+            /* Font Color */
722
+            if ( true === $this->field['color'] ) {
723
+                $default = '';
724
+
725
+                if ( empty( $this->field['default']['color'] ) && ! empty( $this->field['color'] ) ) {
726
+                    $default = $this->value['color'];
727
+                } elseif ( ! empty( $this->field['default']['color'] ) ) {
728
+                    $default = $this->field['default']['color'];
729
+                }
730
+
731
+                echo '<div class="picker-wrapper">';
732
+                echo '<label for="' . esc_attr( $this->field['id'] ) . '-color">' . esc_html__( 'Font Color', 'redux-framework' ) . '</label>';
733
+                echo '<div id="' . esc_attr( $this->field['id'] ) . '_color_picker" class="colorSelector typography-color">';
734
+                echo '<div style="background-color: ' . esc_attr( $this->value['color'] ) . '"></div>';
735
+                echo '</div>';
736
+                echo '<input ';
737
+                echo 'data-default-color="' . esc_attr( $default ) . '"';
738
+                echo 'class="color-picker redux-color redux-typography-color ' . esc_attr( $this->field['class'] ) . '"';
739
+                echo 'original-title="' . esc_html__( 'Font color', 'redux-framework' ) . '"';
740
+                echo 'id="' . esc_attr( $this->field['id'] ) . '-color"';
741
+                echo 'name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[color]"';
742
+                echo 'type="text"';
743
+                echo 'value="' . esc_attr( $this->value['color'] ) . '"';
744
+                echo 'data-id="' . esc_attr( $this->field['id'] ) . '"';
745
+
746
+                $data = array(
747
+                    'field' => $this->field,
748
+                    'index' => 'color',
749
+                );
750
+
751
+                echo Redux_Functions_Ex::output_alpha_data( $data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
752
+
753
+                echo '>';
754
+                echo '</div>';
755
+            }
756
+
757
+            echo '<div class="clearfix"></div>';
758
+
759
+            /* Font Preview */
760
+            if ( ! isset( $this->field['preview'] ) || false !== $this->field['preview'] ) {
761
+                $g_text = $this->field['preview']['text'] ?? '1 2 3 4 5 6 7 8 9 0 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z';
762
+
763
+                $style = '';
764
+                if ( isset( $this->field['preview']['always_display'] ) ) {
765
+                    if ( true === filter_var( $this->field['preview']['always_display'], FILTER_VALIDATE_BOOLEAN ) ) {
766
+                        if ( true === (bool) $is_google_font ) {
767
+                            $this->typography_preview[ $font_family[0] ] = array(
768
+                                'font-style' => array( $this->value['font-weight'] . $this->value['font-style'] ),
769
+                                'subset'     => array( $this->value['subsets'] ),
770
+                            );
771
+
772
+                            wp_deregister_style( 'redux-typography-preview' );
773
+                            wp_dequeue_style( 'redux-typography-preview' );
774
+
775
+                            wp_enqueue_style( 'redux-typography-preview', $this->make_google_web_font_link( $this->typography_preview ), array(), $this->timestamp );
776
+                        }
777
+
778
+                        $style = 'display: block; font-family: ' . esc_attr( $this->value['font-family'] ) . '; font-weight: ' . esc_attr( $this->value['font-weight'] ) . ';';
779
+                    }
780
+                }
781
+
782
+                if ( isset( $this->field['preview']['font-size'] ) ) {
783
+                    $style .= 'font-size: ' . $this->field['preview']['font-size'] . ';';
784
+                    $in_use = '1';
785
+                } else {
786
+                    $in_use = '0';
787
+                }
788
+
789
+                // Filter to disable Google font updates.
790
+                if ( apply_filters( "redux/{$this->parent->args['opt_name']}/field/typography/google_font_update", true ) ) { // phpcs:ignored WordPress.NamingConventions.ValidHookName
791
+                    if ( Redux_Helpers::google_fonts_update_needed() && ! get_option( 'auto_update_redux_google_fonts', false ) && $this->field['font-family'] && $this->field['google'] ) {
792
+                        $nonce = wp_create_nonce( 'redux_update_google_fonts' );
793
+
794
+                        echo '<div data-nonce="' . esc_attr( $nonce ) . '" class="redux-update-google-fonts update-message notice inline notice-warning notice-alt">';
795
+                        echo '<p>' . esc_html__( 'Your Google Fonts are out of date. To update them, please click one of the following:', 'redux-framework' );
796
+                        echo '&nbsp;<a href="#" class="update-google-fonts" data-action="automatic" aria-label="' . esc_attr__( 'Automated updates', 'redux-framework' ) . '">' . esc_html__( 'Automated updates', 'redux-framework' ) . '</a> ' . esc_html__( 'or', 'redux-framework' ) . ' <a href="#" class="update-google-fonts" data-action="manual" aria-label="' . esc_attr__( 'one-time update', 'redux-framework' ) . '">' . esc_html__( 'one-time update', 'redux-framework' ) . '</a>.';
797
+                        echo '</p>';
798
+                        echo '</div>';
799
+                    }
800
+                }
801
+
802
+                echo '<p data-preview-size="' . esc_attr( $in_use ) . '" class="clear ' . esc_attr( $this->field['id'] ) . '_previewer typography-preview" style="' . esc_attr( $style ) . '">' . esc_html( $g_text ) . '</p>';
803
+
804
+                if ( $this->field['text-shadow'] ) {
805
+
806
+                    /* Shadow Colour */
807
+                    echo '<div class="picker-wrapper">';
808
+                    echo '<label for="' . esc_attr( $this->field['id'] ) . '-shadow-color">' . esc_html__( 'Shadow Color', 'redux-framework' ) . '</label>';
809
+                    echo '<div id="' . esc_attr( $this->field['id'] ) . '_color_picker" class="colorSelector typography-shadow-color"><div style="background-color: ' . esc_attr( $this->value['color'] ) . '"></div></div>';
810
+                    echo '<input
811 811
 		                    data-default-color="' . esc_attr( $this->value['shadow-color'] ) . '"
812 812
 		                    class="color-picker redux-color redux-typography-shadow-color ' . esc_attr( $this->field['class'] ) . '"
813 813
 		                    original-title="' . esc_html__( 'Shadow color', 'redux-framework' ) . '"
@@ -818,12 +818,12 @@  discard block
 block discarded – undo
818 818
 		                    data-alpha="' . esc_attr( $this->field['color_alpha']['shadow-color'] ) . '"
819 819
 		                    data-id="' . esc_attr( $this->field['id'] ) . '"
820 820
 		                  />';
821
-					echo '</div>';
821
+                    echo '</div>';
822 822
 
823
-					/* Shadow Horizontal Length */
824
-					echo '<div class="input_wrapper shadow-horizontal redux-container-typography" style="top:-60px;margin-left:20px;width:20%">';
825
-					echo '<div class="label">' . esc_html__( 'Horizontal', 'redux-framework' ) . ': <strong>' . esc_attr( $this->value['shadow-horizontal'] ) . 'px</strong></div>';
826
-					echo '<div
823
+                    /* Shadow Horizontal Length */
824
+                    echo '<div class="input_wrapper shadow-horizontal redux-container-typography" style="top:-60px;margin-left:20px;width:20%">';
825
+                    echo '<div class="label">' . esc_html__( 'Horizontal', 'redux-framework' ) . ': <strong>' . esc_attr( $this->value['shadow-horizontal'] ) . 'px</strong></div>';
826
+                    echo '<div
827 827
                             class="redux-typography-slider span2 redux-typography redux-typography-shadow-horizontal mini typography-input ' . esc_attr( $this->field['class'] ) . '"
828 828
                             id="' . esc_attr( $this->field['id'] ) . '"
829 829
                             data-id="' . esc_attr( $this->field['id'] ) . '-h"
@@ -834,13 +834,13 @@  discard block
 block discarded – undo
834 834
                             data-label="' . esc_attr__( 'Horizontal', 'redux-framework' ) . '"
835 835
                             data-default = "' . esc_attr( $this->value['shadow-horizontal'] ) . '">
836 836
                         </div>';
837
-					echo '<input type="hidden" id="redux-slider-value-' . esc_attr( $this->field['id'] ) . '-h" class="typography-shadow-horizontal" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[shadow-horizontal]" value="' . esc_attr( $this->value['shadow-horizontal'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"  />';
838
-					echo '</div>';
837
+                    echo '<input type="hidden" id="redux-slider-value-' . esc_attr( $this->field['id'] ) . '-h" class="typography-shadow-horizontal" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[shadow-horizontal]" value="' . esc_attr( $this->value['shadow-horizontal'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"  />';
838
+                    echo '</div>';
839 839
 
840
-					/* Shadow Vertical Length */
841
-					echo '<div class="input_wrapper shadow-vertical redux-container-typography" style="top:-60px;margin-left:20px;width:20%">';
842
-					echo '<div>' . esc_html__( 'Vertical', 'redux-framework' ) . ': <strong>' . esc_attr( $this->value['shadow-vertical'] ) . 'px</strong></div>';
843
-					echo '<div
840
+                    /* Shadow Vertical Length */
841
+                    echo '<div class="input_wrapper shadow-vertical redux-container-typography" style="top:-60px;margin-left:20px;width:20%">';
842
+                    echo '<div>' . esc_html__( 'Vertical', 'redux-framework' ) . ': <strong>' . esc_attr( $this->value['shadow-vertical'] ) . 'px</strong></div>';
843
+                    echo '<div
844 844
                             class="redux-typography-slider span2 redux-typography redux-typography-shadow-vertical mini typography-input ' . esc_attr( $this->field['class'] ) . '"
845 845
                             id="' . esc_attr( $this->field['id'] ) . '"
846 846
                             data-id="' . esc_attr( $this->field['id'] ) . '-v"
@@ -851,13 +851,13 @@  discard block
 block discarded – undo
851 851
                             data-label="' . esc_attr__( 'Vertical', 'redux-framework' ) . '"
852 852
                             data-default = "' . esc_attr( $this->value['shadow-vertical'] ) . '">
853 853
                         </div>';
854
-					echo '<input type="hidden" id="redux-slider-value-' . esc_attr( $this->field['id'] ) . '-v" class="typography-shadow-vertical" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[shadow-vertical]" value="' . esc_attr( $this->value['shadow-vertical'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"  />';
855
-					echo '</div>';
854
+                    echo '<input type="hidden" id="redux-slider-value-' . esc_attr( $this->field['id'] ) . '-v" class="typography-shadow-vertical" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[shadow-vertical]" value="' . esc_attr( $this->value['shadow-vertical'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"  />';
855
+                    echo '</div>';
856 856
 
857
-					/* Shadow Blur */
858
-					echo '<div class="input_wrapper shadow-blur redux-container-typography" style="top:-60px;margin-left:20px;width:20%">';
859
-					echo '<div>' . esc_html__( 'Blur', 'redux-framework' ) . ': <strong>' . esc_attr( $this->value['shadow-blur'] ) . 'px</strong></div>';
860
-					echo '<div
857
+                    /* Shadow Blur */
858
+                    echo '<div class="input_wrapper shadow-blur redux-container-typography" style="top:-60px;margin-left:20px;width:20%">';
859
+                    echo '<div>' . esc_html__( 'Blur', 'redux-framework' ) . ': <strong>' . esc_attr( $this->value['shadow-blur'] ) . 'px</strong></div>';
860
+                    echo '<div
861 861
                             class="redux-typography-slider span2 redux-typography redux-typography-shadow-blur mini typography-input ' . esc_attr( $this->field['class'] ) . '"
862 862
                             id="' . esc_attr( $this->field['id'] ) . '"
863 863
                             data-id="' . esc_attr( $this->field['id'] ) . '-b"
@@ -868,739 +868,739 @@  discard block
 block discarded – undo
868 868
                             data-label="' . esc_attr__( 'Blur', 'redux-framework' ) . '"
869 869
                             data-default = "' . esc_attr( $this->value['shadow-blur'] ) . '">
870 870
                         </div>';
871
-					echo '<input type="hidden" id="redux-slider-value-' . esc_attr( $this->field['id'] ) . '-b" class="typography-shadow-blur" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[shadow-blur]" value="' . esc_attr( $this->value['shadow-blur'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"  />';
872
-					echo '</div>';
873
-				}
874
-
875
-				echo '</div>'; // end typography container.
876
-			}
877
-		}
878
-
879
-		/**
880
-		 * Enqueue for every field instance.
881
-		 */
882
-		public function always_enqueue() {
883
-			$min = Redux_Functions::is_min();
884
-
885
-			if ( isset( $this->field['color_alpha'] ) && is_array( $this->field['color_alpha'] ) ) {
886
-				if ( $this->field['color_alpha']['color'] || $this->field['color_alpha']['shadow-color'] ) {
887
-					wp_enqueue_script( 'redux-wp-color-picker-alpha' );
888
-				}
889
-			}
890
-
891
-			if ( ! wp_style_is( 'redux-nouislider' ) && isset( $this->field['text-shadow'] ) && $this->field['text-shadow'] ) {
892
-				wp_enqueue_style(
893
-					'redux-nouislider',
894
-					Redux_Core::$url . "assets/css/vendor/nouislider$min.css",
895
-					array(),
896
-					'5.0.0'
897
-				);
898
-
899
-				wp_enqueue_script(
900
-					'redux-nouislider',
901
-					Redux_Core::$url . "assets/js/vendor/nouislider/redux.jquery.nouislider$min.js",
902
-					array( 'jquery' ),
903
-					'5.0.0',
904
-					true
905
-				);
906
-			}
907
-		}
908
-
909
-		/**
910
-		 * Enqueue Function.
911
-		 * If this field requires any scripts, or CSS define this function and register/enqueue the scripts/css
912
-		 *
913
-		 * @since ReduxFramework 1.0.0
914
-		 */
915
-		public function enqueue() {
916
-			$min = Redux_Functions::is_min();
917
-
918
-			if ( ! wp_style_is( 'select2-css' ) ) {
919
-				wp_enqueue_style( 'select2-css' );
920
-			}
921
-
922
-			if ( ! wp_style_is( 'wp-color-picker' ) ) {
923
-				wp_enqueue_style( 'wp-color-picker' );
924
-			}
925
-
926
-			wp_enqueue_script(
927
-				'redux-webfont',
928
-				'//' . 'ajax' . '.googleapis' . '.com/ajax/libs/webfont/1.6.26/webfont.js', // phpcs:ignore Generic.Strings.UnnecessaryStringConcat
929
-				array(),
930
-				'1.6.26',
931
-				true
932
-			);
933
-
934
-			$dep_array = array( 'jquery', 'wp-color-picker', 'select2-js', 'redux-js', 'redux-webfont' );
935
-
936
-			wp_enqueue_script(
937
-				'redux-field-typography',
938
-				Redux_Core::$url . "inc/fields/typography/redux-typography$min.js",
939
-				$dep_array,
940
-				$this->timestamp,
941
-				true
942
-			);
943
-
944
-			wp_localize_script(
945
-				'redux-field-typography',
946
-				'redux_typography_ajax',
947
-				array(
948
-					'ajaxurl'             => esc_url( admin_url( 'admin-ajax.php' ) ),
949
-					'update_google_fonts' => array(
950
-						'updating' => esc_html__( 'Downloading Google Fonts...', 'redux-framework' ),
951
-						// translators: Aria title, link title.
952
-						'error'    => sprintf( esc_html__( 'Update Failed|msg. %1$s', 'redux-framework' ), sprintf( '<a href="#" class="update-google-fonts" data-action="manual" aria-label="%s">%s</a>', esc_html__( 'Retry?', 'redux-framework' ), esc_html__( 'Retry?', 'redux-framework' ) ) ),
953
-						// translators: Javascript reload command, link title.
954
-						'success'  => sprintf( esc_html__( 'Updated! %1$s to start using your updated fonts.', 'redux-framework' ), sprintf( '<a href="	%1$s">%2$s</a>', 'javascript:location.reload();', esc_html__( 'Reload the page', 'redux-framework' ) ) ),
955
-					),
956
-				)
957
-			);
958
-
959
-			if ( $this->parent->args['dev_mode'] ) {
960
-				wp_enqueue_style( 'redux-color-picker' );
961
-
962
-				wp_enqueue_style(
963
-					'redux-field-typography',
964
-					Redux_Core::$url . 'inc/fields/typography/redux-typography.css',
965
-					array(),
966
-					$this->timestamp
967
-				);
968
-			}
969
-		}
970
-
971
-		/**
972
-		 * Make_google_web_font_link Function.
973
-		 * Creates the Google fonts link.
974
-		 *
975
-		 * @param array $fonts Array of google fonts.
976
-		 *
977
-		 * @return string
978
-		 *
979
-		 * @since ReduxFramework 3.0.0
980
-		 */
981
-		public function make_google_web_font_link( array $fonts ): string {
982
-			$link    = '';
983
-			$subsets = array();
984
-
985
-			foreach ( $fonts as $family => $font ) {
986
-				if ( ! empty( $link ) ) {
987
-					$link .= '|'; // Append a new font to the string.
988
-				}
989
-				$link .= $family;
990
-
991
-				if ( ! empty( $font['font-style'] ) || ! empty( $font['all-styles'] ) ) {
992
-					$link .= ':';
993
-					if ( ! empty( $font['all-styles'] ) ) {
994
-						$link .= implode( ',', $font['all-styles'] );
995
-					} elseif ( ! empty( $font['font-style'] ) ) {
996
-						$link .= implode( ',', $font['font-style'] );
997
-					}
998
-				}
999
-
1000
-				if ( ! empty( $font['subset'] ) || ! empty( $font['all-subsets'] ) ) {
1001
-					if ( ! empty( $font['all-subsets'] ) ) {
1002
-						foreach ( $font['all-subsets'] as $subset ) {
1003
-							if ( ! in_array( $subset, $subsets, true ) ) {
1004
-								$subsets[] = $subset;
1005
-							}
1006
-						}
1007
-					} elseif ( ! empty( $font['subset'] ) ) {
1008
-						foreach ( $font['subset'] as $subset ) {
1009
-							if ( ! in_array( $subset, $subsets, true ) ) {
1010
-								$subsets[] = $subset;
1011
-							}
1012
-						}
1013
-					}
1014
-				}
1015
-			}
1016
-
1017
-			if ( ! empty( $subsets ) ) {
1018
-				$link .= '&subset=' . implode( ',', $subsets );
1019
-			}
1020
-
1021
-			$display = $this->parent->args['font_display'] ?? 'swap';
1022
-
1023
-			$link .= '&display=' . $display;
1024
-
1025
-			// return 'https://fonts.bunny.net/css?family=' . $link;
1026
-			return 'https://fonts.googleapis.com/css?family=' . $link;
1027
-		}
1028
-
1029
-		/**
1030
-		 * Make_google_web_font_string Function.
1031
-		 * Creates the Google fonts link.
1032
-		 *
1033
-		 * @param array $fonts Array of Google fonts.
1034
-		 *
1035
-		 * @return string
1036
-		 *
1037
-		 * @since ReduxFramework 3.1.8
1038
-		 */
1039
-		public function make_google_web_font_string( array $fonts ): string {
1040
-			$link    = '';
1041
-			$subsets = array();
1042
-
1043
-			foreach ( $fonts as $family => $font ) {
1044
-				if ( ! empty( $link ) ) {
1045
-					$link .= "', '"; // Append a new font to the string.
1046
-				}
1047
-				$link .= $family;
1048
-
1049
-				if ( ! empty( $font['font-style'] ) || ! empty( $font['all-styles'] ) ) {
1050
-					$link .= ':';
1051
-					if ( ! empty( $font['all-styles'] ) ) {
1052
-						$link .= implode( ',', $font['all-styles'] );
1053
-					} elseif ( ! empty( $font['font-style'] ) ) {
1054
-						$link .= implode( ',', $font['font-style'] );
1055
-					}
1056
-				}
1057
-
1058
-				if ( ! empty( $font['subset'] ) || ! empty( $font['all-subsets'] ) ) {
1059
-					if ( ! empty( $font['all-subsets'] ) ) {
1060
-						foreach ( $font['all-subsets'] as $subset ) {
1061
-							if ( ! in_array( $subset, $subsets, true ) && ! is_numeric( $subset ) ) {
1062
-								$subsets[] = $subset;
1063
-							}
1064
-						}
1065
-					} elseif ( ! empty( $font['subset'] ) ) {
1066
-						foreach ( $font['subset'] as $subset ) {
1067
-							if ( ! in_array( $subset, $subsets, true ) && ! is_numeric( $subset ) ) {
1068
-								$subsets[] = $subset;
1069
-							}
1070
-						}
1071
-					}
1072
-				}
1073
-			}
1074
-
1075
-			if ( ! empty( $subsets ) ) {
1076
-				$link .= '&subset=' . implode( ',', $subsets );
1077
-			}
1078
-
1079
-			return "'" . $link . "'";
1080
-		}
1081
-
1082
-		/**
1083
-		 * Compiles field CSS for output.
1084
-		 *
1085
-		 * @param array $data Array of data to process.
1086
-		 *
1087
-		 * @return string
1088
-		 */
1089
-		public function css_style( $data ): string {
1090
-			$style = '';
1091
-
1092
-			$font = $data;
1093
-
1094
-			// Shim out old arg to new.
1095
-			if ( isset( $this->field['all_styles'] ) && ! empty( $this->field['all_styles'] ) ) {
1096
-				$this->field['all-styles'] = $this->field['all_styles'];
1097
-				unset( $this->field['all_styles'] );
1098
-			}
1099
-
1100
-			// Check for font-backup.  If it's set, stick it on a variable for
1101
-			// later use.
1102
-			if ( ! empty( $font['font-family'] ) && ! empty( $font['font-backup'] ) ) {
1103
-				$font['font-family'] = str_replace( ', ' . $font['font-backup'], '', $font['font-family'] );
1104
-				$font_backup         = ',' . $font['font-backup'];
1105
-			}
1106
-
1107
-			$font_value_set = false;
1108
-
1109
-			if ( ! empty( $font ) ) {
1110
-				foreach ( $font as $key => $value ) {
1111
-					if ( ! empty( $value ) && in_array( $key, array( 'font-family', 'font-weight' ), true ) ) {
1112
-						$font_value_set = true;
1113
-					}
1114
-				}
1115
-			}
1116
-
1117
-			if ( ! empty( $font ) ) {
1118
-				foreach ( $font as $key => $value ) {
1119
-					if ( 'font-options' === $key ) {
1120
-						continue;
1121
-					}
1122
-
1123
-					// Check for font-family key.
1124
-					if ( 'font-family' === $key ) {
1125
-
1126
-						// Enclose font family in quotes if spaces are in the
1127
-						// name.  This is necessary because if there are numerics
1128
-						// in the font name, they will not render properly.
1129
-						// Google should know better.
1130
-						if ( strpos( $value, ' ' ) && ! strpos( $value, ',' ) ) {
1131
-							$value = '"' . $value . '"';
1132
-						}
1133
-
1134
-						// Ensure fontBackup isn't empty. We already option
1135
-						// checked this earlier.  No need to do it again.
1136
-						if ( ! empty( $font_backup ) ) {
1137
-
1138
-							// Apply the backup font to the font-family element
1139
-							// via the saved variable.  We do this here, so it
1140
-							// doesn't get appended to the Google stuff below.
1141
-							$value .= $font_backup;
1142
-						}
1143
-					}
1144
-
1145
-					if ( empty( $value ) && in_array(
1146
-						$key,
1147
-						array(
1148
-							'font-weight',
1149
-							'font-style',
1150
-						),
1151
-						true
1152
-					) && true === $font_value_set ) {
1153
-						$value = 'normal';
1154
-					}
1155
-
1156
-					if ( 'font-weight' === $key && false === $this->field['font-weight'] ) {
1157
-						continue;
1158
-					}
1159
-
1160
-					if ( 'font-style' === $key && false === $this->field['font-style'] ) {
1161
-						continue;
1162
-					}
1163
-
1164
-					if ( 'google' === $key || 'subsets' === $key || 'font-backup' === $key || empty( $value ) ) {
1165
-						continue;
1166
-					}
1167
-
1168
-					if ( isset( $data['key'] ) ) {
1169
-						return $data;
1170
-					}
1171
-
1172
-					$continue = false;
1173
-
1174
-					if ( 'shadow-horizontal' === $key || 'shadow-vertical' === $key || 'shadow-blur' === $key ) {
1175
-						$continue = true;
1176
-					}
1177
-
1178
-					if ( 'shadow-color' === $key ) {
1179
-						if ( $this->field['text-shadow'] ) {
1180
-							$key   = 'text-shadow';
1181
-							$value = $data['shadow-horizontal'] . 'px ' . $data['shadow-vertical'] . 'px ' . $data['shadow-blur'] . 'px ' . $data['shadow-color'];
1182
-						} else {
1183
-							$continue = true;
1184
-						}
1185
-					}
1186
-
1187
-					if ( $continue ) {
1188
-						continue;
1189
-					}
1190
-
1191
-					$style .= $key . ':' . $value . ';';
1192
-				}
1193
-			}
1194
-
1195
-			return $style;
1196
-		}
1197
-
1198
-		/**
1199
-		 * CSS Output to send to the page.
1200
-		 *
1201
-		 * @param string|null|array $style CSS styles.
1202
-		 */
1203
-		public function output( $style = '' ) {
1204
-			$font = $this->value;
1205
-
1206
-			if ( '' !== $style ) {
1207
-				if ( ! empty( $this->field['output'] ) && ! is_array( $this->field['output'] ) ) {
1208
-					$this->field['output'] = array( $this->field['output'] );
1209
-				}
1210
-
1211
-				if ( ! empty( $this->field['output'] ) && is_array( $this->field['output'] ) ) {
1212
-					$keys                     = implode( ',', $this->field['output'] );
1213
-					$this->parent->outputCSS .= $keys . '{' . $style . '}';
1214
-				}
1215
-
1216
-				if ( ! empty( $this->field['compiler'] ) && ! is_array( $this->field['compiler'] ) ) {
1217
-					$this->field['compiler'] = array( $this->field['compiler'] );
1218
-				}
1219
-
1220
-				if ( ! empty( $this->field['compiler'] ) && is_array( $this->field['compiler'] ) ) {
1221
-					$keys                       = implode( ',', $this->field['compiler'] );
1222
-					$this->parent->compilerCSS .= $keys . '{' . $style . '}';
1223
-				}
1224
-			}
1225
-
1226
-			$this->set_google_fonts( (array) $font );
1227
-		}
1228
-
1229
-		/**
1230
-		 * Set global Google font data for global pointer.
1231
-		 *
1232
-		 * @param array $font Array of font data.
1233
-		 */
1234
-		private function set_google_fonts( array $font ) {
1235
-			// Google only stuff!
1236
-			if ( ! empty( $font['font-family'] ) && ! empty( $this->field['google'] ) && filter_var( $this->field['google'], FILTER_VALIDATE_BOOLEAN ) ) {
1237
-
1238
-				// Added standard font matching check to avoid output to Google fonts call - kp
1239
-				// If no custom font array was supplied, then load it with default
1240
-				// standard fonts.
1241
-				if ( empty( $this->field['fonts'] ) ) {
1242
-					$this->field['fonts'] = $this->std_fonts;
1243
-				}
1244
-
1245
-				// Ensure the fonts array is NOT empty.
1246
-				if ( ! empty( $this->field['fonts'] ) ) {
1247
-
1248
-					// Make the font keys in the array lowercase, for case-insensitive matching.
1249
-					$lc_fonts = array_change_key_case( $this->field['fonts'] );
1250
-
1251
-					// Rebuild font array with all keys stripped of spaces.
1252
-					$arr = array();
1253
-					foreach ( $lc_fonts as $key => $value ) {
1254
-						$key         = str_replace( ', ', ',', $key );
1255
-						$arr[ $key ] = $value;
1256
-					}
1257
-
1258
-					if ( is_array( $this->field['custom_fonts'] ) ) {
1259
-						$lc_fonts = array_change_key_case( $this->field['custom_fonts'] );
1260
-
1261
-						foreach ( $lc_fonts as $font_arr ) {
1262
-							foreach ( $font_arr as $key => $value ) {
1263
-								$arr[ Redux_Core::strtolower( $key ) ] = $key;
1264
-							}
1265
-						}
1266
-					}
1267
-
1268
-					$lc_fonts = $arr;
1269
-
1270
-					unset( $arr );
1271
-
1272
-					// lowercase chosen font for matching purposes.
1273
-					$lc_font = Redux_Core::strtolower( $font['font-family'] );
1274
-
1275
-					// Remove spaces after commas in chosen font for matching purposes.
1276
-					$lc_font = str_replace( ', ', ',', $lc_font );
1277
-
1278
-					// If the lower cased passed font-family is NOT found in the standard font array
1279
-					// Then it's a Google font, so process it for output.
1280
-					if ( ! array_key_exists( $lc_font, $lc_fonts ) ) {
1281
-						$family = $font['font-family'];
1282
-
1283
-						// TODO: This method doesn't respect spaces after commas, hence the reason
1284
-						// Strip out spaces in font names and replace with with plus signs
1285
-						// for the std_font array keys having no spaces after commas.  This could be
1286
-						// fixed with RegEx in the future.
1287
-						$font['font-family'] = str_replace( ' ', '+', $font['font-family'] );
1288
-
1289
-						// Push data to parent typography variable.
1290
-						if ( empty( Redux_Core::$typography[ $font['font-family'] ] ) ) {
1291
-							Redux_Core::$typography[ $font['font-family'] ] = array();
1292
-						}
1293
-
1294
-						if ( isset( $this->field['all-styles'] ) || isset( $this->field['all-subsets'] ) ) {
1295
-							if ( empty( $font['font-options'] ) ) {
1296
-								$this->get_google_array();
1297
-
1298
-								if ( isset( Redux_Core::$google_array ) && ! empty( Redux_Core::$google_array ) && isset( Redux_Core::$google_array[ $family ] ) ) {
1299
-									$font['font-options'] = Redux_Core::$google_array[ $family ];
1300
-								}
1301
-							} else {
1302
-								$font['font-options'] = json_decode( $font['font-options'], true );
1303
-							}
1304
-						}
1305
-
1306
-						if ( isset( $font['font-options'] ) && ! empty( $font['font-options'] ) && isset( $this->field['all-styles'] ) && filter_var( $this->field['all-styles'], FILTER_VALIDATE_BOOLEAN ) ) {
1307
-							if ( ! empty( $font['font-options']['variants'] ) ) {
1308
-								if ( ! isset( Redux_Core::$typography[ $font['font-family'] ]['all-styles'] ) || empty( Redux_Core::$typography[ $font['font-family'] ]['all-styles'] ) ) {
1309
-									Redux_Core::$typography[ $font['font-family'] ]['all-styles'] = array();
1310
-									foreach ( $font['font-options']['variants'] as $variant ) {
1311
-										Redux_Core::$typography[ $font['font-family'] ]['all-styles'][] = $variant['id'];
1312
-									}
1313
-								}
1314
-							}
1315
-						}
1316
-
1317
-						if ( isset( $font['font-options'] ) && ! empty( $font['font-options'] ) && isset( $this->field['all-subsets'] ) && $this->field['all-styles'] ) {
1318
-							if ( ! empty( $font['font-options']['subsets'] ) ) {
1319
-								if ( ! isset( Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] ) || empty( Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] ) ) {
1320
-									Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] = array();
1321
-									foreach ( $font['font-options']['subsets'] as $variant ) {
1322
-										Redux_Core::$typography[ $font['font-family'] ]['all-subsets'][] = $variant['id'];
1323
-									}
1324
-								}
1325
-							}
1326
-						}
1327
-
1328
-						$style = '';
1329
-
1330
-						if ( ! empty( $font['font-weight'] ) ) {
1331
-							if ( empty( Redux_Core::$typography[ $font['font-family'] ]['font-weight'] ) || ! in_array( $font['font-weight'], Redux_Core::$typography[ $font['font-family'] ]['font-weight'], true ) ) {
1332
-								$style = $font['font-weight'];
1333
-							}
1334
-
1335
-							if ( ! empty( $font['font-style'] ) ) {
1336
-								$style .= $font['font-style'];
1337
-							}
1338
-
1339
-							if ( empty( Redux_Core::$typography[ $font['font-family'] ]['font-style'] ) || ! in_array( $style, Redux_Core::$typography[ $font['font-family'] ]['font-style'], true ) ) {
1340
-								Redux_Core::$typography[ $font['font-family'] ]['font-style'][] = $style;
1341
-							}
1342
-						}
1343
-
1344
-						if ( ! empty( $font['subsets'] ) ) {
1345
-							if ( empty( Redux_Core::$typography[ $font['font-family'] ]['subset'] ) || ! in_array( $font['subsets'], Redux_Core::$typography[ $font['font-family'] ]['subset'], true ) ) {
1346
-								Redux_Core::$typography[ $font['font-family'] ]['subset'][] = $font['subsets'];
1347
-							}
1348
-						}
1349
-					}
1350
-				}
1351
-			}
1352
-		}
1353
-
1354
-		/**
1355
-		 * Localize standard, custom and typekit fonts.
1356
-		 */
1357
-		private function localize_std_fonts() {
1358
-			if ( false === $this->user_fonts ) {
1359
-				if ( isset( Redux_Core::$fonts['std'] ) && ! empty( Redux_Core::$fonts['std'] ) ) {
1360
-					return;
1361
-				}
1362
-
1363
-				Redux_Core::$font_groups['std'] = array(
1364
-					'text'     => esc_html__( 'Standard Fonts', 'redux-framework' ),
1365
-					'children' => array(),
1366
-				);
1367
-
1368
-				foreach ( $this->field['fonts'] as $font => $extra ) {
1369
-					Redux_Core::$font_groups['std']['children'][] = array(
1370
-						'id'          => $font,
1371
-						'text'        => $font,
1372
-						'data-google' => 'false',
1373
-					);
1374
-				}
1375
-			}
1376
-
1377
-			if ( false !== $this->field['custom_fonts'] ) {
1378
-				// phpcs:ignored WordPress.NamingConventions.ValidHookName
1379
-				$this->field['custom_fonts'] = apply_filters( "redux/{$this->parent->args['opt_name']}/field/typography/custom_fonts", array() );
1380
-
1381
-				if ( ! empty( $this->field['custom_fonts'] ) ) {
1382
-					foreach ( $this->field['custom_fonts'] as $group => $fonts ) {
1383
-						Redux_Core::$font_groups['customfonts'] = array(
1384
-							'text'     => $group,
1385
-							'children' => array(),
1386
-						);
1387
-
1388
-						foreach ( $fonts as $family => $v ) {
1389
-							Redux_Core::$font_groups['customfonts']['children'][] = array(
1390
-								'id'          => $family,
1391
-								'text'        => $family,
1392
-								'data-google' => 'false',
1393
-							);
1394
-						}
1395
-					}
1396
-				}
1397
-			}
1398
-
1399
-			// Typekit.
1400
-			// phpcs:ignored WordPress.NamingConventions.ValidHookName
1401
-			$typekit_fonts = apply_filters( "redux/{$this->parent->args['opt_name']}/field/typography/typekit_fonts", array() );
1402
-
1403
-			if ( ! empty( $typekit_fonts ) ) {
1404
-				foreach ( $typekit_fonts as $group => $fonts ) {
1405
-					Redux_Core::$font_groups['typekitfonts'] = array(
1406
-						'text'     => $group,
1407
-						'children' => array(),
1408
-					);
1409
-
1410
-					foreach ( $fonts as $family => $v ) {
1411
-						Redux_Core::$font_groups['typekitfonts']['children'][] = array(
1412
-							'text'        => $family,
1413
-							'id'          => $family,
1414
-							'data-google' => 'false',
1415
-						);
1416
-					}
1417
-				}
1418
-			}
1419
-		}
1420
-
1421
-		/**
1422
-		 *   Construct the Google array from the stored JSON/HTML
1423
-		 */
1424
-		private function get_google_array() {
1425
-			if ( ( ( isset( Redux_Core::$fonts['google'] ) && ! empty( Redux_Core::$fonts['google'] ) ) ) || ( isset( Redux_Core::$fonts['google'] ) && false === Redux_Core::$fonts['google'] ) ) {
1426
-				return;
1427
-			}
1428
-
1429
-			$fonts = Redux_Helpers::google_fonts_array( get_option( 'auto_update_redux_google_fonts', false ) );
1430
-			if ( empty( $fonts ) ) {
1431
-				$google_font = __DIR__ . '/googlefonts.php';
1432
-				$fonts       = include $google_font;
1433
-			}
1434
-
1435
-			if ( true === $fonts ) {
1436
-				Redux_Core::$fonts['google'] = false;
1437
-
1438
-				return;
1439
-			}
1440
-
1441
-			if ( isset( $fonts ) && ! empty( $fonts ) && is_array( $fonts ) ) {
1442
-				Redux_Core::$fonts['google'] = $fonts;
1443
-				Redux_Core::$google_array    = $fonts;
1444
-
1445
-				// optgroup.
1446
-				Redux_Core::$font_groups['google'] = array(
1447
-					'text'     => esc_html__( 'Google Webfonts', 'redux-framework' ),
1448
-					'children' => array(),
1449
-				);
1450
-
1451
-				// options.
1452
-				foreach ( Redux_Core::$fonts['google'] as $font => $extra ) {
1453
-					Redux_Core::$font_groups['google']['children'][] = array(
1454
-						'id'          => $font,
1455
-						'text'        => $font,
1456
-						'data-google' => 'true',
1457
-					);
1458
-				}
1459
-			}
1460
-		}
1461
-
1462
-		/**
1463
-		 * Clean up the Google Webfonts subsets to be human-readable
1464
-		 *
1465
-		 * @param array $var Font subset array.
1466
-		 *
1467
-		 * @return array
1468
-		 *
1469
-		 * @since ReduxFramework 0.2.0
1470
-		 */
1471
-		private function get_subsets( array $var ): array {
1472
-			$result = array();
1473
-
1474
-			foreach ( $var as $v ) {
1475
-				if ( strpos( $v, '-ext' ) ) {
1476
-					$name = ucfirst( str_replace( '-ext', ' Extended', $v ) );
1477
-				} else {
1478
-					$name = ucfirst( $v );
1479
-				}
1480
-
1481
-				$result[] = array(
1482
-					'id'   => $v,
1483
-					'name' => $name,
1484
-				);
1485
-			}
1486
-
1487
-			return array_filter( $result );
1488
-		}
1489
-
1490
-		/**
1491
-		 * Clean up the Google Webfonts variants to be human-readable
1492
-		 *
1493
-		 * @param array $var Font variant array.
1494
-		 *
1495
-		 * @return array
1496
-		 *
1497
-		 * @since ReduxFramework 0.2.0
1498
-		 */
1499
-		private function get_variants( array $var ): array {
1500
-			$result = array();
1501
-			$italic = array();
1502
-
1503
-			foreach ( $var as $v ) {
1504
-				$name = '';
1505
-				if ( 1 === $v[0] ) {
1506
-					$name = 'Ultra-Light 100';
1507
-				} elseif ( 2 === $v[0] ) {
1508
-					$name = 'Light 200';
1509
-				} elseif ( 3 === $v[0] ) {
1510
-					$name = 'Book 300';
1511
-				} elseif ( 4 === $v[0] || 'r' === $v[0] || 'i' === $v[0] ) {
1512
-					$name = 'Normal 400';
1513
-				} elseif ( 5 === $v[0] ) {
1514
-					$name = 'Medium 500';
1515
-				} elseif ( 6 === $v[0] ) {
1516
-					$name = 'Semi-Bold 600';
1517
-				} elseif ( 7 === $v[0] ) {
1518
-					$name = 'Bold 700';
1519
-				} elseif ( 8 === $v[0] ) {
1520
-					$name = 'Extra-Bold 800';
1521
-				} elseif ( 9 === $v[0] ) {
1522
-					$name = 'Ultra-Bold 900';
1523
-				}
1524
-
1525
-				if ( 'regular' === $v ) {
1526
-					$v = '400';
1527
-				}
1528
-
1529
-				if ( strpos( $v, 'italic' ) || 'italic' === $v ) {
1530
-					$name .= ' Italic';
1531
-					$name  = trim( $name );
1532
-					if ( 'italic' === $v ) {
1533
-						$v = '400italic';
1534
-					}
1535
-					$italic[] = array(
1536
-						'id'   => $v,
1537
-						'name' => $name,
1538
-					);
1539
-				} else {
1540
-					$result[] = array(
1541
-						'id'   => $v,
1542
-						'name' => $name,
1543
-					);
1544
-				}
1545
-			}
1546
-
1547
-			foreach ( $italic as $item ) {
1548
-				$result[] = $item;
1549
-			}
1550
-
1551
-			return array_filter( $result );
1552
-		}
1553
-
1554
-		/**
1555
-		 * Update google font array via AJAX call.
1556
-		 */
1557
-		public function google_fonts_update_ajax() {
1558
-			if ( ! isset( $_POST['nonce'] ) || ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'redux_update_google_fonts' ) ) ) {
1559
-				die( 'Security check' );
1560
-			}
1561
-
1562
-			if ( isset( $_POST['data'] ) && 'automatic' === $_POST['data'] ) {
1563
-				update_option( 'auto_update_redux_google_fonts', true );
1564
-			}
1565
-
1566
-			$fonts = Redux_Helpers::google_fonts_array( true );
1567
-
1568
-			if ( ! empty( $fonts ) && ! is_wp_error( $fonts ) ) {
1569
-				echo wp_json_encode(
1570
-					array(
1571
-						'status' => 'success',
1572
-						'fonts'  => $fonts,
1573
-					)
1574
-				);
1575
-			} else {
1576
-				$err_msg = '';
1577
-
1578
-				if ( is_wp_error( $fonts ) ) {
1579
-					$err_msg = $fonts->get_error_code();
1580
-				}
1581
-
1582
-				echo wp_json_encode(
1583
-					array(
1584
-						'status' => 'error',
1585
-						'error'  => $err_msg,
1586
-					)
1587
-				);
1588
-			}
1589
-
1590
-			die();
1591
-		}
1592
-
1593
-		/**
1594
-		 * Enable output_variables to be generated.
1595
-		 *
1596
-		 * @since       4.0.3
1597
-		 * @return void
1598
-		 */
1599
-		public function output_variables() {
1600
-			// No code needed, just defining the method is enough.
1601
-		}
1602
-	}
871
+                    echo '<input type="hidden" id="redux-slider-value-' . esc_attr( $this->field['id'] ) . '-b" class="typography-shadow-blur" name="' . esc_attr( $this->field['name'] . $this->field['name_suffix'] ) . '[shadow-blur]" value="' . esc_attr( $this->value['shadow-blur'] ) . '" data-id="' . esc_attr( $this->field['id'] ) . '"  />';
872
+                    echo '</div>';
873
+                }
874
+
875
+                echo '</div>'; // end typography container.
876
+            }
877
+        }
878
+
879
+        /**
880
+         * Enqueue for every field instance.
881
+         */
882
+        public function always_enqueue() {
883
+            $min = Redux_Functions::is_min();
884
+
885
+            if ( isset( $this->field['color_alpha'] ) && is_array( $this->field['color_alpha'] ) ) {
886
+                if ( $this->field['color_alpha']['color'] || $this->field['color_alpha']['shadow-color'] ) {
887
+                    wp_enqueue_script( 'redux-wp-color-picker-alpha' );
888
+                }
889
+            }
890
+
891
+            if ( ! wp_style_is( 'redux-nouislider' ) && isset( $this->field['text-shadow'] ) && $this->field['text-shadow'] ) {
892
+                wp_enqueue_style(
893
+                    'redux-nouislider',
894
+                    Redux_Core::$url . "assets/css/vendor/nouislider$min.css",
895
+                    array(),
896
+                    '5.0.0'
897
+                );
898
+
899
+                wp_enqueue_script(
900
+                    'redux-nouislider',
901
+                    Redux_Core::$url . "assets/js/vendor/nouislider/redux.jquery.nouislider$min.js",
902
+                    array( 'jquery' ),
903
+                    '5.0.0',
904
+                    true
905
+                );
906
+            }
907
+        }
908
+
909
+        /**
910
+         * Enqueue Function.
911
+         * If this field requires any scripts, or CSS define this function and register/enqueue the scripts/css
912
+         *
913
+         * @since ReduxFramework 1.0.0
914
+         */
915
+        public function enqueue() {
916
+            $min = Redux_Functions::is_min();
917
+
918
+            if ( ! wp_style_is( 'select2-css' ) ) {
919
+                wp_enqueue_style( 'select2-css' );
920
+            }
921
+
922
+            if ( ! wp_style_is( 'wp-color-picker' ) ) {
923
+                wp_enqueue_style( 'wp-color-picker' );
924
+            }
925
+
926
+            wp_enqueue_script(
927
+                'redux-webfont',
928
+                '//' . 'ajax' . '.googleapis' . '.com/ajax/libs/webfont/1.6.26/webfont.js', // phpcs:ignore Generic.Strings.UnnecessaryStringConcat
929
+                array(),
930
+                '1.6.26',
931
+                true
932
+            );
933
+
934
+            $dep_array = array( 'jquery', 'wp-color-picker', 'select2-js', 'redux-js', 'redux-webfont' );
935
+
936
+            wp_enqueue_script(
937
+                'redux-field-typography',
938
+                Redux_Core::$url . "inc/fields/typography/redux-typography$min.js",
939
+                $dep_array,
940
+                $this->timestamp,
941
+                true
942
+            );
943
+
944
+            wp_localize_script(
945
+                'redux-field-typography',
946
+                'redux_typography_ajax',
947
+                array(
948
+                    'ajaxurl'             => esc_url( admin_url( 'admin-ajax.php' ) ),
949
+                    'update_google_fonts' => array(
950
+                        'updating' => esc_html__( 'Downloading Google Fonts...', 'redux-framework' ),
951
+                        // translators: Aria title, link title.
952
+                        'error'    => sprintf( esc_html__( 'Update Failed|msg. %1$s', 'redux-framework' ), sprintf( '<a href="#" class="update-google-fonts" data-action="manual" aria-label="%s">%s</a>', esc_html__( 'Retry?', 'redux-framework' ), esc_html__( 'Retry?', 'redux-framework' ) ) ),
953
+                        // translators: Javascript reload command, link title.
954
+                        'success'  => sprintf( esc_html__( 'Updated! %1$s to start using your updated fonts.', 'redux-framework' ), sprintf( '<a href="	%1$s">%2$s</a>', 'javascript:location.reload();', esc_html__( 'Reload the page', 'redux-framework' ) ) ),
955
+                    ),
956
+                )
957
+            );
958
+
959
+            if ( $this->parent->args['dev_mode'] ) {
960
+                wp_enqueue_style( 'redux-color-picker' );
961
+
962
+                wp_enqueue_style(
963
+                    'redux-field-typography',
964
+                    Redux_Core::$url . 'inc/fields/typography/redux-typography.css',
965
+                    array(),
966
+                    $this->timestamp
967
+                );
968
+            }
969
+        }
970
+
971
+        /**
972
+         * Make_google_web_font_link Function.
973
+         * Creates the Google fonts link.
974
+         *
975
+         * @param array $fonts Array of google fonts.
976
+         *
977
+         * @return string
978
+         *
979
+         * @since ReduxFramework 3.0.0
980
+         */
981
+        public function make_google_web_font_link( array $fonts ): string {
982
+            $link    = '';
983
+            $subsets = array();
984
+
985
+            foreach ( $fonts as $family => $font ) {
986
+                if ( ! empty( $link ) ) {
987
+                    $link .= '|'; // Append a new font to the string.
988
+                }
989
+                $link .= $family;
990
+
991
+                if ( ! empty( $font['font-style'] ) || ! empty( $font['all-styles'] ) ) {
992
+                    $link .= ':';
993
+                    if ( ! empty( $font['all-styles'] ) ) {
994
+                        $link .= implode( ',', $font['all-styles'] );
995
+                    } elseif ( ! empty( $font['font-style'] ) ) {
996
+                        $link .= implode( ',', $font['font-style'] );
997
+                    }
998
+                }
999
+
1000
+                if ( ! empty( $font['subset'] ) || ! empty( $font['all-subsets'] ) ) {
1001
+                    if ( ! empty( $font['all-subsets'] ) ) {
1002
+                        foreach ( $font['all-subsets'] as $subset ) {
1003
+                            if ( ! in_array( $subset, $subsets, true ) ) {
1004
+                                $subsets[] = $subset;
1005
+                            }
1006
+                        }
1007
+                    } elseif ( ! empty( $font['subset'] ) ) {
1008
+                        foreach ( $font['subset'] as $subset ) {
1009
+                            if ( ! in_array( $subset, $subsets, true ) ) {
1010
+                                $subsets[] = $subset;
1011
+                            }
1012
+                        }
1013
+                    }
1014
+                }
1015
+            }
1016
+
1017
+            if ( ! empty( $subsets ) ) {
1018
+                $link .= '&subset=' . implode( ',', $subsets );
1019
+            }
1020
+
1021
+            $display = $this->parent->args['font_display'] ?? 'swap';
1022
+
1023
+            $link .= '&display=' . $display;
1024
+
1025
+            // return 'https://fonts.bunny.net/css?family=' . $link;
1026
+            return 'https://fonts.googleapis.com/css?family=' . $link;
1027
+        }
1028
+
1029
+        /**
1030
+         * Make_google_web_font_string Function.
1031
+         * Creates the Google fonts link.
1032
+         *
1033
+         * @param array $fonts Array of Google fonts.
1034
+         *
1035
+         * @return string
1036
+         *
1037
+         * @since ReduxFramework 3.1.8
1038
+         */
1039
+        public function make_google_web_font_string( array $fonts ): string {
1040
+            $link    = '';
1041
+            $subsets = array();
1042
+
1043
+            foreach ( $fonts as $family => $font ) {
1044
+                if ( ! empty( $link ) ) {
1045
+                    $link .= "', '"; // Append a new font to the string.
1046
+                }
1047
+                $link .= $family;
1048
+
1049
+                if ( ! empty( $font['font-style'] ) || ! empty( $font['all-styles'] ) ) {
1050
+                    $link .= ':';
1051
+                    if ( ! empty( $font['all-styles'] ) ) {
1052
+                        $link .= implode( ',', $font['all-styles'] );
1053
+                    } elseif ( ! empty( $font['font-style'] ) ) {
1054
+                        $link .= implode( ',', $font['font-style'] );
1055
+                    }
1056
+                }
1057
+
1058
+                if ( ! empty( $font['subset'] ) || ! empty( $font['all-subsets'] ) ) {
1059
+                    if ( ! empty( $font['all-subsets'] ) ) {
1060
+                        foreach ( $font['all-subsets'] as $subset ) {
1061
+                            if ( ! in_array( $subset, $subsets, true ) && ! is_numeric( $subset ) ) {
1062
+                                $subsets[] = $subset;
1063
+                            }
1064
+                        }
1065
+                    } elseif ( ! empty( $font['subset'] ) ) {
1066
+                        foreach ( $font['subset'] as $subset ) {
1067
+                            if ( ! in_array( $subset, $subsets, true ) && ! is_numeric( $subset ) ) {
1068
+                                $subsets[] = $subset;
1069
+                            }
1070
+                        }
1071
+                    }
1072
+                }
1073
+            }
1074
+
1075
+            if ( ! empty( $subsets ) ) {
1076
+                $link .= '&subset=' . implode( ',', $subsets );
1077
+            }
1078
+
1079
+            return "'" . $link . "'";
1080
+        }
1081
+
1082
+        /**
1083
+         * Compiles field CSS for output.
1084
+         *
1085
+         * @param array $data Array of data to process.
1086
+         *
1087
+         * @return string
1088
+         */
1089
+        public function css_style( $data ): string {
1090
+            $style = '';
1091
+
1092
+            $font = $data;
1093
+
1094
+            // Shim out old arg to new.
1095
+            if ( isset( $this->field['all_styles'] ) && ! empty( $this->field['all_styles'] ) ) {
1096
+                $this->field['all-styles'] = $this->field['all_styles'];
1097
+                unset( $this->field['all_styles'] );
1098
+            }
1099
+
1100
+            // Check for font-backup.  If it's set, stick it on a variable for
1101
+            // later use.
1102
+            if ( ! empty( $font['font-family'] ) && ! empty( $font['font-backup'] ) ) {
1103
+                $font['font-family'] = str_replace( ', ' . $font['font-backup'], '', $font['font-family'] );
1104
+                $font_backup         = ',' . $font['font-backup'];
1105
+            }
1106
+
1107
+            $font_value_set = false;
1108
+
1109
+            if ( ! empty( $font ) ) {
1110
+                foreach ( $font as $key => $value ) {
1111
+                    if ( ! empty( $value ) && in_array( $key, array( 'font-family', 'font-weight' ), true ) ) {
1112
+                        $font_value_set = true;
1113
+                    }
1114
+                }
1115
+            }
1116
+
1117
+            if ( ! empty( $font ) ) {
1118
+                foreach ( $font as $key => $value ) {
1119
+                    if ( 'font-options' === $key ) {
1120
+                        continue;
1121
+                    }
1122
+
1123
+                    // Check for font-family key.
1124
+                    if ( 'font-family' === $key ) {
1125
+
1126
+                        // Enclose font family in quotes if spaces are in the
1127
+                        // name.  This is necessary because if there are numerics
1128
+                        // in the font name, they will not render properly.
1129
+                        // Google should know better.
1130
+                        if ( strpos( $value, ' ' ) && ! strpos( $value, ',' ) ) {
1131
+                            $value = '"' . $value . '"';
1132
+                        }
1133
+
1134
+                        // Ensure fontBackup isn't empty. We already option
1135
+                        // checked this earlier.  No need to do it again.
1136
+                        if ( ! empty( $font_backup ) ) {
1137
+
1138
+                            // Apply the backup font to the font-family element
1139
+                            // via the saved variable.  We do this here, so it
1140
+                            // doesn't get appended to the Google stuff below.
1141
+                            $value .= $font_backup;
1142
+                        }
1143
+                    }
1144
+
1145
+                    if ( empty( $value ) && in_array(
1146
+                        $key,
1147
+                        array(
1148
+                            'font-weight',
1149
+                            'font-style',
1150
+                        ),
1151
+                        true
1152
+                    ) && true === $font_value_set ) {
1153
+                        $value = 'normal';
1154
+                    }
1155
+
1156
+                    if ( 'font-weight' === $key && false === $this->field['font-weight'] ) {
1157
+                        continue;
1158
+                    }
1159
+
1160
+                    if ( 'font-style' === $key && false === $this->field['font-style'] ) {
1161
+                        continue;
1162
+                    }
1163
+
1164
+                    if ( 'google' === $key || 'subsets' === $key || 'font-backup' === $key || empty( $value ) ) {
1165
+                        continue;
1166
+                    }
1167
+
1168
+                    if ( isset( $data['key'] ) ) {
1169
+                        return $data;
1170
+                    }
1171
+
1172
+                    $continue = false;
1173
+
1174
+                    if ( 'shadow-horizontal' === $key || 'shadow-vertical' === $key || 'shadow-blur' === $key ) {
1175
+                        $continue = true;
1176
+                    }
1177
+
1178
+                    if ( 'shadow-color' === $key ) {
1179
+                        if ( $this->field['text-shadow'] ) {
1180
+                            $key   = 'text-shadow';
1181
+                            $value = $data['shadow-horizontal'] . 'px ' . $data['shadow-vertical'] . 'px ' . $data['shadow-blur'] . 'px ' . $data['shadow-color'];
1182
+                        } else {
1183
+                            $continue = true;
1184
+                        }
1185
+                    }
1186
+
1187
+                    if ( $continue ) {
1188
+                        continue;
1189
+                    }
1190
+
1191
+                    $style .= $key . ':' . $value . ';';
1192
+                }
1193
+            }
1194
+
1195
+            return $style;
1196
+        }
1197
+
1198
+        /**
1199
+         * CSS Output to send to the page.
1200
+         *
1201
+         * @param string|null|array $style CSS styles.
1202
+         */
1203
+        public function output( $style = '' ) {
1204
+            $font = $this->value;
1205
+
1206
+            if ( '' !== $style ) {
1207
+                if ( ! empty( $this->field['output'] ) && ! is_array( $this->field['output'] ) ) {
1208
+                    $this->field['output'] = array( $this->field['output'] );
1209
+                }
1210
+
1211
+                if ( ! empty( $this->field['output'] ) && is_array( $this->field['output'] ) ) {
1212
+                    $keys                     = implode( ',', $this->field['output'] );
1213
+                    $this->parent->outputCSS .= $keys . '{' . $style . '}';
1214
+                }
1215
+
1216
+                if ( ! empty( $this->field['compiler'] ) && ! is_array( $this->field['compiler'] ) ) {
1217
+                    $this->field['compiler'] = array( $this->field['compiler'] );
1218
+                }
1219
+
1220
+                if ( ! empty( $this->field['compiler'] ) && is_array( $this->field['compiler'] ) ) {
1221
+                    $keys                       = implode( ',', $this->field['compiler'] );
1222
+                    $this->parent->compilerCSS .= $keys . '{' . $style . '}';
1223
+                }
1224
+            }
1225
+
1226
+            $this->set_google_fonts( (array) $font );
1227
+        }
1228
+
1229
+        /**
1230
+         * Set global Google font data for global pointer.
1231
+         *
1232
+         * @param array $font Array of font data.
1233
+         */
1234
+        private function set_google_fonts( array $font ) {
1235
+            // Google only stuff!
1236
+            if ( ! empty( $font['font-family'] ) && ! empty( $this->field['google'] ) && filter_var( $this->field['google'], FILTER_VALIDATE_BOOLEAN ) ) {
1237
+
1238
+                // Added standard font matching check to avoid output to Google fonts call - kp
1239
+                // If no custom font array was supplied, then load it with default
1240
+                // standard fonts.
1241
+                if ( empty( $this->field['fonts'] ) ) {
1242
+                    $this->field['fonts'] = $this->std_fonts;
1243
+                }
1244
+
1245
+                // Ensure the fonts array is NOT empty.
1246
+                if ( ! empty( $this->field['fonts'] ) ) {
1247
+
1248
+                    // Make the font keys in the array lowercase, for case-insensitive matching.
1249
+                    $lc_fonts = array_change_key_case( $this->field['fonts'] );
1250
+
1251
+                    // Rebuild font array with all keys stripped of spaces.
1252
+                    $arr = array();
1253
+                    foreach ( $lc_fonts as $key => $value ) {
1254
+                        $key         = str_replace( ', ', ',', $key );
1255
+                        $arr[ $key ] = $value;
1256
+                    }
1257
+
1258
+                    if ( is_array( $this->field['custom_fonts'] ) ) {
1259
+                        $lc_fonts = array_change_key_case( $this->field['custom_fonts'] );
1260
+
1261
+                        foreach ( $lc_fonts as $font_arr ) {
1262
+                            foreach ( $font_arr as $key => $value ) {
1263
+                                $arr[ Redux_Core::strtolower( $key ) ] = $key;
1264
+                            }
1265
+                        }
1266
+                    }
1267
+
1268
+                    $lc_fonts = $arr;
1269
+
1270
+                    unset( $arr );
1271
+
1272
+                    // lowercase chosen font for matching purposes.
1273
+                    $lc_font = Redux_Core::strtolower( $font['font-family'] );
1274
+
1275
+                    // Remove spaces after commas in chosen font for matching purposes.
1276
+                    $lc_font = str_replace( ', ', ',', $lc_font );
1277
+
1278
+                    // If the lower cased passed font-family is NOT found in the standard font array
1279
+                    // Then it's a Google font, so process it for output.
1280
+                    if ( ! array_key_exists( $lc_font, $lc_fonts ) ) {
1281
+                        $family = $font['font-family'];
1282
+
1283
+                        // TODO: This method doesn't respect spaces after commas, hence the reason
1284
+                        // Strip out spaces in font names and replace with with plus signs
1285
+                        // for the std_font array keys having no spaces after commas.  This could be
1286
+                        // fixed with RegEx in the future.
1287
+                        $font['font-family'] = str_replace( ' ', '+', $font['font-family'] );
1288
+
1289
+                        // Push data to parent typography variable.
1290
+                        if ( empty( Redux_Core::$typography[ $font['font-family'] ] ) ) {
1291
+                            Redux_Core::$typography[ $font['font-family'] ] = array();
1292
+                        }
1293
+
1294
+                        if ( isset( $this->field['all-styles'] ) || isset( $this->field['all-subsets'] ) ) {
1295
+                            if ( empty( $font['font-options'] ) ) {
1296
+                                $this->get_google_array();
1297
+
1298
+                                if ( isset( Redux_Core::$google_array ) && ! empty( Redux_Core::$google_array ) && isset( Redux_Core::$google_array[ $family ] ) ) {
1299
+                                    $font['font-options'] = Redux_Core::$google_array[ $family ];
1300
+                                }
1301
+                            } else {
1302
+                                $font['font-options'] = json_decode( $font['font-options'], true );
1303
+                            }
1304
+                        }
1305
+
1306
+                        if ( isset( $font['font-options'] ) && ! empty( $font['font-options'] ) && isset( $this->field['all-styles'] ) && filter_var( $this->field['all-styles'], FILTER_VALIDATE_BOOLEAN ) ) {
1307
+                            if ( ! empty( $font['font-options']['variants'] ) ) {
1308
+                                if ( ! isset( Redux_Core::$typography[ $font['font-family'] ]['all-styles'] ) || empty( Redux_Core::$typography[ $font['font-family'] ]['all-styles'] ) ) {
1309
+                                    Redux_Core::$typography[ $font['font-family'] ]['all-styles'] = array();
1310
+                                    foreach ( $font['font-options']['variants'] as $variant ) {
1311
+                                        Redux_Core::$typography[ $font['font-family'] ]['all-styles'][] = $variant['id'];
1312
+                                    }
1313
+                                }
1314
+                            }
1315
+                        }
1316
+
1317
+                        if ( isset( $font['font-options'] ) && ! empty( $font['font-options'] ) && isset( $this->field['all-subsets'] ) && $this->field['all-styles'] ) {
1318
+                            if ( ! empty( $font['font-options']['subsets'] ) ) {
1319
+                                if ( ! isset( Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] ) || empty( Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] ) ) {
1320
+                                    Redux_Core::$typography[ $font['font-family'] ]['all-subsets'] = array();
1321
+                                    foreach ( $font['font-options']['subsets'] as $variant ) {
1322
+                                        Redux_Core::$typography[ $font['font-family'] ]['all-subsets'][] = $variant['id'];
1323
+                                    }
1324
+                                }
1325
+                            }
1326
+                        }
1327
+
1328
+                        $style = '';
1329
+
1330
+                        if ( ! empty( $font['font-weight'] ) ) {
1331
+                            if ( empty( Redux_Core::$typography[ $font['font-family'] ]['font-weight'] ) || ! in_array( $font['font-weight'], Redux_Core::$typography[ $font['font-family'] ]['font-weight'], true ) ) {
1332
+                                $style = $font['font-weight'];
1333
+                            }
1334
+
1335
+                            if ( ! empty( $font['font-style'] ) ) {
1336
+                                $style .= $font['font-style'];
1337
+                            }
1338
+
1339
+                            if ( empty( Redux_Core::$typography[ $font['font-family'] ]['font-style'] ) || ! in_array( $style, Redux_Core::$typography[ $font['font-family'] ]['font-style'], true ) ) {
1340
+                                Redux_Core::$typography[ $font['font-family'] ]['font-style'][] = $style;
1341
+                            }
1342
+                        }
1343
+
1344
+                        if ( ! empty( $font['subsets'] ) ) {
1345
+                            if ( empty( Redux_Core::$typography[ $font['font-family'] ]['subset'] ) || ! in_array( $font['subsets'], Redux_Core::$typography[ $font['font-family'] ]['subset'], true ) ) {
1346
+                                Redux_Core::$typography[ $font['font-family'] ]['subset'][] = $font['subsets'];
1347
+                            }
1348
+                        }
1349
+                    }
1350
+                }
1351
+            }
1352
+        }
1353
+
1354
+        /**
1355
+         * Localize standard, custom and typekit fonts.
1356
+         */
1357
+        private function localize_std_fonts() {
1358
+            if ( false === $this->user_fonts ) {
1359
+                if ( isset( Redux_Core::$fonts['std'] ) && ! empty( Redux_Core::$fonts['std'] ) ) {
1360
+                    return;
1361
+                }
1362
+
1363
+                Redux_Core::$font_groups['std'] = array(
1364
+                    'text'     => esc_html__( 'Standard Fonts', 'redux-framework' ),
1365
+                    'children' => array(),
1366
+                );
1367
+
1368
+                foreach ( $this->field['fonts'] as $font => $extra ) {
1369
+                    Redux_Core::$font_groups['std']['children'][] = array(
1370
+                        'id'          => $font,
1371
+                        'text'        => $font,
1372
+                        'data-google' => 'false',
1373
+                    );
1374
+                }
1375
+            }
1376
+
1377
+            if ( false !== $this->field['custom_fonts'] ) {
1378
+                // phpcs:ignored WordPress.NamingConventions.ValidHookName
1379
+                $this->field['custom_fonts'] = apply_filters( "redux/{$this->parent->args['opt_name']}/field/typography/custom_fonts", array() );
1380
+
1381
+                if ( ! empty( $this->field['custom_fonts'] ) ) {
1382
+                    foreach ( $this->field['custom_fonts'] as $group => $fonts ) {
1383
+                        Redux_Core::$font_groups['customfonts'] = array(
1384
+                            'text'     => $group,
1385
+                            'children' => array(),
1386
+                        );
1387
+
1388
+                        foreach ( $fonts as $family => $v ) {
1389
+                            Redux_Core::$font_groups['customfonts']['children'][] = array(
1390
+                                'id'          => $family,
1391
+                                'text'        => $family,
1392
+                                'data-google' => 'false',
1393
+                            );
1394
+                        }
1395
+                    }
1396
+                }
1397
+            }
1398
+
1399
+            // Typekit.
1400
+            // phpcs:ignored WordPress.NamingConventions.ValidHookName
1401
+            $typekit_fonts = apply_filters( "redux/{$this->parent->args['opt_name']}/field/typography/typekit_fonts", array() );
1402
+
1403
+            if ( ! empty( $typekit_fonts ) ) {
1404
+                foreach ( $typekit_fonts as $group => $fonts ) {
1405
+                    Redux_Core::$font_groups['typekitfonts'] = array(
1406
+                        'text'     => $group,
1407
+                        'children' => array(),
1408
+                    );
1409
+
1410
+                    foreach ( $fonts as $family => $v ) {
1411
+                        Redux_Core::$font_groups['typekitfonts']['children'][] = array(
1412
+                            'text'        => $family,
1413
+                            'id'          => $family,
1414
+                            'data-google' => 'false',
1415
+                        );
1416
+                    }
1417
+                }
1418
+            }
1419
+        }
1420
+
1421
+        /**
1422
+         *   Construct the Google array from the stored JSON/HTML
1423
+         */
1424
+        private function get_google_array() {
1425
+            if ( ( ( isset( Redux_Core::$fonts['google'] ) && ! empty( Redux_Core::$fonts['google'] ) ) ) || ( isset( Redux_Core::$fonts['google'] ) && false === Redux_Core::$fonts['google'] ) ) {
1426
+                return;
1427
+            }
1428
+
1429
+            $fonts = Redux_Helpers::google_fonts_array( get_option( 'auto_update_redux_google_fonts', false ) );
1430
+            if ( empty( $fonts ) ) {
1431
+                $google_font = __DIR__ . '/googlefonts.php';
1432
+                $fonts       = include $google_font;
1433
+            }
1434
+
1435
+            if ( true === $fonts ) {
1436
+                Redux_Core::$fonts['google'] = false;
1437
+
1438
+                return;
1439
+            }
1440
+
1441
+            if ( isset( $fonts ) && ! empty( $fonts ) && is_array( $fonts ) ) {
1442
+                Redux_Core::$fonts['google'] = $fonts;
1443
+                Redux_Core::$google_array    = $fonts;
1444
+
1445
+                // optgroup.
1446
+                Redux_Core::$font_groups['google'] = array(
1447
+                    'text'     => esc_html__( 'Google Webfonts', 'redux-framework' ),
1448
+                    'children' => array(),
1449
+                );
1450
+
1451
+                // options.
1452
+                foreach ( Redux_Core::$fonts['google'] as $font => $extra ) {
1453
+                    Redux_Core::$font_groups['google']['children'][] = array(
1454
+                        'id'          => $font,
1455
+                        'text'        => $font,
1456
+                        'data-google' => 'true',
1457
+                    );
1458
+                }
1459
+            }
1460
+        }
1461
+
1462
+        /**
1463
+         * Clean up the Google Webfonts subsets to be human-readable
1464
+         *
1465
+         * @param array $var Font subset array.
1466
+         *
1467
+         * @return array
1468
+         *
1469
+         * @since ReduxFramework 0.2.0
1470
+         */
1471
+        private function get_subsets( array $var ): array {
1472
+            $result = array();
1473
+
1474
+            foreach ( $var as $v ) {
1475
+                if ( strpos( $v, '-ext' ) ) {
1476
+                    $name = ucfirst( str_replace( '-ext', ' Extended', $v ) );
1477
+                } else {
1478
+                    $name = ucfirst( $v );
1479
+                }
1480
+
1481
+                $result[] = array(
1482
+                    'id'   => $v,
1483
+                    'name' => $name,
1484
+                );
1485
+            }
1486
+
1487
+            return array_filter( $result );
1488
+        }
1489
+
1490
+        /**
1491
+         * Clean up the Google Webfonts variants to be human-readable
1492
+         *
1493
+         * @param array $var Font variant array.
1494
+         *
1495
+         * @return array
1496
+         *
1497
+         * @since ReduxFramework 0.2.0
1498
+         */
1499
+        private function get_variants( array $var ): array {
1500
+            $result = array();
1501
+            $italic = array();
1502
+
1503
+            foreach ( $var as $v ) {
1504
+                $name = '';
1505
+                if ( 1 === $v[0] ) {
1506
+                    $name = 'Ultra-Light 100';
1507
+                } elseif ( 2 === $v[0] ) {
1508
+                    $name = 'Light 200';
1509
+                } elseif ( 3 === $v[0] ) {
1510
+                    $name = 'Book 300';
1511
+                } elseif ( 4 === $v[0] || 'r' === $v[0] || 'i' === $v[0] ) {
1512
+                    $name = 'Normal 400';
1513
+                } elseif ( 5 === $v[0] ) {
1514
+                    $name = 'Medium 500';
1515
+                } elseif ( 6 === $v[0] ) {
1516
+                    $name = 'Semi-Bold 600';
1517
+                } elseif ( 7 === $v[0] ) {
1518
+                    $name = 'Bold 700';
1519
+                } elseif ( 8 === $v[0] ) {
1520
+                    $name = 'Extra-Bold 800';
1521
+                } elseif ( 9 === $v[0] ) {
1522
+                    $name = 'Ultra-Bold 900';
1523
+                }
1524
+
1525
+                if ( 'regular' === $v ) {
1526
+                    $v = '400';
1527
+                }
1528
+
1529
+                if ( strpos( $v, 'italic' ) || 'italic' === $v ) {
1530
+                    $name .= ' Italic';
1531
+                    $name  = trim( $name );
1532
+                    if ( 'italic' === $v ) {
1533
+                        $v = '400italic';
1534
+                    }
1535
+                    $italic[] = array(
1536
+                        'id'   => $v,
1537
+                        'name' => $name,
1538
+                    );
1539
+                } else {
1540
+                    $result[] = array(
1541
+                        'id'   => $v,
1542
+                        'name' => $name,
1543
+                    );
1544
+                }
1545
+            }
1546
+
1547
+            foreach ( $italic as $item ) {
1548
+                $result[] = $item;
1549
+            }
1550
+
1551
+            return array_filter( $result );
1552
+        }
1553
+
1554
+        /**
1555
+         * Update google font array via AJAX call.
1556
+         */
1557
+        public function google_fonts_update_ajax() {
1558
+            if ( ! isset( $_POST['nonce'] ) || ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'redux_update_google_fonts' ) ) ) {
1559
+                die( 'Security check' );
1560
+            }
1561
+
1562
+            if ( isset( $_POST['data'] ) && 'automatic' === $_POST['data'] ) {
1563
+                update_option( 'auto_update_redux_google_fonts', true );
1564
+            }
1565
+
1566
+            $fonts = Redux_Helpers::google_fonts_array( true );
1567
+
1568
+            if ( ! empty( $fonts ) && ! is_wp_error( $fonts ) ) {
1569
+                echo wp_json_encode(
1570
+                    array(
1571
+                        'status' => 'success',
1572
+                        'fonts'  => $fonts,
1573
+                    )
1574
+                );
1575
+            } else {
1576
+                $err_msg = '';
1577
+
1578
+                if ( is_wp_error( $fonts ) ) {
1579
+                    $err_msg = $fonts->get_error_code();
1580
+                }
1581
+
1582
+                echo wp_json_encode(
1583
+                    array(
1584
+                        'status' => 'error',
1585
+                        'error'  => $err_msg,
1586
+                    )
1587
+                );
1588
+            }
1589
+
1590
+            die();
1591
+        }
1592
+
1593
+        /**
1594
+         * Enable output_variables to be generated.
1595
+         *
1596
+         * @since       4.0.3
1597
+         * @return void
1598
+         */
1599
+        public function output_variables() {
1600
+            // No code needed, just defining the method is enough.
1601
+        }
1602
+    }
1603 1603
 }
1604 1604
 if ( ! class_exists( 'ReduxFramework_Typography' ) ) {
1605
-	class_alias( 'Redux_Typography', 'ReduxFramework_Typography' );
1605
+    class_alias( 'Redux_Typography', 'ReduxFramework_Typography' );
1606 1606
 }
Please login to merge, or discard this patch.
redux-core/inc/fields/raw/class-redux-raw.php 1 patch
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -11,53 +11,53 @@
 block discarded – undo
11 11
 
12 12
 if ( ! class_exists( 'Redux_Raw', false ) ) {
13 13
 
14
-	/**
15
-	 * Class Redux_Raw
16
-	 */
17
-	class Redux_Raw extends Redux_Field {
18
-
19
-		/**
20
-		 * Set field defaults.
21
-		 */
22
-		public function set_defaults() {
23
-			$defaults = array(
24
-				'full_width' => true,
25
-				'markdown'   => false,
26
-			);
27
-
28
-			$this->field = wp_parse_args( $this->field, $defaults );
29
-		}
30
-
31
-		/**
32
-		 * Field Render Function.
33
-		 * Takes the vars and outputs the HTML for the field in the settings
34
-		 *
35
-		 * @since ReduxFramework 1.0.0
36
-		 */
37
-		public function render() {
38
-			if ( ! empty( $this->field['include'] ) && file_exists( $this->field['include'] ) ) {
39
-				require_once $this->field['include'];
40
-			}
41
-
42
-			if ( isset( $this->field['content_path'] ) && ! empty( $this->field['content_path'] ) && file_exists( $this->field['content_path'] ) ) {
43
-				$this->field['content'] = Redux_Core::$filesystem->execute( 'get_contents', $this->field['content_path'] );
44
-			}
45
-
46
-			if ( ! empty( $this->field['content'] ) && isset( $this->field['content'] ) ) {
47
-				if ( isset( $this->field['markdown'] ) && true === $this->field['markdown'] && ! empty( $this->field['content'] ) ) {
48
-					require_once __DIR__ . '/parsedown.php';
49
-					$parsedown = new Redux_Parsedown();
50
-
51
-					echo( $parsedown->text( $this->field['content'] ) ); // phpcs:ignore WordPress.Security.EscapeOutput
52
-				} else {
53
-					echo( $this->field['content'] ); // phpcs:ignore WordPress.Security.EscapeOutput
54
-				}
55
-			}
56
-
57
-			// phpcs:ignore WordPress.NamingConventions.ValidHookName
58
-			do_action( 'redux-field-raw-' . $this->parent->args['opt_name'] . '-' . $this->field['id'] );
59
-		}
60
-	}
14
+    /**
15
+     * Class Redux_Raw
16
+     */
17
+    class Redux_Raw extends Redux_Field {
18
+
19
+        /**
20
+         * Set field defaults.
21
+         */
22
+        public function set_defaults() {
23
+            $defaults = array(
24
+                'full_width' => true,
25
+                'markdown'   => false,
26
+            );
27
+
28
+            $this->field = wp_parse_args( $this->field, $defaults );
29
+        }
30
+
31
+        /**
32
+         * Field Render Function.
33
+         * Takes the vars and outputs the HTML for the field in the settings
34
+         *
35
+         * @since ReduxFramework 1.0.0
36
+         */
37
+        public function render() {
38
+            if ( ! empty( $this->field['include'] ) && file_exists( $this->field['include'] ) ) {
39
+                require_once $this->field['include'];
40
+            }
41
+
42
+            if ( isset( $this->field['content_path'] ) && ! empty( $this->field['content_path'] ) && file_exists( $this->field['content_path'] ) ) {
43
+                $this->field['content'] = Redux_Core::$filesystem->execute( 'get_contents', $this->field['content_path'] );
44
+            }
45
+
46
+            if ( ! empty( $this->field['content'] ) && isset( $this->field['content'] ) ) {
47
+                if ( isset( $this->field['markdown'] ) && true === $this->field['markdown'] && ! empty( $this->field['content'] ) ) {
48
+                    require_once __DIR__ . '/parsedown.php';
49
+                    $parsedown = new Redux_Parsedown();
50
+
51
+                    echo( $parsedown->text( $this->field['content'] ) ); // phpcs:ignore WordPress.Security.EscapeOutput
52
+                } else {
53
+                    echo( $this->field['content'] ); // phpcs:ignore WordPress.Security.EscapeOutput
54
+                }
55
+            }
56
+
57
+            // phpcs:ignore WordPress.NamingConventions.ValidHookName
58
+            do_action( 'redux-field-raw-' . $this->parent->args['opt_name'] . '-' . $this->field['id'] );
59
+        }
60
+    }
61 61
 }
62 62
 
63 63
 class_alias( 'Redux_Raw', 'ReduxFramework_Raw' );
Please login to merge, or discard this patch.
inc/extensions/custom_fonts/class-redux-extension-custom-fonts.php 2 patches
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
 								continue;
279 279
 							}
280 280
 
281
-							$this->custom_fonts[ $section['name'] ] = $this->custom_fonts[ $section['name'] ] ?? array();
281
+							$this->custom_fonts[$section['name']] = $this->custom_fonts[$section['name']] ?? array();
282 282
 
283 283
 							foreach ( $section['files'] as $font ) {
284 284
 								if ( ! empty( $font['name'] ) ) {
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
 										}
296 296
 									}
297 297
 
298
-									$this->custom_fonts[ $section['name'] ][ $font['name'] ] = $kinds;
298
+									$this->custom_fonts[$section['name']][$font['name']] = $kinds;
299 299
 								}
300 300
 							}
301 301
 						}
@@ -416,7 +416,7 @@  discard block
 block discarded – undo
416 416
 				} elseif ( 'f' === $file['type'] ) {
417 417
 					$valid = $this->check_font_name( $file );
418 418
 					if ( $valid ) {
419
-						$output[ $valid ] = trailingslashit( $path ) . $file['name'];
419
+						$output[$valid] = trailingslashit( $path ) . $file['name'];
420 420
 					}
421 421
 				}
422 422
 			}
@@ -477,7 +477,7 @@  discard block
 block discarded – undo
477 477
 
478 478
 			$filename = explode( '/', $this->selected_file );
479 479
 
480
-			$filename = $filename[ ( count( $filename ) - 1 ) ];
480
+			$filename = $filename[( count( $filename ) - 1 )];
481 481
 
482 482
 			$fontname = ucfirst(
483 483
 				str_replace(
@@ -523,7 +523,7 @@  discard block
 block discarded – undo
523 523
 
524 524
 				if ( ! empty( $output ) ) {
525 525
 					foreach ( $complete as $test ) {
526
-						if ( ! isset( $output[ $test ] ) ) {
526
+						if ( ! isset( $output[$test] ) ) {
527 527
 							$missing[] = $test;
528 528
 						}
529 529
 					}
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
 			} elseif ( 'svg+xml' === $subtype || 'vnd.ms-fontobject' === $subtype || 'x-font-ttf' === $subtype || 'ttf' === $subtype || 'otf' === $subtype || 'font-woff' === $subtype || 'font-woff2' === $subtype || 'application-octet-stream' === $subtype || 'octet-stream' === $subtype ) {
556 556
 				foreach ( $complete as $test ) {
557 557
 					if ( $subtype !== $test ) {
558
-						if ( ! isset( $output[ $test ] ) ) {
558
+						if ( ! isset( $output[$test] ) ) {
559 559
 							$missing[] = $test;
560 560
 						}
561 561
 					}
@@ -691,12 +691,12 @@  discard block
 block discarded – undo
691 691
 				$payload .= md5( 'redux_custom_font' );
692 692
 				$payload .= "\r\n";
693 693
 
694
-				if ( $output[ $main ] ) {
694
+				if ( $output[$main] ) {
695 695
 					$payload .= '--' . $boundary;
696 696
 					$payload .= "\r\n";
697
-					$payload .= 'Content-Disposition: form-data; name="convert"; filename="' . basename( $output[ $main ] ) . '"' . "\r\n";
697
+					$payload .= 'Content-Disposition: form-data; name="convert"; filename="' . basename( $output[$main] ) . '"' . "\r\n";
698 698
 					$payload .= "\r\n";
699
-					$payload .= Redux_Core::$filesystem->execute( 'get_contents', $output[ $main ] );
699
+					$payload .= Redux_Core::$filesystem->execute( 'get_contents', $output[$main] );
700 700
 					$payload .= "\r\n";
701 701
 				}
702 702
 
@@ -760,7 +760,7 @@  discard block
 block discarded – undo
760 760
 						Redux_Core::$filesystem->execute( 'move', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . ( $file['name'] ), $param_array );
761 761
 					}
762 762
 				} else {
763
-					$path_parts = pathinfo( $output[ $main ] );
763
+					$path_parts = pathinfo( $output[$main] );
764 764
 
765 765
 					$param_array = array(
766 766
 						'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $path_parts['basename'] ),
@@ -768,7 +768,7 @@  discard block
 block discarded – undo
768 768
 						'chmod'       => 755,
769 769
 					);
770 770
 
771
-					Redux_Core::$filesystem->execute( 'move', $output[ $main ], $param_array );
771
+					Redux_Core::$filesystem->execute( 'move', $output[$main], $param_array );
772 772
 
773 773
 					if ( in_array( $font_ext, $unsupported, true ) ) {
774 774
 						return array(
@@ -897,7 +897,7 @@  discard block
 block discarded – undo
897 897
 			$output = array();
898 898
 
899 899
 			foreach ( $files as $file ) {
900
-				$output[ $this->check_font_name( $file ) ] = $file['name'];
900
+				$output[$this->check_font_name( $file )] = $file['name'];
901 901
 			}
902 902
 
903 903
 			$css = '@font-face {';
@@ -959,9 +959,9 @@  discard block
 block discarded – undo
959 959
 				);
960 960
 
961 961
 				for ( $i = count( $this->parent->sections ); $i >= 1; $i-- ) {
962
-					if ( isset( $this->parent->sections[ $i ] ) && isset( $this->parent->sections[ $i ]['title'] ) && esc_html__( 'Font Control', 'redux-framework' ) === $this->parent->sections[ $i ]['title'] ) {
962
+					if ( isset( $this->parent->sections[$i] ) && isset( $this->parent->sections[$i]['title'] ) && esc_html__( 'Font Control', 'redux-framework' ) === $this->parent->sections[$i]['title'] ) {
963 963
 						$this->parent->fontControl                                        = $i;
964
-						$this->parent->sections[ $this->parent->fontControl ]['fields'][] = array(
964
+						$this->parent->sections[$this->parent->fontControl]['fields'][] = array(
965 965
 							'id'   => 'redux_font_control',
966 966
 							'type' => 'custom_fonts',
967 967
 						);
Please login to merge, or discard this patch.
Indentation   +963 added lines, -963 removed lines patch added patch discarded remove patch
@@ -16,967 +16,967 @@
 block discarded – undo
16 16
 
17 17
 if ( ! class_exists( 'Redux_Extension_Custom_Fonts' ) ) {
18 18
 
19
-	/**
20
-	 * Class Redux_Extension_Custom_Fonts
21
-	 */
22
-	class Redux_Extension_Custom_Fonts extends Redux_Extension_Abstract {
23
-
24
-		/**
25
-		 * Extension version.
26
-		 *
27
-		 * @var string
28
-		 */
29
-		public static $version = '4.5.6';
30
-
31
-		/**
32
-		 * Extension friendly name.
33
-		 *
34
-		 * @var string
35
-		 */
36
-		public string $extension_name = 'Custom Fonts';
37
-		/**
38
-		 * Class instance.
39
-		 *
40
-		 * @var object|null
41
-		 */
42
-		public static ?object $instance;
43
-
44
-		/**
45
-		 * Custom fonts array.
46
-		 *
47
-		 * @var array|null
48
-		 */
49
-		public ?array $custom_fonts = array();
50
-
51
-		/**
52
-		 * WordPress upload directory.
53
-		 *
54
-		 * @var string|null
55
-		 */
56
-		public ?string $upload_dir = '';
57
-
58
-		/**
59
-		 * WordPress upload URI.
60
-		 *
61
-		 * @var string|null
62
-		 */
63
-		public ?string $upload_url = '';
64
-
65
-		/**
66
-		 * Subfolder name.
67
-		 *
68
-		 * @var string
69
-		 */
70
-		public string $subfolder = 'custom/';
71
-
72
-		/**
73
-		 * Font folder.
74
-		 *
75
-		 * @var string|null
76
-		 */
77
-		public ?string $font_folder = '';
78
-
79
-		/**
80
-		 * Font Filename.
81
-		 *
82
-		 * @var string|null
83
-		 */
84
-		public ?string $font_filename = '';
85
-
86
-		/**
87
-		 * File selected in media upload.
88
-		 *
89
-		 * @var string|null
90
-		 */
91
-		public ?string $selected_file = '';
92
-
93
-		/**
94
-		 * Is font conversation service available?
95
-		 *
96
-		 * @var bool
97
-		 */
98
-		private bool $can_convert;
99
-
100
-		/**
101
-		 * Class Constructor. Defines the args for the extensions class
102
-		 *
103
-		 * @param ReduxFramework $redux ReduxFramework pointer.
104
-		 *
105
-		 * @return      void
106
-		 * @since       1.0.0
107
-		 * @access      public
108
-		 */
109
-		public function __construct( $redux ) {
110
-			if ( false === $redux->args['custom_fonts'] ) {
111
-				return;
112
-			}
113
-
114
-			parent::__construct( $redux, __FILE__ );
115
-
116
-			self::$instance = parent::get_instance();
117
-
118
-			$this->add_field( 'custom_fonts' );
119
-
120
-			$this->upload_dir = Redux_Core::$upload_dir . 'custom-fonts/';
121
-			$this->upload_url = Redux_Core::$upload_url . 'custom-fonts/';
122
-
123
-			if ( ! is_dir( $this->upload_dir ) ) {
124
-				Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir );
125
-			}
126
-
127
-			if ( ! is_dir( $this->upload_dir . '/custom' ) ) {
128
-				Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . '/custom' );
129
-			}
130
-
131
-			$this->get_fonts();
132
-
133
-			if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
134
-				if ( filemtime( $this->upload_dir . 'custom' ) > ( filemtime( $this->upload_dir . 'fonts.css' ) + 10 ) ) {
135
-					$this->generate_css();
136
-				}
137
-			} else {
138
-				$this->generate_css();
139
-			}
140
-
141
-			add_action( 'wp_ajax_redux_custom_fonts', array( $this, 'ajax' ) );
142
-			add_action( 'wp_ajax_redux_custom_font_timer', array( $this, 'timer' ) );
143
-
144
-			add_filter( "redux/{$this->parent->args['opt_name']}/field/typography/custom_fonts", array( $this, 'add_custom_fonts' ) );
145
-
146
-			// phpcs:disable
147
-			// $this->is_field = Redux_Helpers::is_field_in_use( $parent, 'custom_fonts' );
148
-
149
-			// if ( ! $this->is_field ) {
150
-			// 	$this->add_section();
151
-			// }
152
-
153
-			add_filter( "redux/options/{$this->parent->args['opt_name']}/section/redux_dynamic_font_control", array( $this, 'remove_dynamic_section' ) ); // phpcs:ignore WordPress.NamingConventions.ValidHookName
154
-			add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
155
-			add_action( 'wp_head', array( $this, 'enqueue_output' ), 150 );
156
-			add_filter( 'tiny_mce_before_init', array( $this, 'extend_tinymce_dropdown' ) );
157
-
158
-			$this->can_convert = true; // has_filter( 'redux/' . $this->parent->args['opt_name'] . '/extensions/custom_fonts/api_url' );
159
-			// phpcs:enable
160
-		}
161
-
162
-		/**
163
-		 * Timer.
164
-		 */
165
-		public function timer() {
166
-			$name = get_option( 'redux_custom_font_current' );
167
-
168
-			if ( ! empty( $name ) ) {
169
-				echo esc_html( $name );
170
-			}
171
-
172
-			die();
173
-		}
174
-
175
-		/**
176
-		 * Remove the dynamically added section if the field was used elsewhere
177
-		 *
178
-		 * @param array $section Section array.
179
-		 *
180
-		 * @return array
181
-		 * @since  Redux_Framework 3.1.1
182
-		 */
183
-		public function remove_dynamic_section( array $section ): array {
184
-			if ( isset( $this->parent->field_types['custom_fonts'] ) ) {
185
-				$section = array();
186
-			}
187
-
188
-			return $section;
189
-		}
190
-
191
-		/**
192
-		 * Adds FontMeister fonts to the TinyMCE drop-down.
193
-		 * Typekit's fonts don't render properly in the drop-down and in the editor,
194
-		 * because Typekit needs JS and TinyMCE doesn't support that.
195
-		 *
196
-		 * @param array $opt Option array.
197
-		 *
198
-		 * @return array
199
-		 */
200
-		public function extend_tinymce_dropdown( array $opt ): array {
201
-			if ( ! is_admin() ) {
202
-				return $opt;
203
-			}
204
-
205
-			if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
206
-				$theme_advanced_fonts = $opt['font_formats'] ?? 'Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats';
207
-				$custom_fonts         = '';
208
-
209
-				$stylesheet = $this->upload_url . 'fonts.css';
210
-
211
-				if ( empty( $opt['content_css'] ) ) {
212
-					$opt['content_css'] = $stylesheet;
213
-				} else {
214
-					$opt['content_css'] = $opt['content_css'] . ',' . $stylesheet;
215
-				}
216
-
217
-				foreach ( $this->custom_fonts as $arr ) {
218
-					foreach ( $arr as $font => $pieces ) {
219
-						$custom_fonts .= ';' . $font . '=' . $font;
220
-					}
221
-				}
222
-
223
-				$opt['font_formats'] = $theme_advanced_fonts . $custom_fonts;
224
-			}
225
-
226
-			return $opt;
227
-		}
228
-
229
-
230
-		/**
231
-		 * Function to enqueue the custom fonts css
232
-		 */
233
-		public function enqueue_output() {
234
-			if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
235
-				wp_enqueue_style(
236
-					'redux-custom-fonts',
237
-					$this->upload_url . 'fonts.css',
238
-					array(),
239
-					filemtime( $this->upload_dir . 'fonts.css' )
240
-				);
241
-			}
242
-		}
243
-
244
-		/**
245
-		 * Adds the appropriate mime types to WordPress
246
-		 *
247
-		 * @param array $existing_mimes Mine array.
248
-		 *
249
-		 * @return array
250
-		 */
251
-		public function custom_upload_mimes( array $existing_mimes = array() ): array {
252
-			$existing_mimes['ttf']   = 'font/ttf';
253
-			$existing_mimes['otf']   = 'font/otf';
254
-			$existing_mimes['eot']   = 'application/vnd.ms-fontobject';
255
-			$existing_mimes['woff']  = 'application/font-woff';
256
-			$existing_mimes['woff2'] = 'application/font-woff2';
257
-			$existing_mimes['svg']   = 'image/svg+xml';
258
-			$existing_mimes['zip']   = 'application/zip';
259
-
260
-			return $existing_mimes;
261
-		}
262
-
263
-		/**
264
-		 * Gets all the fonts in the custom_fonts directory
265
-		 */
266
-		public function get_fonts() {
267
-			if ( empty( $this->custom_fonts ) ) {
268
-				$params = array(
269
-					'include_hidden' => false,
270
-					'recursive'      => true,
271
-				);
272
-
273
-				$fonts = Redux_Core::$filesystem->execute( 'dirlist', $this->upload_dir, $params );
274
-
275
-				if ( ! empty( $fonts ) ) {
276
-					foreach ( $fonts as $section ) {
277
-						if ( 'd' === $section['type'] && ! empty( $section['name'] ) ) {
278
-							if ( 'custom' === $section['name'] ) {
279
-								$section['name'] = esc_html__( 'Custom Fonts', 'redux-framework' );
280
-							}
281
-
282
-							if ( empty( $section['files'] ) ) {
283
-								continue;
284
-							}
285
-
286
-							$this->custom_fonts[ $section['name'] ] = $this->custom_fonts[ $section['name'] ] ?? array();
287
-
288
-							foreach ( $section['files'] as $font ) {
289
-								if ( ! empty( $font['name'] ) ) {
290
-									if ( empty( $font['files'] ) ) {
291
-										continue;
292
-									}
293
-
294
-									$kinds = array();
295
-
296
-									foreach ( $font['files'] as $f ) {
297
-										$valid = $this->check_font_name( $f );
298
-										if ( $valid ) {
299
-											$kinds[] = $valid;
300
-										}
301
-									}
302
-
303
-									$this->custom_fonts[ $section['name'] ][ $font['name'] ] = $kinds;
304
-								}
305
-							}
306
-						}
307
-					}
308
-				}
309
-			}
310
-		}
311
-
312
-		/**
313
-		 * Add custom fonts.
314
-		 *
315
-		 * @param mixed $custom_fonts Custom fonts.
316
-		 *
317
-		 * @return array
318
-		 */
319
-		public function add_custom_fonts( $custom_fonts ): array {
320
-			if ( empty( $custom_fonts ) ) {
321
-				$custom_fonts = array();
322
-			}
323
-
324
-			return wp_parse_args( $custom_fonts, $this->custom_fonts );
325
-		}
326
-
327
-		/**
328
-		 * Ajax used within the panel to add and process the fonts
329
-		 */
330
-		public function ajax() {
331
-			if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'redux_custom_fonts' ) ) {
332
-				die( 0 );
333
-			}
334
-
335
-			if ( isset( $_POST['type'] ) && 'delete' === $_POST['type'] ) {
336
-				if ( isset( $_POST['section'] ) ) {
337
-					if ( esc_html__( 'Custom Fonts', 'redux-framework' ) === $_POST['section'] ) {
338
-						$_POST['section'] = 'custom';
339
-					}
340
-				}
341
-
342
-				try {
343
-					if ( isset( $_POST['section'] ) || isset( $_POST['name'] ) ) {
344
-						$ret = Redux_Core::$filesystem->execute( 'rmdir', $this->upload_dir . sanitize_file_name( wp_unslash( $_POST['section'] ) ) . '/' . sanitize_file_name( wp_unslash( $_POST['name'] ) ) . '/', array( 'recursive' => true ) );
345
-
346
-						if ( true === $ret ) {
347
-							$result = array( 'type' => 'success' );
348
-						} else {
349
-							$result = array(
350
-								'type' => 'error',
351
-								'msg'  => esc_html__( 'File system failure. Could not delete temp dir.', 'redux-framework' ),
352
-							);
353
-						}
354
-
355
-						echo wp_json_encode( $result );
356
-					}
357
-				} catch ( Exception $e ) {
358
-					echo wp_json_encode(
359
-						array(
360
-							'type' => 'error',
361
-							'msg'  => esc_html__( 'Unable to delete font file(s).', 'redux-framework' ),
362
-						)
363
-					);
364
-				}
365
-
366
-				die();
367
-			}
368
-
369
-			if ( ! isset( $_POST['title'] ) ) {
370
-				$_POST['title'] = '';
371
-			}
372
-
373
-			if ( ! isset( $_POST['filename'] ) ) {
374
-				$_POST['filename'] = '';
375
-			}
376
-
377
-			$this->font_folder   = sanitize_file_name( wp_unslash( $_POST['title'] ) );
378
-			$this->font_filename = sanitize_file_name( wp_unslash( $_POST['filename'] ) );
379
-
380
-			if ( ! empty( $_POST['attachment_id'] ) ) {
381
-				if ( isset( $_POST['title'] ) || isset( $_POST['mime'] ) ) {
382
-					$msg = $this->process_web_font( sanitize_key( wp_unslash( $_POST['attachment_id'] ) ), sanitize_text_field( wp_unslash( $_POST['mime'] ) ) );
383
-
384
-					if ( empty( $msg ) ) {
385
-						$msg = '';
386
-					}
387
-
388
-					$result = array(
389
-						'type' => 'success',
390
-						'msg'  => $msg,
391
-					);
392
-
393
-					echo wp_json_encode( $result );
394
-				}
395
-			}
396
-
397
-			die();
398
-		}
399
-
400
-		/**
401
-		 * Get only valid files. Ensure everything is proper for processing.
402
-		 *
403
-		 * @param string $path Path.
404
-		 *
405
-		 * @return array
406
-		 */
407
-		public function get_valid_files( string $path ): array {
408
-			$output = array();
409
-			$path   = trailingslashit( $path );
410
-
411
-			$params = array(
412
-				'include_hidden' => false,
413
-				'recursive'      => true,
414
-			);
415
-
416
-			$files = Redux_Core::$filesystem->execute( 'dirlist', $path, $params );
417
-
418
-			foreach ( $files as $file ) {
419
-				if ( 'd' === $file['type'] ) {
420
-					$output = array_merge( $output, $this->get_valid_files( $path . $file['name'] ) );
421
-				} elseif ( 'f' === $file['type'] ) {
422
-					$valid = $this->check_font_name( $file );
423
-					if ( $valid ) {
424
-						$output[ $valid ] = trailingslashit( $path ) . $file['name'];
425
-					}
426
-				}
427
-			}
428
-
429
-			return $output;
430
-		}
431
-
432
-		/**
433
-		 * Take a valid web font and process the missing pieces.
434
-		 *
435
-		 * @param string $attachment_id ID.
436
-		 * @param string $mime_type     Mine type.
437
-		 */
438
-		public function process_web_font( string $attachment_id, string $mime_type ) {
439
-			// phpcs:ignore WordPress.Security.NonceVerification
440
-			if ( ! isset( $_POST['conversion'] ) ) {
441
-				$_POST['conversion'] = 'false';
442
-			}
443
-
444
-			// phpcs:ignore WordPress.Security.NonceVerification
445
-			$conversion = sanitize_text_field( wp_unslash( $_POST['conversion'] ) );
446
-
447
-			$missing = array();
448
-
449
-			$complete = array(
450
-				'ttf',
451
-				'woff',
452
-				'woff2',
453
-				'eot',
454
-				'svg',
455
-				'otf',
456
-			);
457
-
458
-			$subtype = explode( '/', $mime_type );
459
-			$subtype = trim( max( $subtype ) );
460
-
461
-			if ( ! is_dir( $this->upload_dir ) ) {
462
-				Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir );
463
-			}
464
-
465
-			if ( ! is_dir( $this->upload_dir . $this->subfolder ) ) {
466
-				Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder );
467
-			}
468
-
469
-			$temp                = $this->upload_dir . 'temp';
470
-			$this->selected_file = get_attached_file( $attachment_id );
471
-
472
-			if ( empty( $this->selected_file ) ) {
473
-				echo wp_json_encode(
474
-					array(
475
-						'type' => 'error',
476
-						'msg'  => esc_html__( 'Attachment does not exist.', 'redux-framework' ),
477
-					)
478
-				);
479
-
480
-				die();
481
-			}
482
-
483
-			$filename = explode( '/', $this->selected_file );
484
-
485
-			$filename = $filename[ ( count( $filename ) - 1 ) ];
486
-
487
-			$fontname = ucfirst(
488
-				str_replace(
489
-					array(
490
-						'.zip',
491
-						'.ttf',
492
-						'.woff',
493
-						'.woff2',
494
-						'.eot',
495
-						'.svg',
496
-						'.otf',
497
-					),
498
-					'',
499
-					strtolower( $filename )
500
-				)
501
-			);
502
-
503
-			if ( empty( $this->font_folder ) ) {
504
-				$this->font_folder = $fontname;
505
-			}
506
-
507
-			$ret = array();
508
-
509
-			if ( ! is_dir( $temp ) ) {
510
-				Redux_Core::$filesystem->execute( 'mkdir', $temp );
511
-			}
512
-
513
-			if ( 'zip' === $subtype ) {
514
-				$unzipfile = unzip_file( $this->selected_file, $temp );
515
-
516
-				if ( is_wp_error( $unzipfile ) ) {
517
-					echo wp_json_encode(
518
-						array(
519
-							'type' => 'error',
520
-							'msg'  => $unzipfile->get_error_message() . '<br><br>' . esc_html__( 'Unzipping failed.', 'redux-framework' ),
521
-						)
522
-					);
523
-
524
-					die();
525
-				}
526
-
527
-				$output = $this->get_valid_files( $temp );
528
-
529
-				if ( ! empty( $output ) ) {
530
-					foreach ( $complete as $test ) {
531
-						if ( ! isset( $output[ $test ] ) ) {
532
-							$missing[] = $test;
533
-						}
534
-					}
535
-
536
-					if ( ! is_dir( $this->upload_dir . $this->subfolder . $this->font_folder . '/' ) ) {
537
-						Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/' );
538
-					}
539
-
540
-					foreach ( $output as $key => $value ) {
541
-						$param_array = array(
542
-							'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . '/' . $fontname . '.' . $key,
543
-							'overwrite'   => true,
544
-							'chmod'       => 755,
545
-						);
546
-
547
-						Redux_Core::$filesystem->execute( 'copy', $value, $param_array );
548
-					}
549
-
550
-					if ( true === $this->can_convert && 'true' === $conversion ) {
551
-						$ret = $this->get_missing_files( $fontname, $missing, $output );
552
-					}
553
-				}
554
-
555
-				Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
556
-
557
-				$this->generate_css();
558
-
559
-				wp_delete_attachment( $attachment_id, true );
560
-			} elseif ( 'svg+xml' === $subtype || 'vnd.ms-fontobject' === $subtype || 'x-font-ttf' === $subtype || 'ttf' === $subtype || 'otf' === $subtype || 'font-woff' === $subtype || 'font-woff2' === $subtype || 'application-octet-stream' === $subtype || 'octet-stream' === $subtype ) {
561
-				foreach ( $complete as $test ) {
562
-					if ( $subtype !== $test ) {
563
-						if ( ! isset( $output[ $test ] ) ) {
564
-							$missing[] = $test;
565
-						}
566
-					}
567
-				}
568
-
569
-				if ( ! is_dir( $this->upload_dir . $this->subfolder . $this->font_folder . '/' ) ) {
570
-					Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/' );
571
-				}
572
-
573
-				$output = array( $subtype => $this->selected_file );
574
-
575
-				if ( true === $this->can_convert && 'true' === $conversion ) {
576
-					$ret = $this->get_missing_files( $fontname, $missing, $output );
577
-
578
-					if ( false === $ret ) {
579
-						if ( false === $this->convert_local_font() ) {
580
-							echo wp_json_encode(
581
-								array(
582
-									'type' => 'error',
583
-									'msg'  => esc_html__( 'File permission error. Local file could not be installed.', 'redux-framework' ) . ' ' . $subtype,
584
-								)
585
-							);
586
-
587
-							die;
588
-						}
589
-					}
590
-				} elseif ( false === $this->convert_local_font() ) {
591
-						echo wp_json_encode(
592
-							array(
593
-								'type' => 'error',
594
-								'msg'  => esc_html__( 'File permission error. Local file could not be installed.', 'redux-framework' ) . ' ' . $subtype,
595
-							)
596
-						);
597
-
598
-						die;
599
-				}
600
-
601
-				Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
602
-
603
-				$this->generate_css();
604
-
605
-				wp_delete_attachment( $attachment_id, true );
606
-			} else {
607
-				echo wp_json_encode(
608
-					array(
609
-						'type' => 'error',
610
-						'msg'  => esc_html__( 'File type not recognized.', 'redux-framework' ) . ' ' . $subtype,
611
-					)
612
-				);
613
-
614
-				die();
615
-			}
616
-
617
-			if ( is_array( $ret ) && ! empty( $ret ) ) {
618
-				$msg = esc_html__( 'Unidentified error.', 'redux-framework' );
619
-
620
-				if ( isset( $ret['msg'] ) ) {
621
-					$msg = $ret['msg'];
622
-				}
623
-
624
-				return $msg;
625
-			}
626
-
627
-			return '';
628
-		}
629
-
630
-		/**
631
-		 * Install selected file into Custom Fonts.
632
-		 *
633
-		 * @return bool
634
-		 */
635
-		private function convert_local_font(): bool {
636
-			$param_array = array(
637
-				'destination' => $this->upload_dir . $this->subfolder . '/' . $this->font_folder . '/' . $this->font_filename,
638
-				'overwrite'   => true,
639
-				'chmod'       => 755,
640
-			);
641
-
642
-			return Redux_Core::$filesystem->execute( 'copy', $this->selected_file, $param_array );
643
-		}
644
-
645
-		/**
646
-		 * Ping the WebFontOMatic API to get the missing files.
647
-		 *
648
-		 * @param string $fontname  Font name.
649
-		 * @param array  $missing   Missing.
650
-		 * @param array  $output    Output.
651
-		 */
652
-		private function get_missing_files( string $fontname, array $missing, array $output ) {
653
-			if ( ! empty( $this->font_folder ) && ! empty( $missing ) ) {
654
-				$temp = $this->upload_dir . 'temp';
655
-
656
-				$font_ext = pathinfo( $this->font_filename, PATHINFO_EXTENSION );
657
-
658
-				$unsupported = array( 'eot', 'woff', 'woff2' );
659
-
660
-				// Find a file to convert from.
661
-				foreach ( $output as $key => $value ) {
662
-					if ( 'eot' === $key ) {
663
-						continue;
664
-					} else {
665
-						$main = $key;
666
-						break;
667
-					}
668
-				}
669
-
670
-				if ( ! isset( $main ) ) {
671
-					echo wp_json_encode(
672
-						array(
673
-							'type' => 'error',
674
-							'msg'  => esc_html__( 'No valid font file was found.', 'redux-framework' ),
675
-						)
676
-					);
677
-
678
-					Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
679
-					Redux_Core::$filesystem->execute( 'rmdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/', array( 'recursive' => true ) );
680
-
681
-					die();
682
-				}
683
-
684
-				update_option( 'redux_custom_font_current', $this->font_folder . '.zip' );
685
-
686
-				$boundary = wp_generate_password( 24 );
687
-
688
-				$headers = array(
689
-					'content-type' => 'multipart/form-data; boundary=' . $boundary,
690
-					'user-agent'   => 'redux-custom-fonts-' . self::$version . ' using ' . wp_get_theme(),
691
-				);
692
-
693
-				$payload  = '--' . $boundary;
694
-				$payload .= "\r\n";
695
-				$payload .= 'Content-Disposition: form-data; name="md5"' . "\r\n\r\n";
696
-				$payload .= md5( 'redux_custom_font' );
697
-				$payload .= "\r\n";
698
-
699
-				if ( $output[ $main ] ) {
700
-					$payload .= '--' . $boundary;
701
-					$payload .= "\r\n";
702
-					$payload .= 'Content-Disposition: form-data; name="convert"; filename="' . basename( $output[ $main ] ) . '"' . "\r\n";
703
-					$payload .= "\r\n";
704
-					$payload .= Redux_Core::$filesystem->execute( 'get_contents', $output[ $main ] );
705
-					$payload .= "\r\n";
706
-				}
707
-
708
-				$payload .= '--' . $boundary . '--';
709
-
710
-				$args = array(
711
-					'headers'    => $headers,
712
-					'body'       => $payload,
713
-					'user-agent' => $headers['user-agent'],
714
-					'timeout'    => 300,
715
-					'sslverify'  => true,
716
-				);
717
-
718
-				// phpcs:disable WordPress.NamingConventions.ValidHookName
719
-				$api_url = apply_filters( 'redux/' . $this->parent->args['opt_name'] . '/extensions/custom_fonts/api_url', 'https://redux.io/fonts' );
720
-
721
-				$response = wp_remote_post( $api_url, $args );
722
-
723
-				if ( is_wp_error( $response ) ) {
724
-					return array(
725
-						'type' => 'error',
726
-						'msg'  => $response->get_error_message() . '<br><br>' . esc_html__( 'Your font could not be converted at this time. Please try again later.', 'redux-framework' ),
727
-					);
728
-				} elseif ( isset( $response['body'] ) ) {
729
-					if ( null !== json_decode( $response['body'] ) ) {
730
-						return json_decode( $response['body'], true );
731
-					}
732
-				}
733
-
734
-				$param_array = array(
735
-					'content'   => $response['body'],
736
-					'overwrite' => true,
737
-					'chmod'     => FS_CHMOD_FILE,
738
-				);
739
-
740
-				$zip_file = $temp . DIRECTORY_SEPARATOR . $fontname . '.zip';
741
-
742
-				Redux_Core::$filesystem->execute( 'put_contents', $zip_file, $param_array );
743
-
744
-				if ( 0 === filesize( $zip_file ) ) {
745
-					return false;
746
-				}
747
-
748
-				$zip = unzip_file( $zip_file, $temp );
749
-
750
-				if ( ! is_wp_error( $zip ) ) {
751
-					$params = array(
752
-						'include_hidden' => false,
753
-						'recursive'      => false,
754
-					);
755
-
756
-					$files = Redux_Core::$filesystem->execute( 'dirlist', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR, $params );
757
-
758
-					foreach ( $files as $file ) {
759
-						$param_array = array(
760
-							'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $file['name'] ),
761
-							'overwrite'   => true,
762
-							'chmod'       => 755,
763
-						);
764
-
765
-						Redux_Core::$filesystem->execute( 'move', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . ( $file['name'] ), $param_array );
766
-					}
767
-				} else {
768
-					$path_parts = pathinfo( $output[ $main ] );
769
-
770
-					$param_array = array(
771
-						'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $path_parts['basename'] ),
772
-						'overwrite'   => true,
773
-						'chmod'       => 755,
774
-					);
775
-
776
-					Redux_Core::$filesystem->execute( 'move', $output[ $main ], $param_array );
777
-
778
-					if ( in_array( $font_ext, $unsupported, true ) ) {
779
-						return array(
780
-							'type' => 'error',
781
-							// translators: %s = font extension.
782
-							'msg'  => $zip->get_error_message() . '<br><br>' . sprintf( esc_html__( 'The font converter does not support %s fonts.', 'redux-framework' ), $font_ext ),
783
-						);
784
-					} else {
785
-						return array(
786
-							'type' => 'error',
787
-							'msg'  => $zip->get_error_message() . '<br><br>' . esc_html__( 'ZIP error. Your font could not be converted at this time. Please try again later.', 'redux-framework' ),
788
-						);
789
-					}
790
-				}
791
-
792
-				delete_option( 'redux_custom_font_current' );
793
-			}
794
-
795
-			return true;
796
-		}
797
-
798
-		/**
799
-		 * Check if the file name is a valid font file.
800
-		 *
801
-		 * @param array $file File.
802
-		 *
803
-		 * @return bool|string
804
-		 */
805
-		private function check_font_name( array $file ) {
806
-			if ( '.woff' === strtolower( substr( $file['name'], - 5 ) ) ) {
807
-				return 'woff';
808
-			}
809
-
810
-			if ( '.woff2' === strtolower( substr( $file['name'], - 6 ) ) ) {
811
-				return 'woff2';
812
-			}
813
-
814
-			$sub = strtolower( substr( $file['name'], - 4 ) );
815
-
816
-			if ( '.ttf' === $sub ) {
817
-				return 'ttf';
818
-			}
819
-
820
-			if ( '.eot' === $sub ) {
821
-				return 'eot';
822
-			}
823
-
824
-			if ( '.svg' === $sub ) {
825
-				return 'svg';
826
-			}
827
-
828
-			if ( '.otf' === $sub ) {
829
-				return 'otf';
830
-			}
831
-
832
-			return false;
833
-		}
834
-
835
-		/**
836
-		 * Generate a new custom CSS file for enqueuing on the frontend and backend.
837
-		 */
838
-		private function generate_css() {
839
-			$params = array(
840
-				'include_hidden' => false,
841
-				'recursive'      => true,
842
-			);
843
-
844
-			$fonts = Redux_Core::$filesystem->execute( 'dirlist', $this->upload_dir . 'custom' . DIRECTORY_SEPARATOR, $params );
845
-
846
-			if ( empty( $fonts ) || ! is_array( $fonts ) ) {
847
-				return;
848
-			}
849
-
850
-			foreach ( $fonts as $font ) {
851
-				if ( 'd' === $font['type'] ) {
852
-					break;
853
-				}
854
-
855
-				if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
856
-					Redux_Core::$filesystem->execute( 'delete', $this->upload_dir . 'fonts.css' );
857
-				}
858
-
859
-				return;
860
-			}
861
-
862
-			$css = '';
863
-
864
-			foreach ( $fonts as $font ) {
865
-				if ( 'd' === $font['type'] ) {
866
-					$css .= $this->generate_font_css( $font['name'], $this->upload_dir . 'custom' . DIRECTORY_SEPARATOR );
867
-				}
868
-			}
869
-
870
-			if ( '' !== $css ) {
871
-				$param_array = array(
872
-					'content' => $css,
873
-					'chmod'   => FS_CHMOD_FILE,
874
-				);
875
-
876
-				Redux_Core::$filesystem->execute( 'put_contents', $this->upload_dir . 'fonts.css', $param_array );
877
-			}
878
-		}
879
-
880
-		/**
881
-		 * Process to actually construct the custom font css file.
882
-		 *
883
-		 * @param string $name Name.
884
-		 * @param string $dir  Directory.
885
-		 *
886
-		 * @return string
887
-		 */
888
-		private function generate_font_css( string $name, string $dir ): ?string {
889
-			$path = $dir . $name;
890
-
891
-			$params = array(
892
-				'include_hidden' => false,
893
-				'recursive'      => true,
894
-			);
895
-
896
-			$files = Redux_Core::$filesystem->execute( 'dirlist', $path, $params );
897
-
898
-			if ( empty( $files ) ) {
899
-				return null;
900
-			}
901
-
902
-			$output = array();
903
-
904
-			foreach ( $files as $file ) {
905
-				$output[ $this->check_font_name( $file ) ] = $file['name'];
906
-			}
907
-
908
-			$css = '@font-face {';
909
-
910
-			$css .= 'font-family:"' . $name . '";';
911
-
912
-			$src = array();
913
-
914
-			if ( isset( $output['eot'] ) ) {
915
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['eot']}?#iefix') format('embedded-opentype')";
916
-			}
917
-
918
-			if ( isset( $output['woff'] ) ) {
919
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['woff']}') format('woff')";
920
-			}
921
-
922
-			if ( isset( $output['woff2'] ) ) {
923
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['woff2']}') format('woff2')";
924
-			}
925
-
926
-			if ( isset( $output['ttf'] ) ) {
927
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['ttf']}') format('truetype')";
928
-			}
929
-
930
-			if ( isset( $output['svg'] ) ) {
931
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['svg']}#svg$name') format('svg')";
932
-			}
933
-
934
-			if ( ! empty( $src ) ) {
935
-				$css .= 'src:' . implode( ', ', $src ) . ';';
936
-			}
937
-
938
-			// Replace font weight and style with sub-sets.
939
-			$css .= 'font-weight: normal;';
940
-
941
-			$css .= 'font-style: normal;';
942
-
943
-			$css .= '}';
944
-
945
-			return $css;
946
-		}
947
-
948
-		/**
949
-		 * Custom function for filtering the section array.
950
-		 * Good for child themes to override or add to the sections.
951
-		 * Simply include this function in the child themes functions.php file.
952
-		 * NOTE: the defined constants for URLs and directories will NOT be available at this point in a child theme,
953
-		 * so you must use get_template_directory_uri() if you want to use any of the built-in icons
954
-		 */
955
-		public function add_section() {
956
-			if ( ! isset( $this->parent->fontControl ) ) {
957
-				$this->parent->sections[] = array(
958
-					'title'  => esc_html__( 'Font Control', 'redux-framework' ),
959
-					'desc'   => '<p class="description"></p>',
960
-					'icon'   => 'el-icon-font',
961
-					'id'     => 'redux_dynamic_font_control',
962
-					// Leave this as a blank section, no options just some intro text set above.
963
-					'fields' => array(),
964
-				);
965
-
966
-				for ( $i = count( $this->parent->sections ); $i >= 1; $i-- ) {
967
-					if ( isset( $this->parent->sections[ $i ] ) && isset( $this->parent->sections[ $i ]['title'] ) && esc_html__( 'Font Control', 'redux-framework' ) === $this->parent->sections[ $i ]['title'] ) {
968
-						$this->parent->fontControl                                        = $i;
969
-						$this->parent->sections[ $this->parent->fontControl ]['fields'][] = array(
970
-							'id'   => 'redux_font_control',
971
-							'type' => 'custom_fonts',
972
-						);
973
-
974
-						break;
975
-					}
976
-				}
977
-			}
978
-		}
979
-	}
980
-
981
-	class_alias( Redux_Extension_Custom_Fonts::class, 'ReduxFramework_Extension_custom_fonts' );
19
+    /**
20
+     * Class Redux_Extension_Custom_Fonts
21
+     */
22
+    class Redux_Extension_Custom_Fonts extends Redux_Extension_Abstract {
23
+
24
+        /**
25
+         * Extension version.
26
+         *
27
+         * @var string
28
+         */
29
+        public static $version = '4.5.6';
30
+
31
+        /**
32
+         * Extension friendly name.
33
+         *
34
+         * @var string
35
+         */
36
+        public string $extension_name = 'Custom Fonts';
37
+        /**
38
+         * Class instance.
39
+         *
40
+         * @var object|null
41
+         */
42
+        public static ?object $instance;
43
+
44
+        /**
45
+         * Custom fonts array.
46
+         *
47
+         * @var array|null
48
+         */
49
+        public ?array $custom_fonts = array();
50
+
51
+        /**
52
+         * WordPress upload directory.
53
+         *
54
+         * @var string|null
55
+         */
56
+        public ?string $upload_dir = '';
57
+
58
+        /**
59
+         * WordPress upload URI.
60
+         *
61
+         * @var string|null
62
+         */
63
+        public ?string $upload_url = '';
64
+
65
+        /**
66
+         * Subfolder name.
67
+         *
68
+         * @var string
69
+         */
70
+        public string $subfolder = 'custom/';
71
+
72
+        /**
73
+         * Font folder.
74
+         *
75
+         * @var string|null
76
+         */
77
+        public ?string $font_folder = '';
78
+
79
+        /**
80
+         * Font Filename.
81
+         *
82
+         * @var string|null
83
+         */
84
+        public ?string $font_filename = '';
85
+
86
+        /**
87
+         * File selected in media upload.
88
+         *
89
+         * @var string|null
90
+         */
91
+        public ?string $selected_file = '';
92
+
93
+        /**
94
+         * Is font conversation service available?
95
+         *
96
+         * @var bool
97
+         */
98
+        private bool $can_convert;
99
+
100
+        /**
101
+         * Class Constructor. Defines the args for the extensions class
102
+         *
103
+         * @param ReduxFramework $redux ReduxFramework pointer.
104
+         *
105
+         * @return      void
106
+         * @since       1.0.0
107
+         * @access      public
108
+         */
109
+        public function __construct( $redux ) {
110
+            if ( false === $redux->args['custom_fonts'] ) {
111
+                return;
112
+            }
113
+
114
+            parent::__construct( $redux, __FILE__ );
115
+
116
+            self::$instance = parent::get_instance();
117
+
118
+            $this->add_field( 'custom_fonts' );
119
+
120
+            $this->upload_dir = Redux_Core::$upload_dir . 'custom-fonts/';
121
+            $this->upload_url = Redux_Core::$upload_url . 'custom-fonts/';
122
+
123
+            if ( ! is_dir( $this->upload_dir ) ) {
124
+                Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir );
125
+            }
126
+
127
+            if ( ! is_dir( $this->upload_dir . '/custom' ) ) {
128
+                Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . '/custom' );
129
+            }
130
+
131
+            $this->get_fonts();
132
+
133
+            if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
134
+                if ( filemtime( $this->upload_dir . 'custom' ) > ( filemtime( $this->upload_dir . 'fonts.css' ) + 10 ) ) {
135
+                    $this->generate_css();
136
+                }
137
+            } else {
138
+                $this->generate_css();
139
+            }
140
+
141
+            add_action( 'wp_ajax_redux_custom_fonts', array( $this, 'ajax' ) );
142
+            add_action( 'wp_ajax_redux_custom_font_timer', array( $this, 'timer' ) );
143
+
144
+            add_filter( "redux/{$this->parent->args['opt_name']}/field/typography/custom_fonts", array( $this, 'add_custom_fonts' ) );
145
+
146
+            // phpcs:disable
147
+            // $this->is_field = Redux_Helpers::is_field_in_use( $parent, 'custom_fonts' );
148
+
149
+            // if ( ! $this->is_field ) {
150
+            // 	$this->add_section();
151
+            // }
152
+
153
+            add_filter( "redux/options/{$this->parent->args['opt_name']}/section/redux_dynamic_font_control", array( $this, 'remove_dynamic_section' ) ); // phpcs:ignore WordPress.NamingConventions.ValidHookName
154
+            add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
155
+            add_action( 'wp_head', array( $this, 'enqueue_output' ), 150 );
156
+            add_filter( 'tiny_mce_before_init', array( $this, 'extend_tinymce_dropdown' ) );
157
+
158
+            $this->can_convert = true; // has_filter( 'redux/' . $this->parent->args['opt_name'] . '/extensions/custom_fonts/api_url' );
159
+            // phpcs:enable
160
+        }
161
+
162
+        /**
163
+         * Timer.
164
+         */
165
+        public function timer() {
166
+            $name = get_option( 'redux_custom_font_current' );
167
+
168
+            if ( ! empty( $name ) ) {
169
+                echo esc_html( $name );
170
+            }
171
+
172
+            die();
173
+        }
174
+
175
+        /**
176
+         * Remove the dynamically added section if the field was used elsewhere
177
+         *
178
+         * @param array $section Section array.
179
+         *
180
+         * @return array
181
+         * @since  Redux_Framework 3.1.1
182
+         */
183
+        public function remove_dynamic_section( array $section ): array {
184
+            if ( isset( $this->parent->field_types['custom_fonts'] ) ) {
185
+                $section = array();
186
+            }
187
+
188
+            return $section;
189
+        }
190
+
191
+        /**
192
+         * Adds FontMeister fonts to the TinyMCE drop-down.
193
+         * Typekit's fonts don't render properly in the drop-down and in the editor,
194
+         * because Typekit needs JS and TinyMCE doesn't support that.
195
+         *
196
+         * @param array $opt Option array.
197
+         *
198
+         * @return array
199
+         */
200
+        public function extend_tinymce_dropdown( array $opt ): array {
201
+            if ( ! is_admin() ) {
202
+                return $opt;
203
+            }
204
+
205
+            if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
206
+                $theme_advanced_fonts = $opt['font_formats'] ?? 'Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats';
207
+                $custom_fonts         = '';
208
+
209
+                $stylesheet = $this->upload_url . 'fonts.css';
210
+
211
+                if ( empty( $opt['content_css'] ) ) {
212
+                    $opt['content_css'] = $stylesheet;
213
+                } else {
214
+                    $opt['content_css'] = $opt['content_css'] . ',' . $stylesheet;
215
+                }
216
+
217
+                foreach ( $this->custom_fonts as $arr ) {
218
+                    foreach ( $arr as $font => $pieces ) {
219
+                        $custom_fonts .= ';' . $font . '=' . $font;
220
+                    }
221
+                }
222
+
223
+                $opt['font_formats'] = $theme_advanced_fonts . $custom_fonts;
224
+            }
225
+
226
+            return $opt;
227
+        }
228
+
229
+
230
+        /**
231
+         * Function to enqueue the custom fonts css
232
+         */
233
+        public function enqueue_output() {
234
+            if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
235
+                wp_enqueue_style(
236
+                    'redux-custom-fonts',
237
+                    $this->upload_url . 'fonts.css',
238
+                    array(),
239
+                    filemtime( $this->upload_dir . 'fonts.css' )
240
+                );
241
+            }
242
+        }
243
+
244
+        /**
245
+         * Adds the appropriate mime types to WordPress
246
+         *
247
+         * @param array $existing_mimes Mine array.
248
+         *
249
+         * @return array
250
+         */
251
+        public function custom_upload_mimes( array $existing_mimes = array() ): array {
252
+            $existing_mimes['ttf']   = 'font/ttf';
253
+            $existing_mimes['otf']   = 'font/otf';
254
+            $existing_mimes['eot']   = 'application/vnd.ms-fontobject';
255
+            $existing_mimes['woff']  = 'application/font-woff';
256
+            $existing_mimes['woff2'] = 'application/font-woff2';
257
+            $existing_mimes['svg']   = 'image/svg+xml';
258
+            $existing_mimes['zip']   = 'application/zip';
259
+
260
+            return $existing_mimes;
261
+        }
262
+
263
+        /**
264
+         * Gets all the fonts in the custom_fonts directory
265
+         */
266
+        public function get_fonts() {
267
+            if ( empty( $this->custom_fonts ) ) {
268
+                $params = array(
269
+                    'include_hidden' => false,
270
+                    'recursive'      => true,
271
+                );
272
+
273
+                $fonts = Redux_Core::$filesystem->execute( 'dirlist', $this->upload_dir, $params );
274
+
275
+                if ( ! empty( $fonts ) ) {
276
+                    foreach ( $fonts as $section ) {
277
+                        if ( 'd' === $section['type'] && ! empty( $section['name'] ) ) {
278
+                            if ( 'custom' === $section['name'] ) {
279
+                                $section['name'] = esc_html__( 'Custom Fonts', 'redux-framework' );
280
+                            }
281
+
282
+                            if ( empty( $section['files'] ) ) {
283
+                                continue;
284
+                            }
285
+
286
+                            $this->custom_fonts[ $section['name'] ] = $this->custom_fonts[ $section['name'] ] ?? array();
287
+
288
+                            foreach ( $section['files'] as $font ) {
289
+                                if ( ! empty( $font['name'] ) ) {
290
+                                    if ( empty( $font['files'] ) ) {
291
+                                        continue;
292
+                                    }
293
+
294
+                                    $kinds = array();
295
+
296
+                                    foreach ( $font['files'] as $f ) {
297
+                                        $valid = $this->check_font_name( $f );
298
+                                        if ( $valid ) {
299
+                                            $kinds[] = $valid;
300
+                                        }
301
+                                    }
302
+
303
+                                    $this->custom_fonts[ $section['name'] ][ $font['name'] ] = $kinds;
304
+                                }
305
+                            }
306
+                        }
307
+                    }
308
+                }
309
+            }
310
+        }
311
+
312
+        /**
313
+         * Add custom fonts.
314
+         *
315
+         * @param mixed $custom_fonts Custom fonts.
316
+         *
317
+         * @return array
318
+         */
319
+        public function add_custom_fonts( $custom_fonts ): array {
320
+            if ( empty( $custom_fonts ) ) {
321
+                $custom_fonts = array();
322
+            }
323
+
324
+            return wp_parse_args( $custom_fonts, $this->custom_fonts );
325
+        }
326
+
327
+        /**
328
+         * Ajax used within the panel to add and process the fonts
329
+         */
330
+        public function ajax() {
331
+            if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'redux_custom_fonts' ) ) {
332
+                die( 0 );
333
+            }
334
+
335
+            if ( isset( $_POST['type'] ) && 'delete' === $_POST['type'] ) {
336
+                if ( isset( $_POST['section'] ) ) {
337
+                    if ( esc_html__( 'Custom Fonts', 'redux-framework' ) === $_POST['section'] ) {
338
+                        $_POST['section'] = 'custom';
339
+                    }
340
+                }
341
+
342
+                try {
343
+                    if ( isset( $_POST['section'] ) || isset( $_POST['name'] ) ) {
344
+                        $ret = Redux_Core::$filesystem->execute( 'rmdir', $this->upload_dir . sanitize_file_name( wp_unslash( $_POST['section'] ) ) . '/' . sanitize_file_name( wp_unslash( $_POST['name'] ) ) . '/', array( 'recursive' => true ) );
345
+
346
+                        if ( true === $ret ) {
347
+                            $result = array( 'type' => 'success' );
348
+                        } else {
349
+                            $result = array(
350
+                                'type' => 'error',
351
+                                'msg'  => esc_html__( 'File system failure. Could not delete temp dir.', 'redux-framework' ),
352
+                            );
353
+                        }
354
+
355
+                        echo wp_json_encode( $result );
356
+                    }
357
+                } catch ( Exception $e ) {
358
+                    echo wp_json_encode(
359
+                        array(
360
+                            'type' => 'error',
361
+                            'msg'  => esc_html__( 'Unable to delete font file(s).', 'redux-framework' ),
362
+                        )
363
+                    );
364
+                }
365
+
366
+                die();
367
+            }
368
+
369
+            if ( ! isset( $_POST['title'] ) ) {
370
+                $_POST['title'] = '';
371
+            }
372
+
373
+            if ( ! isset( $_POST['filename'] ) ) {
374
+                $_POST['filename'] = '';
375
+            }
376
+
377
+            $this->font_folder   = sanitize_file_name( wp_unslash( $_POST['title'] ) );
378
+            $this->font_filename = sanitize_file_name( wp_unslash( $_POST['filename'] ) );
379
+
380
+            if ( ! empty( $_POST['attachment_id'] ) ) {
381
+                if ( isset( $_POST['title'] ) || isset( $_POST['mime'] ) ) {
382
+                    $msg = $this->process_web_font( sanitize_key( wp_unslash( $_POST['attachment_id'] ) ), sanitize_text_field( wp_unslash( $_POST['mime'] ) ) );
383
+
384
+                    if ( empty( $msg ) ) {
385
+                        $msg = '';
386
+                    }
387
+
388
+                    $result = array(
389
+                        'type' => 'success',
390
+                        'msg'  => $msg,
391
+                    );
392
+
393
+                    echo wp_json_encode( $result );
394
+                }
395
+            }
396
+
397
+            die();
398
+        }
399
+
400
+        /**
401
+         * Get only valid files. Ensure everything is proper for processing.
402
+         *
403
+         * @param string $path Path.
404
+         *
405
+         * @return array
406
+         */
407
+        public function get_valid_files( string $path ): array {
408
+            $output = array();
409
+            $path   = trailingslashit( $path );
410
+
411
+            $params = array(
412
+                'include_hidden' => false,
413
+                'recursive'      => true,
414
+            );
415
+
416
+            $files = Redux_Core::$filesystem->execute( 'dirlist', $path, $params );
417
+
418
+            foreach ( $files as $file ) {
419
+                if ( 'd' === $file['type'] ) {
420
+                    $output = array_merge( $output, $this->get_valid_files( $path . $file['name'] ) );
421
+                } elseif ( 'f' === $file['type'] ) {
422
+                    $valid = $this->check_font_name( $file );
423
+                    if ( $valid ) {
424
+                        $output[ $valid ] = trailingslashit( $path ) . $file['name'];
425
+                    }
426
+                }
427
+            }
428
+
429
+            return $output;
430
+        }
431
+
432
+        /**
433
+         * Take a valid web font and process the missing pieces.
434
+         *
435
+         * @param string $attachment_id ID.
436
+         * @param string $mime_type     Mine type.
437
+         */
438
+        public function process_web_font( string $attachment_id, string $mime_type ) {
439
+            // phpcs:ignore WordPress.Security.NonceVerification
440
+            if ( ! isset( $_POST['conversion'] ) ) {
441
+                $_POST['conversion'] = 'false';
442
+            }
443
+
444
+            // phpcs:ignore WordPress.Security.NonceVerification
445
+            $conversion = sanitize_text_field( wp_unslash( $_POST['conversion'] ) );
446
+
447
+            $missing = array();
448
+
449
+            $complete = array(
450
+                'ttf',
451
+                'woff',
452
+                'woff2',
453
+                'eot',
454
+                'svg',
455
+                'otf',
456
+            );
457
+
458
+            $subtype = explode( '/', $mime_type );
459
+            $subtype = trim( max( $subtype ) );
460
+
461
+            if ( ! is_dir( $this->upload_dir ) ) {
462
+                Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir );
463
+            }
464
+
465
+            if ( ! is_dir( $this->upload_dir . $this->subfolder ) ) {
466
+                Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder );
467
+            }
468
+
469
+            $temp                = $this->upload_dir . 'temp';
470
+            $this->selected_file = get_attached_file( $attachment_id );
471
+
472
+            if ( empty( $this->selected_file ) ) {
473
+                echo wp_json_encode(
474
+                    array(
475
+                        'type' => 'error',
476
+                        'msg'  => esc_html__( 'Attachment does not exist.', 'redux-framework' ),
477
+                    )
478
+                );
479
+
480
+                die();
481
+            }
482
+
483
+            $filename = explode( '/', $this->selected_file );
484
+
485
+            $filename = $filename[ ( count( $filename ) - 1 ) ];
486
+
487
+            $fontname = ucfirst(
488
+                str_replace(
489
+                    array(
490
+                        '.zip',
491
+                        '.ttf',
492
+                        '.woff',
493
+                        '.woff2',
494
+                        '.eot',
495
+                        '.svg',
496
+                        '.otf',
497
+                    ),
498
+                    '',
499
+                    strtolower( $filename )
500
+                )
501
+            );
502
+
503
+            if ( empty( $this->font_folder ) ) {
504
+                $this->font_folder = $fontname;
505
+            }
506
+
507
+            $ret = array();
508
+
509
+            if ( ! is_dir( $temp ) ) {
510
+                Redux_Core::$filesystem->execute( 'mkdir', $temp );
511
+            }
512
+
513
+            if ( 'zip' === $subtype ) {
514
+                $unzipfile = unzip_file( $this->selected_file, $temp );
515
+
516
+                if ( is_wp_error( $unzipfile ) ) {
517
+                    echo wp_json_encode(
518
+                        array(
519
+                            'type' => 'error',
520
+                            'msg'  => $unzipfile->get_error_message() . '<br><br>' . esc_html__( 'Unzipping failed.', 'redux-framework' ),
521
+                        )
522
+                    );
523
+
524
+                    die();
525
+                }
526
+
527
+                $output = $this->get_valid_files( $temp );
528
+
529
+                if ( ! empty( $output ) ) {
530
+                    foreach ( $complete as $test ) {
531
+                        if ( ! isset( $output[ $test ] ) ) {
532
+                            $missing[] = $test;
533
+                        }
534
+                    }
535
+
536
+                    if ( ! is_dir( $this->upload_dir . $this->subfolder . $this->font_folder . '/' ) ) {
537
+                        Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/' );
538
+                    }
539
+
540
+                    foreach ( $output as $key => $value ) {
541
+                        $param_array = array(
542
+                            'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . '/' . $fontname . '.' . $key,
543
+                            'overwrite'   => true,
544
+                            'chmod'       => 755,
545
+                        );
546
+
547
+                        Redux_Core::$filesystem->execute( 'copy', $value, $param_array );
548
+                    }
549
+
550
+                    if ( true === $this->can_convert && 'true' === $conversion ) {
551
+                        $ret = $this->get_missing_files( $fontname, $missing, $output );
552
+                    }
553
+                }
554
+
555
+                Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
556
+
557
+                $this->generate_css();
558
+
559
+                wp_delete_attachment( $attachment_id, true );
560
+            } elseif ( 'svg+xml' === $subtype || 'vnd.ms-fontobject' === $subtype || 'x-font-ttf' === $subtype || 'ttf' === $subtype || 'otf' === $subtype || 'font-woff' === $subtype || 'font-woff2' === $subtype || 'application-octet-stream' === $subtype || 'octet-stream' === $subtype ) {
561
+                foreach ( $complete as $test ) {
562
+                    if ( $subtype !== $test ) {
563
+                        if ( ! isset( $output[ $test ] ) ) {
564
+                            $missing[] = $test;
565
+                        }
566
+                    }
567
+                }
568
+
569
+                if ( ! is_dir( $this->upload_dir . $this->subfolder . $this->font_folder . '/' ) ) {
570
+                    Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/' );
571
+                }
572
+
573
+                $output = array( $subtype => $this->selected_file );
574
+
575
+                if ( true === $this->can_convert && 'true' === $conversion ) {
576
+                    $ret = $this->get_missing_files( $fontname, $missing, $output );
577
+
578
+                    if ( false === $ret ) {
579
+                        if ( false === $this->convert_local_font() ) {
580
+                            echo wp_json_encode(
581
+                                array(
582
+                                    'type' => 'error',
583
+                                    'msg'  => esc_html__( 'File permission error. Local file could not be installed.', 'redux-framework' ) . ' ' . $subtype,
584
+                                )
585
+                            );
586
+
587
+                            die;
588
+                        }
589
+                    }
590
+                } elseif ( false === $this->convert_local_font() ) {
591
+                        echo wp_json_encode(
592
+                            array(
593
+                                'type' => 'error',
594
+                                'msg'  => esc_html__( 'File permission error. Local file could not be installed.', 'redux-framework' ) . ' ' . $subtype,
595
+                            )
596
+                        );
597
+
598
+                        die;
599
+                }
600
+
601
+                Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
602
+
603
+                $this->generate_css();
604
+
605
+                wp_delete_attachment( $attachment_id, true );
606
+            } else {
607
+                echo wp_json_encode(
608
+                    array(
609
+                        'type' => 'error',
610
+                        'msg'  => esc_html__( 'File type not recognized.', 'redux-framework' ) . ' ' . $subtype,
611
+                    )
612
+                );
613
+
614
+                die();
615
+            }
616
+
617
+            if ( is_array( $ret ) && ! empty( $ret ) ) {
618
+                $msg = esc_html__( 'Unidentified error.', 'redux-framework' );
619
+
620
+                if ( isset( $ret['msg'] ) ) {
621
+                    $msg = $ret['msg'];
622
+                }
623
+
624
+                return $msg;
625
+            }
626
+
627
+            return '';
628
+        }
629
+
630
+        /**
631
+         * Install selected file into Custom Fonts.
632
+         *
633
+         * @return bool
634
+         */
635
+        private function convert_local_font(): bool {
636
+            $param_array = array(
637
+                'destination' => $this->upload_dir . $this->subfolder . '/' . $this->font_folder . '/' . $this->font_filename,
638
+                'overwrite'   => true,
639
+                'chmod'       => 755,
640
+            );
641
+
642
+            return Redux_Core::$filesystem->execute( 'copy', $this->selected_file, $param_array );
643
+        }
644
+
645
+        /**
646
+         * Ping the WebFontOMatic API to get the missing files.
647
+         *
648
+         * @param string $fontname  Font name.
649
+         * @param array  $missing   Missing.
650
+         * @param array  $output    Output.
651
+         */
652
+        private function get_missing_files( string $fontname, array $missing, array $output ) {
653
+            if ( ! empty( $this->font_folder ) && ! empty( $missing ) ) {
654
+                $temp = $this->upload_dir . 'temp';
655
+
656
+                $font_ext = pathinfo( $this->font_filename, PATHINFO_EXTENSION );
657
+
658
+                $unsupported = array( 'eot', 'woff', 'woff2' );
659
+
660
+                // Find a file to convert from.
661
+                foreach ( $output as $key => $value ) {
662
+                    if ( 'eot' === $key ) {
663
+                        continue;
664
+                    } else {
665
+                        $main = $key;
666
+                        break;
667
+                    }
668
+                }
669
+
670
+                if ( ! isset( $main ) ) {
671
+                    echo wp_json_encode(
672
+                        array(
673
+                            'type' => 'error',
674
+                            'msg'  => esc_html__( 'No valid font file was found.', 'redux-framework' ),
675
+                        )
676
+                    );
677
+
678
+                    Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
679
+                    Redux_Core::$filesystem->execute( 'rmdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/', array( 'recursive' => true ) );
680
+
681
+                    die();
682
+                }
683
+
684
+                update_option( 'redux_custom_font_current', $this->font_folder . '.zip' );
685
+
686
+                $boundary = wp_generate_password( 24 );
687
+
688
+                $headers = array(
689
+                    'content-type' => 'multipart/form-data; boundary=' . $boundary,
690
+                    'user-agent'   => 'redux-custom-fonts-' . self::$version . ' using ' . wp_get_theme(),
691
+                );
692
+
693
+                $payload  = '--' . $boundary;
694
+                $payload .= "\r\n";
695
+                $payload .= 'Content-Disposition: form-data; name="md5"' . "\r\n\r\n";
696
+                $payload .= md5( 'redux_custom_font' );
697
+                $payload .= "\r\n";
698
+
699
+                if ( $output[ $main ] ) {
700
+                    $payload .= '--' . $boundary;
701
+                    $payload .= "\r\n";
702
+                    $payload .= 'Content-Disposition: form-data; name="convert"; filename="' . basename( $output[ $main ] ) . '"' . "\r\n";
703
+                    $payload .= "\r\n";
704
+                    $payload .= Redux_Core::$filesystem->execute( 'get_contents', $output[ $main ] );
705
+                    $payload .= "\r\n";
706
+                }
707
+
708
+                $payload .= '--' . $boundary . '--';
709
+
710
+                $args = array(
711
+                    'headers'    => $headers,
712
+                    'body'       => $payload,
713
+                    'user-agent' => $headers['user-agent'],
714
+                    'timeout'    => 300,
715
+                    'sslverify'  => true,
716
+                );
717
+
718
+                // phpcs:disable WordPress.NamingConventions.ValidHookName
719
+                $api_url = apply_filters( 'redux/' . $this->parent->args['opt_name'] . '/extensions/custom_fonts/api_url', 'https://redux.io/fonts' );
720
+
721
+                $response = wp_remote_post( $api_url, $args );
722
+
723
+                if ( is_wp_error( $response ) ) {
724
+                    return array(
725
+                        'type' => 'error',
726
+                        'msg'  => $response->get_error_message() . '<br><br>' . esc_html__( 'Your font could not be converted at this time. Please try again later.', 'redux-framework' ),
727
+                    );
728
+                } elseif ( isset( $response['body'] ) ) {
729
+                    if ( null !== json_decode( $response['body'] ) ) {
730
+                        return json_decode( $response['body'], true );
731
+                    }
732
+                }
733
+
734
+                $param_array = array(
735
+                    'content'   => $response['body'],
736
+                    'overwrite' => true,
737
+                    'chmod'     => FS_CHMOD_FILE,
738
+                );
739
+
740
+                $zip_file = $temp . DIRECTORY_SEPARATOR . $fontname . '.zip';
741
+
742
+                Redux_Core::$filesystem->execute( 'put_contents', $zip_file, $param_array );
743
+
744
+                if ( 0 === filesize( $zip_file ) ) {
745
+                    return false;
746
+                }
747
+
748
+                $zip = unzip_file( $zip_file, $temp );
749
+
750
+                if ( ! is_wp_error( $zip ) ) {
751
+                    $params = array(
752
+                        'include_hidden' => false,
753
+                        'recursive'      => false,
754
+                    );
755
+
756
+                    $files = Redux_Core::$filesystem->execute( 'dirlist', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR, $params );
757
+
758
+                    foreach ( $files as $file ) {
759
+                        $param_array = array(
760
+                            'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $file['name'] ),
761
+                            'overwrite'   => true,
762
+                            'chmod'       => 755,
763
+                        );
764
+
765
+                        Redux_Core::$filesystem->execute( 'move', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . ( $file['name'] ), $param_array );
766
+                    }
767
+                } else {
768
+                    $path_parts = pathinfo( $output[ $main ] );
769
+
770
+                    $param_array = array(
771
+                        'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $path_parts['basename'] ),
772
+                        'overwrite'   => true,
773
+                        'chmod'       => 755,
774
+                    );
775
+
776
+                    Redux_Core::$filesystem->execute( 'move', $output[ $main ], $param_array );
777
+
778
+                    if ( in_array( $font_ext, $unsupported, true ) ) {
779
+                        return array(
780
+                            'type' => 'error',
781
+                            // translators: %s = font extension.
782
+                            'msg'  => $zip->get_error_message() . '<br><br>' . sprintf( esc_html__( 'The font converter does not support %s fonts.', 'redux-framework' ), $font_ext ),
783
+                        );
784
+                    } else {
785
+                        return array(
786
+                            'type' => 'error',
787
+                            'msg'  => $zip->get_error_message() . '<br><br>' . esc_html__( 'ZIP error. Your font could not be converted at this time. Please try again later.', 'redux-framework' ),
788
+                        );
789
+                    }
790
+                }
791
+
792
+                delete_option( 'redux_custom_font_current' );
793
+            }
794
+
795
+            return true;
796
+        }
797
+
798
+        /**
799
+         * Check if the file name is a valid font file.
800
+         *
801
+         * @param array $file File.
802
+         *
803
+         * @return bool|string
804
+         */
805
+        private function check_font_name( array $file ) {
806
+            if ( '.woff' === strtolower( substr( $file['name'], - 5 ) ) ) {
807
+                return 'woff';
808
+            }
809
+
810
+            if ( '.woff2' === strtolower( substr( $file['name'], - 6 ) ) ) {
811
+                return 'woff2';
812
+            }
813
+
814
+            $sub = strtolower( substr( $file['name'], - 4 ) );
815
+
816
+            if ( '.ttf' === $sub ) {
817
+                return 'ttf';
818
+            }
819
+
820
+            if ( '.eot' === $sub ) {
821
+                return 'eot';
822
+            }
823
+
824
+            if ( '.svg' === $sub ) {
825
+                return 'svg';
826
+            }
827
+
828
+            if ( '.otf' === $sub ) {
829
+                return 'otf';
830
+            }
831
+
832
+            return false;
833
+        }
834
+
835
+        /**
836
+         * Generate a new custom CSS file for enqueuing on the frontend and backend.
837
+         */
838
+        private function generate_css() {
839
+            $params = array(
840
+                'include_hidden' => false,
841
+                'recursive'      => true,
842
+            );
843
+
844
+            $fonts = Redux_Core::$filesystem->execute( 'dirlist', $this->upload_dir . 'custom' . DIRECTORY_SEPARATOR, $params );
845
+
846
+            if ( empty( $fonts ) || ! is_array( $fonts ) ) {
847
+                return;
848
+            }
849
+
850
+            foreach ( $fonts as $font ) {
851
+                if ( 'd' === $font['type'] ) {
852
+                    break;
853
+                }
854
+
855
+                if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
856
+                    Redux_Core::$filesystem->execute( 'delete', $this->upload_dir . 'fonts.css' );
857
+                }
858
+
859
+                return;
860
+            }
861
+
862
+            $css = '';
863
+
864
+            foreach ( $fonts as $font ) {
865
+                if ( 'd' === $font['type'] ) {
866
+                    $css .= $this->generate_font_css( $font['name'], $this->upload_dir . 'custom' . DIRECTORY_SEPARATOR );
867
+                }
868
+            }
869
+
870
+            if ( '' !== $css ) {
871
+                $param_array = array(
872
+                    'content' => $css,
873
+                    'chmod'   => FS_CHMOD_FILE,
874
+                );
875
+
876
+                Redux_Core::$filesystem->execute( 'put_contents', $this->upload_dir . 'fonts.css', $param_array );
877
+            }
878
+        }
879
+
880
+        /**
881
+         * Process to actually construct the custom font css file.
882
+         *
883
+         * @param string $name Name.
884
+         * @param string $dir  Directory.
885
+         *
886
+         * @return string
887
+         */
888
+        private function generate_font_css( string $name, string $dir ): ?string {
889
+            $path = $dir . $name;
890
+
891
+            $params = array(
892
+                'include_hidden' => false,
893
+                'recursive'      => true,
894
+            );
895
+
896
+            $files = Redux_Core::$filesystem->execute( 'dirlist', $path, $params );
897
+
898
+            if ( empty( $files ) ) {
899
+                return null;
900
+            }
901
+
902
+            $output = array();
903
+
904
+            foreach ( $files as $file ) {
905
+                $output[ $this->check_font_name( $file ) ] = $file['name'];
906
+            }
907
+
908
+            $css = '@font-face {';
909
+
910
+            $css .= 'font-family:"' . $name . '";';
911
+
912
+            $src = array();
913
+
914
+            if ( isset( $output['eot'] ) ) {
915
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['eot']}?#iefix') format('embedded-opentype')";
916
+            }
917
+
918
+            if ( isset( $output['woff'] ) ) {
919
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['woff']}') format('woff')";
920
+            }
921
+
922
+            if ( isset( $output['woff2'] ) ) {
923
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['woff2']}') format('woff2')";
924
+            }
925
+
926
+            if ( isset( $output['ttf'] ) ) {
927
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['ttf']}') format('truetype')";
928
+            }
929
+
930
+            if ( isset( $output['svg'] ) ) {
931
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['svg']}#svg$name') format('svg')";
932
+            }
933
+
934
+            if ( ! empty( $src ) ) {
935
+                $css .= 'src:' . implode( ', ', $src ) . ';';
936
+            }
937
+
938
+            // Replace font weight and style with sub-sets.
939
+            $css .= 'font-weight: normal;';
940
+
941
+            $css .= 'font-style: normal;';
942
+
943
+            $css .= '}';
944
+
945
+            return $css;
946
+        }
947
+
948
+        /**
949
+         * Custom function for filtering the section array.
950
+         * Good for child themes to override or add to the sections.
951
+         * Simply include this function in the child themes functions.php file.
952
+         * NOTE: the defined constants for URLs and directories will NOT be available at this point in a child theme,
953
+         * so you must use get_template_directory_uri() if you want to use any of the built-in icons
954
+         */
955
+        public function add_section() {
956
+            if ( ! isset( $this->parent->fontControl ) ) {
957
+                $this->parent->sections[] = array(
958
+                    'title'  => esc_html__( 'Font Control', 'redux-framework' ),
959
+                    'desc'   => '<p class="description"></p>',
960
+                    'icon'   => 'el-icon-font',
961
+                    'id'     => 'redux_dynamic_font_control',
962
+                    // Leave this as a blank section, no options just some intro text set above.
963
+                    'fields' => array(),
964
+                );
965
+
966
+                for ( $i = count( $this->parent->sections ); $i >= 1; $i-- ) {
967
+                    if ( isset( $this->parent->sections[ $i ] ) && isset( $this->parent->sections[ $i ]['title'] ) && esc_html__( 'Font Control', 'redux-framework' ) === $this->parent->sections[ $i ]['title'] ) {
968
+                        $this->parent->fontControl                                        = $i;
969
+                        $this->parent->sections[ $this->parent->fontControl ]['fields'][] = array(
970
+                            'id'   => 'redux_font_control',
971
+                            'type' => 'custom_fonts',
972
+                        );
973
+
974
+                        break;
975
+                    }
976
+                }
977
+            }
978
+        }
979
+    }
980
+
981
+    class_alias( Redux_Extension_Custom_Fonts::class, 'ReduxFramework_Extension_custom_fonts' );
982 982
 }
Please login to merge, or discard this patch.