Completed
Push — master ( 7388a0...c197b7 )
by
unknown
45s
created
redux-core/inc/classes/class-redux-args.php 1 patch
Indentation   +384 added lines, -384 removed lines patch added patch discarded remove patch
@@ -11,388 +11,388 @@
 block discarded – undo
11 11
 
12 12
 if ( ! class_exists( 'Redux_Args', false ) ) {
13 13
 
14
-	/**
15
-	 * Class Redux_Args
16
-	 */
17
-	class Redux_Args {
18
-
19
-		/**
20
-		 * Returns entire arguments array.
21
-		 *
22
-		 * @var array|mixed
23
-		 */
24
-		public $get = array();
25
-
26
-		/**
27
-		 * ReduxFramework object.
28
-		 *
29
-		 * @var ReduxFramework|null
30
-		 */
31
-		private ?ReduxFramework $parent;
32
-
33
-		/**
34
-		 * Switch to omit social icons if dev_mode is set to true and Redux defaults are used.
35
-		 *
36
-		 * @var bool
37
-		 */
38
-		public bool $omit_icons = false;
39
-
40
-		/**
41
-		 * Switch to omit support menu items if dev_mode is set to true and redux defaults are used.
42
-		 *
43
-		 * @var bool
44
-		 */
45
-		public bool $omit_items = false;
46
-
47
-		/**
48
-		 * Flag to force dev_mod to true if in localhost or WP_DEBUG is set to true.
49
-		 *
50
-		 * @var bool
51
-		 */
52
-		public bool $dev_mode_forced = false;
53
-
54
-		/**
55
-		 * Redux_Args constructor.
56
-		 *
57
-		 * @param ReduxFramework $redux ReduxFramework object.
58
-		 * @param array          $args  Global arguments array.
59
-		 */
60
-		public function __construct( ReduxFramework $redux, array $args ) {
61
-			$this->parent = $redux;
62
-
63
-			$default = array(
64
-				'opt_name'                         => '',
65
-				'last_tab'                         => '',
66
-				'menu_icon'                        => '',
67
-				'menu_title'                       => '',
68
-				'page_title'                       => '',
69
-				'page_slug'                        => '',
70
-				'page_permissions'                 => 'manage_options',
71
-				'menu_type'                        => 'menu',
72
-				'page_parent'                      => 'themes.php',
73
-				'page_priority'                    => null,
74
-				'allow_sub_menu'                   => true,
75
-				'save_defaults'                    => true,
76
-				'footer_credit'                    => '',
77
-				'async_typography'                 => false,
78
-				'disable_google_fonts_link'        => false,
79
-				'class'                            => '',
80
-				'admin_bar'                        => true,
81
-				'admin_bar_priority'               => 999,
82
-				'admin_bar_icon'                   => '',
83
-				'help_tabs'                        => array(),
84
-				'help_sidebar'                     => '',
85
-				'database'                         => '',
86
-				'customizer'                       => false,
87
-				'global_variable'                  => '',
88
-				'output'                           => true,
89
-				'output_variables_prefix'          => '--',
90
-				'compiler_output_variables_prefix' => '$',
91
-				'compiler'                         => true,
92
-				'output_tag'                       => true,
93
-				'output_location'                  => array( 'frontend' ),
94
-				'transient_time'                   => '',
95
-				'default_show'                     => false,
96
-				'default_mark'                     => '',
97
-				'disable_save_warn'                => false,
98
-				'open_expanded'                    => false,
99
-				'hide_expand'                      => false,
100
-				'network_admin'                    => false,
101
-				'network_sites'                    => true,
102
-				'hide_reset'                       => false,
103
-				'hide_save'                        => false,
104
-				'hints'                            => array(
105
-					'icon'          => 'el el-question-sign',
106
-					'icon_position' => 'right',
107
-					'icon_color'    => 'lightgray',
108
-					'icon_size'     => 'normal',
109
-					'tip_style'     => array(
110
-						'color'   => 'light',
111
-						'shadow'  => true,
112
-						'rounded' => false,
113
-						'style'   => '',
114
-					),
115
-					'tip_position'  => array(
116
-						'my' => 'top_left',
117
-						'at' => 'bottom_right',
118
-					),
119
-					'tip_effect'    => array(
120
-						'show' => array(
121
-							'effect'   => 'slide',
122
-							'duration' => '500',
123
-							'event'    => 'mouseover',
124
-						),
125
-						'hide' => array(
126
-							'effect'   => 'fade',
127
-							'duration' => '500',
128
-							'event'    => 'click mouseleave',
129
-						),
130
-					),
131
-				),
132
-				'font_weights'                     => array(
133
-					array(
134
-						'id'   => '400',
135
-						'name' => __( 'Regular 400', 'redux-framework' ),
136
-					),
137
-					array(
138
-						'id'   => '400italic',
139
-						'name' => __( 'Regular 400 Italic', 'redux-framework' ),
140
-					),
141
-					array(
142
-						'id'   => '700',
143
-						'name' => __( 'Bold 700', 'redux-framework' ),
144
-					),
145
-					array(
146
-						'id'   => '700italic',
147
-						'name' => __( 'Bold 700 Italic', 'redux-framework' ),
148
-					),
149
-				),
150
-				'show_import_export'               => true,
151
-				'show_options_object'              => true,
152
-				'dev_mode'                         => true,
153
-				'templates_path'                   => '',
154
-				'ajax_save'                        => true,
155
-				'use_cdn'                          => true,
156
-				'cdn_check_time'                   => 1440,
157
-				'options_api'                      => true,
158
-				'allow_tracking'                   => true,
159
-				'admin_theme'                      => 'wp',
160
-				'elusive_frontend'                 => false,
161
-				'fontawesome_frontend'             => false,
162
-				'flyout_submenus'                  => true,
163
-				'font_display'                     => 'swap', // block|swap|fallback|optional.
164
-				'load_on_cron'                     => false,
165
-				'search'                           => false,
166
-			);
167
-
168
-			$args = Redux_Functions::parse_args( $args, $default );
169
-
170
-			$args = $this->args( $args );
171
-
172
-			$args = $this->default_cleanup( $args );
173
-
174
-			if ( ! in_array( $args['font_display'], array( 'block', 'swap', 'fallback', 'optional' ), true ) ) {
175
-				$args['font_display'] = 'swap';
176
-			}
177
-
178
-			if ( isset( $args['async_typography'] ) && $args['async_typography'] ) {
179
-				$args['async_typography'] = false;
180
-			}
181
-
182
-			$this->get = $args;
183
-
184
-			$this->parent->args = $args;
185
-
186
-			if ( 'redux_extensions_demo' !== $args['opt_name'] && 'redux_demo' !== $args['opt_name'] ) {
187
-				$this->change_demo_defaults( $args );
188
-			}
189
-		}
190
-
191
-		/**
192
-		 * Builds and sanitizes a global args array.
193
-		 *
194
-		 * @param     array $args Global args.
195
-		 *
196
-		 * @return array
197
-		 */
198
-		private function args( array $args ): array {
199
-			$args = $this->no_errors_please( $args );
200
-
201
-			$this->parent->old_opt_name = $args['opt_name'];
202
-
203
-			$args = $this->filters( $args );
204
-
205
-			if ( ! function_exists( 'wp_rand' ) ) {
206
-				require_once ABSPATH . '/wp-includes/pluggable.php';
207
-			}
208
-
209
-			if ( $args['opt_name'] === $this->parent->old_opt_name ) {
210
-				$this->parent->old_opt_name = null;
211
-				unset( $this->parent->old_opt_name );
212
-			}
213
-
214
-			// Do not save the defaults if we're on a live preview!
215
-			if ( 'customize' === $GLOBALS['pagenow'] && isset( $_GET['customize_theme'] ) && ! empty( $_GET['customize_theme'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
216
-				$args['save_defaults'] = false;
217
-			}
218
-
219
-			return $this->shim( $args );
220
-		}
221
-
222
-		/**
223
-		 * Apply filters to arg data.
224
-		 *
225
-		 * @param     array $args Global args.
226
-		 *
227
-		 * @return mixed|void
228
-		 */
229
-		private function filters( array $args ) {
230
-			/**
231
-			 * Filter 'redux/args/{opt_name}'
232
-			 *
233
-			 * @param     array     $args ReduxFramework configuration
234
-			 */
235
-
236
-			// phpcs:ignore WordPress.NamingConventions.ValidHookName
237
-			$args = apply_filters( "redux/args/{$args['opt_name']}", $args );
238
-
239
-			/**
240
-			 * Filter 'redux/options/{opt_name}/args'
241
-			 *
242
-			 * @param     array     $args ReduxFramework configuration
243
-			 */
244
-
245
-			// phpcs:ignore WordPress.NamingConventions.ValidHookName
246
-			return apply_filters( "redux/options/{$args['opt_name']}/args", $args );
247
-		}
248
-
249
-		/**
250
-		 * Sanitize args that should not be empty.
251
-		 *
252
-		 * @param     array $args Global args.
253
-		 *
254
-		 * @return array
255
-		 */
256
-		private function no_errors_please( array $args ): array {
257
-			if ( empty( $args['transient_time'] ) ) {
258
-				$args['transient_time'] = 60 * MINUTE_IN_SECONDS;
259
-			}
260
-
261
-			if ( empty( $args['footer_credit'] ) ) {
262
-
263
-				$footer_text = sprintf(
264
-				/* translators: 1: Redux, 2: Link to plugin review */
265
-					__( 'Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!', 'redux-framework' ),
266
-					'<strong>' . __( 'Redux', 'redux-framework' ) . '</strong>',
267
-					'<a href="https://wordpress.org/support/plugin/redux-framework/reviews/?filter=5/#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
268
-				);
269
-				$args['footer_credit'] = '<span id="footer-thankyou">' . $footer_text . '</span>';
270
-			}
271
-
272
-			if ( empty( $args['menu_title'] ) ) {
273
-				$args['menu_title'] = esc_html__( 'Options', 'redux-framework' );
274
-			}
275
-
276
-			if ( empty( $args['page_title'] ) ) {
277
-				$args['page_title'] = esc_html__( 'Options', 'redux-framework' );
278
-			}
279
-
280
-			// Auto creates the page_slug appropriately.
281
-			if ( empty( $args['page_slug'] ) ) {
282
-				if ( ! empty( $args['display_name'] ) ) {
283
-					$args['page_slug'] = sanitize_html_class( $args['display_name'] );
284
-				} elseif ( ! empty( $args['page_title'] ) ) {
285
-					$args['page_slug'] = sanitize_html_class( $args['page_title'] );
286
-				} elseif ( ! empty( $args['menu_title'] ) ) {
287
-					$args['page_slug'] = sanitize_html_class( $args['menu_title'] );
288
-				} else {
289
-					$args['page_slug'] = str_replace( '-', '_', $args['opt_name'] );
290
-				}
291
-			}
292
-
293
-			return $args;
294
-		}
295
-
296
-		/**
297
-		 * Shims for much older v3 configs.
298
-		 *
299
-		 * @param     array $args Global args.
300
-		 *
301
-		 * @return array
302
-		 */
303
-		private function shim( array $args ): array {
304
-			/**
305
-			 * SHIM SECTION
306
-			 * Old variables and ways of doing things that need correcting.  ;)
307
-			 * */
308
-			// Variable name change.
309
-			if ( ! empty( $args['page_cap'] ) ) {
310
-				$args['page_permissions'] = $args['page_cap'];
311
-				unset( $args['page_cap'] );
312
-			}
313
-
314
-			if ( ! empty( $args['page_position'] ) ) {
315
-				$args['page_priority'] = $args['page_position'];
316
-				unset( $args['page_position'] );
317
-			}
318
-
319
-			if ( ! empty( $args['page_type'] ) ) {
320
-				$args['menu_type'] = $args['page_type'];
321
-				unset( $args['page_type'] );
322
-			}
323
-
324
-			return $args;
325
-		}
326
-
327
-		/**
328
-		 * Verify to see if dev has bothered to change admin bar links and share icons from demo data to their own.
329
-		 *
330
-		 * @param array $args Global args.
331
-		 */
332
-		private function change_demo_defaults( array $args ) {
333
-			if ( $args['dev_mode'] || true === Redux_Helpers::is_local_host() ) {
334
-				if ( ! empty( $args['admin_bar_links'] ) ) {
335
-					foreach ( $args['admin_bar_links'] as $arr ) {
336
-						if ( is_array( $arr ) && ! empty( $arr ) ) {
337
-							foreach ( $arr as $y ) {
338
-								if ( strpos( Redux_Core::strtolower( $y ), 'redux' ) !== false ) {
339
-									$this->omit_items = true;
340
-									break;
341
-								}
342
-							}
343
-						}
344
-					}
345
-				}
346
-
347
-				if ( ! empty( $args['share_icons'] ) ) {
348
-					foreach ( $args['share_icons'] as $arr ) {
349
-						if ( is_array( $arr ) && ! empty( $arr ) ) {
350
-							foreach ( $arr as $y ) {
351
-								if ( strpos( Redux_Core::strtolower( $y ), 'redux' ) !== false ) {
352
-									$this->omit_icons = true;
353
-								}
354
-							}
355
-						}
356
-					}
357
-				}
358
-			}
359
-		}
360
-
361
-		/**
362
-		 * Fix other arg criteria that sometimes gets hosed up.
363
-		 *
364
-		 * @param array $args Global args.
365
-		 *
366
-		 * @return array
367
-		 * @noinspection PhpStrictComparisonWithOperandsOfDifferentTypesInspection
368
-		 */
369
-		private function default_cleanup( array $args ): array {
370
-
371
-			// Fix the global variable name.
372
-			if ( '' === $args['global_variable'] && false !== $args['global_variable'] ) {
373
-				$args['global_variable'] = str_replace( '-', '_', $args['opt_name'] );
374
-			}
375
-
376
-			if ( isset( $args['customizer_only'] ) && $args['customizer_only'] ) {
377
-				$args['menu_type']      = 'hidden';
378
-				$args['customizer']     = true;
379
-				$args['admin_bar']      = false;
380
-				$args['allow_sub_menu'] = false;
381
-			}
382
-
383
-			// Check if the Airplane Mode plugin is installed.
384
-			if ( class_exists( 'Airplane_Mode_Core' ) ) {
385
-				$airplane = Airplane_Mode_Core::getInstance();
386
-				if ( method_exists( $airplane, 'enabled' ) ) {
387
-					if ( $airplane->enabled() ) {
388
-						$args['use_cdn'] = false;
389
-					}
390
-				} elseif ( 'on' === $airplane->check_status() ) {
391
-					$args['use_cdn'] = false;
392
-				}
393
-			}
394
-
395
-			return $args;
396
-		}
397
-	}
14
+    /**
15
+     * Class Redux_Args
16
+     */
17
+    class Redux_Args {
18
+
19
+        /**
20
+         * Returns entire arguments array.
21
+         *
22
+         * @var array|mixed
23
+         */
24
+        public $get = array();
25
+
26
+        /**
27
+         * ReduxFramework object.
28
+         *
29
+         * @var ReduxFramework|null
30
+         */
31
+        private ?ReduxFramework $parent;
32
+
33
+        /**
34
+         * Switch to omit social icons if dev_mode is set to true and Redux defaults are used.
35
+         *
36
+         * @var bool
37
+         */
38
+        public bool $omit_icons = false;
39
+
40
+        /**
41
+         * Switch to omit support menu items if dev_mode is set to true and redux defaults are used.
42
+         *
43
+         * @var bool
44
+         */
45
+        public bool $omit_items = false;
46
+
47
+        /**
48
+         * Flag to force dev_mod to true if in localhost or WP_DEBUG is set to true.
49
+         *
50
+         * @var bool
51
+         */
52
+        public bool $dev_mode_forced = false;
53
+
54
+        /**
55
+         * Redux_Args constructor.
56
+         *
57
+         * @param ReduxFramework $redux ReduxFramework object.
58
+         * @param array          $args  Global arguments array.
59
+         */
60
+        public function __construct( ReduxFramework $redux, array $args ) {
61
+            $this->parent = $redux;
62
+
63
+            $default = array(
64
+                'opt_name'                         => '',
65
+                'last_tab'                         => '',
66
+                'menu_icon'                        => '',
67
+                'menu_title'                       => '',
68
+                'page_title'                       => '',
69
+                'page_slug'                        => '',
70
+                'page_permissions'                 => 'manage_options',
71
+                'menu_type'                        => 'menu',
72
+                'page_parent'                      => 'themes.php',
73
+                'page_priority'                    => null,
74
+                'allow_sub_menu'                   => true,
75
+                'save_defaults'                    => true,
76
+                'footer_credit'                    => '',
77
+                'async_typography'                 => false,
78
+                'disable_google_fonts_link'        => false,
79
+                'class'                            => '',
80
+                'admin_bar'                        => true,
81
+                'admin_bar_priority'               => 999,
82
+                'admin_bar_icon'                   => '',
83
+                'help_tabs'                        => array(),
84
+                'help_sidebar'                     => '',
85
+                'database'                         => '',
86
+                'customizer'                       => false,
87
+                'global_variable'                  => '',
88
+                'output'                           => true,
89
+                'output_variables_prefix'          => '--',
90
+                'compiler_output_variables_prefix' => '$',
91
+                'compiler'                         => true,
92
+                'output_tag'                       => true,
93
+                'output_location'                  => array( 'frontend' ),
94
+                'transient_time'                   => '',
95
+                'default_show'                     => false,
96
+                'default_mark'                     => '',
97
+                'disable_save_warn'                => false,
98
+                'open_expanded'                    => false,
99
+                'hide_expand'                      => false,
100
+                'network_admin'                    => false,
101
+                'network_sites'                    => true,
102
+                'hide_reset'                       => false,
103
+                'hide_save'                        => false,
104
+                'hints'                            => array(
105
+                    'icon'          => 'el el-question-sign',
106
+                    'icon_position' => 'right',
107
+                    'icon_color'    => 'lightgray',
108
+                    'icon_size'     => 'normal',
109
+                    'tip_style'     => array(
110
+                        'color'   => 'light',
111
+                        'shadow'  => true,
112
+                        'rounded' => false,
113
+                        'style'   => '',
114
+                    ),
115
+                    'tip_position'  => array(
116
+                        'my' => 'top_left',
117
+                        'at' => 'bottom_right',
118
+                    ),
119
+                    'tip_effect'    => array(
120
+                        'show' => array(
121
+                            'effect'   => 'slide',
122
+                            'duration' => '500',
123
+                            'event'    => 'mouseover',
124
+                        ),
125
+                        'hide' => array(
126
+                            'effect'   => 'fade',
127
+                            'duration' => '500',
128
+                            'event'    => 'click mouseleave',
129
+                        ),
130
+                    ),
131
+                ),
132
+                'font_weights'                     => array(
133
+                    array(
134
+                        'id'   => '400',
135
+                        'name' => __( 'Regular 400', 'redux-framework' ),
136
+                    ),
137
+                    array(
138
+                        'id'   => '400italic',
139
+                        'name' => __( 'Regular 400 Italic', 'redux-framework' ),
140
+                    ),
141
+                    array(
142
+                        'id'   => '700',
143
+                        'name' => __( 'Bold 700', 'redux-framework' ),
144
+                    ),
145
+                    array(
146
+                        'id'   => '700italic',
147
+                        'name' => __( 'Bold 700 Italic', 'redux-framework' ),
148
+                    ),
149
+                ),
150
+                'show_import_export'               => true,
151
+                'show_options_object'              => true,
152
+                'dev_mode'                         => true,
153
+                'templates_path'                   => '',
154
+                'ajax_save'                        => true,
155
+                'use_cdn'                          => true,
156
+                'cdn_check_time'                   => 1440,
157
+                'options_api'                      => true,
158
+                'allow_tracking'                   => true,
159
+                'admin_theme'                      => 'wp',
160
+                'elusive_frontend'                 => false,
161
+                'fontawesome_frontend'             => false,
162
+                'flyout_submenus'                  => true,
163
+                'font_display'                     => 'swap', // block|swap|fallback|optional.
164
+                'load_on_cron'                     => false,
165
+                'search'                           => false,
166
+            );
167
+
168
+            $args = Redux_Functions::parse_args( $args, $default );
169
+
170
+            $args = $this->args( $args );
171
+
172
+            $args = $this->default_cleanup( $args );
173
+
174
+            if ( ! in_array( $args['font_display'], array( 'block', 'swap', 'fallback', 'optional' ), true ) ) {
175
+                $args['font_display'] = 'swap';
176
+            }
177
+
178
+            if ( isset( $args['async_typography'] ) && $args['async_typography'] ) {
179
+                $args['async_typography'] = false;
180
+            }
181
+
182
+            $this->get = $args;
183
+
184
+            $this->parent->args = $args;
185
+
186
+            if ( 'redux_extensions_demo' !== $args['opt_name'] && 'redux_demo' !== $args['opt_name'] ) {
187
+                $this->change_demo_defaults( $args );
188
+            }
189
+        }
190
+
191
+        /**
192
+         * Builds and sanitizes a global args array.
193
+         *
194
+         * @param     array $args Global args.
195
+         *
196
+         * @return array
197
+         */
198
+        private function args( array $args ): array {
199
+            $args = $this->no_errors_please( $args );
200
+
201
+            $this->parent->old_opt_name = $args['opt_name'];
202
+
203
+            $args = $this->filters( $args );
204
+
205
+            if ( ! function_exists( 'wp_rand' ) ) {
206
+                require_once ABSPATH . '/wp-includes/pluggable.php';
207
+            }
208
+
209
+            if ( $args['opt_name'] === $this->parent->old_opt_name ) {
210
+                $this->parent->old_opt_name = null;
211
+                unset( $this->parent->old_opt_name );
212
+            }
213
+
214
+            // Do not save the defaults if we're on a live preview!
215
+            if ( 'customize' === $GLOBALS['pagenow'] && isset( $_GET['customize_theme'] ) && ! empty( $_GET['customize_theme'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
216
+                $args['save_defaults'] = false;
217
+            }
218
+
219
+            return $this->shim( $args );
220
+        }
221
+
222
+        /**
223
+         * Apply filters to arg data.
224
+         *
225
+         * @param     array $args Global args.
226
+         *
227
+         * @return mixed|void
228
+         */
229
+        private function filters( array $args ) {
230
+            /**
231
+             * Filter 'redux/args/{opt_name}'
232
+             *
233
+             * @param     array     $args ReduxFramework configuration
234
+             */
235
+
236
+            // phpcs:ignore WordPress.NamingConventions.ValidHookName
237
+            $args = apply_filters( "redux/args/{$args['opt_name']}", $args );
238
+
239
+            /**
240
+             * Filter 'redux/options/{opt_name}/args'
241
+             *
242
+             * @param     array     $args ReduxFramework configuration
243
+             */
244
+
245
+            // phpcs:ignore WordPress.NamingConventions.ValidHookName
246
+            return apply_filters( "redux/options/{$args['opt_name']}/args", $args );
247
+        }
248
+
249
+        /**
250
+         * Sanitize args that should not be empty.
251
+         *
252
+         * @param     array $args Global args.
253
+         *
254
+         * @return array
255
+         */
256
+        private function no_errors_please( array $args ): array {
257
+            if ( empty( $args['transient_time'] ) ) {
258
+                $args['transient_time'] = 60 * MINUTE_IN_SECONDS;
259
+            }
260
+
261
+            if ( empty( $args['footer_credit'] ) ) {
262
+
263
+                $footer_text = sprintf(
264
+                /* translators: 1: Redux, 2: Link to plugin review */
265
+                    __( 'Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!', 'redux-framework' ),
266
+                    '<strong>' . __( 'Redux', 'redux-framework' ) . '</strong>',
267
+                    '<a href="https://wordpress.org/support/plugin/redux-framework/reviews/?filter=5/#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
268
+                );
269
+                $args['footer_credit'] = '<span id="footer-thankyou">' . $footer_text . '</span>';
270
+            }
271
+
272
+            if ( empty( $args['menu_title'] ) ) {
273
+                $args['menu_title'] = esc_html__( 'Options', 'redux-framework' );
274
+            }
275
+
276
+            if ( empty( $args['page_title'] ) ) {
277
+                $args['page_title'] = esc_html__( 'Options', 'redux-framework' );
278
+            }
279
+
280
+            // Auto creates the page_slug appropriately.
281
+            if ( empty( $args['page_slug'] ) ) {
282
+                if ( ! empty( $args['display_name'] ) ) {
283
+                    $args['page_slug'] = sanitize_html_class( $args['display_name'] );
284
+                } elseif ( ! empty( $args['page_title'] ) ) {
285
+                    $args['page_slug'] = sanitize_html_class( $args['page_title'] );
286
+                } elseif ( ! empty( $args['menu_title'] ) ) {
287
+                    $args['page_slug'] = sanitize_html_class( $args['menu_title'] );
288
+                } else {
289
+                    $args['page_slug'] = str_replace( '-', '_', $args['opt_name'] );
290
+                }
291
+            }
292
+
293
+            return $args;
294
+        }
295
+
296
+        /**
297
+         * Shims for much older v3 configs.
298
+         *
299
+         * @param     array $args Global args.
300
+         *
301
+         * @return array
302
+         */
303
+        private function shim( array $args ): array {
304
+            /**
305
+             * SHIM SECTION
306
+             * Old variables and ways of doing things that need correcting.  ;)
307
+             * */
308
+            // Variable name change.
309
+            if ( ! empty( $args['page_cap'] ) ) {
310
+                $args['page_permissions'] = $args['page_cap'];
311
+                unset( $args['page_cap'] );
312
+            }
313
+
314
+            if ( ! empty( $args['page_position'] ) ) {
315
+                $args['page_priority'] = $args['page_position'];
316
+                unset( $args['page_position'] );
317
+            }
318
+
319
+            if ( ! empty( $args['page_type'] ) ) {
320
+                $args['menu_type'] = $args['page_type'];
321
+                unset( $args['page_type'] );
322
+            }
323
+
324
+            return $args;
325
+        }
326
+
327
+        /**
328
+         * Verify to see if dev has bothered to change admin bar links and share icons from demo data to their own.
329
+         *
330
+         * @param array $args Global args.
331
+         */
332
+        private function change_demo_defaults( array $args ) {
333
+            if ( $args['dev_mode'] || true === Redux_Helpers::is_local_host() ) {
334
+                if ( ! empty( $args['admin_bar_links'] ) ) {
335
+                    foreach ( $args['admin_bar_links'] as $arr ) {
336
+                        if ( is_array( $arr ) && ! empty( $arr ) ) {
337
+                            foreach ( $arr as $y ) {
338
+                                if ( strpos( Redux_Core::strtolower( $y ), 'redux' ) !== false ) {
339
+                                    $this->omit_items = true;
340
+                                    break;
341
+                                }
342
+                            }
343
+                        }
344
+                    }
345
+                }
346
+
347
+                if ( ! empty( $args['share_icons'] ) ) {
348
+                    foreach ( $args['share_icons'] as $arr ) {
349
+                        if ( is_array( $arr ) && ! empty( $arr ) ) {
350
+                            foreach ( $arr as $y ) {
351
+                                if ( strpos( Redux_Core::strtolower( $y ), 'redux' ) !== false ) {
352
+                                    $this->omit_icons = true;
353
+                                }
354
+                            }
355
+                        }
356
+                    }
357
+                }
358
+            }
359
+        }
360
+
361
+        /**
362
+         * Fix other arg criteria that sometimes gets hosed up.
363
+         *
364
+         * @param array $args Global args.
365
+         *
366
+         * @return array
367
+         * @noinspection PhpStrictComparisonWithOperandsOfDifferentTypesInspection
368
+         */
369
+        private function default_cleanup( array $args ): array {
370
+
371
+            // Fix the global variable name.
372
+            if ( '' === $args['global_variable'] && false !== $args['global_variable'] ) {
373
+                $args['global_variable'] = str_replace( '-', '_', $args['opt_name'] );
374
+            }
375
+
376
+            if ( isset( $args['customizer_only'] ) && $args['customizer_only'] ) {
377
+                $args['menu_type']      = 'hidden';
378
+                $args['customizer']     = true;
379
+                $args['admin_bar']      = false;
380
+                $args['allow_sub_menu'] = false;
381
+            }
382
+
383
+            // Check if the Airplane Mode plugin is installed.
384
+            if ( class_exists( 'Airplane_Mode_Core' ) ) {
385
+                $airplane = Airplane_Mode_Core::getInstance();
386
+                if ( method_exists( $airplane, 'enabled' ) ) {
387
+                    if ( $airplane->enabled() ) {
388
+                        $args['use_cdn'] = false;
389
+                    }
390
+                } elseif ( 'on' === $airplane->check_status() ) {
391
+                    $args['use_cdn'] = false;
392
+                }
393
+            }
394
+
395
+            return $args;
396
+        }
397
+    }
398 398
 }
Please login to merge, or discard this patch.
inc/validation/unique_slug/class-redux-validation-unique-slug.php 1 patch
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -12,82 +12,82 @@
 block discarded – undo
12 12
 
13 13
 if ( ! class_exists( 'Redux_Validation_Unique_Slug', false ) ) {
14 14
 
15
-	/**
16
-	 * Class Redux_Validation_Unique_Slug
17
-	 */
18
-	class Redux_Validation_Unique_Slug extends Redux_Validate {
19
-
20
-		/**
21
-		 * Field Validation Function.
22
-		 * Takes the vars and validates them
23
-		 *
24
-		 * @since ReduxFramework 3.0.0
25
-		 */
26
-		public function validate() {
27
-			global $wpdb, $wp_rewrite;
28
-
29
-			$this->field['msg']              = $this->field['msg'] ?? esc_html__( 'That URL slug is in use, please choose another.', 'redux-framework' );
30
-			$this->field['flush_permalinks'] = $this->field['flush_permalinks'] ?? false;
31
-
32
-			$slug = $this->value;
33
-
34
-			$post_name_check = '';
35
-
36
-			$feeds = $wp_rewrite->feeds;
37
-			if ( ! is_array( $feeds ) ) {
38
-				$feeds = array();
39
-			}
40
-
41
-			// Post slugs must be unique across all posts.
42
-			$result = wp_cache_get( 'redux-post-name' );
43
-			if ( false === $result ) {
44
-				// phpcs:ignore WordPress.DB.DirectDatabaseQuery
45
-				$post_name_check = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $slug ) );
46
-
47
-				wp_cache_set( 'redux-post-name', $post_name_check );
48
-			}
49
-
50
-			/**
51
-			 * Filter whether the post slug would be bad as a flat slug.
52
-			 *
53
-			 * @since 3.1.0
54
-			 *
55
-			 * @param bool   $bad_slug  Whether the post slug would be bad as a flat slug.
56
-			 * @param string $slug      The post slug.
57
-			 * @param string $post_type Post type.
58
-			 */
59
-			if ( $post_name_check || in_array( $slug, $feeds, true ) || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) {
60
-				$suffix = 2;
61
-
62
-				do {
63
-					$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
64
-
65
-					$result = wp_cache_get( 'redux-alt-post-name' );
66
-					if ( false === $result ) {
67
-						// phpcs:ignore WordPress.DB.DirectDatabaseQuery
68
-						$post_name_check = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $alt_post_name ) );
69
-
70
-						wp_cache_set( 'redux-alt-post-name', $result );
71
-					}
72
-
73
-					++$suffix;
74
-				} while ( $post_name_check );
75
-
76
-				$slug                   = $alt_post_name;
77
-				$this->value            = ( isset( $this->current ) ) ? $this->current : '';
78
-				$this->field['msg']     = sprintf( $this->field['msg'], $slug );
79
-				$this->field['current'] = $this->value;
80
-				$this->error            = $this->field;
81
-			} elseif ( isset( $this->field['flush_permalinks'] ) && true === $this->field['flush_permalinks'] ) {
82
-				add_action( 'init', array( $this, 'flush_permalinks' ), 99 );
83
-			}
84
-		}
85
-
86
-		/**
87
-		 * Flush WordPress permalinks.
88
-		 */
89
-		public function flush_permalinks() {
90
-			flush_rewrite_rules();
91
-		}
92
-	}
15
+    /**
16
+     * Class Redux_Validation_Unique_Slug
17
+     */
18
+    class Redux_Validation_Unique_Slug extends Redux_Validate {
19
+
20
+        /**
21
+         * Field Validation Function.
22
+         * Takes the vars and validates them
23
+         *
24
+         * @since ReduxFramework 3.0.0
25
+         */
26
+        public function validate() {
27
+            global $wpdb, $wp_rewrite;
28
+
29
+            $this->field['msg']              = $this->field['msg'] ?? esc_html__( 'That URL slug is in use, please choose another.', 'redux-framework' );
30
+            $this->field['flush_permalinks'] = $this->field['flush_permalinks'] ?? false;
31
+
32
+            $slug = $this->value;
33
+
34
+            $post_name_check = '';
35
+
36
+            $feeds = $wp_rewrite->feeds;
37
+            if ( ! is_array( $feeds ) ) {
38
+                $feeds = array();
39
+            }
40
+
41
+            // Post slugs must be unique across all posts.
42
+            $result = wp_cache_get( 'redux-post-name' );
43
+            if ( false === $result ) {
44
+                // phpcs:ignore WordPress.DB.DirectDatabaseQuery
45
+                $post_name_check = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $slug ) );
46
+
47
+                wp_cache_set( 'redux-post-name', $post_name_check );
48
+            }
49
+
50
+            /**
51
+             * Filter whether the post slug would be bad as a flat slug.
52
+             *
53
+             * @since 3.1.0
54
+             *
55
+             * @param bool   $bad_slug  Whether the post slug would be bad as a flat slug.
56
+             * @param string $slug      The post slug.
57
+             * @param string $post_type Post type.
58
+             */
59
+            if ( $post_name_check || in_array( $slug, $feeds, true ) || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) {
60
+                $suffix = 2;
61
+
62
+                do {
63
+                    $alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
64
+
65
+                    $result = wp_cache_get( 'redux-alt-post-name' );
66
+                    if ( false === $result ) {
67
+                        // phpcs:ignore WordPress.DB.DirectDatabaseQuery
68
+                        $post_name_check = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $alt_post_name ) );
69
+
70
+                        wp_cache_set( 'redux-alt-post-name', $result );
71
+                    }
72
+
73
+                    ++$suffix;
74
+                } while ( $post_name_check );
75
+
76
+                $slug                   = $alt_post_name;
77
+                $this->value            = ( isset( $this->current ) ) ? $this->current : '';
78
+                $this->field['msg']     = sprintf( $this->field['msg'], $slug );
79
+                $this->field['current'] = $this->value;
80
+                $this->error            = $this->field;
81
+            } elseif ( isset( $this->field['flush_permalinks'] ) && true === $this->field['flush_permalinks'] ) {
82
+                add_action( 'init', array( $this, 'flush_permalinks' ), 99 );
83
+            }
84
+        }
85
+
86
+        /**
87
+         * Flush WordPress permalinks.
88
+         */
89
+        public function flush_permalinks() {
90
+            flush_rewrite_rules();
91
+        }
92
+    }
93 93
 }
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   +959 added lines, -959 removed lines patch added patch discarded remove patch
@@ -16,963 +16,963 @@
 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
