PluginProbe
Customify / 1.4.2
Customify v1.4.2
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.4.2, at class-pixcustomify.php

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