PluginProbe
Customify / 1.3.1
Customify v1.3.1
2.10.9 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.7.1 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.0.1 1.6.5 1.7.0 1.7.1 All 77 releases
customify / class-pixcustomify.php

class-pixcustomify.php in Customify 1.3.1, at class-pixcustomify.php

1,884 lines 55.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * PixCustomify.
4 * @package PixCustomify
5 * @author Pixelgrade <contact@pixelgrade.com>
6 * @license GPL-2.0+
7 * @link http://pixelgrade.com
8 * @copyright 2014 Pixelgrade
9 */
10
11 /**
12 * Plugin class.
13 * @package PixCustomify
14 * @author Pixelgrade <contact@pixelgrade.com>
15 */
16 class PixCustomifyPlugin {
17
18 /**
19 * Plugin version, used for cache-busting of style and script file references.
20 * @since 1.0.0
21 * @const string
22 */
23 protected $version = '1.3.1';
24 /**
25 * Unique identifier for your plugin.
26 * Use this value (not the variable name) as the text domain when internationalizing strings of text. It should
27 * match the Text Domain file header in the main plugin file.
28 * @since 1.0.0
29 * @var string
30 */
31 protected $plugin_slug = 'customify';
32
33 /**
34 * Instance of this class.
35 * @since 1.0.0
36 * @var object
37 */
38 protected static $instance = null;
39
40 /**
41 * Slug of the plugin screen.
42 * @since 1.0.0
43 * @var string
44 */
45 protected $plugin_screen_hook_suffix = null;
46
47 /**
48 * Path to the plugin.
49 * @since 1.0.0
50 * @var string
51 */
52 protected $plugin_basepath = null;
53
54 public $display_admin_menu = false;
55
56 private static $config;
57
58 private static $customizer_config;
59
60 public static $plugin_settings;
61
62 protected static $localized = array();
63
64 protected static $current_values = array();
65
66 protected static $options_list = array();
67
68 protected static $media_queries = array();
69
70 protected static $customizer_values;
71
72 protected static $opt_name;
73
74 protected static $typo_settings;
75
76 protected static $google_fonts = null;
77
78 protected static $theme_fonts = null;
79
80 // these properties will get 'px' as a default unit
81 protected static $pixel_dependent_css_properties = array(
82 'width',
83 'max-width',
84 'min-width',
85
86 'height',
87 'max-height',
88 'min-height',
89
90 'padding',
91 'padding-left',
92 'padding-right',
93 'padding-top',
94 'padding-bottom',
95
96 'margin',
97 'margin-right',
98 'margin-left',
99 'margin-top',
100 'margin-bottom',
101
102 'right',
103 'left',
104 'top',
105 'bottom',
106
107 'font-size',
108 'letter-spacing',
109
110 'border-size',
111 'border-width',
112 'border-bottom-width',
113 'border-left-width',
114 'border-right-width',
115 'border-top-width'
116 );
117
118 protected static $jetpack_default_modules = array();
119 protected static $jetpack_blocked_modules = array();
120 protected static $jetpack_sharing_default_options = array();
121
122 /**
123 * Initialize the plugin by setting localization, filters, and administration functions.
124 * @since 1.0.0
125 */
126 protected function __construct() {
127
128 $this->plugin_basepath = plugin_dir_path( __FILE__ );
129 self::$config = self::get_config();
130 self::$plugin_settings = get_option( 'pixcustomify_settings' );
131
132 // load custom modules
133 include_once( self::get_base_path() . '/features/class-CSS_Editor.php' );
134 include_once( self::get_base_path() . 'features/class-Font_Selector.php' );
135
136 self::check_for_customizer_values();
137
138 // Load plugin text domain
139 add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
140
141 add_action( 'wp_loaded', array( $this, 'init_plugin_configs' ), 5 );
142
143 add_action( 'admin_menu', array( $this, 'add_plugin_admin_menu' ) );
144
145 // Add an action link pointing to the options page.
146 $plugin_basename = plugin_basename( plugin_dir_path( __FILE__ ) . 'pixcustomify.php' );
147 add_filter( 'plugin_action_links_' . $plugin_basename, array( $this, 'add_action_links' ) );
148
149 // Load admin style sheet and JavaScript.
150 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
151 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
152
153 // add_action( 'plugins_loaded', array( $this, 'register_metaboxes' ), 14 );
154 add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_styles' ), 10 );
155 add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 10 );
156 add_action( 'customize_preview_init', array( $this, 'customizer_live_preview_enqueue_scripts' ), 99999 );
157
158 $load_location = self::get_plugin_option( 'style_resources_location', 'wp_head' );
159
160 add_action( $load_location, array( $this, 'output_dynamic_style' ), 99999 );
161 add_action( 'wp_head', array( $this, 'output_typography_dynamic_style' ), 10 );
162
163 add_action( 'customize_register', array( $this, 'remove_default_sections' ), 11 );
164 add_action( 'customize_register', array( $this, 'register_customizer' ), 12 );
165
166 if ( self::get_plugin_option( 'enable_editor_style', true ) ) {
167 add_action( 'admin_head', array( $this, 'add_customizer_settings_into_wp_editor' ) );
168 }
169
170 // Jetpack Related
171 add_action( 'init', array( $this, 'set_jetpack_modules_config') );
172 add_filter( 'default_option_jetpack_active_modules', array( $this, 'default_jetpack_active_modules' ), 10, 1 );
173 add_filter( 'jetpack_get_available_modules', array( $this, 'jetpack_hide_blocked_modules'), 10, 1 );
174 add_filter( 'default_option_sharing-options', array( $this, 'default_jetpack_sharing_options' ), 10, 1 );
175 }
176
177 /**
178 * Return an instance of this class.
179 * @since 1.0.0
180 * @return object A single instance of this class.
181 */
182 public static function get_instance() {
183
184 // If the single instance hasn't been set, set it now.
185 if ( null == self::$instance ) {
186 self::$instance = new self;
187 }
188
189 return self::$instance;
190 }
191
192 /**
193 * Configs, Options and Values methods
194 */
195
196 function init_plugin_configs() {
197 self::$customizer_config = get_option( 'pixcustomify_config' );
198
199 // no option so go for default
200 if ( empty( self::$customizer_config ) ) {
201 self::$customizer_config = self::get_config_option( 'default_options' );
202 }
203
204 if ( empty( self::$customizer_config ) ) {
205 self::$customizer_config = array();
206 }
207
208 // allow themes or other plugins to filter the config
209 self::$customizer_config = apply_filters( 'customify_filter_fields', self::$customizer_config );
210
211 self::$opt_name = self::$localized['options_name'] = self::$customizer_config['opt-name'];
212
213 self::get_current_values();
214 self::$options_list = $this->get_options();
215
216 if ( $this->import_button_exists() ) {
217 self::$opt_name = self::$localized['import_rest_url'] = get_rest_url( '/customify/1.0/' );
218 self::$opt_name = self::$localized['import_rest_nonce'] = wp_create_nonce( 'wp_rest' );
219
220 $this->register_import_api();
221 }
222
223 $font_selector = new Customify_Font_Selector( $this );
224 self::$localized['theme_fonts'] = self::$theme_fonts = Customify_Font_Selector::$theme_fonts;
225 }
226
227 function set_jetpack_modules_config() {
228 // We expect an array of string module names like array( 'infinite-scroll', 'widgets' )
229 // See jetpack/modules/modules-heading.php for module names
230 self::$jetpack_default_modules = apply_filters ( 'customify_filter_jetpack_default_modules', array(
231 'shortcodes',
232 'widget-visibility',
233 'widgets',
234 ) );
235
236 // We expect an array of string module names like array( 'infinite-scroll', 'widgets' )
237 // See jetpack/modules/modules-heading.php for module names
238 self::$jetpack_blocked_modules = apply_filters ( 'customify_filter_jetpack_blocked_modules', array() );
239
240 self::$jetpack_sharing_default_options = apply_filters ( 'customify_filter_jetpack_sharing_default_options', array() );
241 }
242
243 /**
244 * Control the default modules that are activated in Jetpack.
245 * Use the `customify_filter_jetpack_default_modules` to set your's.
246 *
247 * @param array $default The default value to return if the option does not exist
248 * in the database.
249 * @return array
250 */
251 function default_jetpack_active_modules( $default ) {
252 if ( ! is_array( $default ) ) {
253 $default = array();
254 }
255
256 return array_merge( $default, self::$jetpack_default_modules );
257 }
258
259 /**
260 * Control the default Jetpack Sharing options.
261 * Use the `customify_filter_jetpack_sharing_default_options` to set your's.
262 *
263 * @param array $default The default value to return if the option does not exist
264 * in the database.
265 *
266 * @return array
267 */
268 function default_jetpack_sharing_options( $default ) {
269 if ( ! is_array( $default ) ) {
270 $default = array();
271 }
272
273 return array_merge( $default, self::$jetpack_sharing_default_options );
274 }
275
276 /**
277 * Control the modules that are available in Jetpack (hide some of them).
278 * Use the `customify_filter_jetpack_blocked_modules` filter to set your's.
279 *
280 * @param array $modules
281 *
282 * @return array
283 */
284 function jetpack_hide_blocked_modules( $modules ) {
285 return array_diff_key( $modules, array_flip( self::$jetpack_blocked_modules ) );
286 }
287
288 /**
289 * Fired when the plugin is activated.
290 * @since 1.0.0
291 *
292 * @param boolean $network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is disabled or plugin is activated on an individual blog.
293 */
294 public static function activate( $network_wide ) {
295
296 }
297
298 /**
299 * Fired when the plugin is deactivated.
300 * @since 1.0.0
301 *
302 * @param boolean $network_wide True if WPMU superadmin uses "Network Deactivate" action, false if WPMU is disabled or plugin is deactivated on an individual blog.
303 */
304 static function deactivate( $network_wide ) {
305 // TODO: Define deactivation functionality here
306 }
307
308 /**
309 * Load the plugin text domain for translation.
310 * @since 1.0.0
311 */
312 function load_plugin_textdomain() {
313
314 $domain = $this->plugin_slug;
315 $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
316
317 load_textdomain( $domain, WP_LANG_DIR . '/' . $domain . '/' . $domain . '-' . $locale . '.mo' );
318 load_plugin_textdomain( $domain, false, basename( dirname( __FILE__ ) ) . '/lang/' );
319 }
320
321 /** === RESOURCES === **/
322
323 /**
324 * Customizer admin styles
325 */
326 function enqueue_admin_customizer_styles() {
327 wp_enqueue_style( 'select2', plugins_url( 'js/select2/css/select2.css', __FILE__ ), array(), $this->version );
328 wp_enqueue_style( 'customify_style', plugins_url( 'css/customizer.css', __FILE__ ), array(), $this->version );
329 }
330
331 /**
332 * Customizer admin scripts
333 */
334 function enqueue_admin_customizer_scripts() {
335
336 wp_enqueue_script( 'select2', plugins_url( 'js/select2/js/select2.js', __FILE__ ), array( 'jquery' ), $this->version );
337 wp_enqueue_script( 'jquery-react', plugins_url( 'js/jquery-react.js', __FILE__ ), array( 'jquery' ), $this->version );
338 wp_enqueue_script( $this->plugin_slug . '-customizer-scripts', plugins_url( 'js/customizer.js', __FILE__ ), array(
339 'jquery',
340 'select2',
341 'underscore',
342 ), $this->version );
343
344 wp_localize_script( $this->plugin_slug . '-customizer-scripts', 'customify_settings', self::$localized );
345 }
346
347 /** Customizer scripts loaded only on previewer page */
348 function customizer_live_preview_enqueue_scripts() {
349
350 wp_register_script( $this->plugin_slug . 'CSSOM', plugins_url( 'js/CSSOM.js', __FILE__ ), array( 'jquery' ), $this->version, true );
351 wp_register_script( $this->plugin_slug . 'cssUpdate', plugins_url( 'js/jquery.cssUpdate.js', __FILE__ ), array(), $this->version, true );
352 wp_enqueue_script( $this->plugin_slug . '-previewer-scripts', plugins_url( 'js/customizer_preview.js', __FILE__ ), array(
353 'jquery',
354 $this->plugin_slug . 'CSSOM',
355 $this->plugin_slug . 'cssUpdate'
356 ), $this->version, true );
357
358 // when a live preview field is in action we need to know which props need 'px' as defaults
359 self::$localized['px_dependent_css_props'] = self::$pixel_dependent_css_properties;
360
361 wp_localize_script( $this->plugin_slug . '-previewer-scripts', 'customify_settings', self::$localized );
362 }
363
364 /**
365 * Add dynamic style only on the previewer page
366 */
367
368 /**
369 * Settings page styles
370 */
371 function enqueue_admin_styles() {
372
373 if ( ! isset( $this->plugin_screen_hook_suffix ) ) {
374 return;
375 }
376
377 $screen = get_current_screen();
378 if ( $screen->id == $this->plugin_screen_hook_suffix ) {
379 wp_enqueue_style( $this->plugin_slug . '-admin-styles', plugins_url( 'css/admin.css', __FILE__ ), array(), $this->version );
380 }
381 }
382
383 /**
384 * Settings page scripts
385 */
386 function enqueue_admin_scripts() {
387
388 if ( ! isset( $this->plugin_screen_hook_suffix ) ) {
389 return;
390 }
391
392 $screen = get_current_screen();
393 if ( $screen->id == $this->plugin_screen_hook_suffix ) {
394 wp_enqueue_script( $this->plugin_slug . '-admin-script', plugins_url( 'js/admin.js', __FILE__ ), array( 'jquery' ), $this->version );
395 wp_localize_script( $this->plugin_slug . '-admin-script', 'locals', array(
396 'ajax_url' => admin_url( 'admin-ajax.php' )
397 ) );
398 }
399
400
401 wp_localize_script( $this->plugin_slug . '-customizer-scripts', 'WP_API_Settings', array( 'root' => esc_url_raw( rest_url() ), 'nonce' => wp_create_nonce( 'wp_rest' ) ) );
402 }
403
404 /**
405 * Public style generated by customizer
406 */
407 function output_dynamic_style() {
408 $custom_css = "\n";
409
410 foreach ( self::$options_list as $option_id => $option ) {
411
412 if ( isset( $option['css'] ) && ! empty( $option['css'] ) ) {
413 // now process each
414 $custom_css .= $this->convert_setting_to_css( $option_id, $option['css'] );
415 }
416
417 if ( $option['type'] === 'custom_background' ) {
418 $custom_css .= $this->process_custom_background_field_output( $option_id, $option );
419 }
420 }
421
422 if ( ! empty( self::$media_queries ) ) {
423
424 foreach ( self::$media_queries as $media_query => $properties ) {
425
426 if ( empty( $properties ) ) {
427 continue;
428 }
429
430 $custom_css .= '@media ' . $media_query . " {\n";
431
432 foreach ( $properties as $key => $property ) {
433 $property_settings = $property['property'];
434 $property_value = $property['value'];
435 $custom_css .= "\t" . self::proccess_css_property( $property_settings, $property_value );
436 }
437
438 $custom_css .= "\n}\n";
439
440 }
441 }
442
443 $custom_css .= "\n";
444
445 //@todo maybe add a filter to this output ?>
446 <style id="customify_output_style">
447 <?php echo( $custom_css ); ?>
448 </style>
449 <?php
450
451
452 /**
453 * from now on we output only style tags only for the preview purpose
454 * so don't cry if you see 30+ style tags for each section
455 */
456 if ( ! isset( $GLOBALS['wp_customize'] ) ) {
457 return;
458 }
459
460 foreach ( self::$options_list as $option_id => $options ) {
461
462 if ( $options['type'] === 'custom_background' ) {
463 $options['value'] = self::get_option( $option_id );
464 $custom_background_output = $this->process_custom_background_field_output( $option_id, $options ); ?>
465
466 <style id="custom_backgorund_output_for_<?php echo $option_id; ?>">
467 <?php
468 if ( isset( $custom_background_output ) && ! empty( $custom_background_output )) {
469 echo $custom_background_output;
470 } ?>
471 </style>
472 <?php }
473
474 if ( ! isset( $options['live'] ) || $options['live'] !== true ) {
475 continue;
476 }
477
478 $this_value = self::get_option( $option_id );
479 foreach ( $options['css'] as $key => $properties_set ) { ?>
480 <style id="dynamic_setting_<?php echo $option_id . '_property_' . str_replace( '-', '_', $properties_set['property'] ); ?>" type="text/css"><?php
481
482 if ( isset( $properties_set['media'] ) && ! empty( $properties_set['media'] ) ) {
483 echo '@media '. $properties_set['media'] . " {\n";
484 }
485
486 if ( isset( $properties_set['selector'] ) && isset( $properties_set['property'] ) ) {
487 echo self::proccess_css_property($properties_set, $this_value);
488 }
489
490 if ( isset( $properties_set['media'] ) && ! empty( $properties_set['media'] ) ) {
491 echo "}\n";
492 } ?>
493 </style>
494 <?php }
495 }
496
497 if ( ! empty( self::$media_queries ) ) {
498
499 foreach ( self::$media_queries as $media_query => $properties ) {
500
501 if ( empty( $properties ) ) {
502 continue;
503 }
504
505 $display = false;
506 $media_q = '@media ' . $media_query . " {\n";
507
508 foreach ( $properties as $key => $property ) {
509
510 if ( ! isset( $options['live'] ) || $options['live'] !== true ) {
511 continue;
512 }
513
514 $display = true; ?>
515 <style id="dynamic_setting_<?php echo $key; ?>" type="text/css"><?php
516 $property_settings = $property['property'];
517 $property_value = $property['value'];
518 $media_q .= "\t" . self::proccess_css_property( $property_settings, $property_value );?>
519 </style>
520 <?php }
521
522 $media_q .= "\n}\n";
523
524 if ( $display ) {
525 $custom_css .= $media_q;
526 }
527 }
528 }
529 }
530
531 protected function load_google_fonts() {
532
533 $fonts_path = plugin_dir_path( __FILE__ ) . 'features/customizer/controls/resources/google.fonts.php';
534
535 if ( file_exists( $fonts_path ) ) {
536 self::$google_fonts = require( $fonts_path );
537 }
538
539 if ( ! empty( self::$google_fonts ) ) {
540 return self::$google_fonts;
541 }
542
543 return false;
544 }
545
546 function output_typography_dynamic_style() {
547
548 self::get_typography_fields( self::$options_list, 'type', 'typography', self::$typo_settings );
549
550 if ( empty( self::$typo_settings ) ) {
551 return;
552 }
553
554 $families = '';
555
556 foreach ( self::$typo_settings as $id => $font ) {
557 if ( isset ( $font['value'] ) ) {
558
559 $load_all_weights = false;
560 if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
561 $load_all_weights = true;
562 }
563
564 // shim the time when this was an array
565 if ( is_array( $font['value'] ) ) {
566 $font['value'] = stripslashes_deep( $font['value'] );
567 $font['value'] = json_encode( $font['value'] );
568 }
569
570 $value = json_decode( wp_unslash( PixCustomifyPlugin::decodeURIComponent( $font['value'] ) ), true );
571
572 // in case the value is still null, try default value(mostly for google fonts)
573 if ( ! is_array( $value ) || $value === null ) {
574 $value = $this->get_font_defaults_value( str_replace( '"', '', $font['value'] ) );
575 }
576
577 //bail if by this time we don't have a value of some sort
578 if ( empty( $value ) ) {
579 continue;
580 }
581
582 //Handle special logic for when the $value array is not an associative array
583 if ( ! self::is_assoc( $value ) ) {
584 $value = $this->process_a_not_associative_font_default( $value );
585 }
586
587 if ( isset( $value['font_family'] ) && isset( $value['type'] ) && $value['type'] == 'google' ) {
588 $families .= "'" . $value['font_family'];
589
590 if ( $load_all_weights && is_array( $value['variants'] ) ) {
591 $families .= ":" . implode( ',', $value['variants'] );
592 } elseif ( isset( $value['selected_variants'] ) && ! empty( $value['selected_variants'] ) ) {
593 if ( is_array( $value['selected_variants'] ) ) {
594 $families .= ":" . implode( ',', $value['selected_variants'] );
595 } elseif ( is_string( $value['selected_variants'] ) || is_numeric( $value['selected_variants'] ) ) {
596 $families .= ":" . $value['selected_variants'];
597 }
598 } elseif ( isset( $value['variants'] ) && ! empty( $value['variants'] ) ) {
599 if ( is_array( $value['variants'] ) ) {
600 $families .= ":" . implode( ',', $value['variants'] );
601 } else {
602 $families .= ":" . $value['variants'];
603 }
604 }
605
606 if ( isset( $value['selected_subsets'] ) && ! empty( $value['selected_subsets'] ) ) {
607 if ( is_array( $value['selected_subsets'] ) ) {
608 $families .= ":" . implode( ',', $value['selected_subsets'] );
609 } else {
610 $families .= ":" . $value['selected_subsets'];
611 }
612 } elseif ( isset( $value['subsets'] ) && ! empty( $value['subsets'] ) ) {
613 if ( is_array( $value['subsets'] ) ) {
614 $families .= ":" . implode( ',', $value['subsets'] );
615 } else {
616 $families .= ":" . $value['subsets'];
617 }
618 }
619
620 $families .= '\',';
621 }
622 }
623 }
624
625 if ( ! empty ( $families ) && self::get_plugin_option( 'typography', '1' ) && self::get_plugin_option( 'typography_google_fonts', 1 ) ) { ?>
626 <script type="text/javascript">
627 if ( typeof WebFont !== 'undefined' ) {<?php // if there is a WebFont object, use it ?>
628 WebFont.load( {
629 google: {families: [<?php echo( rtrim( $families, ',' ) ); ?>]},
630 classes: false,
631 events: false
632 } );
633 } else {<?php // basically when we don't have the WebFont object we create the google script dynamically ?>
634
635 var tk = document.createElement( 'script' );
636 tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
637 tk.type = 'text/javascript';
638
639 tk.onload = tk.onreadystatechange = function() {
640 WebFont.load( {
641 google: {families: [<?php echo( rtrim( $families, ',' ) ); ?>]},
642 classes: false,
643 events: false
644 } );
645 };
646
647 var s = document.getElementsByTagName( 'script' )[0];
648 s.parentNode.insertBefore( tk, s );
649 }
650 </script>
651 <?php } ?>
652 <style id="customify_typography_output_style">
653 <?php
654 foreach ( self::$typo_settings as $key => $font ) {
655 $load_all_weights = false;
656 if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
657 $load_all_weights = true;
658 }
659
660 if ( isset( $font['selector'] ) && isset( $font['value'] ) && ! empty( $font['value'] ) ) {
661
662 $value = json_decode( PixCustomifyPlugin::decodeURIComponent( $font['value'] ), true );
663 // in case the value is still null, try default value(mostly for google fonts)
664 if ( $value === null ) {
665 $value = $this->get_font_defaults_value( $font['value'] );
666 }
667
668 // shim the old case when the default was only the font name
669 if ( is_string( $value ) && ! empty( $value ) ) {
670 $value = array( 'font_family' => $value );
671 }
672
673 //Handle special logic for when the $value array is not an associative array
674 if ( ! self::is_assoc( $value ) ) {
675 $value = $this->process_a_not_associative_font_default( $value );
676 }
677
678 $selected_variant = '';
679 if ( ! empty( $value['selected_variants'] ) ) {
680 if ( is_array( $value['selected_variants'] ) ) {
681 $selected_variant = $value['selected_variants'][0];
682 } else {
683 $selected_variant = $value['selected_variants'];
684 }
685 }
686
687 // First handle the case where we have the font-family in the selected variant (usually this means a custom font from our Fonto plugin)
688 if ( ! empty( $selected_variant ) && is_array( $selected_variant ) && ! empty( $selected_variant['font-family'] ) ) {
689 //the variant's font-family
690 echo $font['selector'] . " {\nfont-family: " . $selected_variant['font-family'] . ";\n";
691
692 if ( ! $load_all_weights ) {
693 // if this is a custom font (like from our plugin Fonto) with individual styles & weights - i.e. the font-family says it all
694 // we need to "force" the font-weight and font-style
695 if ( ! empty( $value['type'] ) && 'custom_individual' == $value['type'] ) {
696 $selected_variant['font-weight'] = '400 !important';
697 $selected_variant['font-style'] = 'normal !important';
698 }
699
700 // output the font weight, if available
701 if ( ! empty( $selected_variant['font-weight'] ) ) {
702 echo "font-weight: " . $selected_variant['font-weight'] . ";\n";
703 }
704
705 // output the font style, if available
706 if ( ! empty( $selected_variant['font-style'] ) ) {
707 echo "font-style: " . $selected_variant['font-style'] . ";\n";
708 }
709 }
710
711 echo "}\n";
712 } elseif ( isset( $value['font_family'] ) ) {
713 // the selected font family
714 echo $font['selector'] . " {\n font-family: " . $value['font_family'] . ";\n";
715
716 if ( ! empty( $selected_variant ) && ! $load_all_weights ) {
717 $weight_and_style = strtolower( $selected_variant );
718
719 $italic_font = false;
720
721 //determine if this is an italic font (the $weight_and_style is usually like '400' or '400italic' )
722 if ( strpos( $weight_and_style, 'italic' ) !== false ) {
723 $weight_and_style = str_replace( 'italic', '', $weight_and_style);
724 $italic_font = true;
725 }
726
727 if ( ! empty( $weight_and_style ) ) {
728 //a little bit of sanity check - in case it's not a number
729 if( $weight_and_style === 'regular' ) {
730 $weight_and_style = 'normal';
731 }
732 echo "font-weight: " . $weight_and_style . ";\n";
733 }
734
735 if ( $italic_font ) {
736 echo "font-style: italic;\n";
737 }
738 }
739
740 echo "}\n";
741 }
742 }
743 } ?>
744 </style>
745 <?php }
746
747 /**
748 * Handle special logic for when the $value array is not an associative array
749 * Return a new associative array with proper keys
750 */
751 protected function process_a_not_associative_font_default( $value ) {
752
753 $new_value = array();
754
755 //Let's determine some type of font
756 if ( ! isset( $value[2] ) || ( isset( $value[2] ) && 'google' == $value[2] ) ) {
757 $new_value = $this->get_font_defaults_value( $value[0] );
758 } else {
759 $new_value['type'] = $value[2];
760 }
761
762 if ( null == $new_value ) {
763 $new_value = array();
764 }
765
766 //The first entry is the font-family
767 if ( isset( $value[0] ) ) {
768 $new_value['font_family'] = $value[0];
769 }
770
771 //In case we don't have an associative array
772 //The second entry is the variants
773 if ( isset( $value[1] ) ) {
774 $new_value['selected_variants'] = $value[1];
775 }
776
777 return $new_value;
778 }
779
780 /**
781 *
782 * @param $font_name
783 *
784 * @return null
785 */
786 protected function get_font_defaults_value( $font_name ) {
787
788 if ( empty( self::$google_fonts ) ) {
789 $this->load_google_fonts();
790 }
791
792 if ( isset( self::$google_fonts[ $font_name ] ) ) {
793 $value = self::$google_fonts[ $font_name ];
794 $value['font_family'] = $font_name;
795 $value['type'] = 'google';
796 return $value;
797 } elseif ( isset( self::$theme_fonts[ $font_name ] ) ) {
798 $value['type'] = 'theme_font';
799 $value['src'] = self::$theme_fonts[ $font_name ]['src'];
800 $value['variants'] = self::$theme_fonts[ $font_name ]['variants'];
801 $value['font_family'] = self::$theme_fonts[ $font_name ]['family'];
802 return $value;
803 }
804
805 return null;
806 }
807
808 /**
809 * Turn css options into a valid CSS output
810 *
811 * @param $option_id
812 * @param array $css_config
813 *
814 * @return string
815 */
816 protected function convert_setting_to_css( $option_id, $css_config = array() ) {
817 $output = '';
818
819 $this_value = self::get_option( $option_id );
820
821 if ( empty( $css_config ) ) {
822 return $output;
823 }
824
825 foreach ( $css_config as $css_property ) {
826
827 if ( isset( $css_property['media'] ) && ! empty( $css_property['media'] ) ) {
828 self::$media_queries[ $css_property['media'] ][ $option_id ] = array(
829 'property' => $css_property,
830 'value' => $this_value
831 );
832 continue;
833 }
834
835 if ( ! isset( $css_property['selector'] ) || isset( $css_property['property'] ) ) {
836 $output .= self::proccess_css_property( $css_property, $this_value );
837 }
838 }
839
840 return $output;
841 }
842
843 protected function proccess_css_property( $css_property, $this_value ) {
844 $unit = '';
845
846 if ( isset( $css_property['unit'] ) ) {
847 $unit = $css_property['unit'];
848 }
849
850 // if the unit isn't specified but the property should have a unit force 'px' as it
851 if ( empty( $unit ) && in_array( $css_property['property'], self::$pixel_dependent_css_properties ) ) {
852 $unit = 'px';
853 }
854
855 $this_property_output = $css_property['selector'] . ' { ' . $css_property['property'] . ': ' . $this_value . $unit . "; } \n";
856
857 if ( isset( $css_property['callback_filter'] ) && function_exists( $css_property['callback_filter'] ) ) {
858 $this_property_output = call_user_func( $css_property['callback_filter'], $this_value, $css_property['selector'], $css_property['property'], $unit );
859 }
860
861 return $this_property_output;
862 }
863
864 protected function process_custom_background_field_output( $option_id, $options ) {
865 $selector = '';
866
867 if ( ! isset( $options['value'] ) ) {
868 return false;
869 }
870 $value = $options['value'];
871
872 if ( ! isset( $options['output'] ) ) {
873 return $selector;
874 } elseif ( is_string( $options['output'] ) ) {
875 $selector = $options['output'];
876 } elseif ( is_array( $options['output'] ) ) {
877 $selector = implode( ' ', $options['output'] );
878 }
879 ob_start();
880
881 echo "\n" . $selector . " { \n";
882 if ( isset( $value['background-image'] ) && ! empty( $value['background-image'] ) ) {
883 echo "background-image: url( " . $value['background-image'] . ");\n";
884 } else {
885 echo "background-image: none;\n";
886 }
887
888 if ( isset( $value['background-repeat'] ) && ! empty( $value['background-repeat'] ) ) {
889 echo "background-repeat:" . $value['background-repeat'] . ";\n";
890 }
891
892 if ( isset( $value['background-position'] ) && ! empty( $value['background-position'] ) ) {
893 echo "background-position:" . $value['background-position'] . ";\n";
894 }
895
896 if ( isset( $value['background-size'] ) && ! empty( $value['background-size'] ) ) {
897 echo "background-size:" . $value['background-size'] . ";\n";
898 }
899
900 if ( isset( $value['background-attachment'] ) && ! empty( $value['background-attachment'] ) ) {
901 echo "background-attachment:" . $value['background-attachment'] . ";\n";
902 }
903 echo "\n}\n";
904
905 return ob_get_clean();
906 }
907
908 /**
909 * add our customizer styling edits into the wp_editor
910 */
911 function add_customizer_settings_into_wp_editor() {
912
913 ob_start();
914 $this->output_typography_dynamic_style();
915 $this->output_dynamic_style();
916
917 $custom_css = ob_get_clean(); ?>
918 <script type="text/javascript">
919 /* <![CDATA[ */
920 (function( $ ) {
921 $( window ).load( function() {
922 /**
923 * @param iframe_id the id of the frame you whant to append the style
924 * @param style_element the style element you want to append
925 */
926 var append_script_to_iframe = function( ifrm_id, scriptEl ) {
927 var myIframe = document.getElementById( ifrm_id );
928
929 var script = myIframe.contentWindow.document.createElement( "script" );
930 script.type = "text/javascript";
931 script.innerHTML = scriptEl.innerHTML;
932
933 myIframe.contentWindow.document.head.appendChild( script );
934 };
935
936 var append_style_to_iframe = function( ifrm_id, styleElment ) {
937 var ifrm = window.frames[ifrm_id];
938 ifrm = ( ifrm.contentDocument || ifrm.contentDocument || ifrm.document );
939 var head = ifrm.getElementsByTagName( 'head' )[0];
940
941 if ( typeof styleElment !== "undefined" ) {
942 head.appendChild( styleElment );
943 }
944 };
945
946 var xmlString = <?php echo json_encode( str_replace( "\n", "", $custom_css ) ); ?>,
947 parser = new DOMParser(),
948 doc = parser.parseFromString( xmlString, "text/html" );
949
950 if ( typeof window.frames['content_ifr'] !== 'undefined' ) {
951
952 $.each( doc.head.childNodes, function( key, el ) {
953
954 if ( typeof el !== "undefined" && typeof el.tagName !== "undefined" ) {
955
956 switch ( el.tagName ) {
957
958 case 'STYLE' :
959 append_style_to_iframe( 'content_ifr', el );
960 break;
961
962 case 'SCRIPT' :
963 append_script_to_iframe( 'content_ifr', el );
964 break;
965 default:
966 break;
967 }
968 }
969 } );
970 }
971 } );
972 })( jQuery );
973 /* ]]> */
974 </script>
975 <?php }
976
977 /**
978 * Register the administration menu for this plugin into the WordPress Dashboard menu.
979 */
980 function add_plugin_admin_menu() {
981 $this->plugin_screen_hook_suffix = add_options_page( __( 'Customify', $this->plugin_slug ), __( 'Customify', $this->plugin_slug ), 'edit_plugins', $this->plugin_slug, array(
982 $this,
983 'display_plugin_admin_page'
984 ) );
985 }
986
987 /**
988 * Render the settings page for this plugin.
989 */
990 function display_plugin_admin_page() {
991 include_once( 'views/admin.php' );
992 }
993
994 /**
995 * Add settings action link to the plugins page.
996 */
997 function add_action_links( $links ) {
998 return array_merge( array( 'settings' => '<a href="' . admin_url( 'options-general.php?page=pixcustomify' ) . '">' . __( 'Settings', $this->plugin_slug ) . '</a>' ), $links );
999 }
1000
1001 protected function register_customizer_controls() {
1002
1003 // first get the base customizer extend class
1004 require_once( self::get_base_path() . '/features/customizer/class-Pix_Customize_Control.php' );
1005
1006 // now get all the controls
1007 $path = self::get_base_path() . '/features/customizer/controls/';
1008 pixcustomify::require_all( $path );
1009 }
1010
1011 function register_customizer( $wp_customize ) {
1012
1013 $this->register_customizer_controls();
1014
1015 $customizer_settings = self::$customizer_config;
1016
1017 if ( ! empty ( $customizer_settings ) ) {
1018
1019 // first check the very needed options name
1020 if ( ! isset ( $customizer_settings['opt-name'] ) || empty( $customizer_settings['opt-name'] ) ) {
1021 return;
1022 }
1023 $options_name = $customizer_settings['opt-name'];
1024 $wp_customize->options_key = $options_name;
1025
1026 // let's check if we have sections or panels
1027 if ( isset( $customizer_settings['panels'] ) && ! empty( $customizer_settings['panels'] ) ) {
1028
1029 foreach ( $customizer_settings['panels'] as $panel_id => $panel_settings ) {
1030
1031 if ( ! empty( $panel_id ) && isset( $panel_settings['sections'] ) && ! empty( $panel_settings['sections'] ) ) {
1032
1033 $panel_id = $options_name . '[' . $panel_id . ']';
1034 $panel_args = array(
1035 'priority' => 10,
1036 'capability' => 'edit_theme_options',
1037 'title' => __( 'Panel title is required', 'textdomain' ),
1038 'description' => __( 'Description of what this panel does.', 'textdomain' ),
1039 );
1040
1041 if ( isset( $panel_settings['priority'] ) && ! empty( $panel_settings['priority'] ) ) {
1042 $panel_args['priority'] = $panel_settings['priority'];
1043 }
1044
1045 if ( isset( $panel_settings['title'] ) && ! empty( $panel_settings['title'] ) ) {
1046 $panel_args['title'] = $panel_settings['title'];
1047 }
1048
1049 if ( isset( $panel_settings['description'] ) && ! empty( $panel_settings['description'] ) ) {
1050 $panel_args[10] = $panel_settings['description'];
1051 }
1052
1053 $wp_customize->add_panel( $panel_id, $panel_args );
1054
1055 foreach ( $panel_settings['sections'] as $section_id => $section_settings ) {
1056 if ( ! empty( $section_id ) && isset( $section_settings['options'] ) && ! empty( $section_settings['options'] ) ) {
1057 $this->register_section( $panel_id, $section_id, $options_name, $section_settings, $wp_customize );
1058 }
1059 }
1060 }
1061 }
1062 }
1063
1064 if ( isset( $customizer_settings['sections'] ) && ! empty( $customizer_settings['sections'] ) ) {
1065
1066 foreach ( $customizer_settings['sections'] as $section_id => $section_settings ) {
1067 if ( ! empty( $section_id ) && isset( $section_settings['options'] ) && ! empty( $section_settings['options'] ) ) {
1068 $this->register_section( $panel_id = false, $section_id, $options_name, $section_settings, $wp_customize );
1069 }
1070 }
1071 }
1072
1073 if ( self::$plugin_settings['enable_reset_buttons'] ) {
1074 // create a toolbar section which will be present all the time
1075 $reset_section_settings = array(
1076 'title' => 'Customify toolbar',
1077 'options' => array(
1078 'reset_all_button' => array(
1079 'type' => 'button',
1080 'label' => 'Reset Customify',
1081 'action' => 'reset_customify',
1082 'value' => 'Reset'
1083 ),
1084 )
1085 );
1086
1087 $wp_customize->add_section(
1088 'customify_toolbar',
1089 array(
1090 'title' => '',
1091 'priority' => 999999999
1092 )
1093 );
1094
1095 $wp_customize->add_setting(
1096 'reset_customify',
1097 array()
1098 );
1099 $wp_customize->add_control( new Pix_Customize_Button_Control(
1100 $wp_customize,
1101 'reset_customify',
1102 array(
1103 'label' => __( 'Reset Customify to Defaults', 'customify_txtd' ),
1104 'section' => 'customify_toolbar',
1105 'settings' => 'reset_customify',
1106 'action' => 'reset_customify',
1107 )
1108 ) );
1109 }
1110
1111 // register typekit options
1112 if ( isset( $customizer_settings['typekit_options'] ) ) {
1113
1114 // create a toolbar section which will be present all the time
1115 $reset_section_settings = array(
1116 'title' => 'Customify Typekit Options',
1117 'capability' => 'manage_options',
1118 'options' => array(
1119 'typkit_user' => array(
1120 'type' => 'text',
1121 'label' => 'Typekit Username',
1122 ),
1123 'typkit_password' => array(
1124 'type' => 'text',
1125 'label' => 'Typekit Username',
1126 ),
1127 )
1128 );
1129 }
1130 }
1131
1132 do_action( 'customify_create_custom_control', $wp_customize );
1133 }
1134
1135 protected function register_section( $panel_id, $section_key, $options_name, $section_settings, $wp_customize ) {
1136
1137 if ( isset( self::$plugin_settings['disable_customify_sections'] ) && isset( self::$plugin_settings['disable_customify_sections'][ $section_key ] ) ) {
1138 return;
1139 }
1140
1141 $section_args = array(
1142 'priority' => 10,
1143 'capability' => 'edit_theme_options',
1144 'title' => __( 'Title Section is required', 'textdomain' ),
1145 'panel' => $panel_id,
1146 );
1147 $section_id = $options_name . '[' . $section_key . ']';
1148
1149 if ( isset( $section_settings['priority'] ) && ! empty( $section_settings['priority'] ) ) {
1150 $section_args['priority'] = $section_settings['priority'];
1151 }
1152
1153 if ( isset( $section_settings['title'] ) && ! empty( $section_settings['title'] ) ) {
1154 $section_args['title'] = $section_settings['title'];
1155 }
1156
1157 if ( isset( $section_settings['theme_supports'] ) && ! empty( $section_settings['theme_supports'] ) ) {
1158 $section_args['theme_supports'] = $section_settings['theme_supports'];
1159 }
1160
1161 if ( isset( $section_settings['description'] ) && ! empty( $section_settings['description'] ) ) {
1162 $section_args['description'] = $section_settings['description'];
1163 }
1164
1165 $wp_customize->add_section( $section_id, $section_args );
1166
1167 foreach ( $section_settings['options'] as $option_id => $option_config ) {
1168
1169 if ( empty( $option_id ) || ! isset( $option_config['type'] ) ) {
1170 continue;
1171 }
1172
1173 $option_id = $options_name . '[' . $option_id . ']';
1174
1175 $this->register_field( $section_id, $option_id, $option_config, $wp_customize );
1176 }
1177
1178 }
1179
1180 protected function register_field( $section_id, $setting_id, $setting_config, $wp_customize ) {
1181
1182 $add_control = true;
1183 // defaults
1184 $setting_args = array(
1185 'default' => '',
1186 'capability' => 'edit_theme_options',
1187 'transport' => 'refresh',
1188 );
1189 $control_args = array(
1190 'label' => '',
1191 'section' => $section_id,
1192 'settings' => $setting_id,
1193 );
1194
1195 self::$localized['settings'][ $setting_id ] = $setting_config;
1196
1197 // sanitize settings
1198 if ( ( isset( $setting_config['live'] ) && $setting_config['live'] ) || $setting_config['type'] === 'font' ) {
1199 $setting_args['transport'] = 'postMessage';
1200 }
1201
1202 if ( isset( $setting_config['default'] ) ) {
1203 $setting_args['default'] = $setting_config['default'];
1204 }
1205
1206 if ( isset( $setting_config['capability'] ) && ! empty( $setting_config['capability'] ) ) {
1207 $setting_args['capability'] = $setting_config['capability'];
1208 }
1209
1210 if ( self::$plugin_settings['values_store_mod'] == 'option' ) {
1211 $setting_args['type'] = 'option';
1212 }
1213
1214 // if we arrive here this means we have a custom field control
1215 switch ( $setting_config['type'] ) {
1216
1217 case 'checkbox':
1218
1219 $setting_args['sanitize_callback'] = array( $this, 'setting_sanitize_checkbox' );
1220 break;
1221
1222 default:
1223 break;
1224 }
1225
1226 if ( isset( $setting_config['sanitize_callback'] ) && ! empty( $setting_config['sanitize_callback'] ) && function_exists( $setting_config['sanitize_callback'] ) ) {
1227 $setting_args['sanitize_callback'] = $setting_config['sanitize_callback'];
1228 }
1229
1230 // and add it
1231 $wp_customize->add_setting( $setting_id, $setting_args );
1232
1233 // now sanitize the control
1234 if ( isset( $setting_config['label'] ) && ! empty( $setting_config['label'] ) ) {
1235 $control_args['label'] = $setting_config['label'];
1236 }
1237
1238 if ( isset( $setting_config['priority'] ) && ! empty( $setting_config['priority'] ) ) {
1239 $control_args['priority'] = $setting_config['priority'];
1240 }
1241
1242 if ( isset( $setting_config['desc'] ) && ! empty( $setting_config['desc'] ) ) {
1243 $control_args['description'] = $setting_config['desc'];
1244 }
1245
1246
1247 $control_args['type'] = $setting_config['type'];
1248
1249 // select the control type
1250 // but first init a default
1251 $control_class_name = 'Pix_Customize_Text_Control';
1252
1253 // if is a standard wp field type call it here and skip the rest
1254 if ( in_array( $setting_config['type'], array(
1255 'checkbox',
1256 'dropdown-pages',
1257 'url',
1258 'date',
1259 'time',
1260 'datetime',
1261 'week',
1262 'search'
1263 ) ) ) {
1264 $wp_customize->add_control( $setting_id . '_control', $control_args );
1265
1266 return;
1267 } elseif ( in_array( $setting_config['type'], array(
1268 'radio',
1269 'select'
1270 ) ) && isset( $setting_config['choices'] ) && ! empty( $setting_config['choices'] )
1271 ) {
1272 $control_args['choices'] = $setting_config['choices'];
1273 $wp_customize->add_control( $setting_id . '_control', $control_args );
1274
1275 return;
1276 } elseif ( in_array( $setting_config['type'], array( 'range' ) ) && isset( $setting_config['input_attrs'] ) && ! empty( $setting_config['input_attrs'] ) ) {
1277
1278 $control_args['input_attrs'] = $setting_config['input_attrs'];
1279
1280 $wp_customize->add_control( $setting_id . '_control', $control_args );
1281 }
1282
1283 // if we arrive here this means we have a custom field control
1284 switch ( $setting_config['type'] ) {
1285
1286 case 'text':
1287
1288 if ( isset( $setting_config['live'] ) ) {
1289 $control_args['live'] = $setting_config['live'];
1290 }
1291
1292 $control_class_name = 'Pix_Customize_Text_Control';
1293 break;
1294
1295 case 'textarea':
1296
1297 if ( isset( $setting_config['live'] ) ) {
1298 $control_args['live'] = $setting_config['live'];
1299 }
1300
1301 $control_class_name = 'Pix_Customize_Textarea_Control';
1302 break;
1303
1304 case 'color':
1305
1306 $control_class_name = 'WP_Customize_Color_Control';
1307 break;
1308
1309 case 'color_drop':
1310
1311 $control_class_name = 'Pix_Customize_Color_Drop_Control';
1312 break;
1313
1314 case 'ace_editor':
1315
1316 if ( isset( $setting_config['live'] ) ) {
1317 $control_args['live'] = $setting_config['live'];
1318 }
1319
1320 if ( isset( $setting_config['editor_type'] ) ) {
1321 $control_args['editor_type'] = $setting_config['editor_type'];
1322 }
1323
1324 $control_class_name = 'Pix_Customize_Ace_Editor_Control';
1325 break;
1326
1327 case 'upload':
1328
1329 $control_class_name = 'WP_Customize_Upload_Control';
1330 break;
1331
1332 case 'image':
1333
1334 $control_class_name = 'WP_Customize_Image_Control';
1335 break;
1336
1337 case 'media':
1338
1339 $control_class_name = 'WP_Customize_Media_Control';
1340 break;
1341
1342 case 'custom_background':
1343 if ( isset( $setting_config['field'] ) ) {
1344 $control_args['field'] = $setting_config['field'];
1345 }
1346
1347 $control_class_name = 'Pix_Customize_Background_Control';
1348 break;
1349
1350 case 'cropped_media':
1351
1352 if ( isset( $setting_config['width'] ) ) {
1353 $control_args['width'] = $setting_config['width'];
1354 }
1355
1356 if ( isset( $setting_config['height'] ) ) {
1357 $control_args['height'] = $setting_config['height'];
1358 }
1359
1360 if ( isset( $setting_config['flex_width'] ) ) {
1361 $control_args['flex_width'] = $setting_config['flex_width'];
1362 }
1363
1364 if ( isset( $setting_config['flex_height'] ) ) {
1365 $control_args['flex_height'] = $setting_config['flex_height'];
1366 }
1367
1368 $control_class_name = 'WP_Customize_Cropped_Image_Control';
1369 break;
1370
1371 // Custom types
1372 case 'typography' :
1373
1374 $use_typography = self::get_plugin_option( 'typography', '1' );
1375
1376 if ( $use_typography === false ) {
1377 $add_control = false;
1378 continue;
1379 }
1380
1381 $control_class_name = 'Pix_Customize_Typography_Control';
1382
1383 if ( isset( $setting_config['backup'] ) ) {
1384 $control_args['backup'] = $setting_config['backup'];
1385 }
1386
1387 if ( isset( $setting_config['font_weight'] ) ) {
1388 $control_args['font_weight'] = $setting_config['font_weight'];
1389 }
1390
1391 if ( isset( $setting_config['subsets'] ) ) {
1392 $control_args['subsets'] = $setting_config['subsets'];
1393 }
1394
1395 if ( isset( $setting_config['recommended'] ) ) {
1396 $control_args['recommended'] = array_flip( $setting_config['recommended'] );
1397 }
1398
1399 if ( isset( $setting_config['load_all_weights'] ) ) {
1400 $control_args['load_all_weights'] = $setting_config['load_all_weights'];
1401 }
1402
1403 if ( isset( $setting_config['default'] ) ) {
1404 $control_args['default'] = $setting_config['default'];
1405 }
1406
1407 break;
1408
1409 // Custom types
1410 case 'font' :
1411
1412 $use_typography = self::get_plugin_option( 'typography', '1' );
1413
1414 if ( $use_typography === false ) {
1415 $add_control = false;
1416 continue;
1417 }
1418
1419 $control_class_name = 'Pix_Customize_Font_Control';
1420
1421 if ( isset( $setting_config['backup'] ) ) {
1422 $control_args['backup'] = $setting_config['backup'];
1423 }
1424
1425 if ( isset( $setting_config['font_weight'] ) ) {
1426 $control_args['font_weight'] = $setting_config['font_weight'];
1427 }
1428
1429 if ( isset( $setting_config['subsets'] ) ) {
1430 $control_args['subsets'] = $setting_config['subsets'];
1431 }
1432
1433 if ( isset( $setting_config['recommended'] ) ) {
1434 $control_args['recommended'] = array_flip( $setting_config['recommended'] );
1435 }
1436
1437 if ( isset( $setting_config['load_all_weights'] ) ) {
1438 $control_args['load_all_weights'] = $setting_config['load_all_weights'];
1439 }
1440
1441 if ( isset( $setting_config['default'] ) ) {
1442 $control_args['default'] = $setting_config['default'];
1443 }
1444
1445 if ( isset( $setting_config['fields'] ) ) {
1446 $control_args['fields'] = $setting_config['fields'];
1447 }
1448 $control_args['live'] = true;
1449
1450 break;
1451
1452 case 'select2' :
1453
1454 if ( ! isset( $setting_config['choices'] ) || empty( $setting_config['choices'] ) ) {
1455 return;
1456 }
1457
1458 $control_args['choices'] = $setting_config['choices'];
1459
1460 $control_class_name = 'Pix_Customize_Select2_Control';
1461 break;
1462
1463 case 'preset' :
1464
1465 if ( ! isset( $setting_config['choices'] ) || empty( $setting_config['choices'] ) ) {
1466 return;
1467 }
1468
1469 $control_args['choices'] = $setting_config['choices'];
1470
1471 if ( isset( $setting_config['choices_type'] ) || ! empty( $setting_config['choices_type'] ) ) {
1472 $control_args['choices_type'] = $setting_config['choices_type'];
1473 }
1474
1475 if ( isset( $setting_config['desc'] ) || ! empty( $setting_config['desc'] ) ) {
1476 $control_args['description'] = $setting_config['desc'];
1477 }
1478
1479
1480 $control_class_name = 'Pix_Customize_Preset_Control';
1481 break;
1482
1483 case 'radio_image' :
1484
1485 if ( ! isset( $setting_config['choices'] ) || empty( $setting_config['choices'] ) ) {
1486 return;
1487 }
1488
1489 $control_args['choices'] = $setting_config['choices'];
1490
1491 if ( isset( $setting_config['choices_type'] ) || ! empty( $setting_config['choices_type'] ) ) {
1492 $control_args['choices_type'] = $setting_config['choices_type'];
1493 }
1494
1495 if ( isset( $setting_config['desc'] ) || ! empty( $setting_config['desc'] ) ) {
1496 $control_args['description'] = $setting_config['desc'];
1497 }
1498
1499
1500 $control_class_name = 'Pix_Customize_Radio_Image_Control';
1501 break;
1502
1503 case 'button' :
1504
1505 if ( ! isset( $setting_config['action'] ) || empty( $setting_config['action'] ) ) {
1506 return;
1507 }
1508
1509 $control_args['action'] = $setting_config['action'];
1510
1511 $control_class_name = 'Pix_Customize_Button_Control';
1512
1513 break;
1514
1515 case 'html' :
1516
1517 if ( isset( $setting_config['html'] ) || ! empty( $setting_config['html'] ) ) {
1518 $control_args['html'] = $setting_config['html'];
1519 }
1520
1521 $control_class_name = 'Pix_Customize_HTML_Control';
1522 break;
1523
1524 case 'import_demo_data' :
1525
1526 if ( isset( $setting_config['html'] ) || ! empty( $setting_config['html'] ) ) {
1527 $control_args['html'] = $setting_config['html'];
1528 }
1529
1530 if ( ! isset( $setting_config['label'] ) || empty( $setting_config['label'] ) ) {
1531 $control_args['label'] = esc_html__( 'Import', 'customify' );
1532 } else {
1533 $control_args['label'] = $setting_config['label'];
1534 }
1535
1536 if ( isset( $setting_config['notices'] ) && ! empty( $setting_config['notices'] ) ) {
1537 $control_args['notices'] = $setting_config['notices'];
1538 }
1539
1540 $control_class_name = 'Pix_Customize_Import_Demo_Data_Control';
1541 break;
1542
1543 default:
1544 // if we don't have a real control just quit, it doesn't even matter
1545 return;
1546 break;
1547 }
1548
1549 $this_control = new $control_class_name(
1550 $wp_customize,
1551 $setting_id . '_control',
1552 $control_args
1553 );
1554
1555 if ( $add_control ) {
1556 $wp_customize->add_control( $this_control );
1557 }
1558 }
1559
1560 /**
1561 * Remove the sections selected by user
1562 *
1563 * @param $wp_customize
1564 */
1565 function remove_default_sections( $wp_customize ) {
1566 global $wp_registered_sidebars;
1567
1568 $to_remove = self::get_plugin_option( 'disable_default_sections' );
1569
1570 if ( ! empty( $to_remove ) ) {
1571 foreach ( $to_remove as $section => $nothing ) {
1572
1573 if ( $section === 'widgets' ) {
1574 foreach ( $wp_registered_sidebars as $widget => $settings ) {
1575 $wp_customize->remove_section( 'sidebar-widgets-' . $widget );
1576 }
1577 continue;
1578 }
1579
1580 $wp_customize->remove_section( $section );
1581 }
1582 }
1583 }
1584
1585 static function get_base_path() {
1586 return plugin_dir_path( __FILE__ );
1587 }
1588
1589 protected static function get_typography_fields( $array, $key, $value, &$results, $input_key = 0 ) {
1590 if ( ! is_array( $array ) ) {
1591 return;
1592 }
1593
1594 if ( isset( $array[ $key ] ) && $array[ $key ] == $value ) {
1595 $results[ $input_key ] = $array;
1596
1597 $default = null;
1598
1599 if ( isset( $array['default'] ) && is_array( $array['default'] ) ) {
1600 $default = json_encode( $array['default'] );
1601 }
1602
1603 $results[ $input_key ]['value'] = self::get_option( $input_key, $default );
1604 }
1605
1606 foreach ( $array as $i => $subarray ) {
1607 self::get_typography_fields( $subarray, $key, $value, $results, $i );
1608 }
1609 }
1610
1611 function get_options_key() {
1612 if ( ! empty( self::$opt_name ) ) {
1613 return self::$opt_name;
1614 }
1615
1616 return false;
1617 }
1618
1619 /**
1620 * Use this function when you need to know if an import button is used
1621 * @return bool
1622 */
1623 function import_button_exists() {
1624
1625 if ( empty( self::$options_list ) ) {
1626 self::$options_list = $this->get_options();
1627 }
1628
1629 foreach ( self::$options_list as $option ) {
1630 if ( isset( $option['type'] ) && 'import_demo_data' === $option['type'] ) {
1631 return true;
1632 break;
1633 }
1634 }
1635
1636 return false;
1637 }
1638
1639 /** == Helpers == */
1640
1641
1642 protected static function check_for_customizer_values() {
1643 if ( isset( $_POST['customized'] ) && $_POST['customized'] !== '{}' ) {
1644 $the_value = $_POST['customized'];
1645 self::$customizer_values = json_decode( $the_value, true );
1646
1647 /**
1648 * if still empty, use stripslashes_deep to ensure compatibility with 5.2
1649 * http://stackoverflow.com/questions/28698165/json-data-cannot-be-accessed-in-php-version-5-2-17
1650 */
1651 if ( empty( self::$customizer_values ) ) {
1652 $stripped_value = stripslashes_deep( $the_value );
1653 self::$customizer_values = json_decode( $stripped_value, true );
1654 }
1655 } else {
1656 self::$customizer_values = false;
1657 }
1658 }
1659
1660 protected static function get_current_values() {
1661 $store_type = self::get_plugin_option( 'values_store_mod', 'option' );
1662 if ( $store_type === 'option' ) {
1663 self::$current_values = get_option( self::$opt_name );
1664 } elseif ( $store_type === 'theme_mod' ) {
1665 self::$current_values = get_theme_mod( self::$opt_name );
1666 }
1667 }
1668
1669 public function get_options() {
1670
1671 $settings = array();
1672
1673 if ( isset ( self::$customizer_config['panels'] ) ) {
1674
1675 foreach ( self::$customizer_config['panels'] as $pane_id => $panel_settings ) {
1676
1677 if ( isset( $panel_settings['sections'] ) ) {
1678 foreach ( $panel_settings['sections'] as $section_id => $section_settings ) {
1679 if ( isset( $section_settings['options'] ) ) {
1680 foreach ( $section_settings['options'] as $option_id => $option ) {
1681 $settings[ $option_id ] = $option;
1682 if ( isset( self::$current_values[ $option_id ] ) ) {
1683 $settings[ $option_id ]['value'] = self::$current_values[ $option_id ];
1684 }
1685 }
1686 }
1687 }
1688 }
1689 }
1690 }
1691
1692 if ( isset ( self::$customizer_config['sections'] ) ) {
1693 foreach ( self::$customizer_config['sections'] as $section_id => $section_settings ) {
1694 if ( isset( $section_settings['options'] ) ) {
1695 foreach ( $section_settings['options'] as $option_id => $option ) {
1696 $settings[ $option_id ] = $option;
1697 if ( isset( self::$current_values[ $option_id ] ) ) {
1698 $settings[ $option_id ]['value'] = self::$current_values[ $option_id ];
1699 }
1700 }
1701 }
1702 }
1703 }
1704
1705 return $settings;
1706 }
1707
1708 protected static function get_value( $option ) {
1709
1710 if ( isset( self::$customizer_values[ self::$opt_name . '[' . $option . ']' ] ) ) {
1711 return self::$customizer_values[ self::$opt_name . '[' . $option . ']' ];
1712 }
1713
1714 // shim
1715 if ( strpos( $option, self::$opt_name . '[' ) !== false ) {
1716 // get only the setting id
1717 $option = explode( '[', $option );
1718 $option = rtrim( $option[1], ']' );
1719 }
1720
1721 if ( isset( self::$current_values[ $option ] ) ) {
1722 return self::$current_values[ $option ];
1723 }
1724
1725 return null;
1726 }
1727
1728 /**
1729 * A public function to retreat an option's value
1730 * If there is a value and return it
1731 * Otherwise try to get the default parameter or the default from config
1732 *
1733 * @param $option
1734 * @param null $default
1735 *
1736 * @return bool|null|string
1737 */
1738 static function get_option( $option, $default = null ) {
1739
1740 $return = self::get_value( $option );
1741
1742 if ( $return !== null ) {
1743 return $return;
1744 } elseif ( $default !== null ) {
1745 return $default;
1746 } elseif ( isset( self::$options_list[ $option ] ) && isset( self::$options_list[ $option ]['default'] ) ) {
1747 return self::$options_list[ $option ]['default'];
1748 }
1749
1750 return null;
1751 }
1752
1753 static function has_option( $option ) {
1754
1755 if ( isset( self::$options_list[ $option ] ) ) {
1756 return true;
1757 }
1758
1759 return false;
1760 }
1761
1762 protected static function get_config() {
1763 // @TODO maybe check this
1764 return include 'plugin-config.php';
1765 }
1766
1767 /**
1768 * Get an option's value from the config file
1769 *
1770 * @param $option
1771 * @param null $default
1772 *
1773 * @return bool|null
1774 */
1775 public static function get_config_option( $option, $default = null ) {
1776
1777 if ( isset( self::$config[ $option ] ) ) {
1778 return self::$config[ $option ];
1779 } elseif ( $default !== null ) {
1780 return $default;
1781 }
1782
1783 return false;
1784 }
1785
1786 static function get_plugin_option( $option, $default = null ) {
1787
1788 if ( isset( self::$plugin_settings[ $option ] ) ) {
1789 return self::$plugin_settings[ $option ];
1790 } elseif ( $default !== null ) {
1791 return $default;
1792 }
1793
1794 return false;
1795 }
1796
1797 /**
1798 * Sanitize functions
1799 */
1800
1801 /**
1802 * Sanitize the checkbox.
1803 *
1804 * @param boolean $input .
1805 *
1806 * @return boolean true if is 1 or '1', false if anything else
1807 */
1808 function setting_sanitize_checkbox( $input ) {
1809 if ( 1 == $input ) {
1810 return true;
1811 } else {
1812 return false;
1813 }
1814 }
1815
1816 /**
1817 * Checks whether an array is associative or not
1818 *
1819 * @param array $array
1820 *
1821 * @return bool
1822 */
1823 public static function is_assoc( $array ) {
1824
1825 if ( ! is_array( $array ) ) {
1826 return false;
1827 }
1828
1829 // Keys of the array
1830 $keys = array_keys( $array );
1831
1832 // If the array keys of the keys match the keys, then the array must
1833 // not be associative (e.g. the keys array looked like {0:0, 1:1...}).
1834 return array_keys( $keys ) !== $keys;
1835 }
1836
1837 function register_import_api(){
1838
1839 include_once( self::get_base_path() . '/features/class-Customify_Importer.php' );
1840 $controller = new Customify_Importer_Controller();
1841 $controller->init();
1842 }
1843
1844 function get_options_configs () {
1845 return self::$options_list;
1846 }
1847
1848 /**
1849 * Does the same thing the JS encodeURIComponent() does
1850 *
1851 * @param string $str
1852 *
1853 * @return string
1854 */
1855 public static function encodeURIComponent( $str ) {
1856 //if we get an array we just let it be
1857 if ( is_string( $str ) ) {
1858 $revert = array( '%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')' );
1859
1860 $str = strtr( rawurlencode( $str ), $revert );
1861 } else {
1862 var_dump('boooom');die;
1863 }
1864
1865 return $str;
1866 }
1867
1868 /**
1869 * Does the same thing the JS decodeURIComponent() does
1870 *
1871 * @param string $str
1872 *
1873 * @return string
1874 */
1875 public static function decodeURIComponent( $str ) {
1876 //if we get an array we just let it be
1877 if ( is_string( $str ) ) {
1878 $revert = array( '!' => '%21', '*' => '%2A', "'" => '%27', '(' => '%28', ')' => '%29' );
1879 $str = rawurldecode( strtr( $str, $revert ) );
1880 }
1881
1882 return $str;
1883 }
1884 }