-			parent::__construct( $redux, __FILE__ );
111
-
112
-			self::$instance = parent::get_instance();
113
-
114
-			$this->add_field( 'custom_fonts' );
115
-
116
-			$this->upload_dir = Redux_Core::$upload_dir . 'custom-fonts/';
117
-			$this->upload_url = Redux_Core::$upload_url . 'custom-fonts/';
118
-
119
-			if ( ! is_dir( $this->upload_dir ) ) {
120
-				Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir );
121
-			}
122
-
123
-			if ( ! is_dir( $this->upload_dir . '/custom' ) ) {
124
-				Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . '/custom' );
125
-			}
126
-
127
-			$this->get_fonts();
128
-
129
-			if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
130
-				if ( filemtime( $this->upload_dir . 'custom' ) > ( filemtime( $this->upload_dir . 'fonts.css' ) + 10 ) ) {
131
-					$this->generate_css();
132
-				}
133
-			} else {
134
-				$this->generate_css();
135
-			}
136
-
137
-			add_action( 'wp_ajax_redux_custom_fonts', array( $this, 'ajax' ) );
138
-			add_action( 'wp_ajax_redux_custom_font_timer', array( $this, 'timer' ) );
139
-
140
-			add_filter( "redux/{$this->parent->args['opt_name']}/field/typography/custom_fonts", array( $this, 'add_custom_fonts' ) );
141
-
142
-			// phpcs:disable
143
-			// $this->is_field = Redux_Helpers::is_field_in_use( $parent, 'custom_fonts' );
144
-
145
-			// if ( ! $this->is_field ) {
146
-			// 	$this->add_section();
147
-			// }
148
-
149
-			add_filter( "redux/options/{$this->parent->args['opt_name']}/section/redux_dynamic_font_control", array( $this, 'remove_dynamic_section' ) ); // phpcs:ignore WordPress.NamingConventions.ValidHookName
150
-			add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
151
-			add_action( 'wp_head', array( $this, 'enqueue_output' ), 150 );
152
-			add_filter( 'tiny_mce_before_init', array( $this, 'extend_tinymce_dropdown' ) );
153
-
154
-			$this->can_convert = true; // has_filter( 'redux/' . $this->parent->args['opt_name'] . '/extensions/custom_fonts/api_url' );
155
-			// phpcs:enable
156
-		}
157
-
158
-		/**
159
-		 * Timer.
160
-		 */
161
-		public function timer() {
162
-			$name = get_option( 'redux_custom_font_current' );
163
-
164
-			if ( ! empty( $name ) ) {
165
-				echo esc_html( $name );
166
-			}
167
-
168
-			die();
169
-		}
170
-
171
-		/**
172
-		 * Remove the dynamically added section if the field was used elsewhere
173
-		 *
174
-		 * @param array $section Section array.
175
-		 *
176
-		 * @return array
177
-		 * @since  Redux_Framework 3.1.1
178
-		 */
179
-		public function remove_dynamic_section( array $section ): array {
180
-			if ( isset( $this->parent->field_types['custom_fonts'] ) ) {
181
-				$section = array();
182
-			}
183
-
184
-			return $section;
185
-		}
186
-
187
-		/**
188
-		 * Adds FontMeister fonts to the TinyMCE drop-down.
189
-		 * Typekit's fonts don't render properly in the drop-down and in the editor,
190
-		 * because Typekit needs JS and TinyMCE doesn't support that.
191
-		 *
192
-		 * @param array $opt Option array.
193
-		 *
194
-		 * @return array
195
-		 */
196
-		public function extend_tinymce_dropdown( array $opt ): array {
197
-			if ( ! is_admin() ) {
198
-				return $opt;
199
-			}
200
-
201
-			if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
202
-				$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';
203
-				$custom_fonts         = '';
204
-
205
-				$stylesheet = $this->upload_url . 'fonts.css';
206
-
207
-				if ( empty( $opt['content_css'] ) ) {
208
-					$opt['content_css'] = $stylesheet;
209
-				} else {
210
-					$opt['content_css'] = $opt['content_css'] . ',' . $stylesheet;
211
-				}
212
-
213
-				foreach ( $this->custom_fonts as $arr ) {
214
-					foreach ( $arr as $font => $pieces ) {
215
-						$custom_fonts .= ';' . $font . '=' . $font;
216
-					}
217
-				}
218
-
219
-				$opt['font_formats'] = $theme_advanced_fonts . $custom_fonts;
220
-			}
221
-
222
-			return $opt;
223
-		}
224
-
225
-
226
-		/**
227
-		 * Function to enqueue the custom fonts css
228
-		 */
229
-		public function enqueue_output() {
230
-			if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
231
-				wp_enqueue_style(
232
-					'redux-custom-fonts',
233
-					$this->upload_url . 'fonts.css',
234
-					array(),
235
-					filemtime( $this->upload_dir . 'fonts.css' )
236
-				);
237
-			}
238
-		}
239
-
240
-		/**
241
-		 * Adds the appropriate mime types to WordPress
242
-		 *
243
-		 * @param array $existing_mimes Mine array.
244
-		 *
245
-		 * @return array
246
-		 */
247
-		public function custom_upload_mimes( array $existing_mimes = array() ): array {
248
-			$existing_mimes['ttf']   = 'font/ttf';
249
-			$existing_mimes['otf']   = 'font/otf';
250
-			$existing_mimes['eot']   = 'application/vnd.ms-fontobject';
251
-			$existing_mimes['woff']  = 'application/font-woff';
252
-			$existing_mimes['woff2'] = 'application/font-woff2';
253
-			$existing_mimes['svg']   = 'image/svg+xml';
254
-			$existing_mimes['zip']   = 'application/zip';
255
-
256
-			return $existing_mimes;
257
-		}
258
-
259
-		/**
260
-		 * Gets all the fonts in the custom_fonts directory
261
-		 */
262
-		public function get_fonts() {
263
-			if ( empty( $this->custom_fonts ) ) {
264
-				$params = array(
265
-					'include_hidden' => false,
266
-					'recursive'      => true,
267
-				);
268
-
269
-				$fonts = Redux_Core::$filesystem->execute( 'dirlist', $this->upload_dir, $params );
270
-
271
-				if ( ! empty( $fonts ) ) {
272
-					foreach ( $fonts as $section ) {
273
-						if ( 'd' === $section['type'] && ! empty( $section['name'] ) ) {
274
-							if ( 'custom' === $section['name'] ) {
275
-								$section['name'] = esc_html__( 'Custom Fonts', 'redux-framework' );
276
-							}
277
-
278
-							if ( empty( $section['files'] ) ) {
279
-								continue;
280
-							}
281
-
282
-							$this->custom_fonts[ $section['name'] ] = $this->custom_fonts[ $section['name'] ] ?? array();
283
-
284
-							foreach ( $section['files'] as $font ) {
285
-								if ( ! empty( $font['name'] ) ) {
286
-									if ( empty( $font['files'] ) ) {
287
-										continue;
288
-									}
289
-
290
-									$kinds = array();
291
-
292
-									foreach ( $font['files'] as $f ) {
293
-										$valid = $this->check_font_name( $f );
294
-										if ( $valid ) {
295
-											$kinds[] = $valid;
296
-										}
297
-									}
298
-
299
-									$this->custom_fonts[ $section['name'] ][ $font['name'] ] = $kinds;
300
-								}
301
-							}
302
-						}
303
-					}
304
-				}
305
-			}
306
-		}
307
-
308
-		/**
309
-		 * Add custom fonts.
310
-		 *
311
-		 * @param mixed $custom_fonts Custom fonts.
312
-		 *
313
-		 * @return array
314
-		 */
315
-		public function add_custom_fonts( $custom_fonts ): array {
316
-			if ( empty( $custom_fonts ) ) {
317
-				$custom_fonts = array();
318
-			}
319
-
320
-			return wp_parse_args( $custom_fonts, $this->custom_fonts );
321
-		}
322
-
323
-		/**
324
-		 * Ajax used within the panel to add and process the fonts
325
-		 */
326
-		public function ajax() {
327
-			if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'redux_custom_fonts' ) ) {
328
-				die( 0 );
329
-			}
330
-
331
-			if ( isset( $_POST['type'] ) && 'delete' === $_POST['type'] ) {
332
-				if ( isset( $_POST['section'] ) ) {
333
-					if ( esc_html__( 'Custom Fonts', 'redux-framework' ) === $_POST['section'] ) {
334
-						$_POST['section'] = 'custom';
335
-					}
336
-				}
337
-
338
-				try {
339
-					if ( isset( $_POST['section'] ) || isset( $_POST['name'] ) ) {
340
-						$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 ) );
341
-
342
-						if ( true === $ret ) {
343
-							$result = array( 'type' => 'success' );
344
-						} else {
345
-							$result = array(
346
-								'type' => 'error',
347
-								'msg'  => esc_html__( 'File system failure. Could not delete temp dir.', 'redux-framework' ),
348
-							);
349
-						}
350
-
351
-						echo wp_json_encode( $result );
352
-					}
353
-				} catch ( Exception $e ) {
354
-					echo wp_json_encode(
355
-						array(
356
-							'type' => 'error',
357
-							'msg'  => esc_html__( 'Unable to delete font file(s).', 'redux-framework' ),
358
-						)
359
-					);
360
-				}
361
-
362
-				die();
363
-			}
364
-
365
-			if ( ! isset( $_POST['title'] ) ) {
366
-				$_POST['title'] = '';
367
-			}
368
-
369
-			if ( ! isset( $_POST['filename'] ) ) {
370
-				$_POST['filename'] = '';
371
-			}
372
-
373
-			$this->font_folder   = sanitize_file_name( wp_unslash( $_POST['title'] ) );
374
-			$this->font_filename = sanitize_file_name( wp_unslash( $_POST['filename'] ) );
375
-
376
-			if ( ! empty( $_POST['attachment_id'] ) ) {
377
-				if ( isset( $_POST['title'] ) || isset( $_POST['mime'] ) ) {
378
-					$msg = $this->process_web_font( sanitize_key( wp_unslash( $_POST['attachment_id'] ) ), sanitize_text_field( wp_unslash( $_POST['mime'] ) ) );
379
-
380
-					if ( empty( $msg ) ) {
381
-						$msg = '';
382
-					}
383
-
384
-					$result = array(
385
-						'type' => 'success',
386
-						'msg'  => $msg,
387
-					);
388
-
389
-					echo wp_json_encode( $result );
390
-				}
391
-			}
392
-
393
-			die();
394
-		}
395
-
396
-		/**
397
-		 * Get only valid files. Ensure everything is proper for processing.
398
-		 *
399
-		 * @param string $path Path.
400
-		 *
401
-		 * @return array
402
-		 */
403
-		public function get_valid_files( string $path ): array {
404
-			$output = array();
405
-			$path   = trailingslashit( $path );
406
-
407
-			$params = array(
408
-				'include_hidden' => false,
409
-				'recursive'      => true,
410
-			);
411
-
412
-			$files = Redux_Core::$filesystem->execute( 'dirlist', $path, $params );
413
-
414
-			foreach ( $files as $file ) {
415
-				if ( 'd' === $file['type'] ) {
416
-					$output = array_merge( $output, $this->get_valid_files( $path . $file['name'] ) );
417
-				} elseif ( 'f' === $file['type'] ) {
418
-					$valid = $this->check_font_name( $file );
419
-					if ( $valid ) {
420
-						$output[ $valid ] = trailingslashit( $path ) . $file['name'];
421
-					}
422
-				}
423
-			}
424
-
425
-			return $output;
426
-		}
427
-
428
-		/**
429
-		 * Take a valid web font and process the missing pieces.
430
-		 *
431
-		 * @param string $attachment_id ID.
432
-		 * @param string $mime_type     Mine type.
433
-		 */
434
-		public function process_web_font( string $attachment_id, string $mime_type ) {
435
-			// phpcs:ignore WordPress.Security.NonceVerification
436
-			if ( ! isset( $_POST['conversion'] ) ) {
437
-				$_POST['conversion'] = 'false';
438
-			}
439
-
440
-			// phpcs:ignore WordPress.Security.NonceVerification
441
-			$conversion = sanitize_text_field( wp_unslash( $_POST['conversion'] ) );
442
-
443
-			$missing = array();
444
-
445
-			$complete = array(
446
-				'ttf',
447
-				'woff',
448
-				'woff2',
449
-				'eot',
450
-				'svg',
451
-				'otf',
452
-			);
453
-
454
-			$subtype = explode( '/', $mime_type );
455
-			$subtype = trim( max( $subtype ) );
456
-
457
-			if ( ! is_dir( $this->upload_dir ) ) {
458
-				Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir );
459
-			}
460
-
461
-			if ( ! is_dir( $this->upload_dir . $this->subfolder ) ) {
462
-				Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder );
463
-			}
464
-
465
-			$temp                = $this->upload_dir . 'temp';
466
-			$this->selected_file = get_attached_file( $attachment_id );
467
-
468
-			if ( empty( $this->selected_file ) ) {
469
-				echo wp_json_encode(
470
-					array(
471
-						'type' => 'error',
472
-						'msg'  => esc_html__( 'Attachment does not exist.', 'redux-framework' ),
473
-					)
474
-				);
475
-
476
-				die();
477
-			}
478
-
479
-			$filename = explode( '/', $this->selected_file );
480
-
481
-			$filename = $filename[ ( count( $filename ) - 1 ) ];
482
-
483
-			$fontname = ucfirst(
484
-				str_replace(
485
-					array(
486
-						'.zip',
487
-						'.ttf',
488
-						'.woff',
489
-						'.woff2',
490
-						'.eot',
491
-						'.svg',
492
-						'.otf',
493
-					),
494
-					'',
495
-					strtolower( $filename )
496
-				)
497
-			);
498
-
499
-			if ( empty( $this->font_folder ) ) {
500
-				$this->font_folder = $fontname;
501
-			}
502
-
503
-			$ret = array();
504
-
505
-			if ( ! is_dir( $temp ) ) {
506
-				Redux_Core::$filesystem->execute( 'mkdir', $temp );
507
-			}
508
-
509
-			if ( 'zip' === $subtype ) {
510
-				$unzipfile = unzip_file( $this->selected_file, $temp );
511
-
512
-				if ( is_wp_error( $unzipfile ) ) {
513
-					echo wp_json_encode(
514
-						array(
515
-							'type' => 'error',
516
-							'msg'  => $unzipfile->get_error_message() . '<br><br>' . esc_html__( 'Unzipping failed.', 'redux-framework' ),
517
-						)
518
-					);
519
-
520
-					die();
521
-				}
522
-
523
-				$output = $this->get_valid_files( $temp );
524
-
525
-				if ( ! empty( $output ) ) {
526
-					foreach ( $complete as $test ) {
527
-						if ( ! isset( $output[ $test ] ) ) {
528
-							$missing[] = $test;
529
-						}
530
-					}
531
-
532
-					if ( ! is_dir( $this->upload_dir . $this->subfolder . $this->font_folder . '/' ) ) {
533
-						Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/' );
534
-					}
535
-
536
-					foreach ( $output as $key => $value ) {
537
-						$param_array = array(
538
-							'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . '/' . $fontname . '.' . $key,
539
-							'overwrite'   => true,
540
-							'chmod'       => 755,
541
-						);
542
-
543
-						Redux_Core::$filesystem->execute( 'copy', $value, $param_array );
544
-					}
545
-
546
-					if ( true === $this->can_convert && 'true' === $conversion ) {
547
-						$ret = $this->get_missing_files( $fontname, $missing, $output );
548
-					}
549
-				}
550
-
551
-				Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
552
-
553
-				$this->generate_css();
554
-
555
-				wp_delete_attachment( $attachment_id, true );
556
-			} 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 ) {
557
-				foreach ( $complete as $test ) {
558
-					if ( $subtype !== $test ) {
559
-						if ( ! isset( $output[ $test ] ) ) {
560
-							$missing[] = $test;
561
-						}
562
-					}
563
-				}
564
-
565
-				if ( ! is_dir( $this->upload_dir . $this->subfolder . $this->font_folder . '/' ) ) {
566
-					Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/' );
567
-				}
568
-
569
-				$output = array( $subtype => $this->selected_file );
570
-
571
-				if ( true === $this->can_convert && 'true' === $conversion ) {
572
-					$ret = $this->get_missing_files( $fontname, $missing, $output );
573
-
574
-					if ( false === $ret ) {
575
-						if ( false === $this->convert_local_font() ) {
576
-							echo wp_json_encode(
577
-								array(
578
-									'type' => 'error',
579
-									'msg'  => esc_html__( 'File permission error. Local file could not be installed.', 'redux-framework' ) . ' ' . $subtype,
580
-								)
581
-							);
582
-
583
-							die;
584
-						}
585
-					}
586
-				} elseif ( false === $this->convert_local_font() ) {
587
-						echo wp_json_encode(
588
-							array(
589
-								'type' => 'error',
590
-								'msg'  => esc_html__( 'File permission error. Local file could not be installed.', 'redux-framework' ) . ' ' . $subtype,
591
-							)
592
-						);
593
-
594
-						die;
595
-				}
596
-
597
-				Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
598
-
599
-				$this->generate_css();
600
-
601
-				wp_delete_attachment( $attachment_id, true );
602
-			} else {
603
-				echo wp_json_encode(
604
-					array(
605
-						'type' => 'error',
606
-						'msg'  => esc_html__( 'File type not recognized.', 'redux-framework' ) . ' ' . $subtype,
607
-					)
608
-				);
609
-
610
-				die();
611
-			}
612
-
613
-			if ( is_array( $ret ) && ! empty( $ret ) ) {
614
-				$msg = esc_html__( 'Unidentified error.', 'redux-framework' );
615
-
616
-				if ( isset( $ret['msg'] ) ) {
617
-					$msg = $ret['msg'];
618
-				}
619
-
620
-				return $msg;
621
-			}
622
-
623
-			return '';
624
-		}
625
-
626
-		/**
627
-		 * Install selected file into Custom Fonts.
628
-		 *
629
-		 * @return bool
630
-		 */
631
-		private function convert_local_font(): bool {
632
-			$param_array = array(
633
-				'destination' => $this->upload_dir . $this->subfolder . '/' . $this->font_folder . '/' . $this->font_filename,
634
-				'overwrite'   => true,
635
-				'chmod'       => 755,
636
-			);
637
-
638
-			return Redux_Core::$filesystem->execute( 'copy', $this->selected_file, $param_array );
639
-		}
640
-
641
-		/**
642
-		 * Ping the WebFontOMatic API to get the missing files.
643
-		 *
644
-		 * @param string $fontname  Font name.
645
-		 * @param array  $missing   Missing.
646
-		 * @param array  $output    Output.
647
-		 */
648
-		private function get_missing_files( string $fontname, array $missing, array $output ) {
649
-			if ( ! empty( $this->font_folder ) && ! empty( $missing ) ) {
650
-				$temp = $this->upload_dir . 'temp';
651
-
652
-				$font_ext = pathinfo( $this->font_filename, PATHINFO_EXTENSION );
653
-
654
-				$unsupported = array( 'eot', 'woff', 'woff2' );
655
-
656
-				// Find a file to convert from.
657
-				foreach ( $output as $key => $value ) {
658
-					if ( 'eot' === $key ) {
659
-						continue;
660
-					} else {
661
-						$main = $key;
662
-						break;
663
-					}
664
-				}
665
-
666
-				if ( ! isset( $main ) ) {
667
-					echo wp_json_encode(
668
-						array(
669
-							'type' => 'error',
670
-							'msg'  => esc_html__( 'No valid font file was found.', 'redux-framework' ),
671
-						)
672
-					);
673
-
674
-					Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
675
-					Redux_Core::$filesystem->execute( 'rmdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/', array( 'recursive' => true ) );
676
-
677
-					die();
678
-				}
679
-
680
-				update_option( 'redux_custom_font_current', $this->font_folder . '.zip' );
681
-
682
-				$boundary = wp_generate_password( 24 );
683
-
684
-				$headers = array(
685
-					'content-type' => 'multipart/form-data; boundary=' . $boundary,
686
-					'user-agent'   => 'redux-custom-fonts-' . self::$version . ' using ' . wp_get_theme(),
687
-				);
688
-
689
-				$payload  = '--' . $boundary;
690
-				$payload .= "\r\n";
691
-				$payload .= 'Content-Disposition: form-data; name="md5"' . "\r\n\r\n";
692
-				$payload .= md5( 'redux_custom_font' );
693
-				$payload .= "\r\n";
694
-
695
-				if ( $output[ $main ] ) {
696
-					$payload .= '--' . $boundary;
697
-					$payload .= "\r\n";
698
-					$payload .= 'Content-Disposition: form-data; name="convert"; filename="' . basename( $output[ $main ] ) . '"' . "\r\n";
699
-					$payload .= "\r\n";
700
-					$payload .= Redux_Core::$filesystem->execute( 'get_contents', $output[ $main ] );
701
-					$payload .= "\r\n";
702
-				}
703
-
704
-				$payload .= '--' . $boundary . '--';
705
-
706
-				$args = array(
707
-					'headers'    => $headers,
708
-					'body'       => $payload,
709
-					'user-agent' => $headers['user-agent'],
710
-					'timeout'    => 300,
711
-					'sslverify'  => true,
712
-				);
713
-
714
-				// phpcs:disable WordPress.NamingConventions.ValidHookName
715
-				$api_url = apply_filters( 'redux/' . $this->parent->args['opt_name'] . '/extensions/custom_fonts/api_url', 'https://redux.io/fonts' );
716
-
717
-				$response = wp_remote_post( $api_url, $args );
718
-
719
-				if ( is_wp_error( $response ) ) {
720
-					return array(
721
-						'type' => 'error',
722
-						'msg'  => $response->get_error_message() . '<br><br>' . esc_html__( 'Your font could not be converted at this time. Please try again later.', 'redux-framework' ),
723
-					);
724
-				} elseif ( isset( $response['body'] ) ) {
725
-					if ( null !== json_decode( $response['body'] ) ) {
726
-						return json_decode( $response['body'], true );
727
-					}
728
-				}
729
-
730
-				$param_array = array(
731
-					'content'   => $response['body'],
732
-					'overwrite' => true,
733
-					'chmod'     => FS_CHMOD_FILE,
734
-				);
735
-
736
-				$zip_file = $temp . DIRECTORY_SEPARATOR . $fontname . '.zip';
737
-
738
-				Redux_Core::$filesystem->execute( 'put_contents', $zip_file, $param_array );
739
-
740
-				if ( 0 === filesize( $zip_file ) ) {
741
-					return false;
742
-				}
743
-
744
-				$zip = unzip_file( $zip_file, $temp );
745
-
746
-				if ( ! is_wp_error( $zip ) ) {
747
-					$params = array(
748
-						'include_hidden' => false,
749
-						'recursive'      => false,
750
-					);
751
-
752
-					$files = Redux_Core::$filesystem->execute( 'dirlist', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR, $params );
753
-
754
-					foreach ( $files as $file ) {
755
-						$param_array = array(
756
-							'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $file['name'] ),
757
-							'overwrite'   => true,
758
-							'chmod'       => 755,
759
-						);
760
-
761
-						Redux_Core::$filesystem->execute( 'move', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . ( $file['name'] ), $param_array );
762
-					}
763
-				} else {
764
-					$path_parts = pathinfo( $output[ $main ] );
765
-
766
-					$param_array = array(
767
-						'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $path_parts['basename'] ),
768
-						'overwrite'   => true,
769
-						'chmod'       => 755,
770
-					);
771
-
772
-					Redux_Core::$filesystem->execute( 'move', $output[ $main ], $param_array );
773
-
774
-					if ( in_array( $font_ext, $unsupported, true ) ) {
775
-						return array(
776
-							'type' => 'error',
777
-							// translators: %s = font extension.
778
-							'msg'  => $zip->get_error_message() . '<br><br>' . sprintf( esc_html__( 'The font converter does not support %s fonts.', 'redux-framework' ), $font_ext ),
779
-						);
780
-					} else {
781
-						return array(
782
-							'type' => 'error',
783
-							'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' ),
784
-						);
785
-					}
786
-				}
787
-
788
-				delete_option( 'redux_custom_font_current' );
789
-			}
790
-
791
-			return true;
792
-		}
793
-
794
-		/**
795
-		 * Check if the file name is a valid font file.
796
-		 *
797
-		 * @param array $file File.
798
-		 *
799
-		 * @return bool|string
800
-		 */
801
-		private function check_font_name( array $file ) {
802
-			if ( '.woff' === strtolower( substr( $file['name'], - 5 ) ) ) {
803
-				return 'woff';
804
-			}
805
-
806
-			if ( '.woff2' === strtolower( substr( $file['name'], - 6 ) ) ) {
807
-				return 'woff2';
808
-			}
809
-
810
-			$sub = strtolower( substr( $file['name'], - 4 ) );
811
-
812
-			if ( '.ttf' === $sub ) {
813
-				return 'ttf';
814
-			}
815
-
816
-			if ( '.eot' === $sub ) {
817
-				return 'eot';
818
-			}
819
-
820
-			if ( '.svg' === $sub ) {
821
-				return 'svg';
822
-			}
823
-
824
-			if ( '.otf' === $sub ) {
825
-				return 'otf';
826
-			}
827
-
828
-			return false;
829
-		}
830
-
831
-		/**
832
-		 * Generate a new custom CSS file for enqueuing on the frontend and backend.
833
-		 */
834
-		private function generate_css() {
835
-			$params = array(
836
-				'include_hidden' => false,
837
-				'recursive'      => true,
838
-			);
839
-
840
-			$fonts = Redux_Core::$filesystem->execute( 'dirlist', $this->upload_dir . 'custom' . DIRECTORY_SEPARATOR, $params );
841
-
842
-			if ( empty( $fonts ) || ! is_array( $fonts ) ) {
843
-				return;
844
-			}
845
-
846
-			foreach ( $fonts as $font ) {
847
-				if ( 'd' === $font['type'] ) {
848
-					break;
849
-				}
850
-
851
-				if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
852
-					Redux_Core::$filesystem->execute( 'delete', $this->upload_dir . 'fonts.css' );
853
-				}
854
-
855
-				return;
856
-			}
857
-
858
-			$css = '';
859
-
860
-			foreach ( $fonts as $font ) {
861
-				if ( 'd' === $font['type'] ) {
862
-					$css .= $this->generate_font_css( $font['name'], $this->upload_dir . 'custom' . DIRECTORY_SEPARATOR );
863
-				}
864
-			}
865
-
866
-			if ( '' !== $css ) {
867
-				$param_array = array(
868
-					'content' => $css,
869
-					'chmod'   => FS_CHMOD_FILE,
870
-				);
871
-
872
-				Redux_Core::$filesystem->execute( 'put_contents', $this->upload_dir . 'fonts.css', $param_array );
873
-			}
874
-		}
875
-
876
-		/**
877
-		 * Process to actually construct the custom font css file.
878
-		 *
879
-		 * @param string $name Name.
880
-		 * @param string $dir  Directory.
881
-		 *
882
-		 * @return string
883
-		 */
884
-		private function generate_font_css( string $name, string $dir ): ?string {
885
-			$path = $dir . $name;
886
-
887
-			$params = array(
888
-				'include_hidden' => false,
889
-				'recursive'      => true,
890
-			);
891
-
892
-			$files = Redux_Core::$filesystem->execute( 'dirlist', $path, $params );
893
-
894
-			if ( empty( $files ) ) {
895
-				return null;
896
-			}
897
-
898
-			$output = array();
899
-
900
-			foreach ( $files as $file ) {
901
-				$output[ $this->check_font_name( $file ) ] = $file['name'];
902
-			}
903
-
904
-			$css = '@font-face {';
905
-
906
-			$css .= 'font-family:"' . $name . '";';
907
-
908
-			$src = array();
909
-
910
-			if ( isset( $output['eot'] ) ) {
911
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['eot']}?#iefix') format('embedded-opentype')";
912
-			}
913
-
914
-			if ( isset( $output['woff'] ) ) {
915
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['woff']}') format('woff')";
916
-			}
917
-
918
-			if ( isset( $output['woff2'] ) ) {
919
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['woff2']}') format('woff2')";
920
-			}
921
-
922
-			if ( isset( $output['ttf'] ) ) {
923
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['ttf']}') format('truetype')";
924
-			}
925
-
926
-			if ( isset( $output['svg'] ) ) {
927
-				$src[] = "url('{$this->upload_url}custom/$name/{$output['svg']}#svg$name') format('svg')";
928
-			}
929
-
930
-			if ( ! empty( $src ) ) {
931
-				$css .= 'src:' . implode( ', ', $src ) . ';';
932
-			}
933
-
934
-			// Replace font weight and style with sub-sets.
935
-			$css .= 'font-weight: normal;';
936
-
937
-			$css .= 'font-style: normal;';
938
-
939
-			$css .= '}';
940
-
941
-			return $css;
942
-		}
943
-
944
-		/**
945
-		 * Custom function for filtering the section array.
946
-		 * Good for child themes to override or add to the sections.
947
-		 * Simply include this function in the child themes functions.php file.
948
-		 * NOTE: the defined constants for URLs and directories will NOT be available at this point in a child theme,
949
-		 * so you must use get_template_directory_uri() if you want to use any of the built-in icons
950
-		 */
951
-		public function add_section() {
952
-			if ( ! isset( $this->parent->fontControl ) ) {
953
-				$this->parent->sections[] = array(
954
-					'title'  => esc_html__( 'Font Control', 'redux-framework' ),
955
-					'desc'   => '<p class="description"></p>',
956
-					'icon'   => 'el-icon-font',
957
-					'id'     => 'redux_dynamic_font_control',
958
-					// Leave this as a blank section, no options just some intro text set above.
959
-					'fields' => array(),
960
-				);
961
-
962
-				for ( $i = count( $this->parent->sections ); $i >= 1; $i-- ) {
963
-					if ( isset( $this->parent->sections[ $i ] ) && isset( $this->parent->sections[ $i ]['title'] ) && esc_html__( 'Font Control', 'redux-framework' ) === $this->parent->sections[ $i ]['title'] ) {
964
-						$this->parent->fontControl                                        = $i;
965
-						$this->parent->sections[ $this->parent->fontControl ]['fields'][] = array(
966
-							'id'   => 'redux_font_control',
967
-							'type' => 'custom_fonts',
968
-						);
969
-
970
-						break;
971
-					}
972
-				}
973
-			}
974
-		}
975
-	}
976
-
977
-	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
+            parent::__construct( $redux, __FILE__ );
111
+
112
+            self::$instance = parent::get_instance();
113
+
114
+            $this->add_field( 'custom_fonts' );
115
+
116
+            $this->upload_dir = Redux_Core::$upload_dir . 'custom-fonts/';
117
+            $this->upload_url = Redux_Core::$upload_url . 'custom-fonts/';
118
+
119
+            if ( ! is_dir( $this->upload_dir ) ) {
120
+                Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir );
121
+            }
122
+
123
+            if ( ! is_dir( $this->upload_dir . '/custom' ) ) {
124
+                Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . '/custom' );
125
+            }
126
+
127
+            $this->get_fonts();
128
+
129
+            if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
130
+                if ( filemtime( $this->upload_dir . 'custom' ) > ( filemtime( $this->upload_dir . 'fonts.css' ) + 10 ) ) {
131
+                    $this->generate_css();
132
+                }
133
+            } else {
134
+                $this->generate_css();
135
+            }
136
+
137
+            add_action( 'wp_ajax_redux_custom_fonts', array( $this, 'ajax' ) );
138
+            add_action( 'wp_ajax_redux_custom_font_timer', array( $this, 'timer' ) );
139
+
140
+            add_filter( "redux/{$this->parent->args['opt_name']}/field/typography/custom_fonts", array( $this, 'add_custom_fonts' ) );
141
+
142
+            // phpcs:disable
143
+            // $this->is_field = Redux_Helpers::is_field_in_use( $parent, 'custom_fonts' );
144
+
145
+            // if ( ! $this->is_field ) {
146
+            // 	$this->add_section();
147
+            // }
148
+
149
+            add_filter( "redux/options/{$this->parent->args['opt_name']}/section/redux_dynamic_font_control", array( $this, 'remove_dynamic_section' ) ); // phpcs:ignore WordPress.NamingConventions.ValidHookName
150
+            add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
151
+            add_action( 'wp_head', array( $this, 'enqueue_output' ), 150 );
152
+            add_filter( 'tiny_mce_before_init', array( $this, 'extend_tinymce_dropdown' ) );
153
+
154
+            $this->can_convert = true; // has_filter( 'redux/' . $this->parent->args['opt_name'] . '/extensions/custom_fonts/api_url' );
155
+            // phpcs:enable
156
+        }
157
+
158
+        /**
159
+         * Timer.
160
+         */
161
+        public function timer() {
162
+            $name = get_option( 'redux_custom_font_current' );
163
+
164
+            if ( ! empty( $name ) ) {
165
+                echo esc_html( $name );
166
+            }
167
+
168
+            die();
169
+        }
170
+
171
+        /**
172
+         * Remove the dynamically added section if the field was used elsewhere
173
+         *
174
+         * @param array $section Section array.
175
+         *
176
+         * @return array
177
+         * @since  Redux_Framework 3.1.1
178
+         */
179
+        public function remove_dynamic_section( array $section ): array {
180
+            if ( isset( $this->parent->field_types['custom_fonts'] ) ) {
181
+                $section = array();
182
+            }
183
+
184
+            return $section;
185
+        }
186
+
187
+        /**
188
+         * Adds FontMeister fonts to the TinyMCE drop-down.
189
+         * Typekit's fonts don't render properly in the drop-down and in the editor,
190
+         * because Typekit needs JS and TinyMCE doesn't support that.
191
+         *
192
+         * @param array $opt Option array.
193
+         *
194
+         * @return array
195
+         */
196
+        public function extend_tinymce_dropdown( array $opt ): array {
197
+            if ( ! is_admin() ) {
198
+                return $opt;
199
+            }
200
+
201
+            if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
202
+                $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';
203
+                $custom_fonts         = '';
204
+
205
+                $stylesheet = $this->upload_url . 'fonts.css';
206
+
207
+                if ( empty( $opt['content_css'] ) ) {
208
+                    $opt['content_css'] = $stylesheet;
209
+                } else {
210
+                    $opt['content_css'] = $opt['content_css'] . ',' . $stylesheet;
211
+                }
212
+
213
+                foreach ( $this->custom_fonts as $arr ) {
214
+                    foreach ( $arr as $font => $pieces ) {
215
+                        $custom_fonts .= ';' . $font . '=' . $font;
216
+                    }
217
+                }
218
+
219
+                $opt['font_formats'] = $theme_advanced_fonts . $custom_fonts;
220
+            }
221
+
222
+            return $opt;
223
+        }
224
+
225
+
226
+        /**
227
+         * Function to enqueue the custom fonts css
228
+         */
229
+        public function enqueue_output() {
230
+            if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
231
+                wp_enqueue_style(
232
+                    'redux-custom-fonts',
233
+                    $this->upload_url . 'fonts.css',
234
+                    array(),
235
+                    filemtime( $this->upload_dir . 'fonts.css' )
236
+                );
237
+            }
238
+        }
239
+
240
+        /**
241
+         * Adds the appropriate mime types to WordPress
242
+         *
243
+         * @param array $existing_mimes Mine array.
244
+         *
245
+         * @return array
246
+         */
247
+        public function custom_upload_mimes( array $existing_mimes = array() ): array {
248
+            $existing_mimes['ttf']   = 'font/ttf';
249
+            $existing_mimes['otf']   = 'font/otf';
250
+            $existing_mimes['eot']   = 'application/vnd.ms-fontobject';
251
+            $existing_mimes['woff']  = 'application/font-woff';
252
+            $existing_mimes['woff2'] = 'application/font-woff2';
253
+            $existing_mimes['svg']   = 'image/svg+xml';
254
+            $existing_mimes['zip']   = 'application/zip';
255
+
256
+            return $existing_mimes;
257
+        }
258
+
259
+        /**
260
+         * Gets all the fonts in the custom_fonts directory
261
+         */
262
+        public function get_fonts() {
263
+            if ( empty( $this->custom_fonts ) ) {
264
+                $params = array(
265
+                    'include_hidden' => false,
266
+                    'recursive'      => true,
267
+                );
268
+
269
+                $fonts = Redux_Core::$filesystem->execute( 'dirlist', $this->upload_dir, $params );
270
+
271
+                if ( ! empty( $fonts ) ) {
272
+                    foreach ( $fonts as $section ) {
273
+                        if ( 'd' === $section['type'] && ! empty( $section['name'] ) ) {
274
+                            if ( 'custom' === $section['name'] ) {
275
+                                $section['name'] = esc_html__( 'Custom Fonts', 'redux-framework' );
276
+                            }
277
+
278
+                            if ( empty( $section['files'] ) ) {
279
+                                continue;
280
+                            }
281
+
282
+                            $this->custom_fonts[ $section['name'] ] = $this->custom_fonts[ $section['name'] ] ?? array();
283
+
284
+                            foreach ( $section['files'] as $font ) {
285
+                                if ( ! empty( $font['name'] ) ) {
286
+                                    if ( empty( $font['files'] ) ) {
287
+                                        continue;
288
+                                    }
289
+
290
+                                    $kinds = array();
291
+
292
+                                    foreach ( $font['files'] as $f ) {
293
+                                        $valid = $this->check_font_name( $f );
294
+                                        if ( $valid ) {
295
+                                            $kinds[] = $valid;
296
+                                        }
297
+                                    }
298
+
299
+                                    $this->custom_fonts[ $section['name'] ][ $font['name'] ] = $kinds;
300
+                                }
301
+                            }
302
+                        }
303
+                    }
304
+                }
305
+            }
306
+        }
307
+
308
+        /**
309
+         * Add custom fonts.
310
+         *
311
+         * @param mixed $custom_fonts Custom fonts.
312
+         *
313
+         * @return array
314
+         */
315
+        public function add_custom_fonts( $custom_fonts ): array {
316
+            if ( empty( $custom_fonts ) ) {
317
+                $custom_fonts = array();
318
+            }
319
+
320
+            return wp_parse_args( $custom_fonts, $this->custom_fonts );
321
+        }
322
+
323
+        /**
324
+         * Ajax used within the panel to add and process the fonts
325
+         */
326
+        public function ajax() {
327
+            if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'redux_custom_fonts' ) ) {
328
+                die( 0 );
329
+            }
330
+
331
+            if ( isset( $_POST['type'] ) && 'delete' === $_POST['type'] ) {
332
+                if ( isset( $_POST['section'] ) ) {
333
+                    if ( esc_html__( 'Custom Fonts', 'redux-framework' ) === $_POST['section'] ) {
334
+                        $_POST['section'] = 'custom';
335
+                    }
336
+                }
337
+
338
+                try {
339
+                    if ( isset( $_POST['section'] ) || isset( $_POST['name'] ) ) {
340
+                        $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 ) );
341
+
342
+                        if ( true === $ret ) {
343
+                            $result = array( 'type' => 'success' );
344
+                        } else {
345
+                            $result = array(
346
+                                'type' => 'error',
347
+                                'msg'  => esc_html__( 'File system failure. Could not delete temp dir.', 'redux-framework' ),
348
+                            );
349
+                        }
350
+
351
+                        echo wp_json_encode( $result );
352
+                    }
353
+                } catch ( Exception $e ) {
354
+                    echo wp_json_encode(
355
+                        array(
356
+                            'type' => 'error',
357
+                            'msg'  => esc_html__( 'Unable to delete font file(s).', 'redux-framework' ),
358
+                        )
359
+                    );
360
+                }
361
+
362
+                die();
363
+            }
364
+
365
+            if ( ! isset( $_POST['title'] ) ) {
366
+                $_POST['title'] = '';
367
+            }
368
+
369
+            if ( ! isset( $_POST['filename'] ) ) {
370
+                $_POST['filename'] = '';
371
+            }
372
+
373
+            $this->font_folder   = sanitize_file_name( wp_unslash( $_POST['title'] ) );
374
+            $this->font_filename = sanitize_file_name( wp_unslash( $_POST['filename'] ) );
375
+
376
+            if ( ! empty( $_POST['attachment_id'] ) ) {
377
+                if ( isset( $_POST['title'] ) || isset( $_POST['mime'] ) ) {
378
+                    $msg = $this->process_web_font( sanitize_key( wp_unslash( $_POST['attachment_id'] ) ), sanitize_text_field( wp_unslash( $_POST['mime'] ) ) );
379
+
380
+                    if ( empty( $msg ) ) {
381
+                        $msg = '';
382
+                    }
383
+
384
+                    $result = array(
385
+                        'type' => 'success',
386
+                        'msg'  => $msg,
387
+                    );
388
+
389
+                    echo wp_json_encode( $result );
390
+                }
391
+            }
392
+
393
+            die();
394
+        }
395
+
396
+        /**
397
+         * Get only valid files. Ensure everything is proper for processing.
398
+         *
399
+         * @param string $path Path.
400
+         *
401
+         * @return array
402
+         */
403
+        public function get_valid_files( string $path ): array {
404
+            $output = array();
405
+            $path   = trailingslashit( $path );
406
+
407
+            $params = array(
408
+                'include_hidden' => false,
409
+                'recursive'      => true,
410
+            );
411
+
412
+            $files = Redux_Core::$filesystem->execute( 'dirlist', $path, $params );
413
+
414
+            foreach ( $files as $file ) {
415
+                if ( 'd' === $file['type'] ) {
416
+                    $output = array_merge( $output, $this->get_valid_files( $path . $file['name'] ) );
417
+                } elseif ( 'f' === $file['type'] ) {
418
+                    $valid = $this->check_font_name( $file );
419
+                    if ( $valid ) {
420
+                        $output[ $valid ] = trailingslashit( $path ) . $file['name'];
421
+                    }
422
+                }
423
+            }
424
+
425
+            return $output;
426
+        }
427
+
428
+        /**
429
+         * Take a valid web font and process the missing pieces.
430
+         *
431
+         * @param string $attachment_id ID.
432
+         * @param string $mime_type     Mine type.
433
+         */
434
+        public function process_web_font( string $attachment_id, string $mime_type ) {
435
+            // phpcs:ignore WordPress.Security.NonceVerification
436
+            if ( ! isset( $_POST['conversion'] ) ) {
437
+                $_POST['conversion'] = 'false';
438
+            }
439
+
440
+            // phpcs:ignore WordPress.Security.NonceVerification
441
+            $conversion = sanitize_text_field( wp_unslash( $_POST['conversion'] ) );
442
+
443
+            $missing = array();
444
+
445
+            $complete = array(
446
+                'ttf',
447
+                'woff',
448
+                'woff2',
449
+                'eot',
450
+                'svg',
451
+                'otf',
452
+            );
453
+
454
+            $subtype = explode( '/', $mime_type );
455
+            $subtype = trim( max( $subtype ) );
456
+
457
+            if ( ! is_dir( $this->upload_dir ) ) {
458
+                Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir );
459
+            }
460
+
461
+            if ( ! is_dir( $this->upload_dir . $this->subfolder ) ) {
462
+                Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder );
463
+            }
464
+
465
+            $temp                = $this->upload_dir . 'temp';
466
+            $this->selected_file = get_attached_file( $attachment_id );
467
+
468
+            if ( empty( $this->selected_file ) ) {
469
+                echo wp_json_encode(
470
+                    array(
471
+                        'type' => 'error',
472
+                        'msg'  => esc_html__( 'Attachment does not exist.', 'redux-framework' ),
473
+                    )
474
+                );
475
+
476
+                die();
477
+            }
478
+
479
+            $filename = explode( '/', $this->selected_file );
480
+
481
+            $filename = $filename[ ( count( $filename ) - 1 ) ];
482
+
483
+            $fontname = ucfirst(
484
+                str_replace(
485
+                    array(
486
+                        '.zip',
487
+                        '.ttf',
488
+                        '.woff',
489
+                        '.woff2',
490
+                        '.eot',
491
+                        '.svg',
492
+                        '.otf',
493
+                    ),
494
+                    '',
495
+                    strtolower( $filename )
496
+                )
497
+            );
498
+
499
+            if ( empty( $this->font_folder ) ) {
500
+                $this->font_folder = $fontname;
501
+            }
502
+
503
+            $ret = array();
504
+
505
+            if ( ! is_dir( $temp ) ) {
506
+                Redux_Core::$filesystem->execute( 'mkdir', $temp );
507
+            }
508
+
509
+            if ( 'zip' === $subtype ) {
510
+                $unzipfile = unzip_file( $this->selected_file, $temp );
511
+
512
+                if ( is_wp_error( $unzipfile ) ) {
513
+                    echo wp_json_encode(
514
+                        array(
515
+                            'type' => 'error',
516
+                            'msg'  => $unzipfile->get_error_message() . '<br><br>' . esc_html__( 'Unzipping failed.', 'redux-framework' ),
517
+                        )
518
+                    );
519
+
520
+                    die();
521
+                }
522
+
523
+                $output = $this->get_valid_files( $temp );
524
+
525
+                if ( ! empty( $output ) ) {
526
+                    foreach ( $complete as $test ) {
527
+                        if ( ! isset( $output[ $test ] ) ) {
528
+                            $missing[] = $test;
529
+                        }
530
+                    }
531
+
532
+                    if ( ! is_dir( $this->upload_dir . $this->subfolder . $this->font_folder . '/' ) ) {
533
+                        Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/' );
534
+                    }
535
+
536
+                    foreach ( $output as $key => $value ) {
537
+                        $param_array = array(
538
+                            'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . '/' . $fontname . '.' . $key,
539
+                            'overwrite'   => true,
540
+                            'chmod'       => 755,
541
+                        );
542
+
543
+                        Redux_Core::$filesystem->execute( 'copy', $value, $param_array );
544
+                    }
545
+
546
+                    if ( true === $this->can_convert && 'true' === $conversion ) {
547
+                        $ret = $this->get_missing_files( $fontname, $missing, $output );
548
+                    }
549
+                }
550
+
551
+                Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
552
+
553
+                $this->generate_css();
554
+
555
+                wp_delete_attachment( $attachment_id, true );
556
+            } 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 ) {
557
+                foreach ( $complete as $test ) {
558
+                    if ( $subtype !== $test ) {
559
+                        if ( ! isset( $output[ $test ] ) ) {
560
+                            $missing[] = $test;
561
+                        }
562
+                    }
563
+                }
564
+
565
+                if ( ! is_dir( $this->upload_dir . $this->subfolder . $this->font_folder . '/' ) ) {
566
+                    Redux_Core::$filesystem->execute( 'mkdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/' );
567
+                }
568
+
569
+                $output = array( $subtype => $this->selected_file );
570
+
571
+                if ( true === $this->can_convert && 'true' === $conversion ) {
572
+                    $ret = $this->get_missing_files( $fontname, $missing, $output );
573
+
574
+                    if ( false === $ret ) {
575
+                        if ( false === $this->convert_local_font() ) {
576
+                            echo wp_json_encode(
577
+                                array(
578
+                                    'type' => 'error',
579
+                                    'msg'  => esc_html__( 'File permission error. Local file could not be installed.', 'redux-framework' ) . ' ' . $subtype,
580
+                                )
581
+                            );
582
+
583
+                            die;
584
+                        }
585
+                    }
586
+                } elseif ( false === $this->convert_local_font() ) {
587
+                        echo wp_json_encode(
588
+                            array(
589
+                                'type' => 'error',
590
+                                'msg'  => esc_html__( 'File permission error. Local file could not be installed.', 'redux-framework' ) . ' ' . $subtype,
591
+                            )
592
+                        );
593
+
594
+                        die;
595
+                }
596
+
597
+                Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
598
+
599
+                $this->generate_css();
600
+
601
+                wp_delete_attachment( $attachment_id, true );
602
+            } else {
603
+                echo wp_json_encode(
604
+                    array(
605
+                        'type' => 'error',
606
+                        'msg'  => esc_html__( 'File type not recognized.', 'redux-framework' ) . ' ' . $subtype,
607
+                    )
608
+                );
609
+
610
+                die();
611
+            }
612
+
613
+            if ( is_array( $ret ) && ! empty( $ret ) ) {
614
+                $msg = esc_html__( 'Unidentified error.', 'redux-framework' );
615
+
616
+                if ( isset( $ret['msg'] ) ) {
617
+                    $msg = $ret['msg'];
618
+                }
619
+
620
+                return $msg;
621
+            }
622
+
623
+            return '';
624
+        }
625
+
626
+        /**
627
+         * Install selected file into Custom Fonts.
628
+         *
629
+         * @return bool
630
+         */
631
+        private function convert_local_font(): bool {
632
+            $param_array = array(
633
+                'destination' => $this->upload_dir . $this->subfolder . '/' . $this->font_folder . '/' . $this->font_filename,
634
+                'overwrite'   => true,
635
+                'chmod'       => 755,
636
+            );
637
+
638
+            return Redux_Core::$filesystem->execute( 'copy', $this->selected_file, $param_array );
639
+        }
640
+
641
+        /**
642
+         * Ping the WebFontOMatic API to get the missing files.
643
+         *
644
+         * @param string $fontname  Font name.
645
+         * @param array  $missing   Missing.
646
+         * @param array  $output    Output.
647
+         */
648
+        private function get_missing_files( string $fontname, array $missing, array $output ) {
649
+            if ( ! empty( $this->font_folder ) && ! empty( $missing ) ) {
650
+                $temp = $this->upload_dir . 'temp';
651
+
652
+                $font_ext = pathinfo( $this->font_filename, PATHINFO_EXTENSION );
653
+
654
+                $unsupported = array( 'eot', 'woff', 'woff2' );
655
+
656
+                // Find a file to convert from.
657
+                foreach ( $output as $key => $value ) {
658
+                    if ( 'eot' === $key ) {
659
+                        continue;
660
+                    } else {
661
+                        $main = $key;
662
+                        break;
663
+                    }
664
+                }
665
+
666
+                if ( ! isset( $main ) ) {
667
+                    echo wp_json_encode(
668
+                        array(
669
+                            'type' => 'error',
670
+                            'msg'  => esc_html__( 'No valid font file was found.', 'redux-framework' ),
671
+                        )
672
+                    );
673
+
674
+                    Redux_Core::$filesystem->execute( 'rmdir', $temp, array( 'recursive' => true ) );
675
+                    Redux_Core::$filesystem->execute( 'rmdir', $this->upload_dir . $this->subfolder . $this->font_folder . '/', array( 'recursive' => true ) );
676
+
677
+                    die();
678
+                }
679
+
680
+                update_option( 'redux_custom_font_current', $this->font_folder . '.zip' );
681
+
682
+                $boundary = wp_generate_password( 24 );
683
+
684
+                $headers = array(
685
+                    'content-type' => 'multipart/form-data; boundary=' . $boundary,
686
+                    'user-agent'   => 'redux-custom-fonts-' . self::$version . ' using ' . wp_get_theme(),
687
+                );
688
+
689
+                $payload  = '--' . $boundary;
690
+                $payload .= "\r\n";
691
+                $payload .= 'Content-Disposition: form-data; name="md5"' . "\r\n\r\n";
692
+                $payload .= md5( 'redux_custom_font' );
693
+                $payload .= "\r\n";
694
+
695
+                if ( $output[ $main ] ) {
696
+                    $payload .= '--' . $boundary;
697
+                    $payload .= "\r\n";
698
+                    $payload .= 'Content-Disposition: form-data; name="convert"; filename="' . basename( $output[ $main ] ) . '"' . "\r\n";
699
+                    $payload .= "\r\n";
700
+                    $payload .= Redux_Core::$filesystem->execute( 'get_contents', $output[ $main ] );
701
+                    $payload .= "\r\n";
702
+                }
703
+
704
+                $payload .= '--' . $boundary . '--';
705
+
706
+                $args = array(
707
+                    'headers'    => $headers,
708
+                    'body'       => $payload,
709
+                    'user-agent' => $headers['user-agent'],
710
+                    'timeout'    => 300,
711
+                    'sslverify'  => true,
712
+                );
713
+
714
+                // phpcs:disable WordPress.NamingConventions.ValidHookName
715
+                $api_url = apply_filters( 'redux/' . $this->parent->args['opt_name'] . '/extensions/custom_fonts/api_url', 'https://redux.io/fonts' );
716
+
717
+                $response = wp_remote_post( $api_url, $args );
718
+
719
+                if ( is_wp_error( $response ) ) {
720
+                    return array(
721
+                        'type' => 'error',
722
+                        'msg'  => $response->get_error_message() . '<br><br>' . esc_html__( 'Your font could not be converted at this time. Please try again later.', 'redux-framework' ),
723
+                    );
724
+                } elseif ( isset( $response['body'] ) ) {
725
+                    if ( null !== json_decode( $response['body'] ) ) {
726
+                        return json_decode( $response['body'], true );
727
+                    }
728
+                }
729
+
730
+                $param_array = array(
731
+                    'content'   => $response['body'],
732
+                    'overwrite' => true,
733
+                    'chmod'     => FS_CHMOD_FILE,
734
+                );
735
+
736
+                $zip_file = $temp . DIRECTORY_SEPARATOR . $fontname . '.zip';
737
+
738
+                Redux_Core::$filesystem->execute( 'put_contents', $zip_file, $param_array );
739
+
740
+                if ( 0 === filesize( $zip_file ) ) {
741
+                    return false;
742
+                }
743
+
744
+                $zip = unzip_file( $zip_file, $temp );
745
+
746
+                if ( ! is_wp_error( $zip ) ) {
747
+                    $params = array(
748
+                        'include_hidden' => false,
749
+                        'recursive'      => false,
750
+                    );
751
+
752
+                    $files = Redux_Core::$filesystem->execute( 'dirlist', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR, $params );
753
+
754
+                    foreach ( $files as $file ) {
755
+                        $param_array = array(
756
+                            'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $file['name'] ),
757
+                            'overwrite'   => true,
758
+                            'chmod'       => 755,
759
+                        );
760
+
761
+                        Redux_Core::$filesystem->execute( 'move', $temp . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR . ( $file['name'] ), $param_array );
762
+                    }
763
+                } else {
764
+                    $path_parts = pathinfo( $output[ $main ] );
765
+
766
+                    $param_array = array(
767
+                        'destination' => $this->upload_dir . $this->subfolder . $this->font_folder . DIRECTORY_SEPARATOR . sanitize_file_name( $path_parts['basename'] ),
768
+                        'overwrite'   => true,
769
+                        'chmod'       => 755,
770
+                    );
771
+
772
+                    Redux_Core::$filesystem->execute( 'move', $output[ $main ], $param_array );
773
+
774
+                    if ( in_array( $font_ext, $unsupported, true ) ) {
775
+                        return array(
776
+                            'type' => 'error',
777
+                            // translators: %s = font extension.
778
+                            'msg'  => $zip->get_error_message() . '<br><br>' . sprintf( esc_html__( 'The font converter does not support %s fonts.', 'redux-framework' ), $font_ext ),
779
+                        );
780
+                    } else {
781
+                        return array(
782
+                            'type' => 'error',
783
+                            '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' ),
784
+                        );
785
+                    }
786
+                }
787
+
788
+                delete_option( 'redux_custom_font_current' );
789
+            }
790
+
791
+            return true;
792
+        }
793
+
794
+        /**
795
+         * Check if the file name is a valid font file.
796
+         *
797
+         * @param array $file File.
798
+         *
799
+         * @return bool|string
800
+         */
801
+        private function check_font_name( array $file ) {
802
+            if ( '.woff' === strtolower( substr( $file['name'], - 5 ) ) ) {
803
+                return 'woff';
804
+            }
805
+
806
+            if ( '.woff2' === strtolower( substr( $file['name'], - 6 ) ) ) {
807
+                return 'woff2';
808
+            }
809
+
810
+            $sub = strtolower( substr( $file['name'], - 4 ) );
811
+
812
+            if ( '.ttf' === $sub ) {
813
+                return 'ttf';
814
+            }
815
+
816
+            if ( '.eot' === $sub ) {
817
+                return 'eot';
818
+            }
819
+
820
+            if ( '.svg' === $sub ) {
821
+                return 'svg';
822
+            }
823
+
824
+            if ( '.otf' === $sub ) {
825
+                return 'otf';
826
+            }
827
+
828
+            return false;
829
+        }
830
+
831
+        /**
832
+         * Generate a new custom CSS file for enqueuing on the frontend and backend.
833
+         */
834
+        private function generate_css() {
835
+            $params = array(
836
+                'include_hidden' => false,
837
+                'recursive'      => true,
838
+            );
839
+
840
+            $fonts = Redux_Core::$filesystem->execute( 'dirlist', $this->upload_dir . 'custom' . DIRECTORY_SEPARATOR, $params );
841
+
842
+            if ( empty( $fonts ) || ! is_array( $fonts ) ) {
843
+                return;
844
+            }
845
+
846
+            foreach ( $fonts as $font ) {
847
+                if ( 'd' === $font['type'] ) {
848
+                    break;
849
+                }
850
+
851
+                if ( file_exists( $this->upload_dir . 'fonts.css' ) ) {
852
+                    Redux_Core::$filesystem->execute( 'delete', $this->upload_dir . 'fonts.css' );
853
+                }
854
+
855
+                return;
856
+            }
857
+
858
+            $css = '';
859
+
860
+            foreach ( $fonts as $font ) {
861
+                if ( 'd' === $font['type'] ) {
862
+                    $css .= $this->generate_font_css( $font['name'], $this->upload_dir . 'custom' . DIRECTORY_SEPARATOR );
863
+                }
864
+            }
865
+
866
+            if ( '' !== $css ) {
867
+                $param_array = array(
868
+                    'content' => $css,
869
+                    'chmod'   => FS_CHMOD_FILE,
870
+                );
871
+
872
+                Redux_Core::$filesystem->execute( 'put_contents', $this->upload_dir . 'fonts.css', $param_array );
873
+            }
874
+        }
875
+
876
+        /**
877
+         * Process to actually construct the custom font css file.
878
+         *
879
+         * @param string $name Name.
880
+         * @param string $dir  Directory.
881
+         *
882
+         * @return string
883
+         */
884
+        private function generate_font_css( string $name, string $dir ): ?string {
885
+            $path = $dir . $name;
886
+
887
+            $params = array(
888
+                'include_hidden' => false,
889
+                'recursive'      => true,
890
+            );
891
+
892
+            $files = Redux_Core::$filesystem->execute( 'dirlist', $path, $params );
893
+
894
+            if ( empty( $files ) ) {
895
+                return null;
896
+            }
897
+
898
+            $output = array();
899
+
900
+            foreach ( $files as $file ) {
901
+                $output[ $this->check_font_name( $file ) ] = $file['name'];
902
+            }
903
+
904
+            $css = '@font-face {';
905
+
906
+            $css .= 'font-family:"' . $name . '";';
907
+
908
+            $src = array();
909
+
910
+            if ( isset( $output['eot'] ) ) {
911
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['eot']}?#iefix') format('embedded-opentype')";
912
+            }
913
+
914
+            if ( isset( $output['woff'] ) ) {
915
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['woff']}') format('woff')";
916
+            }
917
+
918
+            if ( isset( $output['woff2'] ) ) {
919
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['woff2']}') format('woff2')";
920
+            }
921
+
922
+            if ( isset( $output['ttf'] ) ) {
923
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['ttf']}') format('truetype')";
924
+            }
925
+
926
+            if ( isset( $output['svg'] ) ) {
927
+                $src[] = "url('{$this->upload_url}custom/$name/{$output['svg']}#svg$name') format('svg')";
928
+            }
929
+
930
+            if ( ! empty( $src ) ) {
931
+                $css .= 'src:' . implode( ', ', $src ) . ';';
932
+            }
933
+
934
+            // Replace font weight and style with sub-sets.
935
+            $css .= 'font-weight: normal;';
936
+
937
+            $css .= 'font-style: normal;';
938
+
939
+            $css .= '}';
940
+
941
+            return $css;
942
+        }
943
+
944
+        /**
945
+         * Custom function for filtering the section array.
946
+         * Good for child themes to override or add to the sections.
947
+         * Simply include this function in the child themes functions.php file.
948
+         * NOTE: the defined constants for URLs and directories will NOT be available at this point in a child theme,
949
+         * so you must use get_template_directory_uri() if you want to use any of the built-in icons
950
+         */
951
+        public function add_section() {
952
+            if ( ! isset( $this->parent->fontControl ) ) {
953
+                $this->parent->sections[] = array(
954
+                    'title'  => esc_html__( 'Font Control', 'redux-framework' ),
955
+                    'desc'   => '<p class="description"></p>',
956
+                    'icon'   => 'el-icon-font',
957
+                    'id'     => 'redux_dynamic_font_control',
958
+                    // Leave this as a blank section, no options just some intro text set above.
959
+                    'fields' => array(),
960
+                );
961
+
962
+                for ( $i = count( $this->parent->sections ); $i >= 1; $i-- ) {
963
+                    if ( isset( $this->parent->sections[ $i ] ) && isset( $this->parent->sections[ $i ]['title'] ) && esc_html__( 'Font Control', 'redux-framework' ) === $this->parent->sections[ $i ]['title'] ) {
964
+                        $this->parent->fontControl                                        = $i;
965
+                        $this->parent->sections[ $this->parent->fontControl ]['fields'][] = array(
966
+                            'id'   => 'redux_font_control',
967
+                            'type' => 'custom_fonts',
968
+                        );
969
+
970
+                        break;
971
+                    }
972
+                }
973
+            }
974
+        }
975
+    }
976
+
977
+    class_alias( Redux_Extension_Custom_Fonts::class, 'ReduxFramework_Extension_custom_fonts' );
978 978
 }
Please login to merge, or discard this patch.
redux-core/inc/classes/class-redux-api.php 2 patches
Indentation   +1754 added lines, -1754 removed lines patch added patch discarded remove patch
@@ -16,1758 +16,1758 @@
 block discarded – undo
16 16
 // Don't duplicate me!
17 17
 if ( ! class_exists( 'Redux', false ) ) {
18 18
 
19
-	/**
20
-	 * Redux API Class
21
-	 * Simple API for Redux Framework
22
-	 *
23
-	 * @since       3.0.0
24
-	 */
25
-	class Redux {
26
-
27
-
28
-		/**
29
-		 *  Option fields.
30
-		 *
31
-		 * @var array
32
-		 */
33
-		public static array $fields = array();
34
-
35
-		/**
36
-		 * Option sections.
37
-		 *
38
-		 * @var array
39
-		 */
40
-		public static array $sections = array();
41
-
42
-		/**
43
-		 * Option defaults.
44
-		 *
45
-		 * @var array
46
-		 */
47
-		public static array $options_defaults = array();
48
-
49
-		/**
50
-		 * Option help array.
51
-		 *
52
-		 * @var array
53
-		 */
54
-		public static array $help = array();
55
-
56
-		/**
57
-		 * Option global args.
58
-		 *
59
-		 * @var array
60
-		 */
61
-		public static array $args = array();
62
-
63
-		/**
64
-		 * Option section priorities.
65
-		 *
66
-		 * @var array
67
-		 */
68
-		public static array $priority = array();
69
-
70
-		/**
71
-		 * Panel validations errors.
72
-		 *
73
-		 * @var array
74
-		 */
75
-		public static array $errors = array();
76
-
77
-		/**
78
-		 * Init.
79
-		 *
80
-		 * @var array
81
-		 */
82
-		public static array $init = array();
83
-
84
-		/**
85
-		 * Delay Init opt_names
86
-		 *
87
-		 * @var array
88
-		 */
89
-		public static array $delay_init = array();
90
-
91
-		/**
92
-		 * Extension list.
93
-		 *
94
-		 * @var array
95
-		 */
96
-		public static array $extensions = array();
97
-
98
-		/**
99
-		 * Extensions in use.
100
-		 *
101
-		 * @var array
102
-		 */
103
-		public static array $uses_extensions = array();
104
-
105
-		/**
106
-		 * Extension paths.
107
-		 *
108
-		 * @var array
109
-		 */
110
-		public static array $extension_paths = array();
111
-
112
-		/**
113
-		 * Extension capability flag.
114
-		 *
115
-		 * @var boolean
116
-		 */
117
-		public static bool $extension_compatibility = false;
118
-
119
-		/**
120
-		 * Code to run at creation in instance.
121
-		 */
122
-		public static function load() {
123
-			add_action( 'after_setup_theme', array( 'Redux', 'create_redux' ) );
124
-			add_action( 'init', array( 'Redux', 'create_redux' ) );
125
-			add_action( 'switch_theme', array( 'Redux', 'create_redux' ) );
126
-
127
-			require_once Redux_Core::$dir . 'inc/extensions/metaboxes/class-redux-metaboxes-api.php';
128
-			require_once Redux_Core::$dir . 'inc/extensions/users/class-redux-users-api.php';
129
-			require_once Redux_Core::$dir . 'inc/extensions/taxonomy/class-redux-taxonomy-api.php';
130
-		}
131
-
132
-		/**
133
-		 * Delay init action function
134
-		 * Delays all Redux objects from loaded before `plugins_loaded` runs.
135
-		 *
136
-		 * @throws ReflectionException Exception.
137
-		 */
138
-		public static function delay_init() {
139
-			if ( ! empty( self::$delay_init ) ) {
140
-
141
-				foreach ( self::$delay_init as $opt_name ) {
142
-					self::init( $opt_name );
143
-					$parent = Redux_Instances::get_instance( $opt_name );
144
-					// translators: This is only shown to developers, should not impact users.
145
-					$msg = sprintf(
146
-						'<strong>%s</strong><br /><code>%s</code> %s',
147
-						esc_html__( 'Warning, Premature Initialization', 'redux-framework' ),
148
-						'self::init("' . esc_html( $opt_name ) . '")',
149
-						// translators: This is only shown to developers, should not impact users.
150
-						sprintf( esc_html__( 'was run before the %s hook and was delayed to avoid errors.', 'redux-framework' ), '<code>plugins_loaded</code>' )
151
-					);
152
-
153
-					if ( isset( $parent->args ) ) {
154
-						$data = array(
155
-							'parent'  => $parent,
156
-							'type'    => 'error',
157
-							'msg'     => $msg,
158
-							'id'      => 'redux_init',
159
-							'dismiss' => true,
160
-						);
161
-
162
-						Redux_Admin_Notices::set_notice( $data );
163
-					}
164
-				}
165
-			}
166
-		}
167
-
168
-		/**
169
-		 * Init Redux object
170
-		 *
171
-		 * @param string $opt_name Panel opt_name.
172
-		 *
173
-		 * @throws ReflectionException  Exception.
174
-		 */
175
-		public static function init( string $opt_name = '' ) {
176
-			if ( ! empty( $opt_name ) ) {
177
-				if ( ! did_action( 'plugins_loaded' ) ) {
178
-
179
-					// We don't want to load before plugins_loaded EVER.
180
-					self::$delay_init[] = $opt_name;
181
-					add_action( 'plugins_loaded', array( 'Redux', 'delay_init' ) );
182
-				} else {
183
-
184
-					// The hook `plugins_loaded` has run, let's get going!
185
-					self::load_redux( $opt_name );
186
-
187
-					remove_action( 'setup_theme', array( 'Redux', 'create_redux' ) );
188
-				}
189
-			}
190
-		}
191
-
192
-		/**
193
-		 * Retrieve ReduxFramework object.
194
-		 *
195
-		 * @param string $opt_name Panel opt_name.
196
-		 *
197
-		 * @return object|ReduxFramework
198
-		 */
199
-		public static function instance( string $opt_name ) {
200
-			return Redux_Instances::get_instance( $opt_name );
201
-		}
202
-
203
-		/**
204
-		 * Retrieve all ReduxFramework Instances.
205
-		 *
206
-		 * @return null|array|ReduxFramework[]
207
-		 */
208
-		public static function all_instances(): ?array {
209
-			return Redux_Instances::get_all_instances();
210
-		}
211
-
212
-		/**
213
-		 * Load external extensions.
214
-		 *
215
-		 * @param object $redux_framework ReduxFramework object.
216
-		 *
217
-		 * @deprecated No longer using camelCase naming conventions.
218
-		 */
219
-		public static function loadExtensions( $redux_framework ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
220
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, ' Redux 4.3', 'Redux::load_extensions( $redux_framework )' );
221
-
222
-			self::load_extensions( $redux_framework );
223
-		}
224
-
225
-		/**
226
-		 * Load external extensions.
227
-		 *
228
-		 * @param object $redux_framework ReduxFramework object.
229
-		 */
230
-		public static function load_extensions( $redux_framework ) {
231
-			$instance_extensions = self::get_extensions( $redux_framework->args['opt_name'] );
232
-
233
-			if ( $instance_extensions ) {
234
-				foreach ( $instance_extensions as $name => $extension ) {
235
-					$old_class = str_replace( 'Redux_', 'ReduxFramework_', $extension['class'] );
236
-
237
-					if ( ! class_exists( $extension['class'] ) && ! class_exists( $old_class ) ) {
238
-						// In case you wanted to override your override, hah.
239
-						// Phpcs:ignore WordPress.NamingConventions.ValidHookName
240
-						$extension['path'] = apply_filters( 'redux/extension/' . $redux_framework->args['opt_name'] . '/' . $name, $extension['path'] );
241
-						if ( file_exists( $extension['path'] ) ) {
242
-							require_once $extension['path'];
243
-						}
244
-					}
245
-					if ( isset( $extension['field'] ) ) {
246
-						require_once $extension['field'];
247
-					}
248
-
249
-					if ( ! isset( $redux_framework->extensions[ $name ] ) ) {
250
-						$field_classes = array( $extension['class'], $old_class );
251
-						$ext_class     = Redux_Functions::class_exists_ex( $field_classes );
252
-						if ( false !== $ext_class ) {
253
-							$redux_framework->extensions[ $name ] = new $ext_class( $redux_framework );
254
-						} elseif ( is_admin() && true === $redux_framework->args['dev_mode'] ) {
255
-							echo '<div id="message" class="error"><p>No class named <strong>' . esc_html( $extension['class'] ) . '</strong> exists. Please verify your extension path.</p></div>';
256
-						}
257
-					}
258
-				}
259
-			}
260
-		}
261
-
262
-		/**
263
-		 * Deprecated function to set an extension path.
264
-		 *
265
-		 * @param string $extension Path.
266
-		 * @param bool   $folder    Set if a path is a folder.
267
-		 *
268
-		 * @return bool|mixed
269
-		 * @deprecated No longer using cameCase naming conventions.
270
-		 */
271
-		public static function extensionPath( string $extension, bool $folder = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
272
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::extension_path( $extension, $folder )' );
273
-
274
-			return self::extension_path( $extension, $folder );
275
-		}
276
-
277
-		/**
278
-		 * Sets a path to an extension.
279
-		 *
280
-		 * @param string $extension Path to an extension.
281
-		 * @param bool   $folder    Set if a path is a folder.
282
-		 *
283
-		 * @return bool|mixed
284
-		 */
285
-		public static function extension_path( string $extension, bool $folder = true ) {
286
-			if ( ! isset( self::$extensions[ $extension ] ) ) {
287
-				return false;
288
-			}
289
-
290
-			$path = end( self::$extensions[ $extension ] );
291
-
292
-			if ( ! $folder ) {
293
-				return $path;
294
-			}
295
-
296
-			return dirname( $path );
297
-		}
298
-
299
-		/**
300
-		 * Deprecated function of Load Redux Framework.
301
-		 *
302
-		 * @param string $opt_name Panel opt_name.
303
-		 *
304
-		 * @throws ReflectionException Exception.
305
-		 *
306
-		 * @deprecated No longer using camelCase naming conventions.
307
-		 */
308
-		public static function loadRedux( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
309
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::load_redux( $opt_name )' );
310
-
311
-			self::load_redux( $opt_name );
312
-		}
313
-
314
-		/**
315
-		 * Load defaults values for a given opt_name.
316
-		 *
317
-		 * @param string $opt_name Panel opt_name.
318
-		 */
319
-		public static function set_defaults( string $opt_name = '' ) {
320
-			// Try to load the class if in the same directory, so the user only has to include the Redux API.
321
-			if ( ! class_exists( 'Redux_Options_Defaults' ) ) {
322
-				$file_check = trailingslashit( __DIR__ ) . 'class-redux-options-defaults.php';
323
-
324
-				if ( file_exists( dirname( $file_check ) ) ) {
325
-					include_once $file_check;
326
-					$file_check = trailingslashit( __DIR__ ) . 'class-redux-wordpress-data.php';
327
-					if ( file_exists( dirname( $file_check ) ) ) {
328
-						include_once $file_check;
329
-					}
330
-				}
331
-			}
332
-
333
-			if ( class_exists( 'Redux_Options_Defaults' ) && ! isset( self::$options_defaults[ $opt_name ] ) ) {
334
-				$sections                            = self::construct_sections( $opt_name );
335
-				$wordpress_data                      = ( ! class_exists( 'Redux_WordPress_Data' ) ) ? null : new Redux_WordPress_Data( $opt_name );
336
-				$options_defaults_class              = new Redux_Options_Defaults();
337
-				self::$options_defaults[ $opt_name ] = $options_defaults_class->default_values( $opt_name, $sections, $wordpress_data );
338
-				if ( ! isset( self::$args[ $opt_name ]['global_variable'] ) || ( '' === self::$args[ $opt_name ]['global_variable'] && false !== self::$args[ $opt_name ]['global_variable'] ) ) {
339
-					self::$args[ $opt_name ]['global_variable'] = str_replace( '-', '_', $opt_name );
340
-				}
341
-				if ( isset( self::$args[ $opt_name ]['global_variable'] ) && self::$args[ $opt_name ]['global_variable'] ) {
342
-					$option_global = self::$args[ $opt_name ]['global_variable'];
343
-
344
-					/**
345
-					 * Filter 'redux/options/{opt_name}/global_variable'
346
-					 *
347
-					 * @param array $value option value to set global_variable with
348
-					 */
349
-					global $$option_global;
350
-
351
-					// phpcs:ignore WordPress.NamingConventions.ValidHookName
352
-					$$option_global = apply_filters( 'redux/options/' . $opt_name . '/global_variable', self::$options_defaults[ $opt_name ] );
353
-				}
354
-			}
355
-		}
356
-
357
-		/**
358
-		 * Load Redux Framework.
359
-		 *
360
-		 * @param string $opt_name Panel opt_name.
361
-		 *
362
-		 * @throws ReflectionException  Exception.
363
-		 */
364
-		public static function load_redux( string $opt_name = '' ) {
365
-			if ( empty( $opt_name ) ) {
366
-				return;
367
-			}
368
-
369
-			if ( class_exists( 'ReduxFramework' ) ) {
370
-				if ( isset( self::$init[ $opt_name ] ) && ! empty( self::$init[ $opt_name ] ) ) {
371
-					return;
372
-				}
373
-			} else {
374
-				echo '<div id="message" class="error"><p>' . esc_html__( 'Redux Framework is not installed. Please install it.', 'redux-framework' ) . '</p></div>';
375
-
376
-				return;
377
-			}
378
-
379
-			self::instance( $opt_name );
380
-
381
-			Redux_Functions_Ex::record_caller( $opt_name );
382
-
383
-			if ( isset( self::$init[ $opt_name ] ) && 1 === self::$init[ $opt_name ] ) {
384
-				return;
385
-			}
386
-
387
-			// self::set_defaults( $opt_name );
388
-
389
-			$args     = self::construct_args( $opt_name );
390
-			$sections = self::construct_sections( $opt_name );
391
-
392
-			if ( isset( self::$uses_extensions[ $opt_name ] ) && ! empty( self::$uses_extensions[ $opt_name ] ) ) {
393
-				add_action( "redux/extensions/$opt_name/before", array( 'Redux', 'load_extensions' ), 0 );
394
-			}
395
-
396
-			$redux                   = new ReduxFramework( $sections, $args );
397
-			self::$init[ $opt_name ] = 1;
398
-
399
-			if ( isset( $redux->args['opt_name'] ) && $redux->args['opt_name'] !== $opt_name ) {
400
-				self::$init[ $redux->args['opt_name'] ] = 1;
401
-			}
402
-		}
403
-
404
-		/**
405
-		 * Deprecated Create Redux instance.
406
-		 *
407
-		 * @throws ReflectionException  Exception.
408
-		 *
409
-		 * @deprecated No longer using camelCase naming convention.
410
-		 */
411
-		public static function createRedux() {       // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
412
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::createRedux()' );
413
-
414
-			self::create_redux();
415
-		}
416
-
417
-		/**
418
-		 * Create Redux instance.
419
-		 *
420
-		 * @throws ReflectionException  Exception.
421
-		 */
422
-		public static function create_redux() {
423
-			foreach ( self::$sections as $opt_name => $the_sections ) {
424
-				if ( ! empty( $the_sections ) ) {
425
-					if ( ! self::$init[ $opt_name ] ) {
426
-						self::load_redux( $opt_name );
427
-					}
428
-				}
429
-			}
430
-		}
431
-
432
-		/**
433
-		 * Construct global arguments.
434
-		 *
435
-		 * @param string $opt_name Panel opt_name.
436
-		 *
437
-		 * @return array|mixed
438
-		 */
439
-		public static function construct_args( string $opt_name ) {
440
-			$args             = self::$args[ $opt_name ] ?? array();
441
-			$args['opt_name'] = $opt_name;
442
-
443
-			if ( ! isset( $args['menu_title'] ) ) {
444
-				$args['menu_title'] = ucfirst( $opt_name ) . ' Options';
445
-			}
446
-
447
-			if ( ! isset( $args['page_title'] ) ) {
448
-				$args['page_title'] = ucfirst( $opt_name ) . ' Options';
449
-			}
450
-
451
-			if ( ! isset( $args['page_slug'] ) ) {
452
-				$args['page_slug'] = $opt_name . '_options';
453
-			}
454
-
455
-			return $args;
456
-		}
457
-
458
-		/**
459
-		 * Construct option panel sections.
460
-		 *
461
-		 * @param string $opt_name Panel opt_name.
462
-		 *
463
-		 * @return array
464
-		 */
465
-		public static function construct_sections( string $opt_name ): array {
466
-			$sections = array();
467
-
468
-			if ( ! isset( self::$sections[ $opt_name ] ) ) {
469
-				return $sections;
470
-			}
471
-
472
-			foreach ( self::$sections[ $opt_name ] as $section_id => $section ) {
473
-				$section['fields'] = self::construct_fields( $opt_name, $section_id );
474
-				$p                 = $section['priority'];
475
-
476
-				while ( isset( $sections[ $p ] ) ) {
477
-					++$p;
478
-				}
479
-
480
-				$sections[ $p ] = $section;
481
-			}
482
-
483
-			ksort( $sections );
484
-
485
-			return $sections;
486
-		}
487
-
488
-		/**
489
-		 * Construct option panel fields.
490
-		 *
491
-		 * @param string $opt_name   Panel opt_name.
492
-		 * @param string $section_id ID of a section.
493
-		 *
494
-		 * @return array
495
-		 */
496
-		public static function construct_fields( string $opt_name = '', string $section_id = '' ): array {
497
-			$fields = array();
498
-
499
-			if ( ! empty( self::$fields[ $opt_name ] ) ) {
500
-				foreach ( self::$fields[ $opt_name ] as $field ) {
501
-					if ( $field['section_id'] === $section_id ) {
502
-						$p = esc_html( $field['priority'] );
503
-
504
-						while ( isset( $fields[ $p ] ) ) {
505
-							echo intval( $p++ );
506
-						}
507
-
508
-						$fields[ $p ] = $field;
509
-					}
510
-				}
511
-			}
512
-
513
-			ksort( $fields );
514
-
515
-			return $fields;
516
-		}
517
-
518
-		/**
519
-		 * Deprecated Retrieve panel section.
520
-		 *
521
-		 * @param string $opt_name Panel opt_name.
522
-		 * @param string $id       Section ID.
523
-		 *
524
-		 * @return bool
525
-		 * @deprecated No longer using camelCase naming convention.
526
-		 */
527
-		public static function getSection( string $opt_name = '', string $id = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
528
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_section( $opt_name, $id )' );
529
-
530
-			return self::get_section( $opt_name, $id );
531
-		}
532
-
533
-		/**
534
-		 * Retrieve panel section.
535
-		 *
536
-		 * @param string     $opt_name Panel opt_name.
537
-		 * @param string|int $id       Section ID.
538
-		 *
539
-		 * @return bool|string|int
540
-		 */
541
-		public static function get_section( string $opt_name = '', $id = '' ) {
542
-			self::check_opt_name( $opt_name );
543
-
544
-			if ( ! empty( $opt_name ) && ! empty( $id ) ) {
545
-				if ( ! isset( self::$sections[ $opt_name ][ $id ] ) ) {
546
-					$id = Redux_Core::strtolower( sanitize_html_class( $id ) );
547
-				}
548
-
549
-				return self::$sections[ $opt_name ][ $id ] ?? false;
550
-			}
551
-
552
-			return false;
553
-		}
554
-
555
-		/**
556
-		 * Deprecated Create a section of the option panel.
557
-		 *
558
-		 * @param string $opt_name Panel opt_name.
559
-		 * @param array  $sections Section ID.
560
-		 *
561
-		 * @deprecated No longer using camelCase naming convention.
562
-		 */
563
-		public static function setSections( string $opt_name = '', array $sections = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
564
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_sections( $opt_name, $sections )' );
565
-
566
-			if ( '' !== $opt_name ) {
567
-				Redux_Functions_Ex::record_caller( $opt_name );
568
-			}
569
-
570
-			self::set_sections( $opt_name, $sections );
571
-		}
572
-
573
-		/**
574
-		 * Create multiple sections of the option panel.
575
-		 *
576
-		 * @param string $opt_name Panel opt_name.
577
-		 * @param array  $sections Section ID.
578
-		 */
579
-		public static function set_sections( string $opt_name = '', array $sections = array() ) {
580
-			if ( empty( $sections ) || '' === $opt_name ) {
581
-				return;
582
-			}
583
-
584
-			self::check_opt_name( $opt_name );
585
-
586
-			Redux_Functions_Ex::record_caller( $opt_name );
587
-
588
-			foreach ( $sections as $section ) {
589
-				self::set_section( $opt_name, $section );
590
-			}
591
-		}
592
-
593
-		/**
594
-		 * Deprecated Retrieve all sections from the option panel.
595
-		 *
596
-		 * @param string $opt_name Panel opt_name.
597
-		 *
598
-		 * @return array|mixed
599
-		 * @deprecated No longer using camelCase naming convention.
600
-		 */
601
-		public static function getSections( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
602
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_sections( $opt_name )' );
603
-
604
-			return self::get_sections( $opt_name );
605
-		}
606
-
607
-		/**
608
-		 * Retrieve all sections from the option panel.
609
-		 *
610
-		 * @param string $opt_name Panel opt_name.
611
-		 *
612
-		 * @return array|mixed
613
-		 */
614
-		public static function get_sections( string $opt_name = '' ) {
615
-			self::check_opt_name( $opt_name );
616
-
617
-			if ( ! empty( self::$sections[ $opt_name ] ) ) {
618
-				return self::$sections[ $opt_name ];
619
-			}
620
-
621
-			return array();
622
-		}
623
-
624
-		/**
625
-		 * Deprecated Remove option panel by ID.
626
-		 *
627
-		 * @param string     $opt_name Panel opt_name.
628
-		 * @param string|int $id       Section ID.
629
-		 * @param bool       $fields   Remove fields.
630
-		 *
631
-		 * @deprecated No longer using camelCase naming convention.
632
-		 */
633
-		public static function removeSection( string $opt_name = '', $id = '', bool $fields = false ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
634
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::remove_section( $opt_name, $id )' );
635
-
636
-			if ( '' !== $opt_name ) {
637
-				Redux_Functions_Ex::record_caller( $opt_name );
638
-			}
639
-
640
-			self::remove_section( $opt_name, $id, $fields );
641
-		}
642
-
643
-		/**
644
-		 * Remove an option panel by ID.
645
-		 *
646
-		 * @param string     $opt_name Panel opt_name.
647
-		 * @param string|int $id       Section ID.
648
-		 * @param bool       $fields   Remove fields.
649
-		 */
650
-		public static function remove_section( string $opt_name = '', $id = '', bool $fields = false ) {
651
-			if ( '' !== $opt_name && '' !== $id ) {
652
-				Redux_Functions_Ex::record_caller( $opt_name );
653
-
654
-				if ( isset( self::$sections[ $opt_name ][ $id ] ) ) {
655
-					$priority = '';
656
-
657
-					foreach ( self::$sections[ $opt_name ] as $key => $section ) {
658
-						if ( $key === $id ) {
659
-							$priority = $section['priority'];
660
-							--self::$priority[ $opt_name ]['sections'];
661
-							unset( self::$sections[ $opt_name ][ $id ] );
662
-							continue;
663
-						}
664
-						if ( '' !== $priority ) {
665
-							$new_priority                        = $section['priority'];
666
-							$section['priority']                 = $priority;
667
-							self::$sections[ $opt_name ][ $key ] = $section;
668
-							$priority                            = $new_priority;
669
-						}
670
-					}
671
-
672
-					if ( isset( self::$fields[ $opt_name ] ) && ! empty( self::$fields[ $opt_name ] ) && true === $fields ) {
673
-						foreach ( self::$fields[ $opt_name ] as $key => $field ) {
674
-							if ( $field['section_id'] === $id ) {
675
-								unset( self::$fields[ $opt_name ][ $key ] );
676
-							}
677
-						}
678
-					}
679
-				}
680
-			}
681
-		}
682
-
683
-		/**
684
-		 * Deprecated Sets a single option panel section.
685
-		 *
686
-		 * @param string     $opt_name Panel opt_name.
687
-		 * @param array|null $section  Section data.
688
-		 *
689
-		 * @deprecated No longer using camelCase naming convention.
690
-		 */
691
-		public static function setSection( string $opt_name = '', ?array $section = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
692
-			// phpcs:ignore Squiz.PHP.CommentedOutCode.Found
693
-			// _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_section( $opt_name, $section )' );
694
-
695
-			if ( '' !== $opt_name ) {
696
-				Redux_Functions_Ex::record_caller( $opt_name );
697
-			}
698
-
699
-			self::set_section( $opt_name, $section );
700
-		}
701
-
702
-		/**
703
-		 * Sets a single option panel section.
704
-		 *
705
-		 * @param string     $opt_name Panel opt_name.
706
-		 * @param array|null $section  Section data.
707
-		 * @param bool       $replace  Replaces a section instead of creating a new one.
708
-		 */
709
-		public static function set_section( string $opt_name = '', ?array $section = array(), bool $replace = false ) {
710
-
711
-			if ( empty( $section ) || '' === $opt_name ) {
712
-				return;
713
-			}
714
-
715
-			self::check_opt_name( $opt_name );
716
-
717
-			Redux_Functions_Ex::record_caller( $opt_name );
718
-
719
-			if ( ! isset( $section['id'] ) ) {
720
-				if ( isset( $section['type'] ) && 'divide' === $section['type'] ) {
721
-					$section['id'] = time();
722
-				} elseif ( isset( $section['title'] ) ) {
723
-						$section['id'] = Redux_Core::strtolower( sanitize_title( $section['title'] ) );
724
-				} else {
725
-					$section['id'] = time();
726
-				}
727
-
728
-				if ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) && ! $replace ) {
729
-					$orig = $section['id'];
730
-					$i    = 0;
731
-
732
-					while ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) ) {
733
-						$section['id'] = $orig . '_' . $i;
734
-						++$i;
735
-					}
736
-				} elseif ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) && $replace ) {
737
-					// If replace is set, let's update the default values with these!
738
-					$fields = false;
739
-					if ( isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) && ! empty( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) ) {
740
-						$fields = self::$sections[ $opt_name ][ $section['id'] ]['fields'];
741
-					}
742
-					self::$sections[ $opt_name ][ $section['id'] ] = wp_parse_args( $section, self::$sections[ $opt_name ][ $section['id'] ] );
743
-					if ( ! empty( $fields ) ) {
744
-						if ( ! isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) || ( isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) && empty( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) ) ) {
745
-							self::$sections[ $opt_name ][ $section['id'] ]['fields'] = $fields;
746
-						}
747
-					}
748
-				}
749
-			}
750
-
751
-			if ( ! empty( $opt_name ) && is_array( $section ) && ! empty( $section ) ) {
752
-				if ( ! isset( $section['id'] ) && ! isset( $section['title'] ) ) {
753
-					self::$errors[ $opt_name ]['section']['missing_title'] = esc_html__( 'Unable to create a section due to missing id and title.', 'redux-framework' );
754
-
755
-					return;
756
-				}
757
-
758
-				if ( ! isset( $section['priority'] ) ) {
759
-					$section['priority'] = self::get_priority( $opt_name, 'sections' );
760
-				}
761
-
762
-				if ( isset( $section['fields'] ) ) {
763
-					if ( ! empty( $section['fields'] ) && is_array( $section['fields'] ) ) {
764
-						self::process_field_array( $opt_name, $section['id'], $section['fields'] );
765
-					}
766
-					unset( $section['fields'] );
767
-				}
768
-				self::$sections[ $opt_name ][ $section['id'] ] = $section;
769
-			} else {
770
-				self::$errors[ $opt_name ]['section']['empty'] = esc_html__( 'Unable to create a section due an empty section array or the section variable passed was not an array.', 'redux-framework' );
771
-			}
772
-		}
773
-
774
-		/**
775
-		 * Deprecated Hides an option panel section.
776
-		 *
777
-		 * @param string     $opt_name Panel opt_name.
778
-		 * @param string|int $id       Section ID.
779
-		 * @param bool       $hide     Flag to hide/show.
780
-		 *
781
-		 * @deprecated No longer using camelCase naming convention.
782
-		 */
783
-		public static function hideSection( string $opt_name = '', $id = '', bool $hide = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
784
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::hide_section( $opt_name, $id )' );
785
-
786
-			if ( '' !== $opt_name ) {
787
-				Redux_Functions_Ex::record_caller( $opt_name );
788
-			}
789
-
790
-			self::hide_section( $opt_name, $id, $hide );
791
-		}
792
-
793
-		/**
794
-		 * Hides an option panel section.
795
-		 *
796
-		 * @param string     $opt_name Panel opt_name.
797
-		 * @param string|int $id       Section ID.
798
-		 * @param bool       $hide     Flag to hide/show.
799
-		 */
800
-		public static function hide_section( string $opt_name = '', $id = '', bool $hide = true ) {
801
-			self::check_opt_name( $opt_name );
802
-
803
-			if ( '' !== $opt_name && '' !== $id ) {
804
-				Redux_Functions_Ex::record_caller( $opt_name );
805
-
806
-				if ( isset( self::$sections[ $opt_name ][ $id ] ) ) {
807
-					self::$sections[ $opt_name ][ $id ]['hidden'] = $hide;
808
-				}
809
-			}
810
-		}
811
-
812
-		/**
813
-		 * Compiles field array data.
814
-		 *
815
-		 * @param string     $opt_name   Panel opt_name.
816
-		 * @param string|int $section_id Section ID.
817
-		 * @param array      $fields     Field data.
818
-		 */
819
-		private static function process_field_array( string $opt_name = '', $section_id = '', array $fields = array() ) {
820
-			if ( ! empty( $opt_name ) && ! empty( $section_id ) && is_array( $fields ) && ! empty( $fields ) ) {
821
-				foreach ( $fields as $field ) {
822
-					if ( ! is_array( $field ) ) {
823
-						continue;
824
-					}
825
-					self::set_field( $opt_name, $section_id, $field );
826
-				}
827
-			}
828
-		}
829
-
830
-		/**
831
-		 * Deprecated Retrieves an option panel field.
832
-		 *
833
-		 * @param string     $opt_name Panel opt_name.
834
-		 * @param string|int $id       Field ID.
835
-		 *
836
-		 * @return int|bool
837
-		 * @deprecated No longer using camelCase naming convention.
838
-		 */
839
-		public static function getField( string $opt_name = '', $id = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
840
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_field( $opt_name, $id )' );
841
-
842
-			return self::get_field( $opt_name, $id );
843
-		}
844
-
845
-		/**
846
-		 * Retrieves an option panel field.
847
-		 *
848
-		 * @param string     $opt_name Panel opt_name.
849
-		 * @param string|int $id       Field ID.
850
-		 *
851
-		 * @return int|bool
852
-		 */
853
-		public static function get_field( string $opt_name = '', $id = '' ) {
854
-			self::check_opt_name( $opt_name );
855
-
856
-			if ( ! empty( $opt_name ) && ! empty( $id ) ) {
857
-				return self::$fields[ $opt_name ][ $id ] ?? false;
858
-			}
859
-
860
-			return false;
861
-		}
862
-
863
-		/**
864
-		 * Deprecated Hides an option panel field.
865
-		 *
866
-		 * @param string     $opt_name Panel opt_name.
867
-		 * @param string|int $id       Field ID.
868
-		 * @param bool       $hide     Set hide/show.
869
-		 *
870
-		 * @deprecated No longer using camelCase naming convention.
871
-		 */
872
-		public static function hideField( string $opt_name = '', $id = '', bool $hide = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
873
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::hide_field( $opt_name, $id )' );
874
-
875
-			if ( '' !== $opt_name ) {
876
-				Redux_Functions_Ex::record_caller( $opt_name );
877
-			}
878
-
879
-			self::hide_field( $opt_name, $id, $hide );
880
-		}
881
-
882
-		/**
883
-		 * Hides an option panel field.
884
-		 *
885
-		 * @param string     $opt_name Panel opt_name.
886
-		 * @param string|int $id       Field ID.
887
-		 * @param bool       $hide     Set hide/show.
888
-		 */
889
-		public static function hide_field( string $opt_name = '', $id = '', bool $hide = true ) {
890
-			self::check_opt_name( $opt_name );
891
-
892
-			if ( '' !== $opt_name && '' !== $id ) {
893
-				if ( isset( self::$fields[ $opt_name ][ $id ] ) ) {
894
-					Redux_Functions_Ex::record_caller( $opt_name );
895
-
896
-					if ( ! $hide ) {
897
-						self::$fields[ $opt_name ][ $id ]['class'] = str_replace( 'hidden', '', self::$fields[ $opt_name ][ $id ]['class'] );
898
-					} else {
899
-						self::$fields[ $opt_name ][ $id ]['class'] .= 'hidden';
900
-					}
901
-				}
902
-			}
903
-		}
904
-
905
-		/**
906
-		 * Deprecated Creates an option panel field.
907
-		 *
908
-		 * @param string     $opt_name   Panel opt_name.
909
-		 * @param string|int $section_id Section ID this field belongs to.
910
-		 * @param array      $field      Field data.
911
-		 *
912
-		 * @deprecated No longer using camelCase naming convention.
913
-		 */
914
-		public static function setField( string $opt_name = '', $section_id = '', array $field = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
915
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_field( $opt_name, $section_id, $field )' );
916
-
917
-			if ( '' !== $opt_name ) {
918
-				Redux_Functions_Ex::record_caller( $opt_name );
919
-			}
920
-
921
-			self::set_field( $opt_name, $section_id, $field );
922
-		}
923
-
924
-		/**
925
-		 * Creates an option panel field and adds to a section.
926
-		 *
927
-		 * @param string     $opt_name   Panel opt_name.
928
-		 * @param string|int $section_id Section ID this field belongs to.
929
-		 * @param array      $field      Field data.
930
-		 */
931
-		public static function set_field( string $opt_name = '', $section_id = '', array $field = array() ) {
932
-
933
-			if ( ! is_array( $field ) || empty( $field ) || '' === $opt_name || '' === $section_id ) {
934
-				return;
935
-			}
936
-
937
-			self::check_opt_name( $opt_name );
938
-
939
-			Redux_Functions_Ex::record_caller( $opt_name );
940
-
941
-			// Shim for the old method!
942
-			if ( is_array( $section_id ) ) {
943
-				$field = $section_id;
944
-				if ( isset( $field['section_id'] ) ) {
945
-					$section_id = $field['section_id'];
946
-				}
947
-			}
948
-
949
-			$field['section_id'] = $section_id;
950
-
951
-			if ( ! isset( $field['priority'] ) ) {
952
-				$field['priority'] = self::get_priority( $opt_name, 'fields' );
953
-			}
954
-			$field['id'] = $field['id'] ?? "{$opt_name}_{$section_id}_{$field['type']}_" . wp_rand( 1, 9999 );
955
-
956
-			self::$fields[ $opt_name ][ $field['id'] ] = $field;
957
-		}
958
-
959
-		/**
960
-		 * Create multiple fields of the option panel and apply to a section.
961
-		 *
962
-		 * @param string     $opt_name   Panel opt_name.
963
-		 * @param int|string $section_id Section ID this field belongs to.
964
-		 * @param array      $fields     Array of field arrays.
965
-		 */
966
-		public static function set_fields( string $opt_name = '', $section_id = '', array $fields = array() ) {
967
-			if ( ! is_array( $fields ) || empty( $fields ) || '' === $opt_name || '' === $section_id ) {
968
-				return;
969
-			}
970
-
971
-			self::check_opt_name( $opt_name );
972
-
973
-			// phpcs:ignore WordPress.PHP.DevelopmentFunctions
974
-			Redux_Functions_Ex::record_caller( $opt_name );
975
-
976
-			foreach ( $fields as $field ) {
977
-				if ( is_array( $field ) ) {
978
-					self::set_field( $opt_name, $section_id, $field );
979
-				}
980
-			}
981
-		}
982
-
983
-		/**
984
-		 * Deprecated Removes an option panel field.
985
-		 *
986
-		 * @param string     $opt_name Panel opt_name.
987
-		 * @param string|int $id       Field ID.
988
-		 *
989
-		 * @return bool
990
-		 * @deprecated No longer using camelCase naming convention.
991
-		 */
992
-		public static function removeField( string $opt_name = '', $id = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
993
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::remove_field( $opt_name, $id )' );
994
-
995
-			if ( '' !== $opt_name ) {
996
-				Redux_Functions_Ex::record_caller( $opt_name );
997
-			}
998
-
999
-			return self::remove_field( $opt_name, $id );
1000
-		}
1001
-
1002
-		/**
1003
-		 * Removes an option panel field.
1004
-		 *
1005
-		 * @param string     $opt_name Panel opt_name.
1006
-		 * @param string|int $id       Field ID.
1007
-		 *
1008
-		 * @return bool
1009
-		 */
1010
-		public static function remove_field( string $opt_name = '', $id = '' ): bool {
1011
-			if ( '' !== $opt_name && '' !== $id ) {
1012
-				self::check_opt_name( $opt_name );
1013
-
1014
-				Redux_Functions_Ex::record_caller( $opt_name );
1015
-
1016
-				if ( isset( self::$fields[ $opt_name ][ $id ] ) ) {
1017
-					foreach ( self::$fields[ $opt_name ] as $key => $field ) {
1018
-						if ( $key === $id ) {
1019
-							$priority = $field['priority'];
1020
-							--self::$priority[ $opt_name ]['fields'];
1021
-							unset( self::$fields[ $opt_name ][ $id ] );
1022
-							continue;
1023
-						}
1024
-
1025
-						if ( isset( $priority ) && '' !== $priority ) {
1026
-							$new_priority                      = $field['priority'];
1027
-							$field['priority']                 = $priority;
1028
-							self::$fields[ $opt_name ][ $key ] = $field;
1029
-							$priority                          = $new_priority;
1030
-						}
1031
-					}
1032
-				}
1033
-			}
1034
-
1035
-			return false;
1036
-		}
1037
-
1038
-		/**
1039
-		 * Deprecated Sets help tabs on option panel admin page.
1040
-		 *
1041
-		 * @param string $opt_name Panel opt_name.
1042
-		 * @param array  $tab      Tab data.
1043
-		 *
1044
-		 * @deprecated No longer using camelCase naming convention.
1045
-		 */
1046
-		public static function setHelpTab( string $opt_name = '', array $tab = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1047
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_help_tab( $opt_name, $tab )' );
1048
-
1049
-			self::set_help_tab( $opt_name, $tab );
1050
-		}
1051
-
1052
-		/**
1053
-		 * Sets help tabs on option panel admin page.
1054
-		 *
1055
-		 * @param string $opt_name Panel opt_name.
1056
-		 * @param array  $tab      Tab data.
1057
-		 */
1058
-		public static function set_help_tab( string $opt_name = '', array $tab = array() ) {
1059
-			if ( ! is_array( $tab ) && empty( $tab ) ) {
1060
-				return;
1061
-			}
1062
-
1063
-			self::check_opt_name( $opt_name );
1064
-
1065
-			if ( '' !== $opt_name ) {
1066
-				if ( ! isset( self::$args[ $opt_name ]['help_tabs'] ) ) {
1067
-					self::$args[ $opt_name ]['help_tabs'] = array();
1068
-				}
1069
-
1070
-				if ( isset( $tab['id'] ) ) {
1071
-					self::$args[ $opt_name ]['help_tabs'][] = $tab;
1072
-				} elseif ( is_array( end( $tab ) ) ) {
1073
-					foreach ( $tab as $tab_item ) {
1074
-						self::$args[ $opt_name ]['help_tabs'][] = $tab_item;
1075
-					}
1076
-				}
1077
-			}
1078
-		}
1079
-
1080
-		/**
1081
-		 * Deprecated Sets the help sidebar content.
1082
-		 *
1083
-		 * @param string $opt_name Panel opt_name.
1084
-		 * @param string $content  Content.
1085
-		 *
1086
-		 * @deprecated No longer using camelCase naming convention.
1087
-		 */
1088
-		public static function setHelpSidebar( string $opt_name = '', string $content = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1089
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_help_sidebar( $opt_name, $content )' );
1090
-
1091
-			self::set_help_sidebar( $opt_name, $content );
1092
-		}
1093
-
1094
-		/**
1095
-		 * Sets the help sidebar content.
1096
-		 *
1097
-		 * @param string $opt_name Panel opt_name.
1098
-		 * @param string $content  Content.
1099
-		 */
1100
-		public static function set_help_sidebar( string $opt_name = '', string $content = '' ) {
1101
-			if ( '' === $content || '' === $opt_name ) {
1102
-				return;
1103
-			}
1104
-			self::check_opt_name( $opt_name );
1105
-
1106
-			self::$args[ $opt_name ]['help_sidebar'] = $content;
1107
-		}
1108
-
1109
-		/**
1110
-		 * Deprecated Sets option panel global arguments.
1111
-		 *
1112
-		 * @param string $opt_name Panel opt_name.
1113
-		 * @param array  $args     Argument data.
1114
-		 *
1115
-		 * @deprecated No longer using camelCase naming convention.
1116
-		 */
1117
-		public static function setArgs( string $opt_name = '', array $args = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1118
-			// phpcs:ignore Squiz.PHP.CommentedOutCode.Found
1119
-			// _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_args( $opt_name, $args )' );
1120
-
1121
-			if ( '' !== $opt_name ) {
1122
-				Redux_Functions_Ex::record_caller( $opt_name );
1123
-			}
1124
-
1125
-			self::set_args( $opt_name, $args );
1126
-		}
1127
-
1128
-		/**
1129
-		 * Sets option panel global arguments.
1130
-		 *
1131
-		 * @param string $opt_name Panel opt_name.
1132
-		 * @param array  $args     Argument data.
1133
-		 */
1134
-		public static function set_args( string $opt_name = '', array $args = array() ) {
1135
-			if ( empty( $args ) || '' === $opt_name ) {
1136
-				return;
1137
-			}
1138
-
1139
-			self::check_opt_name( $opt_name );
1140
-
1141
-			Redux_Functions_Ex::record_caller( $opt_name );
1142
-
1143
-			if ( is_array( $args ) ) {
1144
-				if ( isset( self::$args[ $opt_name ]['clearArgs'] ) ) {
1145
-					self::$args[ $opt_name ] = array();
1146
-				}
1147
-				self::$args[ $opt_name ] = wp_parse_args( $args, self::$args[ $opt_name ] );
1148
-			}
1149
-		}
1150
-
1151
-		/**
1152
-		 * Set's developer key for premium services.
1153
-		 *
1154
-		 * @param string       $opt_name Panel opt_name.
1155
-		 * @param string|array $arg      Args data.
1156
-		 */
1157
-		public static function set_developer( string $opt_name = '', $arg = '' ) {
1158
-			if ( empty( $arg ) || '' === $opt_name ) {
1159
-				return;
1160
-			}
1161
-
1162
-			self::check_opt_name( $opt_name );
1163
-
1164
-			Redux_Functions_Ex::record_caller( $opt_name );
1165
-
1166
-			self::$args[ $opt_name ]['developer'] = $arg;
1167
-		}
1168
-
1169
-		/**
1170
-		 * Deprecated Retries option panel global argument array.
1171
-		 *
1172
-		 * @param string $opt_name Panel opt_name.
1173
-		 *
1174
-		 * @return mixed
1175
-		 * @deprecated No longer camelCase naming convention.
1176
-		 */
1177
-		public static function getArgs( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1178
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_args( $opt_name )' );
1179
-
1180
-			return self::get_args( $opt_name );
1181
-		}
1182
-
1183
-		/**
1184
-		 * Retries option panel global argument array.
1185
-		 *
1186
-		 * @param string $opt_name Panel opt_name.
1187
-		 * @param string $key      Argument key name to be returned.
1188
-		 *
1189
-		 * @return mixed|null|array
1190
-		 */
1191
-		public static function get_args( string $opt_name = '', string $key = '' ) {
1192
-			self::check_opt_name( $opt_name );
1193
-
1194
-			if ( ! empty( $opt_name ) && ! empty( $key ) ) {
1195
-				if ( ! empty( self::$args[ $opt_name ] ) ) {
1196
-					return self::$args[ $opt_name ][ $key ];
1197
-				} else {
1198
-					return null;
1199
-				}
1200
-			} elseif ( ! empty( $opt_name ) && ! empty( self::$args[ $opt_name ] ) ) {
1201
-				return self::$args[ $opt_name ];
1202
-			}
1203
-
1204
-			return null;
1205
-		}
1206
-
1207
-		/**
1208
-		 * Deprecated Retrieves a single global argument.
1209
-		 *
1210
-		 * @param string $opt_name Panel opt_name.
1211
-		 * @param string $key      Argument name.
1212
-		 *
1213
-		 * @return mixed
1214
-		 * @deprecated No longer using camelCase naming convention and using singular function self::get_args() now.
1215
-		 */
1216
-		public static function getArg( string $opt_name = '', string $key = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1217
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_arg( $opt_name, $key )' );
1218
-
1219
-			return self::get_args( $opt_name, $key );
1220
-		}
1221
-
1222
-		/**
1223
-		 * Retrieves a single global argument.
1224
-		 *
1225
-		 * @param string $opt_name Panel opt_name.
1226
-		 * @param string $key      Argument name.
1227
-		 *
1228
-		 * @return mixed|array|null
1229
-		 */
1230
-		public static function get_arg( string $opt_name = '', string $key = '' ) {
1231
-			self::check_opt_name( $opt_name );
1232
-
1233
-			if ( ! empty( $opt_name ) && ! empty( $key ) && ! empty( self::$args[ $opt_name ] ) ) {
1234
-				return self::$args[ $opt_name ][ $key ];
1235
-			} else {
1236
-				return null;
1237
-			}
1238
-		}
1239
-
1240
-		/**
1241
-		 * Deprecated Retrieves a single option from the database.
1242
-		 *
1243
-		 * @param string       $opt_name Panel opt_name.
1244
-		 * @param string       $key      Option key.
1245
-		 * @param string|array $defaults  Default value.
1246
-		 *
1247
-		 * @return mixed
1248
-		 * @deprecated No longer using camelCase naming convention.
1249
-		 */
1250
-		public static function getOption( string $opt_name = '', string $key = '', $defaults = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1251
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_option( $opt_name, $key, $default )' );
1252
-
1253
-			return self::get_option( $opt_name, $key, $defaults );
1254
-		}
1255
-
1256
-		/**
1257
-		 * Retrieves meta for a given post page, IE WordPress meta values
1258
-		 *
1259
-		 * @param string $opt_name Panel opt_name.
1260
-		 * @param mixed  $the_post Post object to denote the current post, or custom.
1261
-		 * @param string $key      Option key.
1262
-		 * @param mixed  $defaults Default value.
1263
-		 *
1264
-		 * @return mixed
1265
-		 */
1266
-		public static function get_post_meta( string $opt_name = '', $the_post = array(), string $key = '', $defaults = null ) {
1267
-			self::check_opt_name( $opt_name );
1268
-
1269
-			if ( empty( $opt_name ) ) {
1270
-				return null;
1271
-			}
1272
-
1273
-			global $post;
1274
-
1275
-			$redux = ReduxFrameworkInstances::get_instance( $opt_name );
1276
-
1277
-			$metaboxes = $redux->extensions['metaboxes'];
1278
-
1279
-			if ( null === $defaults || '' === $defaults ) {
1280
-				$defaults = self::get_option( $opt_name, $key );
1281
-			}
1282
-
1283
-			if ( isset( $the_post ) && is_array( $the_post ) ) {
1284
-				$the_post = $post;
1285
-			} elseif ( ! isset( $the_post ) || 0 === $the_post ) {
1286
-				return $defaults;
1287
-			} elseif ( is_numeric( $the_post ) ) {
1288
-				$the_post = get_post( $the_post );
1289
-			} elseif ( ! is_object( $the_post ) ) {
1290
-				$the_post = $post;
1291
-			}
1292
-
1293
-			$defaults = self::get_option( $opt_name, $key );
1294
-
1295
-			return $metaboxes->get_values( $the_post, $key, $defaults );
1296
-		}
1297
-
1298
-		/**
1299
-		 * Retrieves a single option from the database.
1300
-		 *
1301
-		 * @param string $opt_name Panel opt_name.
1302
-		 * @param string $key      Option key.
1303
-		 * @param mixed  $default  Default value.
1304
-		 *
1305
-		 * @return mixed
1306
-		 */
1307
-		public static function get_option( string $opt_name = '', string $key = '', $default = null ) { // phpcs:ignore Universal.NamingConventions
1308
-			self::check_opt_name( $opt_name );
1309
-
1310
-			if ( ! empty( $opt_name ) && ! empty( $key ) ) {
1311
-				global $$opt_name;
1312
-
1313
-				if ( empty( $$opt_name ) ) {
1314
-					$values    = get_option( $opt_name );
1315
-					$$opt_name = $values;
1316
-				} else {
1317
-					$values = $$opt_name;
1318
-				}
1319
-
1320
-				if ( ! isset( $values[ $key ] ) ) {
1321
-					if ( null === $default ) {
1322
-						$field = self::get_field( $opt_name, $key );
1323
-
1324
-						if ( false !== $field ) {
1325
-							$defaults_class = new Redux_Options_Defaults();
1326
-							$sections       = self::construct_sections( $opt_name );
1327
-							$defaults       = $defaults_class->default_values( $opt_name, $sections );
1328
-
1329
-							if ( isset( $defaults[ $key ] ) ) {
1330
-								$default = $defaults[ $key ];
1331
-							}
1332
-						}
1333
-					}
1334
-				}
1335
-
1336
-				if ( ! empty( $subkeys ) && is_array( $subkeys ) ) {
1337
-					$value = $default;
1338
-
1339
-					if ( isset( $values[ $key ] ) ) {
1340
-						$count = count( $subkeys );
1341
-
1342
-						if ( 1 === $count ) {
1343
-							$value = $values[ $key ][ $subkeys[1] ] ?? $default;
1344
-						} elseif ( 2 === $count ) {
1345
-							if ( isset( $values[ $key ][ $subkeys[1] ] ) ) {
1346
-								$value = $values[ $key ][ $subkeys[1] ][ $subkeys[2] ] ?? $default;
1347
-							}
1348
-						} elseif ( 3 === $count ) {
1349
-							if ( isset( $values[ $key ][ $subkeys[1] ] ) ) {
1350
-								if ( isset( $values[ $key ][ $subkeys[1] ][ $subkeys[2] ] ) ) {
1351
-									$value = $values[ $key ][ $subkeys[1] ][ $subkeys[2] ][ $subkeys[3] ] ?? $default;
1352
-								}
1353
-							}
1354
-						}
1355
-					}
1356
-				} else {
1357
-					$value = $values[ $key ] ?? $default;
1358
-				}
1359
-
1360
-				return $value;
1361
-			} else {
1362
-				return false;
1363
-			}
1364
-		}
1365
-
1366
-		/**
1367
-		 * Deprecated Sets an option into the database.
1368
-		 *
1369
-		 * @param string $opt_name Panel opt_name.
1370
-		 * @param string $key      Option key.
1371
-		 * @param mixed  $option   Option value.
1372
-		 *
1373
-		 * @return bool
1374
-		 * @deprecated No longer using camelCase naming convention.
1375
-		 */
1376
-		public static function setOption( string $opt_name = '', string $key = '', $option = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1377
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_option( $opt_name, $key, $option )' );
1378
-
1379
-			if ( '' !== $opt_name ) {
1380
-				Redux_Functions_Ex::record_caller( $opt_name );
1381
-			}
1382
-
1383
-			return self::set_option( $opt_name, $key, $option );
1384
-		}
1385
-
1386
-		/**
1387
-		 * Sets an option into the database.
1388
-		 *
1389
-		 * @param string $opt_name Panel opt_name.
1390
-		 * @param string $key      Option key.
1391
-		 * @param mixed  $option   Option value.
1392
-		 *
1393
-		 * @return bool
1394
-		 */
1395
-		public static function set_option( string $opt_name = '', string $key = '', $option = '' ): bool {
1396
-			if ( '' === $key ) {
1397
-				return false;
1398
-			}
1399
-
1400
-			self::check_opt_name( $opt_name );
1401
-
1402
-			Redux_Functions_Ex::record_caller( $opt_name );
1403
-
1404
-			if ( '' !== $opt_name ) {
1405
-				$redux         = get_option( $opt_name );
1406
-				$redux[ $key ] = $option;
1407
-
1408
-				return update_option( $opt_name, $redux );
1409
-			} else {
1410
-				return false;
1411
-			}
1412
-		}
1413
-
1414
-		/**
1415
-		 * Get the next available priority for field/section.
1416
-		 *
1417
-		 * @param string $opt_name Panel opt_name.
1418
-		 * @param string $type     Field or section.
1419
-		 *
1420
-		 * @return mixed
1421
-		 */
1422
-		public static function get_priority( string $opt_name, string $type ) {
1423
-			$priority                              = self::$priority[ $opt_name ][ $type ];
1424
-			self::$priority[ $opt_name ][ $type ] += 1;
1425
-
1426
-			return $priority;
1427
-		}
1428
-
1429
-		/**
1430
-		 * Check opt_name integrity.
1431
-		 *
1432
-		 * @param string $opt_name Panel opt_name.
1433
-		 */
1434
-		public static function check_opt_name( string $opt_name = '' ) {
1435
-			if ( empty( $opt_name ) || is_array( $opt_name ) ) {
1436
-				return;
1437
-			}
1438
-
1439
-			if ( ! isset( self::$sections[ $opt_name ] ) ) {
1440
-				self::$sections[ $opt_name ]             = array();
1441
-				self::$priority[ $opt_name ]['sections'] = 1;
1442
-			}
1443
-
1444
-			if ( ! isset( self::$args[ $opt_name ] ) ) {
1445
-				self::$args[ $opt_name ]             = array();
1446
-				self::$priority[ $opt_name ]['args'] = 1;
1447
-			}
1448
-
1449
-			if ( ! isset( self::$fields[ $opt_name ] ) ) {
1450
-				self::$fields[ $opt_name ]             = array();
1451
-				self::$priority[ $opt_name ]['fields'] = 1;
1452
-			}
1453
-
1454
-			if ( ! isset( self::$help[ $opt_name ] ) ) {
1455
-				self::$help[ $opt_name ]             = array();
1456
-				self::$priority[ $opt_name ]['help'] = 1;
1457
-			}
1458
-
1459
-			if ( ! isset( self::$errors[ $opt_name ] ) ) {
1460
-				self::$errors[ $opt_name ] = array();
1461
-			}
1462
-
1463
-			if ( ! isset( self::$init[ $opt_name ] ) ) {
1464
-				self::$init[ $opt_name ] = false;
1465
-			}
1466
-		}
1467
-
1468
-		/**
1469
-		 * Retrieve metadata from a file. Based on WP Core's get_file_data function
1470
-		 *
1471
-		 * @param string $file Path to the file.
1472
-		 *
1473
-		 * @return string
1474
-		 * @since 2.1.1
1475
-		 */
1476
-		public static function get_file_version( string $file ): string {
1477
-			$data = get_file_data( $file, array( 'version' ), 'plugin' );
1478
-
1479
-			return $data[0];
1480
-		}
1481
-
1482
-		/**
1483
-		 * Verify extension class name.
1484
-		 *
1485
-		 * @param string $opt_name   Panel opt_name.
1486
-		 * @param string $name       extension name.
1487
-		 * @param string $class_file Extension class file.
1488
-		 */
1489
-		private static function check_extension_class_file( string $opt_name, string $name = '', string $class_file = '' ) {
1490
-			$instance = null;
1491
-
1492
-			if ( file_exists( $class_file ) ) {
1493
-				self::$uses_extensions[ $opt_name ] = self::$uses_extensions[ $opt_name ] ?? array();
1494
-
1495
-				if ( ! in_array( $name, self::$uses_extensions[ $opt_name ], true ) ) {
1496
-					self::$uses_extensions[ $opt_name ][] = $name;
1497
-				}
1498
-
1499
-				self::$extensions[ $name ] = self::$extensions[ $name ] ?? array();
1500
-
1501
-				$version = Redux_Helpers::get_template_version( $class_file );
1502
-
1503
-				if ( empty( $version ) && ! empty( $instance ) ) {
1504
-					if ( isset( $instance->version ) ) {
1505
-						$version = $instance->version;
1506
-					}
1507
-				}
1508
-				self::$extensions[ $name ][ $version ] = self::$extensions[ $name ][ $version ] ?? $class_file;
1509
-
1510
-				$new_name  = str_replace( '_', '-', $name );
1511
-				$api_check = str_replace(
1512
-					array(
1513
-						'extension_' . $name,
1514
-						'class-redux-extension-' . $new_name,
1515
-					),
1516
-					array(
1517
-						$name . '_api',
1518
-						'class-redux-' . $new_name . '-api',
1519
-					),
1520
-					$class_file
1521
-				);
1522
-
1523
-				if ( file_exists( $api_check ) && ! class_exists( 'Redux_' . ucfirst( $name ) ) ) {
1524
-					include_once $api_check;
1525
-				}
1526
-			}
1527
-		}
1528
-
1529
-		/**
1530
-		 * Deprecated Sets all extensions in a path.
1531
-		 *
1532
-		 * @param string $opt_name Panel opt_name.
1533
-		 * @param string $path     Path to extension folder.
1534
-		 *
1535
-		 * @deprecated No longer using camelCase naming convention.
1536
-		 */
1537
-		public static function setExtensions( string $opt_name, string $path ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1538
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_extensions( $opt_name, $path )' );
1539
-
1540
-			if ( '' !== $opt_name ) {
1541
-				Redux_Functions_Ex::record_caller( $opt_name );
1542
-			}
1543
-
1544
-			self::set_extensions( $opt_name, $path );
1545
-		}
1546
-
1547
-		/**
1548
-		 * Sets all extensions in a path.
1549
-		 *
1550
-		 * @param string $opt_name Panel opt_name.
1551
-		 * @param string $path     Path to extension folder.
1552
-		 * @param bool   $force    Make extension reload.
1553
-		 */
1554
-		public static function set_extensions( string $opt_name, string $path, bool $force = false ) {
1555
-			if ( '' === $path || '' === $opt_name ) {
1556
-				return;
1557
-			}
1558
-
1559
-			self::check_opt_name( $opt_name );
1560
-
1561
-			Redux_Functions_Ex::record_caller( $opt_name );
1562
-
1563
-			if ( is_dir( $path ) ) {
1564
-				$path   = trailingslashit( $path );
1565
-				$folder = str_replace( '.php', '', basename( $path ) );
1566
-
1567
-				$folder_fix = str_replace( '_', '-', $folder );
1568
-
1569
-				$files = array(
1570
-					$path . 'extension_' . $folder . '.php',
1571
-					$path . 'class-redux-extension-' . $folder_fix . '.php',
1572
-				);
1573
-
1574
-				$ext_file = Redux_Functions::file_exists_ex( $files );
1575
-
1576
-				if ( $ext_file ) {
1577
-					self::check_extension_class_file( $opt_name, $folder, $ext_file );
1578
-				} else {
1579
-					$folders = scandir( $path );
1580
-
1581
-					foreach ( $folders as $folder ) {
1582
-						if ( '.' === $folder || '..' === $folder ) {
1583
-							continue;
1584
-						}
1585
-
1586
-						if ( is_dir( $path . $folder ) ) {
1587
-							self::set_extensions( $opt_name, $path . $folder );
1588
-						}
1589
-					}
1590
-				}
1591
-			} elseif ( file_exists( $path ) ) {
1592
-				$name = explode( 'extension_', basename( $path ) );
1593
-				if ( ! empty( $name[1] ) ) {
1594
-					$name = str_replace( '.php', '', $name[1] );
1595
-					self::check_extension_class_file( $opt_name, $name, $path );
1596
-				}
1597
-			}
1598
-
1599
-			self::$extension_paths[ $opt_name ] = $path;
1600
-
1601
-			if ( true === $force ) {
1602
-				if ( isset( self::$uses_extensions[ $opt_name ] ) && ! empty( self::$uses_extensions[ $opt_name ] ) ) {
1603
-					$redux = self::instance( $opt_name );
1604
-
1605
-					if ( isset( $redux ) ) {
1606
-						self::load_extensions( $redux );
1607
-					}
1608
-				}
1609
-			}
1610
-		}
1611
-
1612
-		/**
1613
-		 * Retrieves all loaded extensions.
1614
-		 */
1615
-		private static function get_all_extension() {
1616
-			$redux = self::all_instances();
1617
-
1618
-			foreach ( $redux as $instance ) {
1619
-				if ( ! empty( self::$uses_extensions[ $instance['args']['opt_name'] ] ) ) {
1620
-					continue;
1621
-				}
1622
-				if ( ! empty( $instance['extensions'] ) ) {
1623
-					self::get_instance_extension( $instance['args']['opt_name'], $instance );
1624
-				}
1625
-			}
1626
-		}
1627
-
1628
-		/**
1629
-		 * Gets all loaded extensions for the passed ReduxFramework instance.
1630
-		 *
1631
-		 * @param string      $opt_name Panel opt_name.
1632
-		 * @param object|null $instance ReduxFramework instance.
1633
-		 */
1634
-		public static function get_instance_extension( string $opt_name, $instance ) {
1635
-			if ( ! empty( self::$uses_extensions[ $opt_name ] ) || empty( $opt_name ) ) {
1636
-				return;
1637
-			}
1638
-
1639
-			if ( empty( $instance ) ) {
1640
-				$instance = self::instance( $opt_name );
1641
-			}
1642
-
1643
-			if ( empty( $instance ) || empty( $instance->extensions ) ) {
1644
-				return;
1645
-			}
1646
-
1647
-			foreach ( $instance->extensions as $name => $extension ) {
1648
-				if ( 'widget_areas' === $name ) {
1649
-					new Redux_Widget_Areas( $instance );
1650
-				}
1651
-
1652
-				if ( isset( self::$uses_extensions[ $opt_name ][ $name ] ) ) {
1653
-					continue;
1654
-				}
1655
-
1656
-				if ( isset( $extension->extension_dir ) ) {
1657
-					self::set_extensions( $opt_name, str_replace( $name, '', $extension->extension_dir ) );
1658
-				}
1659
-			}
1660
-		}
1661
-
1662
-		/**
1663
-		 * Deprecated Gets loaded extensions.
1664
-		 *
1665
-		 * @param string $opt_name Panel opt_name.
1666
-		 * @param string $key      Extension name.
1667
-		 *
1668
-		 * @return array|bool|mixed
1669
-		 * @deprecated No longer using camelCase naming convention.
1670
-		 */
1671
-		public static function getExtensions( string $opt_name = '', string $key = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1672
-			_deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.0.0', 'self::get_extensions( $opt_name, $key )' );
1673
-
1674
-			return self::get_extensions( $opt_name, $key );
1675
-		}
1676
-
1677
-		/**
1678
-		 * Gets loaded extensions.
1679
-		 *
1680
-		 * @param string $opt_name Panel opt_name.
1681
-		 * @param string $key      Extension name.
1682
-		 *
1683
-		 * @return array|bool|mixed
1684
-		 */
1685
-		public static function get_extensions( string $opt_name = '', string $key = '' ) {
1686
-			if ( empty( $opt_name ) ) {
1687
-				self::get_all_extension();
1688
-
1689
-				if ( empty( $key ) ) {
1690
-					return self::$extension_paths;
1691
-				} elseif ( isset( self::$extension_paths[ $key ] ) ) {
1692
-						return self::$extension_paths[ $key ];
1693
-				}
1694
-			} else {
1695
-				if ( empty( self::$uses_extensions[ $opt_name ] ) ) {
1696
-					self::get_instance_extension( $opt_name, null );
1697
-				}
1698
-
1699
-				if ( empty( self::$uses_extensions[ $opt_name ] ) ) {
1700
-					return false;
1701
-				}
1702
-
1703
-				$instance_extensions = array();
1704
-
1705
-				foreach ( self::$uses_extensions[ $opt_name ] as $extension ) {
1706
-					$class_file = end( self::$extensions[ $extension ] );
1707
-					$directory  = explode( DIRECTORY_SEPARATOR, $class_file );
1708
-					array_pop( $directory );
1709
-					$directory       = trailingslashit( join( DIRECTORY_SEPARATOR, $directory ) );
1710
-					$name            = str_replace( '.php', '', basename( $extension ) );
1711
-					$extension_class = 'Redux_Extension_' . $name;
1712
-					$the_data        = array(
1713
-						'path'    => $class_file,
1714
-						'dir'     => $directory,
1715
-						'class'   => $extension_class,
1716
-						'version' => Redux_Helpers::get_template_version( $class_file ),
1717
-					);
1718
-
1719
-					if ( is_dir( $the_data['dir'] . $extension ) ) {
1720
-						$test_path = trailingslashit( $the_data['dir'] . $extension );
1721
-						if ( file_exists( $test_path . 'field_' . str_replace( '-', '', $extension ) . '.php' ) ) {
1722
-							$the_data['field'] = $test_path . 'field_' . str_replace( '-', '', $extension ) . '.php';
1723
-						}
1724
-						// Old extensions!
1725
-						if ( file_exists( $test_path . str_replace( '-', '', $extension ) . '.php' ) ) {
1726
-							$the_data['field'] = $test_path . str_replace( '-', '', $extension ) . '.php';
1727
-						}
1728
-					}
1729
-					$instance_extensions[ $extension ] = $the_data;
1730
-				}
1731
-
1732
-				return $instance_extensions;
1733
-			}
1734
-
1735
-			return false;
1736
-		}
1737
-
1738
-		/**
1739
-		 * Method to disables Redux demo mode popup.
1740
-		 */
1741
-		public static function disable_demo() {
1742
-			add_action( 'ReduxFrameworkPlugin_admin_notice', 'Redux::remove_demo' );
1743
-			add_action( 'redux_framework_plugin_admin_notice', 'Redux::remove_demo' );
1744
-		}
1745
-
1746
-		/**
1747
-		 * Callback used by self::disable_demo() to remove the demo mode notice from Redux.
1748
-		 */
1749
-		public static function remove_demo() {
1750
-			update_option( 'ReduxFrameworkPlugin_ACTIVATED_NOTICES', '' );
1751
-		}
1752
-
1753
-		/**
1754
-		 * Function which forces a panel/page to render.
1755
-		 *
1756
-		 * @param string|object $redux Panel opt_name or Redux object.
1757
-		 */
1758
-		public static function render( $redux = '' ) {
1759
-			if ( is_string( $redux ) ) {
1760
-				$redux = Redux_Instances::get_instance( $redux );
1761
-				if ( empty( $redux ) ) {
1762
-					return;
1763
-				}
1764
-			}
1765
-			$enqueue = new Redux_Enqueue( $redux );
1766
-			$enqueue->init();
1767
-			$panel = new Redux_Panel( $redux );
1768
-			$panel->init();
1769
-		}
1770
-	}
1771
-
1772
-	Redux::load();
19
+    /**
20
+     * Redux API Class
21
+     * Simple API for Redux Framework
22
+     *
23
+     * @since       3.0.0
24
+     */
25
+    class Redux {
26
+
27
+
28
+        /**
29
+         *  Option fields.
30
+         *
31
+         * @var array
32
+         */
33
+        public static array $fields = array();
34
+
35
+        /**
36
+         * Option sections.
37
+         *
38
+         * @var array
39
+         */
40
+        public static array $sections = array();
41
+
42
+        /**
43
+         * Option defaults.
44
+         *
45
+         * @var array
46
+         */
47
+        public static array $options_defaults = array();
48
+
49
+        /**
50
+         * Option help array.
51
+         *
52
+         * @var array
53
+         */
54
+        public static array $help = array();
55
+
56
+        /**
57
+         * Option global args.
58
+         *
59
+         * @var array
60
+         */
61
+        public static array $args = array();
62
+
63
+        /**
64
+         * Option section priorities.
65
+         *
66
+         * @var array
67
+         */
68
+        public static array $priority = array();
69
+
70
+        /**
71
+         * Panel validations errors.
72
+         *
73
+         * @var array
74
+         */
75
+        public static array $errors = array();
76
+
77
+        /**
78
+         * Init.
79
+         *
80
+         * @var array
81
+         */
82
+        public static array $init = array();
83
+
84
+        /**
85
+         * Delay Init opt_names
86
+         *
87
+         * @var array
88
+         */
89
+        public static array $delay_init = array();
90
+
91
+        /**
92
+         * Extension list.
93
+         *
94
+         * @var array
95
+         */
96
+        public static array $extensions = array();
97
+
98
+        /**
99
+         * Extensions in use.
100
+         *
101
+         * @var array
102
+         */
103
+        public static array $uses_extensions = array();
104
+
105
+        /**
106
+         * Extension paths.
107
+         *
108
+         * @var array
109
+         */
110
+        public static array $extension_paths = array();
111
+
112
+        /**
113
+         * Extension capability flag.
114
+         *
115
+         * @var boolean
116
+         */
117
+        public static bool $extension_compatibility = false;
118
+
119
+        /**
120
+         * Code to run at creation in instance.
121
+         */
122
+        public static function load() {
123
+            add_action( 'after_setup_theme', array( 'Redux', 'create_redux' ) );
124
+            add_action( 'init', array( 'Redux', 'create_redux' ) );
125
+            add_action( 'switch_theme', array( 'Redux', 'create_redux' ) );
126
+
127
+            require_once Redux_Core::$dir . 'inc/extensions/metaboxes/class-redux-metaboxes-api.php';
128
+            require_once Redux_Core::$dir . 'inc/extensions/users/class-redux-users-api.php';
129
+            require_once Redux_Core::$dir . 'inc/extensions/taxonomy/class-redux-taxonomy-api.php';
130
+        }
131
+
132
+        /**
133
+         * Delay init action function
134
+         * Delays all Redux objects from loaded before `plugins_loaded` runs.
135
+         *
136
+         * @throws ReflectionException Exception.
137
+         */
138
+        public static function delay_init() {
139
+            if ( ! empty( self::$delay_init ) ) {
140
+
141
+                foreach ( self::$delay_init as $opt_name ) {
142
+                    self::init( $opt_name );
143
+                    $parent = Redux_Instances::get_instance( $opt_name );
144
+                    // translators: This is only shown to developers, should not impact users.
145
+                    $msg = sprintf(
146
+                        '<strong>%s</strong><br /><code>%s</code> %s',
147
+                        esc_html__( 'Warning, Premature Initialization', 'redux-framework' ),
148
+                        'self::init("' . esc_html( $opt_name ) . '")',
149
+                        // translators: This is only shown to developers, should not impact users.
150
+                        sprintf( esc_html__( 'was run before the %s hook and was delayed to avoid errors.', 'redux-framework' ), '<code>plugins_loaded</code>' )
151
+                    );
152
+
153
+                    if ( isset( $parent->args ) ) {
154
+                        $data = array(
155
+                            'parent'  => $parent,
156
+                            'type'    => 'error',
157
+                            'msg'     => $msg,
158
+                            'id'      => 'redux_init',
159
+                            'dismiss' => true,
160
+                        );
161
+
162
+                        Redux_Admin_Notices::set_notice( $data );
163
+                    }
164
+                }
165
+            }
166
+        }
167
+
168
+        /**
169
+         * Init Redux object
170
+         *
171
+         * @param string $opt_name Panel opt_name.
172
+         *
173
+         * @throws ReflectionException  Exception.
174
+         */
175
+        public static function init( string $opt_name = '' ) {
176
+            if ( ! empty( $opt_name ) ) {
177
+                if ( ! did_action( 'plugins_loaded' ) ) {
178
+
179
+                    // We don't want to load before plugins_loaded EVER.
180
+                    self::$delay_init[] = $opt_name;
181
+                    add_action( 'plugins_loaded', array( 'Redux', 'delay_init' ) );
182
+                } else {
183
+
184
+                    // The hook `plugins_loaded` has run, let's get going!
185
+                    self::load_redux( $opt_name );
186
+
187
+                    remove_action( 'setup_theme', array( 'Redux', 'create_redux' ) );
188
+                }
189
+            }
190
+        }
191
+
192
+        /**
193
+         * Retrieve ReduxFramework object.
194
+         *
195
+         * @param string $opt_name Panel opt_name.
196
+         *
197
+         * @return object|ReduxFramework
198
+         */
199
+        public static function instance( string $opt_name ) {
200
+            return Redux_Instances::get_instance( $opt_name );
201
+        }
202
+
203
+        /**
204
+         * Retrieve all ReduxFramework Instances.
205
+         *
206
+         * @return null|array|ReduxFramework[]
207
+         */
208
+        public static function all_instances(): ?array {
209
+            return Redux_Instances::get_all_instances();
210
+        }
211
+
212
+        /**
213
+         * Load external extensions.
214
+         *
215
+         * @param object $redux_framework ReduxFramework object.
216
+         *
217
+         * @deprecated No longer using camelCase naming conventions.
218
+         */
219
+        public static function loadExtensions( $redux_framework ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
220
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, ' Redux 4.3', 'Redux::load_extensions( $redux_framework )' );
221
+
222
+            self::load_extensions( $redux_framework );
223
+        }
224
+
225
+        /**
226
+         * Load external extensions.
227
+         *
228
+         * @param object $redux_framework ReduxFramework object.
229
+         */
230
+        public static function load_extensions( $redux_framework ) {
231
+            $instance_extensions = self::get_extensions( $redux_framework->args['opt_name'] );
232
+
233
+            if ( $instance_extensions ) {
234
+                foreach ( $instance_extensions as $name => $extension ) {
235
+                    $old_class = str_replace( 'Redux_', 'ReduxFramework_', $extension['class'] );
236
+
237
+                    if ( ! class_exists( $extension['class'] ) && ! class_exists( $old_class ) ) {
238
+                        // In case you wanted to override your override, hah.
239
+                        // Phpcs:ignore WordPress.NamingConventions.ValidHookName
240
+                        $extension['path'] = apply_filters( 'redux/extension/' . $redux_framework->args['opt_name'] . '/' . $name, $extension['path'] );
241
+                        if ( file_exists( $extension['path'] ) ) {
242
+                            require_once $extension['path'];
243
+                        }
244
+                    }
245
+                    if ( isset( $extension['field'] ) ) {
246
+                        require_once $extension['field'];
247
+                    }
248
+
249
+                    if ( ! isset( $redux_framework->extensions[ $name ] ) ) {
250
+                        $field_classes = array( $extension['class'], $old_class );
251
+                        $ext_class     = Redux_Functions::class_exists_ex( $field_classes );
252
+                        if ( false !== $ext_class ) {
253
+                            $redux_framework->extensions[ $name ] = new $ext_class( $redux_framework );
254
+                        } elseif ( is_admin() && true === $redux_framework->args['dev_mode'] ) {
255
+                            echo '<div id="message" class="error"><p>No class named <strong>' . esc_html( $extension['class'] ) . '</strong> exists. Please verify your extension path.</p></div>';
256
+                        }
257
+                    }
258
+                }
259
+            }
260
+        }
261
+
262
+        /**
263
+         * Deprecated function to set an extension path.
264
+         *
265
+         * @param string $extension Path.
266
+         * @param bool   $folder    Set if a path is a folder.
267
+         *
268
+         * @return bool|mixed
269
+         * @deprecated No longer using cameCase naming conventions.
270
+         */
271
+        public static function extensionPath( string $extension, bool $folder = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
272
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::extension_path( $extension, $folder )' );
273
+
274
+            return self::extension_path( $extension, $folder );
275
+        }
276
+
277
+        /**
278
+         * Sets a path to an extension.
279
+         *
280
+         * @param string $extension Path to an extension.
281
+         * @param bool   $folder    Set if a path is a folder.
282
+         *
283
+         * @return bool|mixed
284
+         */
285
+        public static function extension_path( string $extension, bool $folder = true ) {
286
+            if ( ! isset( self::$extensions[ $extension ] ) ) {
287
+                return false;
288
+            }
289
+
290
+            $path = end( self::$extensions[ $extension ] );
291
+
292
+            if ( ! $folder ) {
293
+                return $path;
294
+            }
295
+
296
+            return dirname( $path );
297
+        }
298
+
299
+        /**
300
+         * Deprecated function of Load Redux Framework.
301
+         *
302
+         * @param string $opt_name Panel opt_name.
303
+         *
304
+         * @throws ReflectionException Exception.
305
+         *
306
+         * @deprecated No longer using camelCase naming conventions.
307
+         */
308
+        public static function loadRedux( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
309
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::load_redux( $opt_name )' );
310
+
311
+            self::load_redux( $opt_name );
312
+        }
313
+
314
+        /**
315
+         * Load defaults values for a given opt_name.
316
+         *
317
+         * @param string $opt_name Panel opt_name.
318
+         */
319
+        public static function set_defaults( string $opt_name = '' ) {
320
+            // Try to load the class if in the same directory, so the user only has to include the Redux API.
321
+            if ( ! class_exists( 'Redux_Options_Defaults' ) ) {
322
+                $file_check = trailingslashit( __DIR__ ) . 'class-redux-options-defaults.php';
323
+
324
+                if ( file_exists( dirname( $file_check ) ) ) {
325
+                    include_once $file_check;
326
+                    $file_check = trailingslashit( __DIR__ ) . 'class-redux-wordpress-data.php';
327
+                    if ( file_exists( dirname( $file_check ) ) ) {
328
+                        include_once $file_check;
329
+                    }
330
+                }
331
+            }
332
+
333
+            if ( class_exists( 'Redux_Options_Defaults' ) && ! isset( self::$options_defaults[ $opt_name ] ) ) {
334
+                $sections                            = self::construct_sections( $opt_name );
335
+                $wordpress_data                      = ( ! class_exists( 'Redux_WordPress_Data' ) ) ? null : new Redux_WordPress_Data( $opt_name );
336
+                $options_defaults_class              = new Redux_Options_Defaults();
337
+                self::$options_defaults[ $opt_name ] = $options_defaults_class->default_values( $opt_name, $sections, $wordpress_data );
338
+                if ( ! isset( self::$args[ $opt_name ]['global_variable'] ) || ( '' === self::$args[ $opt_name ]['global_variable'] && false !== self::$args[ $opt_name ]['global_variable'] ) ) {
339
+                    self::$args[ $opt_name ]['global_variable'] = str_replace( '-', '_', $opt_name );
340
+                }
341
+                if ( isset( self::$args[ $opt_name ]['global_variable'] ) && self::$args[ $opt_name ]['global_variable'] ) {
342
+                    $option_global = self::$args[ $opt_name ]['global_variable'];
343
+
344
+                    /**
345
+                     * Filter 'redux/options/{opt_name}/global_variable'
346
+                     *
347
+                     * @param array $value option value to set global_variable with
348
+                     */
349
+                    global $$option_global;
350
+
351
+                    // phpcs:ignore WordPress.NamingConventions.ValidHookName
352
+                    $$option_global = apply_filters( 'redux/options/' . $opt_name . '/global_variable', self::$options_defaults[ $opt_name ] );
353
+                }
354
+            }
355
+        }
356
+
357
+        /**
358
+         * Load Redux Framework.
359
+         *
360
+         * @param string $opt_name Panel opt_name.
361
+         *
362
+         * @throws ReflectionException  Exception.
363
+         */
364
+        public static function load_redux( string $opt_name = '' ) {
365
+            if ( empty( $opt_name ) ) {
366
+                return;
367
+            }
368
+
369
+            if ( class_exists( 'ReduxFramework' ) ) {
370
+                if ( isset( self::$init[ $opt_name ] ) && ! empty( self::$init[ $opt_name ] ) ) {
371
+                    return;
372
+                }
373
+            } else {
374
+                echo '<div id="message" class="error"><p>' . esc_html__( 'Redux Framework is not installed. Please install it.', 'redux-framework' ) . '</p></div>';
375
+
376
+                return;
377
+            }
378
+
379
+            self::instance( $opt_name );
380
+
381
+            Redux_Functions_Ex::record_caller( $opt_name );
382
+
383
+            if ( isset( self::$init[ $opt_name ] ) && 1 === self::$init[ $opt_name ] ) {
384
+                return;
385
+            }
386
+
387
+            // self::set_defaults( $opt_name );
388
+
389
+            $args     = self::construct_args( $opt_name );
390
+            $sections = self::construct_sections( $opt_name );
391
+
392
+            if ( isset( self::$uses_extensions[ $opt_name ] ) && ! empty( self::$uses_extensions[ $opt_name ] ) ) {
393
+                add_action( "redux/extensions/$opt_name/before", array( 'Redux', 'load_extensions' ), 0 );
394
+            }
395
+
396
+            $redux                   = new ReduxFramework( $sections, $args );
397
+            self::$init[ $opt_name ] = 1;
398
+
399
+            if ( isset( $redux->args['opt_name'] ) && $redux->args['opt_name'] !== $opt_name ) {
400
+                self::$init[ $redux->args['opt_name'] ] = 1;
401
+            }
402
+        }
403
+
404
+        /**
405
+         * Deprecated Create Redux instance.
406
+         *
407
+         * @throws ReflectionException  Exception.
408
+         *
409
+         * @deprecated No longer using camelCase naming convention.
410
+         */
411
+        public static function createRedux() {       // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
412
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::createRedux()' );
413
+
414
+            self::create_redux();
415
+        }
416
+
417
+        /**
418
+         * Create Redux instance.
419
+         *
420
+         * @throws ReflectionException  Exception.
421
+         */
422
+        public static function create_redux() {
423
+            foreach ( self::$sections as $opt_name => $the_sections ) {
424
+                if ( ! empty( $the_sections ) ) {
425
+                    if ( ! self::$init[ $opt_name ] ) {
426
+                        self::load_redux( $opt_name );
427
+                    }
428
+                }
429
+            }
430
+        }
431
+
432
+        /**
433
+         * Construct global arguments.
434
+         *
435
+         * @param string $opt_name Panel opt_name.
436
+         *
437
+         * @return array|mixed
438
+         */
439
+        public static function construct_args( string $opt_name ) {
440
+            $args             = self::$args[ $opt_name ] ?? array();
441
+            $args['opt_name'] = $opt_name;
442
+
443
+            if ( ! isset( $args['menu_title'] ) ) {
444
+                $args['menu_title'] = ucfirst( $opt_name ) . ' Options';
445
+            }
446
+
447
+            if ( ! isset( $args['page_title'] ) ) {
448
+                $args['page_title'] = ucfirst( $opt_name ) . ' Options';
449
+            }
450
+
451
+            if ( ! isset( $args['page_slug'] ) ) {
452
+                $args['page_slug'] = $opt_name . '_options';
453
+            }
454
+
455
+            return $args;
456
+        }
457
+
458
+        /**
459
+         * Construct option panel sections.
460
+         *
461
+         * @param string $opt_name Panel opt_name.
462
+         *
463
+         * @return array
464
+         */
465
+        public static function construct_sections( string $opt_name ): array {
466
+            $sections = array();
467
+
468
+            if ( ! isset( self::$sections[ $opt_name ] ) ) {
469
+                return $sections;
470
+            }
471
+
472
+            foreach ( self::$sections[ $opt_name ] as $section_id => $section ) {
473
+                $section['fields'] = self::construct_fields( $opt_name, $section_id );
474
+                $p                 = $section['priority'];
475
+
476
+                while ( isset( $sections[ $p ] ) ) {
477
+                    ++$p;
478
+                }
479
+
480
+                $sections[ $p ] = $section;
481
+            }
482
+
483
+            ksort( $sections );
484
+
485
+            return $sections;
486
+        }
487
+
488
+        /**
489
+         * Construct option panel fields.
490
+         *
491
+         * @param string $opt_name   Panel opt_name.
492
+         * @param string $section_id ID of a section.
493
+         *
494
+         * @return array
495
+         */
496
+        public static function construct_fields( string $opt_name = '', string $section_id = '' ): array {
497
+            $fields = array();
498
+
499
+            if ( ! empty( self::$fields[ $opt_name ] ) ) {
500
+                foreach ( self::$fields[ $opt_name ] as $field ) {
501
+                    if ( $field['section_id'] === $section_id ) {
502
+                        $p = esc_html( $field['priority'] );
503
+
504
+                        while ( isset( $fields[ $p ] ) ) {
505
+                            echo intval( $p++ );
506
+                        }
507
+
508
+                        $fields[ $p ] = $field;
509
+                    }
510
+                }
511
+            }
512
+
513
+            ksort( $fields );
514
+
515
+            return $fields;
516
+        }
517
+
518
+        /**
519
+         * Deprecated Retrieve panel section.
520
+         *
521
+         * @param string $opt_name Panel opt_name.
522
+         * @param string $id       Section ID.
523
+         *
524
+         * @return bool
525
+         * @deprecated No longer using camelCase naming convention.
526
+         */
527
+        public static function getSection( string $opt_name = '', string $id = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
528
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_section( $opt_name, $id )' );
529
+
530
+            return self::get_section( $opt_name, $id );
531
+        }
532
+
533
+        /**
534
+         * Retrieve panel section.
535
+         *
536
+         * @param string     $opt_name Panel opt_name.
537
+         * @param string|int $id       Section ID.
538
+         *
539
+         * @return bool|string|int
540
+         */
541
+        public static function get_section( string $opt_name = '', $id = '' ) {
542
+            self::check_opt_name( $opt_name );
543
+
544
+            if ( ! empty( $opt_name ) && ! empty( $id ) ) {
545
+                if ( ! isset( self::$sections[ $opt_name ][ $id ] ) ) {
546
+                    $id = Redux_Core::strtolower( sanitize_html_class( $id ) );
547
+                }
548
+
549
+                return self::$sections[ $opt_name ][ $id ] ?? false;
550
+            }
551
+
552
+            return false;
553
+        }
554
+
555
+        /**
556
+         * Deprecated Create a section of the option panel.
557
+         *
558
+         * @param string $opt_name Panel opt_name.
559
+         * @param array  $sections Section ID.
560
+         *
561
+         * @deprecated No longer using camelCase naming convention.
562
+         */
563
+        public static function setSections( string $opt_name = '', array $sections = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
564
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_sections( $opt_name, $sections )' );
565
+
566
+            if ( '' !== $opt_name ) {
567
+                Redux_Functions_Ex::record_caller( $opt_name );
568
+            }
569
+
570
+            self::set_sections( $opt_name, $sections );
571
+        }
572
+
573
+        /**
574
+         * Create multiple sections of the option panel.
575
+         *
576
+         * @param string $opt_name Panel opt_name.
577
+         * @param array  $sections Section ID.
578
+         */
579
+        public static function set_sections( string $opt_name = '', array $sections = array() ) {
580
+            if ( empty( $sections ) || '' === $opt_name ) {
581
+                return;
582
+            }
583
+
584
+            self::check_opt_name( $opt_name );
585
+
586
+            Redux_Functions_Ex::record_caller( $opt_name );
587
+
588
+            foreach ( $sections as $section ) {
589
+                self::set_section( $opt_name, $section );
590
+            }
591
+        }
592
+
593
+        /**
594
+         * Deprecated Retrieve all sections from the option panel.
595
+         *
596
+         * @param string $opt_name Panel opt_name.
597
+         *
598
+         * @return array|mixed
599
+         * @deprecated No longer using camelCase naming convention.
600
+         */
601
+        public static function getSections( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
602
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_sections( $opt_name )' );
603
+
604
+            return self::get_sections( $opt_name );
605
+        }
606
+
607
+        /**
608
+         * Retrieve all sections from the option panel.
609
+         *
610
+         * @param string $opt_name Panel opt_name.
611
+         *
612
+         * @return array|mixed
613
+         */
614
+        public static function get_sections( string $opt_name = '' ) {
615
+            self::check_opt_name( $opt_name );
616
+
617
+            if ( ! empty( self::$sections[ $opt_name ] ) ) {
618
+                return self::$sections[ $opt_name ];
619
+            }
620
+
621
+            return array();
622
+        }
623
+
624
+        /**
625
+         * Deprecated Remove option panel by ID.
626
+         *
627
+         * @param string     $opt_name Panel opt_name.
628
+         * @param string|int $id       Section ID.
629
+         * @param bool       $fields   Remove fields.
630
+         *
631
+         * @deprecated No longer using camelCase naming convention.
632
+         */
633
+        public static function removeSection( string $opt_name = '', $id = '', bool $fields = false ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
634
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::remove_section( $opt_name, $id )' );
635
+
636
+            if ( '' !== $opt_name ) {
637
+                Redux_Functions_Ex::record_caller( $opt_name );
638
+            }
639
+
640
+            self::remove_section( $opt_name, $id, $fields );
641
+        }
642
+
643
+        /**
644
+         * Remove an option panel by ID.
645
+         *
646
+         * @param string     $opt_name Panel opt_name.
647
+         * @param string|int $id       Section ID.
648
+         * @param bool       $fields   Remove fields.
649
+         */
650
+        public static function remove_section( string $opt_name = '', $id = '', bool $fields = false ) {
651
+            if ( '' !== $opt_name && '' !== $id ) {
652
+                Redux_Functions_Ex::record_caller( $opt_name );
653
+
654
+                if ( isset( self::$sections[ $opt_name ][ $id ] ) ) {
655
+                    $priority = '';
656
+
657
+                    foreach ( self::$sections[ $opt_name ] as $key => $section ) {
658
+                        if ( $key === $id ) {
659
+                            $priority = $section['priority'];
660
+                            --self::$priority[ $opt_name ]['sections'];
661
+                            unset( self::$sections[ $opt_name ][ $id ] );
662
+                            continue;
663
+                        }
664
+                        if ( '' !== $priority ) {
665
+                            $new_priority                        = $section['priority'];
666
+                            $section['priority']                 = $priority;
667
+                            self::$sections[ $opt_name ][ $key ] = $section;
668
+                            $priority                            = $new_priority;
669
+                        }
670
+                    }
671
+
672
+                    if ( isset( self::$fields[ $opt_name ] ) && ! empty( self::$fields[ $opt_name ] ) && true === $fields ) {
673
+                        foreach ( self::$fields[ $opt_name ] as $key => $field ) {
674
+                            if ( $field['section_id'] === $id ) {
675
+                                unset( self::$fields[ $opt_name ][ $key ] );
676
+                            }
677
+                        }
678
+                    }
679
+                }
680
+            }
681
+        }
682
+
683
+        /**
684
+         * Deprecated Sets a single option panel section.
685
+         *
686
+         * @param string     $opt_name Panel opt_name.
687
+         * @param array|null $section  Section data.
688
+         *
689
+         * @deprecated No longer using camelCase naming convention.
690
+         */
691
+        public static function setSection( string $opt_name = '', ?array $section = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
692
+            // phpcs:ignore Squiz.PHP.CommentedOutCode.Found
693
+            // _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_section( $opt_name, $section )' );
694
+
695
+            if ( '' !== $opt_name ) {
696
+                Redux_Functions_Ex::record_caller( $opt_name );
697
+            }
698
+
699
+            self::set_section( $opt_name, $section );
700
+        }
701
+
702
+        /**
703
+         * Sets a single option panel section.
704
+         *
705
+         * @param string     $opt_name Panel opt_name.
706
+         * @param array|null $section  Section data.
707
+         * @param bool       $replace  Replaces a section instead of creating a new one.
708
+         */
709
+        public static function set_section( string $opt_name = '', ?array $section = array(), bool $replace = false ) {
710
+
711
+            if ( empty( $section ) || '' === $opt_name ) {
712
+                return;
713
+            }
714
+
715
+            self::check_opt_name( $opt_name );
716
+
717
+            Redux_Functions_Ex::record_caller( $opt_name );
718
+
719
+            if ( ! isset( $section['id'] ) ) {
720
+                if ( isset( $section['type'] ) && 'divide' === $section['type'] ) {
721
+                    $section['id'] = time();
722
+                } elseif ( isset( $section['title'] ) ) {
723
+                        $section['id'] = Redux_Core::strtolower( sanitize_title( $section['title'] ) );
724
+                } else {
725
+                    $section['id'] = time();
726
+                }
727
+
728
+                if ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) && ! $replace ) {
729
+                    $orig = $section['id'];
730
+                    $i    = 0;
731
+
732
+                    while ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) ) {
733
+                        $section['id'] = $orig . '_' . $i;
734
+                        ++$i;
735
+                    }
736
+                } elseif ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) && $replace ) {
737
+                    // If replace is set, let's update the default values with these!
738
+                    $fields = false;
739
+                    if ( isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) && ! empty( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) ) {
740
+                        $fields = self::$sections[ $opt_name ][ $section['id'] ]['fields'];
741
+                    }
742
+                    self::$sections[ $opt_name ][ $section['id'] ] = wp_parse_args( $section, self::$sections[ $opt_name ][ $section['id'] ] );
743
+                    if ( ! empty( $fields ) ) {
744
+                        if ( ! isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) || ( isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) && empty( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) ) ) {
745
+                            self::$sections[ $opt_name ][ $section['id'] ]['fields'] = $fields;
746
+                        }
747
+                    }
748
+                }
749
+            }
750
+
751
+            if ( ! empty( $opt_name ) && is_array( $section ) && ! empty( $section ) ) {
752
+                if ( ! isset( $section['id'] ) && ! isset( $section['title'] ) ) {
753
+                    self::$errors[ $opt_name ]['section']['missing_title'] = esc_html__( 'Unable to create a section due to missing id and title.', 'redux-framework' );
754
+
755
+                    return;
756
+                }
757
+
758
+                if ( ! isset( $section['priority'] ) ) {
759
+                    $section['priority'] = self::get_priority( $opt_name, 'sections' );
760
+                }
761
+
762
+                if ( isset( $section['fields'] ) ) {
763
+                    if ( ! empty( $section['fields'] ) && is_array( $section['fields'] ) ) {
764
+                        self::process_field_array( $opt_name, $section['id'], $section['fields'] );
765
+                    }
766
+                    unset( $section['fields'] );
767
+                }
768
+                self::$sections[ $opt_name ][ $section['id'] ] = $section;
769
+            } else {
770
+                self::$errors[ $opt_name ]['section']['empty'] = esc_html__( 'Unable to create a section due an empty section array or the section variable passed was not an array.', 'redux-framework' );
771
+            }
772
+        }
773
+
774
+        /**
775
+         * Deprecated Hides an option panel section.
776
+         *
777
+         * @param string     $opt_name Panel opt_name.
778
+         * @param string|int $id       Section ID.
779
+         * @param bool       $hide     Flag to hide/show.
780
+         *
781
+         * @deprecated No longer using camelCase naming convention.
782
+         */
783
+        public static function hideSection( string $opt_name = '', $id = '', bool $hide = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
784
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::hide_section( $opt_name, $id )' );
785
+
786
+            if ( '' !== $opt_name ) {
787
+                Redux_Functions_Ex::record_caller( $opt_name );
788
+            }
789
+
790
+            self::hide_section( $opt_name, $id, $hide );
791
+        }
792
+
793
+        /**
794
+         * Hides an option panel section.
795
+         *
796
+         * @param string     $opt_name Panel opt_name.
797
+         * @param string|int $id       Section ID.
798
+         * @param bool       $hide     Flag to hide/show.
799
+         */
800
+        public static function hide_section( string $opt_name = '', $id = '', bool $hide = true ) {
801
+            self::check_opt_name( $opt_name );
802
+
803
+            if ( '' !== $opt_name && '' !== $id ) {
804
+                Redux_Functions_Ex::record_caller( $opt_name );
805
+
806
+                if ( isset( self::$sections[ $opt_name ][ $id ] ) ) {
807
+                    self::$sections[ $opt_name ][ $id ]['hidden'] = $hide;
808
+                }
809
+            }
810
+        }
811
+
812
+        /**
813
+         * Compiles field array data.
814
+         *
815
+         * @param string     $opt_name   Panel opt_name.
816
+         * @param string|int $section_id Section ID.
817
+         * @param array      $fields     Field data.
818
+         */
819
+        private static function process_field_array( string $opt_name = '', $section_id = '', array $fields = array() ) {
820
+            if ( ! empty( $opt_name ) && ! empty( $section_id ) && is_array( $fields ) && ! empty( $fields ) ) {
821
+                foreach ( $fields as $field ) {
822
+                    if ( ! is_array( $field ) ) {
823
+                        continue;
824
+                    }
825
+                    self::set_field( $opt_name, $section_id, $field );
826
+                }
827
+            }
828
+        }
829
+
830
+        /**
831
+         * Deprecated Retrieves an option panel field.
832
+         *
833
+         * @param string     $opt_name Panel opt_name.
834
+         * @param string|int $id       Field ID.
835
+         *
836
+         * @return int|bool
837
+         * @deprecated No longer using camelCase naming convention.
838
+         */
839
+        public static function getField( string $opt_name = '', $id = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
840
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_field( $opt_name, $id )' );
841
+
842
+            return self::get_field( $opt_name, $id );
843
+        }
844
+
845
+        /**
846
+         * Retrieves an option panel field.
847
+         *
848
+         * @param string     $opt_name Panel opt_name.
849
+         * @param string|int $id       Field ID.
850
+         *
851
+         * @return int|bool
852
+         */
853
+        public static function get_field( string $opt_name = '', $id = '' ) {
854
+            self::check_opt_name( $opt_name );
855
+
856
+            if ( ! empty( $opt_name ) && ! empty( $id ) ) {
857
+                return self::$fields[ $opt_name ][ $id ] ?? false;
858
+            }
859
+
860
+            return false;
861
+        }
862
+
863
+        /**
864
+         * Deprecated Hides an option panel field.
865
+         *
866
+         * @param string     $opt_name Panel opt_name.
867
+         * @param string|int $id       Field ID.
868
+         * @param bool       $hide     Set hide/show.
869
+         *
870
+         * @deprecated No longer using camelCase naming convention.
871
+         */
872
+        public static function hideField( string $opt_name = '', $id = '', bool $hide = true ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
873
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::hide_field( $opt_name, $id )' );
874
+
875
+            if ( '' !== $opt_name ) {
876
+                Redux_Functions_Ex::record_caller( $opt_name );
877
+            }
878
+
879
+            self::hide_field( $opt_name, $id, $hide );
880
+        }
881
+
882
+        /**
883
+         * Hides an option panel field.
884
+         *
885
+         * @param string     $opt_name Panel opt_name.
886
+         * @param string|int $id       Field ID.
887
+         * @param bool       $hide     Set hide/show.
888
+         */
889
+        public static function hide_field( string $opt_name = '', $id = '', bool $hide = true ) {
890
+            self::check_opt_name( $opt_name );
891
+
892
+            if ( '' !== $opt_name && '' !== $id ) {
893
+                if ( isset( self::$fields[ $opt_name ][ $id ] ) ) {
894
+                    Redux_Functions_Ex::record_caller( $opt_name );
895
+
896
+                    if ( ! $hide ) {
897
+                        self::$fields[ $opt_name ][ $id ]['class'] = str_replace( 'hidden', '', self::$fields[ $opt_name ][ $id ]['class'] );
898
+                    } else {
899
+                        self::$fields[ $opt_name ][ $id ]['class'] .= 'hidden';
900
+                    }
901
+                }
902
+            }
903
+        }
904
+
905
+        /**
906
+         * Deprecated Creates an option panel field.
907
+         *
908
+         * @param string     $opt_name   Panel opt_name.
909
+         * @param string|int $section_id Section ID this field belongs to.
910
+         * @param array      $field      Field data.
911
+         *
912
+         * @deprecated No longer using camelCase naming convention.
913
+         */
914
+        public static function setField( string $opt_name = '', $section_id = '', array $field = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
915
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_field( $opt_name, $section_id, $field )' );
916
+
917
+            if ( '' !== $opt_name ) {
918
+                Redux_Functions_Ex::record_caller( $opt_name );
919
+            }
920
+
921
+            self::set_field( $opt_name, $section_id, $field );
922
+        }
923
+
924
+        /**
925
+         * Creates an option panel field and adds to a section.
926
+         *
927
+         * @param string     $opt_name   Panel opt_name.
928
+         * @param string|int $section_id Section ID this field belongs to.
929
+         * @param array      $field      Field data.
930
+         */
931
+        public static function set_field( string $opt_name = '', $section_id = '', array $field = array() ) {
932
+
933
+            if ( ! is_array( $field ) || empty( $field ) || '' === $opt_name || '' === $section_id ) {
934
+                return;
935
+            }
936
+
937
+            self::check_opt_name( $opt_name );
938
+
939
+            Redux_Functions_Ex::record_caller( $opt_name );
940
+
941
+            // Shim for the old method!
942
+            if ( is_array( $section_id ) ) {
943
+                $field = $section_id;
944
+                if ( isset( $field['section_id'] ) ) {
945
+                    $section_id = $field['section_id'];
946
+                }
947
+            }
948
+
949
+            $field['section_id'] = $section_id;
950
+
951
+            if ( ! isset( $field['priority'] ) ) {
952
+                $field['priority'] = self::get_priority( $opt_name, 'fields' );
953
+            }
954
+            $field['id'] = $field['id'] ?? "{$opt_name}_{$section_id}_{$field['type']}_" . wp_rand( 1, 9999 );
955
+
956
+            self::$fields[ $opt_name ][ $field['id'] ] = $field;
957
+        }
958
+
959
+        /**
960
+         * Create multiple fields of the option panel and apply to a section.
961
+         *
962
+         * @param string     $opt_name   Panel opt_name.
963
+         * @param int|string $section_id Section ID this field belongs to.
964
+         * @param array      $fields     Array of field arrays.
965
+         */
966
+        public static function set_fields( string $opt_name = '', $section_id = '', array $fields = array() ) {
967
+            if ( ! is_array( $fields ) || empty( $fields ) || '' === $opt_name || '' === $section_id ) {
968
+                return;
969
+            }
970
+
971
+            self::check_opt_name( $opt_name );
972
+
973
+            // phpcs:ignore WordPress.PHP.DevelopmentFunctions
974
+            Redux_Functions_Ex::record_caller( $opt_name );
975
+
976
+            foreach ( $fields as $field ) {
977
+                if ( is_array( $field ) ) {
978
+                    self::set_field( $opt_name, $section_id, $field );
979
+                }
980
+            }
981
+        }
982
+
983
+        /**
984
+         * Deprecated Removes an option panel field.
985
+         *
986
+         * @param string     $opt_name Panel opt_name.
987
+         * @param string|int $id       Field ID.
988
+         *
989
+         * @return bool
990
+         * @deprecated No longer using camelCase naming convention.
991
+         */
992
+        public static function removeField( string $opt_name = '', $id = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
993
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::remove_field( $opt_name, $id )' );
994
+
995
+            if ( '' !== $opt_name ) {
996
+                Redux_Functions_Ex::record_caller( $opt_name );
997
+            }
998
+
999
+            return self::remove_field( $opt_name, $id );
1000
+        }
1001
+
1002
+        /**
1003
+         * Removes an option panel field.
1004
+         *
1005
+         * @param string     $opt_name Panel opt_name.
1006
+         * @param string|int $id       Field ID.
1007
+         *
1008
+         * @return bool
1009
+         */
1010
+        public static function remove_field( string $opt_name = '', $id = '' ): bool {
1011
+            if ( '' !== $opt_name && '' !== $id ) {
1012
+                self::check_opt_name( $opt_name );
1013
+
1014
+                Redux_Functions_Ex::record_caller( $opt_name );
1015
+
1016
+                if ( isset( self::$fields[ $opt_name ][ $id ] ) ) {
1017
+                    foreach ( self::$fields[ $opt_name ] as $key => $field ) {
1018
+                        if ( $key === $id ) {
1019
+                            $priority = $field['priority'];
1020
+                            --self::$priority[ $opt_name ]['fields'];
1021
+                            unset( self::$fields[ $opt_name ][ $id ] );
1022
+                            continue;
1023
+                        }
1024
+
1025
+                        if ( isset( $priority ) && '' !== $priority ) {
1026
+                            $new_priority                      = $field['priority'];
1027
+                            $field['priority']                 = $priority;
1028
+                            self::$fields[ $opt_name ][ $key ] = $field;
1029
+                            $priority                          = $new_priority;
1030
+                        }
1031
+                    }
1032
+                }
1033
+            }
1034
+
1035
+            return false;
1036
+        }
1037
+
1038
+        /**
1039
+         * Deprecated Sets help tabs on option panel admin page.
1040
+         *
1041
+         * @param string $opt_name Panel opt_name.
1042
+         * @param array  $tab      Tab data.
1043
+         *
1044
+         * @deprecated No longer using camelCase naming convention.
1045
+         */
1046
+        public static function setHelpTab( string $opt_name = '', array $tab = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1047
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_help_tab( $opt_name, $tab )' );
1048
+
1049
+            self::set_help_tab( $opt_name, $tab );
1050
+        }
1051
+
1052
+        /**
1053
+         * Sets help tabs on option panel admin page.
1054
+         *
1055
+         * @param string $opt_name Panel opt_name.
1056
+         * @param array  $tab      Tab data.
1057
+         */
1058
+        public static function set_help_tab( string $opt_name = '', array $tab = array() ) {
1059
+            if ( ! is_array( $tab ) && empty( $tab ) ) {
1060
+                return;
1061
+            }
1062
+
1063
+            self::check_opt_name( $opt_name );
1064
+
1065
+            if ( '' !== $opt_name ) {
1066
+                if ( ! isset( self::$args[ $opt_name ]['help_tabs'] ) ) {
1067
+                    self::$args[ $opt_name ]['help_tabs'] = array();
1068
+                }
1069
+
1070
+                if ( isset( $tab['id'] ) ) {
1071
+                    self::$args[ $opt_name ]['help_tabs'][] = $tab;
1072
+                } elseif ( is_array( end( $tab ) ) ) {
1073
+                    foreach ( $tab as $tab_item ) {
1074
+                        self::$args[ $opt_name ]['help_tabs'][] = $tab_item;
1075
+                    }
1076
+                }
1077
+            }
1078
+        }
1079
+
1080
+        /**
1081
+         * Deprecated Sets the help sidebar content.
1082
+         *
1083
+         * @param string $opt_name Panel opt_name.
1084
+         * @param string $content  Content.
1085
+         *
1086
+         * @deprecated No longer using camelCase naming convention.
1087
+         */
1088
+        public static function setHelpSidebar( string $opt_name = '', string $content = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1089
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_help_sidebar( $opt_name, $content )' );
1090
+
1091
+            self::set_help_sidebar( $opt_name, $content );
1092
+        }
1093
+
1094
+        /**
1095
+         * Sets the help sidebar content.
1096
+         *
1097
+         * @param string $opt_name Panel opt_name.
1098
+         * @param string $content  Content.
1099
+         */
1100
+        public static function set_help_sidebar( string $opt_name = '', string $content = '' ) {
1101
+            if ( '' === $content || '' === $opt_name ) {
1102
+                return;
1103
+            }
1104
+            self::check_opt_name( $opt_name );
1105
+
1106
+            self::$args[ $opt_name ]['help_sidebar'] = $content;
1107
+        }
1108
+
1109
+        /**
1110
+         * Deprecated Sets option panel global arguments.
1111
+         *
1112
+         * @param string $opt_name Panel opt_name.
1113
+         * @param array  $args     Argument data.
1114
+         *
1115
+         * @deprecated No longer using camelCase naming convention.
1116
+         */
1117
+        public static function setArgs( string $opt_name = '', array $args = array() ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1118
+            // phpcs:ignore Squiz.PHP.CommentedOutCode.Found
1119
+            // _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_args( $opt_name, $args )' );
1120
+
1121
+            if ( '' !== $opt_name ) {
1122
+                Redux_Functions_Ex::record_caller( $opt_name );
1123
+            }
1124
+
1125
+            self::set_args( $opt_name, $args );
1126
+        }
1127
+
1128
+        /**
1129
+         * Sets option panel global arguments.
1130
+         *
1131
+         * @param string $opt_name Panel opt_name.
1132
+         * @param array  $args     Argument data.
1133
+         */
1134
+        public static function set_args( string $opt_name = '', array $args = array() ) {
1135
+            if ( empty( $args ) || '' === $opt_name ) {
1136
+                return;
1137
+            }
1138
+
1139
+            self::check_opt_name( $opt_name );
1140
+
1141
+            Redux_Functions_Ex::record_caller( $opt_name );
1142
+
1143
+            if ( is_array( $args ) ) {
1144
+                if ( isset( self::$args[ $opt_name ]['clearArgs'] ) ) {
1145
+                    self::$args[ $opt_name ] = array();
1146
+                }
1147
+                self::$args[ $opt_name ] = wp_parse_args( $args, self::$args[ $opt_name ] );
1148
+            }
1149
+        }
1150
+
1151
+        /**
1152
+         * Set's developer key for premium services.
1153
+         *
1154
+         * @param string       $opt_name Panel opt_name.
1155
+         * @param string|array $arg      Args data.
1156
+         */
1157
+        public static function set_developer( string $opt_name = '', $arg = '' ) {
1158
+            if ( empty( $arg ) || '' === $opt_name ) {
1159
+                return;
1160
+            }
1161
+
1162
+            self::check_opt_name( $opt_name );
1163
+
1164
+            Redux_Functions_Ex::record_caller( $opt_name );
1165
+
1166
+            self::$args[ $opt_name ]['developer'] = $arg;
1167
+        }
1168
+
1169
+        /**
1170
+         * Deprecated Retries option panel global argument array.
1171
+         *
1172
+         * @param string $opt_name Panel opt_name.
1173
+         *
1174
+         * @return mixed
1175
+         * @deprecated No longer camelCase naming convention.
1176
+         */
1177
+        public static function getArgs( string $opt_name = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1178
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_args( $opt_name )' );
1179
+
1180
+            return self::get_args( $opt_name );
1181
+        }
1182
+
1183
+        /**
1184
+         * Retries option panel global argument array.
1185
+         *
1186
+         * @param string $opt_name Panel opt_name.
1187
+         * @param string $key      Argument key name to be returned.
1188
+         *
1189
+         * @return mixed|null|array
1190
+         */
1191
+        public static function get_args( string $opt_name = '', string $key = '' ) {
1192
+            self::check_opt_name( $opt_name );
1193
+
1194
+            if ( ! empty( $opt_name ) && ! empty( $key ) ) {
1195
+                if ( ! empty( self::$args[ $opt_name ] ) ) {
1196
+                    return self::$args[ $opt_name ][ $key ];
1197
+                } else {
1198
+                    return null;
1199
+                }
1200
+            } elseif ( ! empty( $opt_name ) && ! empty( self::$args[ $opt_name ] ) ) {
1201
+                return self::$args[ $opt_name ];
1202
+            }
1203
+
1204
+            return null;
1205
+        }
1206
+
1207
+        /**
1208
+         * Deprecated Retrieves a single global argument.
1209
+         *
1210
+         * @param string $opt_name Panel opt_name.
1211
+         * @param string $key      Argument name.
1212
+         *
1213
+         * @return mixed
1214
+         * @deprecated No longer using camelCase naming convention and using singular function self::get_args() now.
1215
+         */
1216
+        public static function getArg( string $opt_name = '', string $key = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1217
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_arg( $opt_name, $key )' );
1218
+
1219
+            return self::get_args( $opt_name, $key );
1220
+        }
1221
+
1222
+        /**
1223
+         * Retrieves a single global argument.
1224
+         *
1225
+         * @param string $opt_name Panel opt_name.
1226
+         * @param string $key      Argument name.
1227
+         *
1228
+         * @return mixed|array|null
1229
+         */
1230
+        public static function get_arg( string $opt_name = '', string $key = '' ) {
1231
+            self::check_opt_name( $opt_name );
1232
+
1233
+            if ( ! empty( $opt_name ) && ! empty( $key ) && ! empty( self::$args[ $opt_name ] ) ) {
1234
+                return self::$args[ $opt_name ][ $key ];
1235
+            } else {
1236
+                return null;
1237
+            }
1238
+        }
1239
+
1240
+        /**
1241
+         * Deprecated Retrieves a single option from the database.
1242
+         *
1243
+         * @param string       $opt_name Panel opt_name.
1244
+         * @param string       $key      Option key.
1245
+         * @param string|array $defaults  Default value.
1246
+         *
1247
+         * @return mixed
1248
+         * @deprecated No longer using camelCase naming convention.
1249
+         */
1250
+        public static function getOption( string $opt_name = '', string $key = '', $defaults = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1251
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_option( $opt_name, $key, $default )' );
1252
+
1253
+            return self::get_option( $opt_name, $key, $defaults );
1254
+        }
1255
+
1256
+        /**
1257
+         * Retrieves meta for a given post page, IE WordPress meta values
1258
+         *
1259
+         * @param string $opt_name Panel opt_name.
1260
+         * @param mixed  $the_post Post object to denote the current post, or custom.
1261
+         * @param string $key      Option key.
1262
+         * @param mixed  $defaults Default value.
1263
+         *
1264
+         * @return mixed
1265
+         */
1266
+        public static function get_post_meta( string $opt_name = '', $the_post = array(), string $key = '', $defaults = null ) {
1267
+            self::check_opt_name( $opt_name );
1268
+
1269
+            if ( empty( $opt_name ) ) {
1270
+                return null;
1271
+            }
1272
+
1273
+            global $post;
1274
+
1275
+            $redux = ReduxFrameworkInstances::get_instance( $opt_name );
1276
+
1277
+            $metaboxes = $redux->extensions['metaboxes'];
1278
+
1279
+            if ( null === $defaults || '' === $defaults ) {
1280
+                $defaults = self::get_option( $opt_name, $key );
1281
+            }
1282
+
1283
+            if ( isset( $the_post ) && is_array( $the_post ) ) {
1284
+                $the_post = $post;
1285
+            } elseif ( ! isset( $the_post ) || 0 === $the_post ) {
1286
+                return $defaults;
1287
+            } elseif ( is_numeric( $the_post ) ) {
1288
+                $the_post = get_post( $the_post );
1289
+            } elseif ( ! is_object( $the_post ) ) {
1290
+                $the_post = $post;
1291
+            }
1292
+
1293
+            $defaults = self::get_option( $opt_name, $key );
1294
+
1295
+            return $metaboxes->get_values( $the_post, $key, $defaults );
1296
+        }
1297
+
1298
+        /**
1299
+         * Retrieves a single option from the database.
1300
+         *
1301
+         * @param string $opt_name Panel opt_name.
1302
+         * @param string $key      Option key.
1303
+         * @param mixed  $default  Default value.
1304
+         *
1305
+         * @return mixed
1306
+         */
1307
+        public static function get_option( string $opt_name = '', string $key = '', $default = null ) { // phpcs:ignore Universal.NamingConventions
1308
+            self::check_opt_name( $opt_name );
1309
+
1310
+            if ( ! empty( $opt_name ) && ! empty( $key ) ) {
1311
+                global $$opt_name;
1312
+
1313
+                if ( empty( $$opt_name ) ) {
1314
+                    $values    = get_option( $opt_name );
1315
+                    $$opt_name = $values;
1316
+                } else {
1317
+                    $values = $$opt_name;
1318
+                }
1319
+
1320
+                if ( ! isset( $values[ $key ] ) ) {
1321
+                    if ( null === $default ) {
1322
+                        $field = self::get_field( $opt_name, $key );
1323
+
1324
+                        if ( false !== $field ) {
1325
+                            $defaults_class = new Redux_Options_Defaults();
1326
+                            $sections       = self::construct_sections( $opt_name );
1327
+                            $defaults       = $defaults_class->default_values( $opt_name, $sections );
1328
+
1329
+                            if ( isset( $defaults[ $key ] ) ) {
1330
+                                $default = $defaults[ $key ];
1331
+                            }
1332
+                        }
1333
+                    }
1334
+                }
1335
+
1336
+                if ( ! empty( $subkeys ) && is_array( $subkeys ) ) {
1337
+                    $value = $default;
1338
+
1339
+                    if ( isset( $values[ $key ] ) ) {
1340
+                        $count = count( $subkeys );
1341
+
1342
+                        if ( 1 === $count ) {
1343
+                            $value = $values[ $key ][ $subkeys[1] ] ?? $default;
1344
+                        } elseif ( 2 === $count ) {
1345
+                            if ( isset( $values[ $key ][ $subkeys[1] ] ) ) {
1346
+                                $value = $values[ $key ][ $subkeys[1] ][ $subkeys[2] ] ?? $default;
1347
+                            }
1348
+                        } elseif ( 3 === $count ) {
1349
+                            if ( isset( $values[ $key ][ $subkeys[1] ] ) ) {
1350
+                                if ( isset( $values[ $key ][ $subkeys[1] ][ $subkeys[2] ] ) ) {
1351
+                                    $value = $values[ $key ][ $subkeys[1] ][ $subkeys[2] ][ $subkeys[3] ] ?? $default;
1352
+                                }
1353
+                            }
1354
+                        }
1355
+                    }
1356
+                } else {
1357
+                    $value = $values[ $key ] ?? $default;
1358
+                }
1359
+
1360
+                return $value;
1361
+            } else {
1362
+                return false;
1363
+            }
1364
+        }
1365
+
1366
+        /**
1367
+         * Deprecated Sets an option into the database.
1368
+         *
1369
+         * @param string $opt_name Panel opt_name.
1370
+         * @param string $key      Option key.
1371
+         * @param mixed  $option   Option value.
1372
+         *
1373
+         * @return bool
1374
+         * @deprecated No longer using camelCase naming convention.
1375
+         */
1376
+        public static function setOption( string $opt_name = '', string $key = '', $option = '' ): bool { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1377
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::set_option( $opt_name, $key, $option )' );
1378
+
1379
+            if ( '' !== $opt_name ) {
1380
+                Redux_Functions_Ex::record_caller( $opt_name );
1381
+            }
1382
+
1383
+            return self::set_option( $opt_name, $key, $option );
1384
+        }
1385
+
1386
+        /**
1387
+         * Sets an option into the database.
1388
+         *
1389
+         * @param string $opt_name Panel opt_name.
1390
+         * @param string $key      Option key.
1391
+         * @param mixed  $option   Option value.
1392
+         *
1393
+         * @return bool
1394
+         */
1395
+        public static function set_option( string $opt_name = '', string $key = '', $option = '' ): bool {
1396
+            if ( '' === $key ) {
1397
+                return false;
1398
+            }
1399
+
1400
+            self::check_opt_name( $opt_name );
1401
+
1402
+            Redux_Functions_Ex::record_caller( $opt_name );
1403
+
1404
+            if ( '' !== $opt_name ) {
1405
+                $redux         = get_option( $opt_name );
1406
+                $redux[ $key ] = $option;
1407
+
1408
+                return update_option( $opt_name, $redux );
1409
+            } else {
1410
+                return false;
1411
+            }
1412
+        }
1413
+
1414
+        /**
1415
+         * Get the next available priority for field/section.
1416
+         *
1417
+         * @param string $opt_name Panel opt_name.
1418
+         * @param string $type     Field or section.
1419
+         *
1420
+         * @return mixed
1421
+         */
1422
+        public static function get_priority( string $opt_name, string $type ) {
1423
+            $priority                              = self::$priority[ $opt_name ][ $type ];
1424
+            self::$priority[ $opt_name ][ $type ] += 1;
1425
+
1426
+            return $priority;
1427
+        }
1428
+
1429
+        /**
1430
+         * Check opt_name integrity.
1431
+         *
1432
+         * @param string $opt_name Panel opt_name.
1433
+         */
1434
+        public static function check_opt_name( string $opt_name = '' ) {
1435
+            if ( empty( $opt_name ) || is_array( $opt_name ) ) {
1436
+                return;
1437
+            }
1438
+
1439
+            if ( ! isset( self::$sections[ $opt_name ] ) ) {
1440
+                self::$sections[ $opt_name ]             = array();
1441
+                self::$priority[ $opt_name ]['sections'] = 1;
1442
+            }
1443
+
1444
+            if ( ! isset( self::$args[ $opt_name ] ) ) {
1445
+                self::$args[ $opt_name ]             = array();
1446
+                self::$priority[ $opt_name ]['args'] = 1;
1447
+            }
1448
+
1449
+            if ( ! isset( self::$fields[ $opt_name ] ) ) {
1450
+                self::$fields[ $opt_name ]             = array();
1451
+                self::$priority[ $opt_name ]['fields'] = 1;
1452
+            }
1453
+
1454
+            if ( ! isset( self::$help[ $opt_name ] ) ) {
1455
+                self::$help[ $opt_name ]             = array();
1456
+                self::$priority[ $opt_name ]['help'] = 1;
1457
+            }
1458
+
1459
+            if ( ! isset( self::$errors[ $opt_name ] ) ) {
1460
+                self::$errors[ $opt_name ] = array();
1461
+            }
1462
+
1463
+            if ( ! isset( self::$init[ $opt_name ] ) ) {
1464
+                self::$init[ $opt_name ] = false;
1465
+            }
1466
+        }
1467
+
1468
+        /**
1469
+         * Retrieve metadata from a file. Based on WP Core's get_file_data function
1470
+         *
1471
+         * @param string $file Path to the file.
1472
+         *
1473
+         * @return string
1474
+         * @since 2.1.1
1475
+         */
1476
+        public static function get_file_version( string $file ): string {
1477
+            $data = get_file_data( $file, array( 'version' ), 'plugin' );
1478
+
1479
+            return $data[0];
1480
+        }
1481
+
1482
+        /**
1483
+         * Verify extension class name.
1484
+         *
1485
+         * @param string $opt_name   Panel opt_name.
1486
+         * @param string $name       extension name.
1487
+         * @param string $class_file Extension class file.
1488
+         */
1489
+        private static function check_extension_class_file( string $opt_name, string $name = '', string $class_file = '' ) {
1490
+            $instance = null;
1491
+
1492
+            if ( file_exists( $class_file ) ) {
1493
+                self::$uses_extensions[ $opt_name ] = self::$uses_extensions[ $opt_name ] ?? array();
1494
+
1495
+                if ( ! in_array( $name, self::$uses_extensions[ $opt_name ], true ) ) {
1496
+                    self::$uses_extensions[ $opt_name ][] = $name;
1497
+                }
1498
+
1499
+                self::$extensions[ $name ] = self::$extensions[ $name ] ?? array();
1500
+
1501
+                $version = Redux_Helpers::get_template_version( $class_file );
1502
+
1503
+                if ( empty( $version ) && ! empty( $instance ) ) {
1504
+                    if ( isset( $instance->version ) ) {
1505
+                        $version = $instance->version;
1506
+                    }
1507
+                }
1508
+                self::$extensions[ $name ][ $version ] = self::$extensions[ $name ][ $version ] ?? $class_file;
1509
+
1510
+                $new_name  = str_replace( '_', '-', $name );
1511
+                $api_check = str_replace(
1512
+                    array(
1513
+                        'extension_' . $name,
1514
+                        'class-redux-extension-' . $new_name,
1515
+                    ),
1516
+                    array(
1517
+                        $name . '_api',
1518
+                        'class-redux-' . $new_name . '-api',
1519
+                    ),
1520
+                    $class_file
1521
+                );
1522
+
1523
+                if ( file_exists( $api_check ) && ! class_exists( 'Redux_' . ucfirst( $name ) ) ) {
1524
+                    include_once $api_check;
1525
+                }
1526
+            }
1527
+        }
1528
+
1529
+        /**
1530
+         * Deprecated Sets all extensions in a path.
1531
+         *
1532
+         * @param string $opt_name Panel opt_name.
1533
+         * @param string $path     Path to extension folder.
1534
+         *
1535
+         * @deprecated No longer using camelCase naming convention.
1536
+         */
1537
+        public static function setExtensions( string $opt_name, string $path ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1538
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.3', 'Redux::get_extensions( $opt_name, $path )' );
1539
+
1540
+            if ( '' !== $opt_name ) {
1541
+                Redux_Functions_Ex::record_caller( $opt_name );
1542
+            }
1543
+
1544
+            self::set_extensions( $opt_name, $path );
1545
+        }
1546
+
1547
+        /**
1548
+         * Sets all extensions in a path.
1549
+         *
1550
+         * @param string $opt_name Panel opt_name.
1551
+         * @param string $path     Path to extension folder.
1552
+         * @param bool   $force    Make extension reload.
1553
+         */
1554
+        public static function set_extensions( string $opt_name, string $path, bool $force = false ) {
1555
+            if ( '' === $path || '' === $opt_name ) {
1556
+                return;
1557
+            }
1558
+
1559
+            self::check_opt_name( $opt_name );
1560
+
1561
+            Redux_Functions_Ex::record_caller( $opt_name );
1562
+
1563
+            if ( is_dir( $path ) ) {
1564
+                $path   = trailingslashit( $path );
1565
+                $folder = str_replace( '.php', '', basename( $path ) );
1566
+
1567
+                $folder_fix = str_replace( '_', '-', $folder );
1568
+
1569
+                $files = array(
1570
+                    $path . 'extension_' . $folder . '.php',
1571
+                    $path . 'class-redux-extension-' . $folder_fix . '.php',
1572
+                );
1573
+
1574
+                $ext_file = Redux_Functions::file_exists_ex( $files );
1575
+
1576
+                if ( $ext_file ) {
1577
+                    self::check_extension_class_file( $opt_name, $folder, $ext_file );
1578
+                } else {
1579
+                    $folders = scandir( $path );
1580
+
1581
+                    foreach ( $folders as $folder ) {
1582
+                        if ( '.' === $folder || '..' === $folder ) {
1583
+                            continue;
1584
+                        }
1585
+
1586
+                        if ( is_dir( $path . $folder ) ) {
1587
+                            self::set_extensions( $opt_name, $path . $folder );
1588
+                        }
1589
+                    }
1590
+                }
1591
+            } elseif ( file_exists( $path ) ) {
1592
+                $name = explode( 'extension_', basename( $path ) );
1593
+                if ( ! empty( $name[1] ) ) {
1594
+                    $name = str_replace( '.php', '', $name[1] );
1595
+                    self::check_extension_class_file( $opt_name, $name, $path );
1596
+                }
1597
+            }
1598
+
1599
+            self::$extension_paths[ $opt_name ] = $path;
1600
+
1601
+            if ( true === $force ) {
1602
+                if ( isset( self::$uses_extensions[ $opt_name ] ) && ! empty( self::$uses_extensions[ $opt_name ] ) ) {
1603
+                    $redux = self::instance( $opt_name );
1604
+
1605
+                    if ( isset( $redux ) ) {
1606
+                        self::load_extensions( $redux );
1607
+                    }
1608
+                }
1609
+            }
1610
+        }
1611
+
1612
+        /**
1613
+         * Retrieves all loaded extensions.
1614
+         */
1615
+        private static function get_all_extension() {
1616
+            $redux = self::all_instances();
1617
+
1618
+            foreach ( $redux as $instance ) {
1619
+                if ( ! empty( self::$uses_extensions[ $instance['args']['opt_name'] ] ) ) {
1620
+                    continue;
1621
+                }
1622
+                if ( ! empty( $instance['extensions'] ) ) {
1623
+                    self::get_instance_extension( $instance['args']['opt_name'], $instance );
1624
+                }
1625
+            }
1626
+        }
1627
+
1628
+        /**
1629
+         * Gets all loaded extensions for the passed ReduxFramework instance.
1630
+         *
1631
+         * @param string      $opt_name Panel opt_name.
1632
+         * @param object|null $instance ReduxFramework instance.
1633
+         */
1634
+        public static function get_instance_extension( string $opt_name, $instance ) {
1635
+            if ( ! empty( self::$uses_extensions[ $opt_name ] ) || empty( $opt_name ) ) {
1636
+                return;
1637
+            }
1638
+
1639
+            if ( empty( $instance ) ) {
1640
+                $instance = self::instance( $opt_name );
1641
+            }
1642
+
1643
+            if ( empty( $instance ) || empty( $instance->extensions ) ) {
1644
+                return;
1645
+            }
1646
+
1647
+            foreach ( $instance->extensions as $name => $extension ) {
1648
+                if ( 'widget_areas' === $name ) {
1649
+                    new Redux_Widget_Areas( $instance );
1650
+                }
1651
+
1652
+                if ( isset( self::$uses_extensions[ $opt_name ][ $name ] ) ) {
1653
+                    continue;
1654
+                }
1655
+
1656
+                if ( isset( $extension->extension_dir ) ) {
1657
+                    self::set_extensions( $opt_name, str_replace( $name, '', $extension->extension_dir ) );
1658
+                }
1659
+            }
1660
+        }
1661
+
1662
+        /**
1663
+         * Deprecated Gets loaded extensions.
1664
+         *
1665
+         * @param string $opt_name Panel opt_name.
1666
+         * @param string $key      Extension name.
1667
+         *
1668
+         * @return array|bool|mixed
1669
+         * @deprecated No longer using camelCase naming convention.
1670
+         */
1671
+        public static function getExtensions( string $opt_name = '', string $key = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
1672
+            _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'Redux 4.0.0', 'self::get_extensions( $opt_name, $key )' );
1673
+
1674
+            return self::get_extensions( $opt_name, $key );
1675
+        }
1676
+
1677
+        /**
1678
+         * Gets loaded extensions.
1679
+         *
1680
+         * @param string $opt_name Panel opt_name.
1681
+         * @param string $key      Extension name.
1682
+         *
1683
+         * @return array|bool|mixed
1684
+         */
1685
+        public static function get_extensions( string $opt_name = '', string $key = '' ) {
1686
+            if ( empty( $opt_name ) ) {
1687
+                self::get_all_extension();
1688
+
1689
+                if ( empty( $key ) ) {
1690
+                    return self::$extension_paths;
1691
+                } elseif ( isset( self::$extension_paths[ $key ] ) ) {
1692
+                        return self::$extension_paths[ $key ];
1693
+                }
1694
+            } else {
1695
+                if ( empty( self::$uses_extensions[ $opt_name ] ) ) {
1696
+                    self::get_instance_extension( $opt_name, null );
1697
+                }
1698
+
1699
+                if ( empty( self::$uses_extensions[ $opt_name ] ) ) {
1700
+                    return false;
1701
+                }
1702
+
1703
+                $instance_extensions = array();
1704
+
1705
+                foreach ( self::$uses_extensions[ $opt_name ] as $extension ) {
1706
+                    $class_file = end( self::$extensions[ $extension ] );
1707
+                    $directory  = explode( DIRECTORY_SEPARATOR, $class_file );
1708
+                    array_pop( $directory );
1709
+                    $directory       = trailingslashit( join( DIRECTORY_SEPARATOR, $directory ) );
1710
+                    $name            = str_replace( '.php', '', basename( $extension ) );
1711
+                    $extension_class = 'Redux_Extension_' . $name;
1712
+                    $the_data        = array(
1713
+                        'path'    => $class_file,
1714
+                        'dir'     => $directory,
1715
+                        'class'   => $extension_class,
1716
+                        'version' => Redux_Helpers::get_template_version( $class_file ),
1717
+                    );
1718
+
1719
+                    if ( is_dir( $the_data['dir'] . $extension ) ) {
1720
+                        $test_path = trailingslashit( $the_data['dir'] . $extension );
1721
+                        if ( file_exists( $test_path . 'field_' . str_replace( '-', '', $extension ) . '.php' ) ) {
1722
+                            $the_data['field'] = $test_path . 'field_' . str_replace( '-', '', $extension ) . '.php';
1723
+                        }
1724
+                        // Old extensions!
1725
+                        if ( file_exists( $test_path . str_replace( '-', '', $extension ) . '.php' ) ) {
1726
+                            $the_data['field'] = $test_path . str_replace( '-', '', $extension ) . '.php';
1727
+                        }
1728
+                    }
1729
+                    $instance_extensions[ $extension ] = $the_data;
1730
+                }
1731
+
1732
+                return $instance_extensions;
1733
+            }
1734
+
1735
+            return false;
1736
+        }
1737
+
1738
+        /**
1739
+         * Method to disables Redux demo mode popup.
1740
+         */
1741
+        public static function disable_demo() {
1742
+            add_action( 'ReduxFrameworkPlugin_admin_notice', 'Redux::remove_demo' );
1743
+            add_action( 'redux_framework_plugin_admin_notice', 'Redux::remove_demo' );
1744
+        }
1745
+
1746
+        /**
1747
+         * Callback used by self::disable_demo() to remove the demo mode notice from Redux.
1748
+         */
1749
+        public static function remove_demo() {
1750
+            update_option( 'ReduxFrameworkPlugin_ACTIVATED_NOTICES', '' );
1751
+        }
1752
+
1753
+        /**
1754
+         * Function which forces a panel/page to render.
1755
+         *
1756
+         * @param string|object $redux Panel opt_name or Redux object.
1757
+         */
1758
+        public static function render( $redux = '' ) {
1759
+            if ( is_string( $redux ) ) {
1760
+                $redux = Redux_Instances::get_instance( $redux );
1761
+                if ( empty( $redux ) ) {
1762
+                    return;
1763
+                }
1764
+            }
1765
+            $enqueue = new Redux_Enqueue( $redux );
1766
+            $enqueue->init();
1767
+            $panel = new Redux_Panel( $redux );
1768
+            $panel->init();
1769
+        }
1770
+    }
1771
+
1772
+    Redux::load();
1773 1773
 }
Please login to merge, or discard this patch.
Spacing   +123 added lines, -125 removed lines patch added patch discarded remove patch
@@ -246,11 +246,11 @@  discard block
 block discarded – undo
246 246
 						require_once $extension['field'];
247 247
 					}
248 248
 
249
-					if ( ! isset( $redux_framework->extensions[ $name ] ) ) {
249
+					if ( ! isset( $redux_framework->extensions[$name] ) ) {
250 250
 						$field_classes = array( $extension['class'], $old_class );
251 251
 						$ext_class     = Redux_Functions::class_exists_ex( $field_classes );
252 252
 						if ( false !== $ext_class ) {
253
-							$redux_framework->extensions[ $name ] = new $ext_class( $redux_framework );
253
+							$redux_framework->extensions[$name] = new $ext_class( $redux_framework );
254 254
 						} elseif ( is_admin() && true === $redux_framework->args['dev_mode'] ) {
255 255
 							echo '<div id="message" class="error"><p>No class named <strong>' . esc_html( $extension['class'] ) . '</strong> exists. Please verify your extension path.</p></div>';
256 256
 						}
@@ -283,11 +283,11 @@  discard block
 block discarded – undo
283 283
 		 * @return bool|mixed
284 284
 		 */
285 285
 		public static function extension_path( string $extension, bool $folder = true ) {
286
-			if ( ! isset( self::$extensions[ $extension ] ) ) {
286
+			if ( ! isset( self::$extensions[$extension] ) ) {
287 287
 				return false;
288 288
 			}
289 289
 
290
-			$path = end( self::$extensions[ $extension ] );
290
+			$path = end( self::$extensions[$extension] );
291 291
 
292 292
 			if ( ! $folder ) {
293 293
 				return $path;
@@ -330,16 +330,16 @@  discard block
 block discarded – undo
330 330
 				}
331 331
 			}
332 332
 
333
-			if ( class_exists( 'Redux_Options_Defaults' ) && ! isset( self::$options_defaults[ $opt_name ] ) ) {
333
+			if ( class_exists( 'Redux_Options_Defaults' ) && ! isset( self::$options_defaults[$opt_name] ) ) {
334 334
 				$sections                            = self::construct_sections( $opt_name );
335 335
 				$wordpress_data                      = ( ! class_exists( 'Redux_WordPress_Data' ) ) ? null : new Redux_WordPress_Data( $opt_name );
336 336
 				$options_defaults_class              = new Redux_Options_Defaults();
337
-				self::$options_defaults[ $opt_name ] = $options_defaults_class->default_values( $opt_name, $sections, $wordpress_data );
338
-				if ( ! isset( self::$args[ $opt_name ]['global_variable'] ) || ( '' === self::$args[ $opt_name ]['global_variable'] && false !== self::$args[ $opt_name ]['global_variable'] ) ) {
339
-					self::$args[ $opt_name ]['global_variable'] = str_replace( '-', '_', $opt_name );
337
+				self::$options_defaults[$opt_name] = $options_defaults_class->default_values( $opt_name, $sections, $wordpress_data );
338
+				if ( ! isset( self::$args[$opt_name]['global_variable'] ) || ( '' === self::$args[$opt_name]['global_variable'] && false !== self::$args[$opt_name]['global_variable'] ) ) {
339
+					self::$args[$opt_name]['global_variable'] = str_replace( '-', '_', $opt_name );
340 340
 				}
341
-				if ( isset( self::$args[ $opt_name ]['global_variable'] ) && self::$args[ $opt_name ]['global_variable'] ) {
342
-					$option_global = self::$args[ $opt_name ]['global_variable'];
341
+				if ( isset( self::$args[$opt_name]['global_variable'] ) && self::$args[$opt_name]['global_variable'] ) {
342
+					$option_global = self::$args[$opt_name]['global_variable'];
343 343
 
344 344
 					/**
345 345
 					 * Filter 'redux/options/{opt_name}/global_variable'
@@ -349,7 +349,7 @@  discard block
 block discarded – undo
349 349
 					global $$option_global;
350 350
 
351 351
 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
352
-					$$option_global = apply_filters( 'redux/options/' . $opt_name . '/global_variable', self::$options_defaults[ $opt_name ] );
352
+					$$option_global = apply_filters( 'redux/options/' . $opt_name . '/global_variable', self::$options_defaults[$opt_name] );
353 353
 				}
354 354
 			}
355 355
 		}
@@ -367,7 +367,7 @@  discard block
 block discarded – undo
367 367
 			}
368 368
 
369 369
 			if ( class_exists( 'ReduxFramework' ) ) {
370
-				if ( isset( self::$init[ $opt_name ] ) && ! empty( self::$init[ $opt_name ] ) ) {
370
+				if ( isset( self::$init[$opt_name] ) && ! empty( self::$init[$opt_name] ) ) {
371 371
 					return;
372 372
 				}
373 373
 			} else {
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
 
381 381
 			Redux_Functions_Ex::record_caller( $opt_name );
382 382
 
383
-			if ( isset( self::$init[ $opt_name ] ) && 1 === self::$init[ $opt_name ] ) {
383
+			if ( isset( self::$init[$opt_name] ) && 1 === self::$init[$opt_name] ) {
384 384
 				return;
385 385
 			}
386 386
 
@@ -389,15 +389,15 @@  discard block
 block discarded – undo
389 389
 			$args     = self::construct_args( $opt_name );
390 390
 			$sections = self::construct_sections( $opt_name );
391 391
 
392
-			if ( isset( self::$uses_extensions[ $opt_name ] ) && ! empty( self::$uses_extensions[ $opt_name ] ) ) {
392
+			if ( isset( self::$uses_extensions[$opt_name] ) && ! empty( self::$uses_extensions[$opt_name] ) ) {
393 393
 				add_action( "redux/extensions/$opt_name/before", array( 'Redux', 'load_extensions' ), 0 );
394 394
 			}
395 395
 
396 396
 			$redux                   = new ReduxFramework( $sections, $args );
397
-			self::$init[ $opt_name ] = 1;
397
+			self::$init[$opt_name] = 1;
398 398
 
399 399
 			if ( isset( $redux->args['opt_name'] ) && $redux->args['opt_name'] !== $opt_name ) {
400
-				self::$init[ $redux->args['opt_name'] ] = 1;
400
+				self::$init[$redux->args['opt_name']] = 1;
401 401
 			}
402 402
 		}
403 403
 
@@ -422,7 +422,7 @@  discard block
 block discarded – undo
422 422
 		public static function create_redux() {
423 423
 			foreach ( self::$sections as $opt_name => $the_sections ) {
424 424
 				if ( ! empty( $the_sections ) ) {
425
-					if ( ! self::$init[ $opt_name ] ) {
425
+					if ( ! self::$init[$opt_name] ) {
426 426
 						self::load_redux( $opt_name );
427 427
 					}
428 428
 				}
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
 		 * @return array|mixed
438 438
 		 */
439 439
 		public static function construct_args( string $opt_name ) {
440
-			$args             = self::$args[ $opt_name ] ?? array();
440
+			$args             = self::$args[$opt_name] ?? array();
441 441
 			$args['opt_name'] = $opt_name;
442 442
 
443 443
 			if ( ! isset( $args['menu_title'] ) ) {
@@ -465,19 +465,19 @@  discard block
 block discarded – undo
465 465
 		public static function construct_sections( string $opt_name ): array {
466 466
 			$sections = array();
467 467
 
468
-			if ( ! isset( self::$sections[ $opt_name ] ) ) {
468
+			if ( ! isset( self::$sections[$opt_name] ) ) {
469 469
 				return $sections;
470 470
 			}
471 471
 
472
-			foreach ( self::$sections[ $opt_name ] as $section_id => $section ) {
472
+			foreach ( self::$sections[$opt_name] as $section_id => $section ) {
473 473
 				$section['fields'] = self::construct_fields( $opt_name, $section_id );
474 474
 				$p                 = $section['priority'];
475 475
 
476
-				while ( isset( $sections[ $p ] ) ) {
476
+				while ( isset( $sections[$p] ) ) {
477 477
 					++$p;
478 478
 				}
479 479
 
480
-				$sections[ $p ] = $section;
480
+				$sections[$p] = $section;
481 481
 			}
482 482
 
483 483
 			ksort( $sections );
@@ -496,16 +496,16 @@  discard block
 block discarded – undo
496 496
 		public static function construct_fields( string $opt_name = '', string $section_id = '' ): array {
497 497
 			$fields = array();
498 498
 
499
-			if ( ! empty( self::$fields[ $opt_name ] ) ) {
500
-				foreach ( self::$fields[ $opt_name ] as $field ) {
499
+			if ( ! empty( self::$fields[$opt_name] ) ) {
500
+				foreach ( self::$fields[$opt_name] as $field ) {
501 501
 					if ( $field['section_id'] === $section_id ) {
502 502
 						$p = esc_html( $field['priority'] );
503 503
 
504
-						while ( isset( $fields[ $p ] ) ) {
504
+						while ( isset( $fields[$p] ) ) {
505 505
 							echo intval( $p++ );
506 506
 						}
507 507
 
508
-						$fields[ $p ] = $field;
508
+						$fields[$p] = $field;
509 509
 					}
510 510
 				}
511 511
 			}
@@ -542,11 +542,11 @@  discard block
 block discarded – undo
542 542
 			self::check_opt_name( $opt_name );
543 543
 
544 544
 			if ( ! empty( $opt_name ) && ! empty( $id ) ) {
545
-				if ( ! isset( self::$sections[ $opt_name ][ $id ] ) ) {
545
+				if ( ! isset( self::$sections[$opt_name][$id] ) ) {
546 546
 					$id = Redux_Core::strtolower( sanitize_html_class( $id ) );
547 547
 				}
548 548
 
549
-				return self::$sections[ $opt_name ][ $id ] ?? false;
549
+				return self::$sections[$opt_name][$id] ?? false;
550 550
 			}
551 551
 
552 552
 			return false;
@@ -614,8 +614,8 @@  discard block
 block discarded – undo
614 614
 		public static function get_sections( string $opt_name = '' ) {
615 615
 			self::check_opt_name( $opt_name );
616 616
 
617
-			if ( ! empty( self::$sections[ $opt_name ] ) ) {
618
-				return self::$sections[ $opt_name ];
617
+			if ( ! empty( self::$sections[$opt_name] ) ) {
618
+				return self::$sections[$opt_name];
619 619
 			}
620 620
 
621 621
 			return array();
@@ -651,28 +651,27 @@  discard block
 block discarded – undo
651 651
 			if ( '' !== $opt_name && '' !== $id ) {
652 652
 				Redux_Functions_Ex::record_caller( $opt_name );
653 653
 
654
-				if ( isset( self::$sections[ $opt_name ][ $id ] ) ) {
654
+				if ( isset( self::$sections[$opt_name][$id] ) ) {
655 655
 					$priority = '';
656 656
 
657
-					foreach ( self::$sections[ $opt_name ] as $key => $section ) {
657
+					foreach ( self::$sections[$opt_name] as $key => $section ) {
658 658
 						if ( $key === $id ) {
659
-							$priority = $section['priority'];
660
-							--self::$priority[ $opt_name ]['sections'];
661
-							unset( self::$sections[ $opt_name ][ $id ] );
659
+							$priority = $section['priority'];--self::$priority[$opt_name]['sections'];
660
+							unset( self::$sections[$opt_name][$id] );
662 661
 							continue;
663 662
 						}
664 663
 						if ( '' !== $priority ) {
665 664
 							$new_priority                        = $section['priority'];
666 665
 							$section['priority']                 = $priority;
667
-							self::$sections[ $opt_name ][ $key ] = $section;
666
+							self::$sections[$opt_name][$key] = $section;
668 667
 							$priority                            = $new_priority;
669 668
 						}
670 669
 					}
671 670
 
672
-					if ( isset( self::$fields[ $opt_name ] ) && ! empty( self::$fields[ $opt_name ] ) && true === $fields ) {
673
-						foreach ( self::$fields[ $opt_name ] as $key => $field ) {
671
+					if ( isset( self::$fields[$opt_name] ) && ! empty( self::$fields[$opt_name] ) && true === $fields ) {
672
+						foreach ( self::$fields[$opt_name] as $key => $field ) {
674 673
 							if ( $field['section_id'] === $id ) {
675
-								unset( self::$fields[ $opt_name ][ $key ] );
674
+								unset( self::$fields[$opt_name][$key] );
676 675
 							}
677 676
 						}
678 677
 					}
@@ -725,24 +724,24 @@  discard block
 block discarded – undo
725 724
 					$section['id'] = time();
726 725
 				}
727 726
 
728
-				if ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) && ! $replace ) {
727
+				if ( isset( self::$sections[$opt_name][$section['id']] ) && ! $replace ) {
729 728
 					$orig = $section['id'];
730 729
 					$i    = 0;
731 730
 
732
-					while ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) ) {
731
+					while ( isset( self::$sections[$opt_name][$section['id']] ) ) {
733 732
 						$section['id'] = $orig . '_' . $i;
734 733
 						++$i;
735 734
 					}
736
-				} elseif ( isset( self::$sections[ $opt_name ][ $section['id'] ] ) && $replace ) {
735
+				} elseif ( isset( self::$sections[$opt_name][$section['id']] ) && $replace ) {
737 736
 					// If replace is set, let's update the default values with these!
738 737
 					$fields = false;
739
-					if ( isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) && ! empty( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) ) {
740
-						$fields = self::$sections[ $opt_name ][ $section['id'] ]['fields'];
738
+					if ( isset( self::$sections[$opt_name][$section['id']]['fields'] ) && ! empty( self::$sections[$opt_name][$section['id']]['fields'] ) ) {
739
+						$fields = self::$sections[$opt_name][$section['id']]['fields'];
741 740
 					}
742
-					self::$sections[ $opt_name ][ $section['id'] ] = wp_parse_args( $section, self::$sections[ $opt_name ][ $section['id'] ] );
741
+					self::$sections[$opt_name][$section['id']] = wp_parse_args( $section, self::$sections[$opt_name][$section['id']] );
743 742
 					if ( ! empty( $fields ) ) {
744
-						if ( ! isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) || ( isset( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) && empty( self::$sections[ $opt_name ][ $section['id'] ]['fields'] ) ) ) {
745
-							self::$sections[ $opt_name ][ $section['id'] ]['fields'] = $fields;
743
+						if ( ! isset( self::$sections[$opt_name][$section['id']]['fields'] ) || ( isset( self::$sections[$opt_name][$section['id']]['fields'] ) && empty( self::$sections[$opt_name][$section['id']]['fields'] ) ) ) {
744
+							self::$sections[$opt_name][$section['id']]['fields'] = $fields;
746 745
 						}
747 746
 					}
748 747
 				}
@@ -750,7 +749,7 @@  discard block
 block discarded – undo
750 749
 
751 750
 			if ( ! empty( $opt_name ) && is_array( $section ) && ! empty( $section ) ) {
752 751
 				if ( ! isset( $section['id'] ) && ! isset( $section['title'] ) ) {
753
-					self::$errors[ $opt_name ]['section']['missing_title'] = esc_html__( 'Unable to create a section due to missing id and title.', 'redux-framework' );
752
+					self::$errors[$opt_name]['section']['missing_title'] = esc_html__( 'Unable to create a section due to missing id and title.', 'redux-framework' );
754 753
 
755 754
 					return;
756 755
 				}
@@ -765,9 +764,9 @@  discard block
 block discarded – undo
765 764
 					}
766 765
 					unset( $section['fields'] );
767 766
 				}
768
-				self::$sections[ $opt_name ][ $section['id'] ] = $section;
767
+				self::$sections[$opt_name][$section['id']] = $section;
769 768
 			} else {
770
-				self::$errors[ $opt_name ]['section']['empty'] = esc_html__( 'Unable to create a section due an empty section array or the section variable passed was not an array.', 'redux-framework' );
769
+				self::$errors[$opt_name]['section']['empty'] = esc_html__( 'Unable to create a section due an empty section array or the section variable passed was not an array.', 'redux-framework' );
771 770
 			}
772 771
 		}
773 772
 
@@ -803,8 +802,8 @@  discard block
 block discarded – undo
803 802
 			if ( '' !== $opt_name && '' !== $id ) {
804 803
 				Redux_Functions_Ex::record_caller( $opt_name );
805 804
 
806
-				if ( isset( self::$sections[ $opt_name ][ $id ] ) ) {
807
-					self::$sections[ $opt_name ][ $id ]['hidden'] = $hide;
805
+				if ( isset( self::$sections[$opt_name][$id] ) ) {
806
+					self::$sections[$opt_name][$id]['hidden'] = $hide;
808 807
 				}
809 808
 			}
810 809
 		}
@@ -854,7 +853,7 @@  discard block
 block discarded – undo
854 853
 			self::check_opt_name( $opt_name );
855 854
 
856 855
 			if ( ! empty( $opt_name ) && ! empty( $id ) ) {
857
-				return self::$fields[ $opt_name ][ $id ] ?? false;
856
+				return self::$fields[$opt_name][$id] ?? false;
858 857
 			}
859 858
 
860 859
 			return false;
@@ -890,13 +889,13 @@  discard block
 block discarded – undo
890 889
 			self::check_opt_name( $opt_name );
891 890
 
892 891
 			if ( '' !== $opt_name && '' !== $id ) {
893
-				if ( isset( self::$fields[ $opt_name ][ $id ] ) ) {
892
+				if ( isset( self::$fields[$opt_name][$id] ) ) {
894 893
 					Redux_Functions_Ex::record_caller( $opt_name );
895 894
 
896 895
 					if ( ! $hide ) {
897
-						self::$fields[ $opt_name ][ $id ]['class'] = str_replace( 'hidden', '', self::$fields[ $opt_name ][ $id ]['class'] );
896
+						self::$fields[$opt_name][$id]['class'] = str_replace( 'hidden', '', self::$fields[$opt_name][$id]['class'] );
898 897
 					} else {
899
-						self::$fields[ $opt_name ][ $id ]['class'] .= 'hidden';
898
+						self::$fields[$opt_name][$id]['class'] .= 'hidden';
900 899
 					}
901 900
 				}
902 901
 			}
@@ -953,7 +952,7 @@  discard block
 block discarded – undo
953 952
 			}
954 953
 			$field['id'] = $field['id'] ?? "{$opt_name}_{$section_id}_{$field['type']}_" . wp_rand( 1, 9999 );
955 954
 
956
-			self::$fields[ $opt_name ][ $field['id'] ] = $field;
955
+			self::$fields[$opt_name][$field['id']] = $field;
957 956
 		}
958 957
 
959 958
 		/**
@@ -1013,19 +1012,18 @@  discard block
 block discarded – undo
1013 1012
 
1014 1013
 				Redux_Functions_Ex::record_caller( $opt_name );
1015 1014
 
1016
-				if ( isset( self::$fields[ $opt_name ][ $id ] ) ) {
1017
-					foreach ( self::$fields[ $opt_name ] as $key => $field ) {
1015
+				if ( isset( self::$fields[$opt_name][$id] ) ) {
1016
+					foreach ( self::$fields[$opt_name] as $key => $field ) {
1018 1017
 						if ( $key === $id ) {
1019
-							$priority = $field['priority'];
1020
-							--self::$priority[ $opt_name ]['fields'];
1021
-							unset( self::$fields[ $opt_name ][ $id ] );
1018
+							$priority = $field['priority'];--self::$priority[$opt_name]['fields'];
1019
+							unset( self::$fields[$opt_name][$id] );
1022 1020
 							continue;
1023 1021
 						}
1024 1022
 
1025 1023
 						if ( isset( $priority ) && '' !== $priority ) {
1026 1024
 							$new_priority                      = $field['priority'];
1027 1025
 							$field['priority']                 = $priority;
1028
-							self::$fields[ $opt_name ][ $key ] = $field;
1026
+							self::$fields[$opt_name][$key] = $field;
1029 1027
 							$priority                          = $new_priority;
1030 1028
 						}
1031 1029
 					}
@@ -1063,15 +1061,15 @@  discard block
 block discarded – undo
1063 1061
 			self::check_opt_name( $opt_name );
1064 1062
 
1065 1063
 			if ( '' !== $opt_name ) {
1066
-				if ( ! isset( self::$args[ $opt_name ]['help_tabs'] ) ) {
1067
-					self::$args[ $opt_name ]['help_tabs'] = array();
1064
+				if ( ! isset( self::$args[$opt_name]['help_tabs'] ) ) {
1065
+					self::$args[$opt_name]['help_tabs'] = array();
1068 1066
 				}
1069 1067
 
1070 1068
 				if ( isset( $tab['id'] ) ) {
1071
-					self::$args[ $opt_name ]['help_tabs'][] = $tab;
1069
+					self::$args[$opt_name]['help_tabs'][] = $tab;
1072 1070
 				} elseif ( is_array( end( $tab ) ) ) {
1073 1071
 					foreach ( $tab as $tab_item ) {
1074
-						self::$args[ $opt_name ]['help_tabs'][] = $tab_item;
1072
+						self::$args[$opt_name]['help_tabs'][] = $tab_item;
1075 1073
 					}
1076 1074
 				}
1077 1075
 			}
@@ -1103,7 +1101,7 @@  discard block
 block discarded – undo
1103 1101
 			}
1104 1102
 			self::check_opt_name( $opt_name );
1105 1103
 
1106
-			self::$args[ $opt_name ]['help_sidebar'] = $content;
1104
+			self::$args[$opt_name]['help_sidebar'] = $content;
1107 1105
 		}
1108 1106
 
1109 1107
 		/**
@@ -1141,10 +1139,10 @@  discard block
 block discarded – undo
1141 1139
 			Redux_Functions_Ex::record_caller( $opt_name );
1142 1140
 
1143 1141
 			if ( is_array( $args ) ) {
1144
-				if ( isset( self::$args[ $opt_name ]['clearArgs'] ) ) {
1145
-					self::$args[ $opt_name ] = array();
1142
+				if ( isset( self::$args[$opt_name]['clearArgs'] ) ) {
1143
+					self::$args[$opt_name] = array();
1146 1144
 				}
1147
-				self::$args[ $opt_name ] = wp_parse_args( $args, self::$args[ $opt_name ] );
1145
+				self::$args[$opt_name] = wp_parse_args( $args, self::$args[$opt_name] );
1148 1146
 			}
1149 1147
 		}
1150 1148
 
@@ -1163,7 +1161,7 @@  discard block
 block discarded – undo
1163 1161
 
1164 1162
 			Redux_Functions_Ex::record_caller( $opt_name );
1165 1163
 
1166
-			self::$args[ $opt_name ]['developer'] = $arg;
1164
+			self::$args[$opt_name]['developer'] = $arg;
1167 1165
 		}
1168 1166
 
1169 1167
 		/**
@@ -1192,13 +1190,13 @@  discard block
 block discarded – undo
1192 1190
 			self::check_opt_name( $opt_name );
1193 1191
 
1194 1192
 			if ( ! empty( $opt_name ) && ! empty( $key ) ) {
1195
-				if ( ! empty( self::$args[ $opt_name ] ) ) {
1196
-					return self::$args[ $opt_name ][ $key ];
1193
+				if ( ! empty( self::$args[$opt_name] ) ) {
1194
+					return self::$args[$opt_name][$key];
1197 1195
 				} else {
1198 1196
 					return null;
1199 1197
 				}
1200
-			} elseif ( ! empty( $opt_name ) && ! empty( self::$args[ $opt_name ] ) ) {
1201
-				return self::$args[ $opt_name ];
1198
+			} elseif ( ! empty( $opt_name ) && ! empty( self::$args[$opt_name] ) ) {
1199
+				return self::$args[$opt_name];
1202 1200
 			}
1203 1201
 
1204 1202
 			return null;
@@ -1230,8 +1228,8 @@  discard block
 block discarded – undo
1230 1228
 		public static function get_arg( string $opt_name = '', string $key = '' ) {
1231 1229
 			self::check_opt_name( $opt_name );
1232 1230
 
1233
-			if ( ! empty( $opt_name ) && ! empty( $key ) && ! empty( self::$args[ $opt_name ] ) ) {
1234
-				return self::$args[ $opt_name ][ $key ];
1231
+			if ( ! empty( $opt_name ) && ! empty( $key ) && ! empty( self::$args[$opt_name] ) ) {
1232
+				return self::$args[$opt_name][$key];
1235 1233
 			} else {
1236 1234
 				return null;
1237 1235
 			}
@@ -1317,7 +1315,7 @@  discard block
 block discarded – undo
1317 1315
 					$values = $$opt_name;
1318 1316
 				}
1319 1317
 
1320
-				if ( ! isset( $values[ $key ] ) ) {
1318
+				if ( ! isset( $values[$key] ) ) {
1321 1319
 					if ( null === $default ) {
1322 1320
 						$field = self::get_field( $opt_name, $key );
1323 1321
 
@@ -1326,8 +1324,8 @@  discard block
 block discarded – undo
1326 1324
 							$sections       = self::construct_sections( $opt_name );
1327 1325
 							$defaults       = $defaults_class->default_values( $opt_name, $sections );
1328 1326
 
1329
-							if ( isset( $defaults[ $key ] ) ) {
1330
-								$default = $defaults[ $key ];
1327
+							if ( isset( $defaults[$key] ) ) {
1328
+								$default = $defaults[$key];
1331 1329
 							}
1332 1330
 						}
1333 1331
 					}
@@ -1336,25 +1334,25 @@  discard block
 block discarded – undo
1336 1334
 				if ( ! empty( $subkeys ) && is_array( $subkeys ) ) {
1337 1335
 					$value = $default;
1338 1336
 
1339
-					if ( isset( $values[ $key ] ) ) {
1337
+					if ( isset( $values[$key] ) ) {
1340 1338
 						$count = count( $subkeys );
1341 1339
 
1342 1340
 						if ( 1 === $count ) {
1343
-							$value = $values[ $key ][ $subkeys[1] ] ?? $default;
1341
+							$value = $values[$key][$subkeys[1]] ?? $default;
1344 1342
 						} elseif ( 2 === $count ) {
1345
-							if ( isset( $values[ $key ][ $subkeys[1] ] ) ) {
1346
-								$value = $values[ $key ][ $subkeys[1] ][ $subkeys[2] ] ?? $default;
1343
+							if ( isset( $values[$key][$subkeys[1]] ) ) {
1344
+								$value = $values[$key][$subkeys[1]][$subkeys[2]] ?? $default;
1347 1345
 							}
1348 1346
 						} elseif ( 3 === $count ) {
1349
-							if ( isset( $values[ $key ][ $subkeys[1] ] ) ) {
1350
-								if ( isset( $values[ $key ][ $subkeys[1] ][ $subkeys[2] ] ) ) {
1351
-									$value = $values[ $key ][ $subkeys[1] ][ $subkeys[2] ][ $subkeys[3] ] ?? $default;
1347
+							if ( isset( $values[$key][$subkeys[1]] ) ) {
1348
+								if ( isset( $values[$key][$subkeys[1]][$subkeys[2]] ) ) {
1349
+									$value = $values[$key][$subkeys[1]][$subkeys[2]][$subkeys[3]] ?? $default;
1352 1350
 								}
1353 1351
 							}
1354 1352
 						}
1355 1353
 					}
1356 1354
 				} else {
1357
-					$value = $values[ $key ] ?? $default;
1355
+					$value = $values[$key] ?? $default;
1358 1356
 				}
1359 1357
 
1360 1358
 				return $value;
@@ -1403,7 +1401,7 @@  discard block
 block discarded – undo
1403 1401
 
1404 1402
 			if ( '' !== $opt_name ) {
1405 1403
 				$redux         = get_option( $opt_name );
1406
-				$redux[ $key ] = $option;
1404
+				$redux[$key] = $option;
1407 1405
 
1408 1406
 				return update_option( $opt_name, $redux );
1409 1407
 			} else {
@@ -1420,8 +1418,8 @@  discard block
 block discarded – undo
1420 1418
 		 * @return mixed
1421 1419
 		 */
1422 1420
 		public static function get_priority( string $opt_name, string $type ) {
1423
-			$priority                              = self::$priority[ $opt_name ][ $type ];
1424
-			self::$priority[ $opt_name ][ $type ] += 1;
1421
+			$priority                              = self::$priority[$opt_name][$type];
1422
+			self::$priority[$opt_name][$type] += 1;
1425 1423
 
1426 1424
 			return $priority;
1427 1425
 		}
@@ -1436,32 +1434,32 @@  discard block
 block discarded – undo
1436 1434
 				return;
1437 1435
 			}
1438 1436
 
1439
-			if ( ! isset( self::$sections[ $opt_name ] ) ) {
1440
-				self::$sections[ $opt_name ]             = array();
1441
-				self::$priority[ $opt_name ]['sections'] = 1;
1437
+			if ( ! isset( self::$sections[$opt_name] ) ) {
1438
+				self::$sections[$opt_name]             = array();
1439
+				self::$priority[$opt_name]['sections'] = 1;
1442 1440
 			}
1443 1441
 
1444
-			if ( ! isset( self::$args[ $opt_name ] ) ) {
1445
-				self::$args[ $opt_name ]             = array();
1446
-				self::$priority[ $opt_name ]['args'] = 1;
1442
+			if ( ! isset( self::$args[$opt_name] ) ) {
1443
+				self::$args[$opt_name]             = array();
1444
+				self::$priority[$opt_name]['args'] = 1;
1447 1445
 			}
1448 1446
 
1449
-			if ( ! isset( self::$fields[ $opt_name ] ) ) {
1450
-				self::$fields[ $opt_name ]             = array();
1451
-				self::$priority[ $opt_name ]['fields'] = 1;
1447
+			if ( ! isset( self::$fields[$opt_name] ) ) {
1448
+				self::$fields[$opt_name]             = array();
1449
+				self::$priority[$opt_name]['fields'] = 1;
1452 1450
 			}
1453 1451
 
1454
-			if ( ! isset( self::$help[ $opt_name ] ) ) {
1455
-				self::$help[ $opt_name ]             = array();
1456
-				self::$priority[ $opt_name ]['help'] = 1;
1452
+			if ( ! isset( self::$help[$opt_name] ) ) {
1453
+				self::$help[$opt_name]             = array();
1454
+				self::$priority[$opt_name]['help'] = 1;
1457 1455
 			}
1458 1456
 
1459
-			if ( ! isset( self::$errors[ $opt_name ] ) ) {
1460
-				self::$errors[ $opt_name ] = array();
1457
+			if ( ! isset( self::$errors[$opt_name] ) ) {
1458
+				self::$errors[$opt_name] = array();
1461 1459
 			}
1462 1460
 
1463
-			if ( ! isset( self::$init[ $opt_name ] ) ) {
1464
-				self::$init[ $opt_name ] = false;
1461
+			if ( ! isset( self::$init[$opt_name] ) ) {
1462
+				self::$init[$opt_name] = false;
1465 1463
 			}
1466 1464
 		}
1467 1465
 
@@ -1490,13 +1488,13 @@  discard block
 block discarded – undo
1490 1488
 			$instance = null;
1491 1489
 
1492 1490
 			if ( file_exists( $class_file ) ) {
1493
-				self::$uses_extensions[ $opt_name ] = self::$uses_extensions[ $opt_name ] ?? array();
1491
+				self::$uses_extensions[$opt_name] = self::$uses_extensions[$opt_name] ?? array();
1494 1492
 
1495
-				if ( ! in_array( $name, self::$uses_extensions[ $opt_name ], true ) ) {
1496
-					self::$uses_extensions[ $opt_name ][] = $name;
1493
+				if ( ! in_array( $name, self::$uses_extensions[$opt_name], true ) ) {
1494
+					self::$uses_extensions[$opt_name][] = $name;
1497 1495
 				}
1498 1496
 
1499
-				self::$extensions[ $name ] = self::$extensions[ $name ] ?? array();
1497
+				self::$extensions[$name] = self::$extensions[$name] ?? array();
1500 1498
 
1501 1499
 				$version = Redux_Helpers::get_template_version( $class_file );
1502 1500
 
@@ -1505,7 +1503,7 @@  discard block
 block discarded – undo
1505 1503
 						$version = $instance->version;
1506 1504
 					}
1507 1505
 				}
1508
-				self::$extensions[ $name ][ $version ] = self::$extensions[ $name ][ $version ] ?? $class_file;
1506
+				self::$extensions[$name][$version] = self::$extensions[$name][$version] ?? $class_file;
1509 1507
 
1510 1508
 				$new_name  = str_replace( '_', '-', $name );
1511 1509
 				$api_check = str_replace(
@@ -1596,10 +1594,10 @@  discard block
 block discarded – undo
1596 1594
 				}
1597 1595
 			}
1598 1596
 
1599
-			self::$extension_paths[ $opt_name ] = $path;
1597
+			self::$extension_paths[$opt_name] = $path;
1600 1598
 
1601 1599
 			if ( true === $force ) {
1602
-				if ( isset( self::$uses_extensions[ $opt_name ] ) && ! empty( self::$uses_extensions[ $opt_name ] ) ) {
1600
+				if ( isset( self::$uses_extensions[$opt_name] ) && ! empty( self::$uses_extensions[$opt_name] ) ) {
1603 1601
 					$redux = self::instance( $opt_name );
1604 1602
 
1605 1603
 					if ( isset( $redux ) ) {
@@ -1616,7 +1614,7 @@  discard block
 block discarded – undo
1616 1614
 			$redux = self::all_instances();
1617 1615
 
1618 1616
 			foreach ( $redux as $instance ) {
1619
-				if ( ! empty( self::$uses_extensions[ $instance['args']['opt_name'] ] ) ) {
1617
+				if ( ! empty( self::$uses_extensions[$instance['args']['opt_name']] ) ) {
1620 1618
 					continue;
1621 1619
 				}
1622 1620
 				if ( ! empty( $instance['extensions'] ) ) {
@@ -1632,7 +1630,7 @@  discard block
 block discarded – undo
1632 1630
 		 * @param object|null $instance ReduxFramework instance.
1633 1631
 		 */
1634 1632
 		public static function get_instance_extension( string $opt_name, $instance ) {
1635
-			if ( ! empty( self::$uses_extensions[ $opt_name ] ) || empty( $opt_name ) ) {
1633
+			if ( ! empty( self::$uses_extensions[$opt_name] ) || empty( $opt_name ) ) {
1636 1634
 				return;
1637 1635
 			}
1638 1636
 
@@ -1649,7 +1647,7 @@  discard block
 block discarded – undo
1649 1647
 					new Redux_Widget_Areas( $instance );
1650 1648
 				}
1651 1649
 
1652
-				if ( isset( self::$uses_extensions[ $opt_name ][ $name ] ) ) {
1650
+				if ( isset( self::$uses_extensions[$opt_name][$name] ) ) {
1653 1651
 					continue;
1654 1652
 				}
1655 1653
 
@@ -1688,22 +1686,22 @@  discard block
 block discarded – undo
1688 1686
 
1689 1687
 				if ( empty( $key ) ) {
1690 1688
 					return self::$extension_paths;
1691
-				} elseif ( isset( self::$extension_paths[ $key ] ) ) {
1692
-						return self::$extension_paths[ $key ];
1689
+				} elseif ( isset( self::$extension_paths[$key] ) ) {
1690
+						return self::$extension_paths[$key];
1693 1691
 				}
1694 1692
 			} else {
1695
-				if ( empty( self::$uses_extensions[ $opt_name ] ) ) {
1693
+				if ( empty( self::$uses_extensions[$opt_name] ) ) {
1696 1694
 					self::get_instance_extension( $opt_name, null );
1697 1695
 				}
1698 1696
 
1699
-				if ( empty( self::$uses_extensions[ $opt_name ] ) ) {
1697
+				if ( empty( self::$uses_extensions[$opt_name] ) ) {
1700 1698
 					return false;
1701 1699
 				}
1702 1700
 
1703 1701
 				$instance_extensions = array();
1704 1702
 
1705
-				foreach ( self::$uses_extensions[ $opt_name ] as $extension ) {
1706
-					$class_file = end( self::$extensions[ $extension ] );
1703
+				foreach ( self::$uses_extensions[$opt_name] as $extension ) {
1704
+					$class_file = end( self::$extensions[$extension] );
1707 1705
 					$directory  = explode( DIRECTORY_SEPARATOR, $class_file );
1708 1706
 					array_pop( $directory );
1709 1707
 					$directory       = trailingslashit( join( DIRECTORY_SEPARATOR, $directory ) );
@@ -1726,7 +1724,7 @@  discard block
 block discarded – undo
1726 1724
 							$the_data['field'] = $test_path . str_replace( '-', '', $extension ) . '.php';
1727 1725
 						}
1728 1726
 					}
1729
-					$instance_extensions[ $extension ] = $the_data;
1727
+					$instance_extensions[$extension] = $the_data;
1730 1728
 				}
1731 1729
 
1732 1730
 				return $instance_extensions;
Please login to merge, or discard this patch.