PluginProbe
Customify / 1.7.3
Customify v1.7.3
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
← All changes | class-pixcustomify.php +1102 -614 1.2.51.7.3 View file →
@@ -3,10 +3,10 @@
3 3 * PixCustomify.
4 4 * @package PixCustomify
5 5 * @author Pixelgrade <contact@pixelgrade.com>
6 6 * @license GPL-2.0+
7 - * @link http://pixelgrade.com
8 - * @copyright 2014 Pixelgrade
7 + * @link https://pixelgrade.com
8 + * @copyright 2014-2017 Pixelgrade
9 9 */
10 10
11 11 /**
12 12 * Plugin class.
@@ -16,12 +16,12 @@
16 16 class PixCustomifyPlugin {
17 17
18 18 /**
19 19 * Plugin version, used for cache-busting of style and script file references.
20 - * @since 1.0.0
20 + * @since 1.5.0
21 21 * @const string
22 22 */
23 - protected $version = '1.2.5';
23 + protected $_version;
24 24 /**
25 25 * Unique identifier for your plugin.
26 26 * Use this value (not the variable name) as the text domain when internationalizing strings of text. It should
27 27 * match the Text Domain file header in the main plugin file.
@@ -31,12 +31,12 @@
31 31 protected $plugin_slug = 'customify';
32 32
33 33 /**
34 34 * Instance of this class.
35 - * @since 1.0.0
35 + * @since 1.5.0
36 36 * @var object
37 37 */
38 - protected static $instance = null;
38 + protected static $_instance = null;
39 39
40 40 /**
41 41 * Slug of the plugin screen.
42 42 * @since 1.0.0
@@ -52,29 +52,29 @@
52 52 protected $plugin_basepath = null;
53 53
54 54 public $display_admin_menu = false;
55 55
56 - protected static $config;
56 + private $config;
57 57
58 - protected static $customizer_config;
58 + private $customizer_config;
59 59
60 - public static $plugin_settings;
60 + public $plugin_settings;
61 61
62 - protected static $localized = array();
62 + protected $localized = array();
63 63
64 - protected static $current_values = array();
64 + protected $current_values = array();
65 65
66 - protected static $options_list = array();
66 + protected $options_list = array();
67 67
68 - protected static $media_queries = array();
68 + protected $media_queries = array();
69 69
70 - protected static $customizer_values;
70 + protected $opt_name;
71 71
72 - protected static $opt_name;
72 + protected $typo_settings;
73 73
74 - protected static $typo_settings;
74 + protected $google_fonts = null;
75 75
76 - protected static $google_fonts = null;
76 + protected $theme_fonts = null;
77 77
78 78 // these properties will get 'px' as a default unit
79 79 protected static $pixel_dependent_css_properties = array(
80 80 'width',
@@ -112,266 +112,203 @@
112 112 'border-right-width',
113 113 'border-top-width'
114 114 );
115 115
116 + protected $jetpack_default_modules = array();
117 + protected $jetpack_blocked_modules = array();
118 + protected $jetpack_sharing_default_options = array();
119 +
116 120 /**
117 - * Initialize the plugin by setting localization, filters, and administration functions.
118 - * @since 1.0.0
121 + * The main plugin file.
122 + * @var string
123 + * @access public
124 + * @since 1.5.0
119 125 */
120 - protected function __construct() {
126 + public $file;
121 127
122 - $this->plugin_basepath = plugin_dir_path( __FILE__ );
123 - self::$config = self::get_config();
124 - self::$plugin_settings = get_option( 'pixcustomify_settings' );
128 + /**
129 + * Style Manager class object.
130 + * @var Customify_Style_Manager
131 + * @access public
132 + * @since 1.0.0
133 + */
134 + public $style_manager = null;
125 135
126 - self::check_for_customizer_values();
136 + /**
137 + * Minimal Required PHP Version
138 + * @var string
139 + * @access private
140 + * @since 1.5.0
141 + */
142 + private $minimalRequiredPhpVersion = 5.2;
127 143
128 - // Load plugin text domain
129 - add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
130 - add_action( 'wp_loaded', array( $this, 'init_plugin_configs' ), 5 );
144 + protected function __construct( $file, $version = '1.0.0' ) {
145 + //the main plugin file (the one that loads all this)
146 + $this->file = $file;
147 + //the current plugin version
148 + $this->_version = $version;
131 149
132 - add_action( 'admin_menu', array( $this, 'add_plugin_admin_menu' ) );
150 + // Remember our base path
151 + $this->plugin_basepath = plugin_dir_path( $file );
133 152
134 - // Add an action link pointing to the options page.
135 - $plugin_basename = plugin_basename( plugin_dir_path( __FILE__ ) . 'pixcustomify.php' );
136 - add_filter( 'plugin_action_links_' . $plugin_basename, array( $this, 'add_action_links' ) );
137 -
138 -
139 - // Load admin style sheet and JavaScript.
140 - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
141 - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
142 -
143 -// add_action( 'plugins_loaded', array( $this, 'register_metaboxes' ), 14 );
144 - add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_styles' ), 10 );
145 - add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 10 );
146 - add_action( 'customize_preview_init', array( $this, 'customizer_live_preview_enqueue_scripts' ), 99999 );
147 -
148 - $load_location = self::get_plugin_option( 'style_resources_location', 'wp_head' );
149 -
150 - add_action( $load_location, array( $this, 'output_dynamic_style' ), 99999 );
151 - add_action( 'wp_head', array( $this, 'output_typography_dynamic_style' ), 10 );
152 -
153 - // add things to the previewer
154 -// add_action( 'customize_preview_init', array( $this, 'customize_preview_js' ) );
155 -
156 - add_action( 'customize_register', array( $this, 'remove_default_sections' ), 11 );
157 - add_action( 'customize_register', array( $this, 'register_customizer' ), 12 );
158 -
159 - if ( self::get_plugin_option( 'enable_editor_style', true ) ) {
160 - add_action( 'admin_head', array( $this, 'add_customizer_settings_into_wp_editor' ) );
153 + if ( $this->php_version_check() ) {
154 + // Only load and run the init function if we know PHP version can parse it.
155 + $this->init();
161 156 }
162 -
163 - /**
164 - * Ajax Callbacks
165 - */
166 -// add_action( 'wp_ajax_pixcustomify_image_click', array( &$this, 'ajax_click_on_photo' ) );
167 -// add_action( 'wp_ajax_nopriv_pixcustomify_image_click', array( &$this, 'ajax_click_on_photo' ) );
168 157 }
169 158
170 159 /**
171 - * Return an instance of this class.
172 - * @since 1.0.0
173 - * @return object A single instance of this class.
160 + * Initialize plugin
174 161 */
175 - public static function get_instance() {
162 + private function init() {
163 + // Load the config file
164 + $this->config = $this->get_config();
165 + // Load the plugin's settings from the DB
166 + $this->plugin_settings = get_option( $this->config['settings-key'] );
176 167
177 - // If the single instance hasn't been set, set it now.
178 - if ( null == self::$instance ) {
179 - self::$instance = new self;
168 + /* Initialize the Style Manager logic. */
169 + require_once( $this->plugin_basepath . 'includes/class-customify-style-manager.php' );
170 + if ( is_null( $this->style_manager ) ) {
171 + $this->style_manager = Customify_Style_Manager::instance( $this );
180 172 }
181 173
182 - return self::$instance;
174 + // Register all the needed hooks
175 + $this->register_hooks();
183 176 }
184 177
185 178 /**
186 - * Configs, Options and Values methods
179 + * Register our actions and filters
187 180 */
181 + function register_hooks() {
182 + /*
183 + * Register hooks that are fired when the plugin is activated, deactivated, and uninstalled, respectively.
184 + */
185 + register_activation_hook( $this->file, array( $this, 'activate' ) );
186 + register_deactivation_hook( $this->file, array( $this, 'deactivate' ) );
188 187
189 - function init_plugin_configs() {
190 - self::$customizer_config = get_option( 'pixcustomify_config' );
188 + /*
189 + * Load plugin text domain
190 + */
191 + add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
191 192
192 - // no option so go for default
193 - if ( empty( self::$customizer_config ) ) {
194 - self::$customizer_config = self::get_config_option( 'default_options' );
195 - }
193 + /*
194 + * Prepare and load the configuration
195 + */
196 + $this->init_plugin_configs();
196 197
197 - if ( empty( self::$customizer_config ) ) {
198 - self::$customizer_config = array();
199 - }
198 + // We need to load the configuration as late as possible so we allow all that want to influence it
199 + // We need the init hook and not after_setup_theme because there a number of plugins that fire up on init (like certain modules from Jetpack)
200 + // We need to be able to load things like components configs depending on those firing up or not
201 + // DO NOT TRY to use the Customify values before this!
202 + add_action( 'init', array( $this, 'load_plugin_configs' ), 15 );
200 203
201 - // allow themes or other plugins to filter the config
202 - self::$customizer_config = apply_filters( 'customify_filter_fields', self::$customizer_config );
204 + /*
205 + * Now setup the admin side of things
206 + */
207 + // Starting with the menu item for this plugin
208 + add_action( 'admin_menu', array( $this, 'add_plugin_admin_menu' ) );
203 209
204 - self::$opt_name = self::$localized['options_name'] = self::$customizer_config['opt-name'];
210 + // Add an action link pointing to the options page.
211 + $plugin_basename = plugin_basename( plugin_dir_path( $this->file ) . 'pixcustomify.php' );
212 + add_filter( 'plugin_action_links_' . $plugin_basename, array( $this, 'add_action_links' ) );
205 213
206 - self::get_current_values();
207 - self::$options_list = $this->get_options();
214 + // Load admin style sheet and JavaScript.
215 + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
216 + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
208 217
209 - if ( $this->import_button_exists() ) {
210 - self::$opt_name = self::$localized['import_rest_url'] = get_rest_url( '/customify/1.0/' );
211 - self::$opt_name = self::$localized['import_rest_nonce'] = wp_create_nonce( 'wp_rest' );
218 + /*
219 + * Now it's time for the Customizer logic to kick in
220 + */
221 + // Styles for the Customizer
222 + add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_styles' ), 10 );
223 + add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_styles' ), 10 );
224 + // Scripts enqueued in the Customizer
225 + add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_scripts' ), 15 );
226 + add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 15 );
212 227
213 - $this->register_import_api();
214 - }
228 + // Scripts enqueued only in the theme preview
229 + add_action( 'customize_preview_init', array( $this, 'customizer_live_preview_register_scripts' ), 10 );
230 + add_action( 'customize_preview_init', array( $this, 'customizer_live_preview_enqueue_scripts' ), 99999 );
215 231
216 - // load custom modules
217 - include_once( self::get_base_path() . '/features/class-CSS_Editor.php' );
218 - }
232 + // Add extra settings data to _wpCustomizeSettings.settings of the parent window.
233 + add_action( 'customize_controls_print_footer_scripts', array( $this, 'customize_pane_settings_additional_data' ), 10000 );
219 234
220 - protected static function check_for_customizer_values() {
221 - if ( isset( $_POST['customized'] ) && $_POST['customized'] !== '{}' ) {
222 - $the_value = $_POST['customized'];
223 - self::$customizer_values = json_decode( $the_value, true );
235 + // The frontend effects of the Customizer controls
236 + $load_location = $this->get_plugin_setting( 'style_resources_location', 'wp_head' );
224 237
225 - /**
226 - * if still empty, use stripslashes_deep to ensure compatibility with 5.2
227 - * http://stackoverflow.com/questions/28698165/json-data-cannot-be-accessed-in-php-version-5-2-17
228 - */
229 - if ( empty( self::$customizer_values ) ) {
230 - $stripped_value = stripslashes_deep( $the_value );
231 - self::$customizer_values = json_decode( $stripped_value, true );
232 - }
233 - } else {
234 - self::$customizer_values = false;
235 - }
236 - }
238 + add_action( $load_location, array( $this, 'output_dynamic_style' ), 99 );
239 + add_action( 'wp_head', array( $this, 'output_typography_dynamic_style' ), 10 );
237 240
238 - protected static function get_current_values() {
239 - $store_type = self::get_plugin_option( 'values_store_mod', 'option' );
240 - if ( $store_type === 'option' ) {
241 - self::$current_values = get_option( self::$opt_name );
242 - } elseif ( $store_type === 'theme_mod' ) {
243 - self::$current_values = get_theme_mod( self::$opt_name );
241 + add_action( 'customize_register', array( $this, 'remove_default_sections' ), 11 );
242 + add_action( 'customize_register', array( $this, 'register_customizer' ), 12 );
243 +
244 + if ( $this->get_plugin_setting( 'enable_editor_style', true ) ) {
245 + add_action( 'admin_head', array( $this, 'add_customizer_settings_into_wp_editor' ) );
244 246 }
245 - }
246 247
247 - public function get_options() {
248 + add_action( 'rest_api_init', array( $this, 'add_rest_routes_api' ) );
248 249
249 - $settings = array();
250 -
251 - if ( isset ( self::$customizer_config['panels'] ) ) {
252 -
253 - foreach ( self::$customizer_config['panels'] as $pane_id => $panel_settings ) {
254 -
255 - if ( isset( $panel_settings['sections'] ) ) {
256 - foreach ( $panel_settings['sections'] as $section_id => $section_settings ) {
257 - if ( isset( $section_settings['options'] ) ) {
258 - foreach ( $section_settings['options'] as $option_id => $option ) {
259 - $settings[ $option_id ] = $option;
260 - if ( isset( self::$current_values[ $option_id ] ) ) {
261 - $settings[ $option_id ]['value'] = self::$current_values[ $option_id ];
262 - }
263 - }
264 - }
265 - }
266 - }
267 - }
250 + /*
251 + * Development related
252 + */
253 + if ( defined( 'CUSTOMIFY_DEV_FORCE_DEFAULTS' ) && true === CUSTOMIFY_DEV_FORCE_DEFAULTS ) {
254 + // If the development constant CUSTOMIFY_DEV_FORCE_DEFAULTS has been defined we will not save anything in the database
255 + // Always go with the default
256 + add_filter( 'customize_changeset_save_data', array( $this, 'prevent_changeset_save_in_devmode' ), 50, 2 );
257 + // Add a JS to display a notification
258 + add_action( 'customize_controls_print_footer_scripts', array( $this, 'prevent_changeset_save_in_devmode_notification' ), 100 );
268 259 }
269 -
270 - if ( isset ( self::$customizer_config['sections'] ) ) {
271 - foreach ( self::$customizer_config['sections'] as $section_id => $section_settings ) {
272 - if ( isset( $section_settings['options'] ) ) {
273 - foreach ( $section_settings['options'] as $option_id => $option ) {
274 - $settings[ $option_id ] = $option;
275 - if ( isset( self::$current_values[ $option_id ] ) ) {
276 - $settings[ $option_id ]['value'] = self::$current_values[ $option_id ];
277 - }
278 - }
279 - }
280 - }
281 - }
282 -
283 - return $settings;
284 260 }
285 261
286 - protected static function get_value( $option ) {
262 + /**
263 + * Initialize Configs, Options and Values methods
264 + */
265 + function init_plugin_configs() {
266 + $this->customizer_config = get_option( 'pixcustomify_config' );
287 267
288 - if ( isset( self::$customizer_values[ self::$opt_name . '[' . $option . ']' ] ) ) {
289 - return self::$customizer_values[ self::$opt_name . '[' . $option . ']' ];
268 + // no option so go for default
269 + if ( empty( $this->customizer_config ) ) {
270 + $this->customizer_config = $this->get_config_option( 'default_options' );
290 271 }
291 272
292 - if ( strpos( $option, self::$opt_name . '[' ) !== false ) {
293 - var_dump( 'this is old and it shouldn\'t be here!' );
294 -
295 - // get only the setting id
296 - $option = explode( '[', $option );
297 - $option = rtrim( $option[1], ']' );
273 + if ( empty( $this->customizer_config ) ) {
274 + $this->customizer_config = array();
298 275 }
299 -
300 - if ( isset( self::$current_values[ $option ] ) ) {
301 - return self::$current_values[ $option ];
302 - }
303 -
304 - return null;
305 276 }
306 277
307 278 /**
308 - * A public function to retreat an option's value
309 - * If there is a value and return it
310 - * Otherwise try to get the default parameter or the default from config
311 - *
312 - * @param $option
313 - * @param null $default
314 - *
315 - * @return bool|null|string
279 + * Load the plugin configuration and options
316 280 */
317 - static function get_option( $option, $default = null ) {
281 + function load_plugin_configs() {
318 282
319 - $return = self::get_value( $option );
283 + // Allow themes or other plugins to filter the config.
284 + $this->customizer_config = apply_filters( 'customify_filter_fields', $this->customizer_config );
285 + $this->opt_name = $this->localized['options_name'] = $this->customizer_config['opt-name'];
286 + $this->options_list = $this->get_options();
320 287
321 - if ( $return !== null ) {
322 - return $return;
323 - } elseif ( $default !== null ) {
324 - return $default;
325 - } elseif ( isset( self::$options_list[ $option ] ) && isset( self::$options_list[ $option ]['default'] ) ) {
326 - return self::$options_list[ $option ]['default'];
327 - }
288 + // Load the current options values.
289 + $this->current_values = $this->get_current_values();
328 290
329 - return null;
330 - }
291 + if ( $this->import_button_exists() ) {
292 + $this->localized['import_rest_url'] = get_rest_url( '/customify/1.0/' );
293 + $this->localized['import_rest_nonce'] = wp_create_nonce( 'wp_rest' );
331 294
332 - static function has_option( $option ) {
333 -
334 - if ( isset( self::$options_list[ $option ] ) ) {
335 - return true;
295 + $this->register_import_api();
336 296 }
337 297
338 - return false;
339 - }
298 + $this->localized['theme_fonts'] = $this->theme_fonts = Customify_Font_Selector::instance()->get_theme_fonts();
340 299
341 - protected static function get_config() {
342 - // @TODO maybe check this
343 - return include 'plugin-config.php';
300 + $this->localized['ajax_url'] = admin_url( 'admin-ajax.php' );
301 + $this->localized['style_manager_user_feedback_nonce'] = wp_create_nonce( 'customify_style_manager_user_feedback' );
302 + $this->localized['style_manager_user_feedback_provided'] = $this->get_option( 'style_manager_user_feedback_provided', false );
344 303 }
345 304
346 - /**
347 - * Get an option's value from the config file
348 - *
349 - * @param $option
350 - * @param null $default
351 - *
352 - * @return bool|null
353 - */
354 - public static function get_config_option( $option, $default = null ) {
355 -
356 - if ( isset( self::$config[ $option ] ) ) {
357 - return self::$config[ $option ];
358 - } elseif ( $default !== null ) {
359 - return $default;
360 - }
361 -
362 - return false;
305 + public function get_version() {
306 + return $this->_version;
363 307 }
364 308
365 - static function get_plugin_option( $option, $default = null ) {
366 -
367 - if ( isset( self::$plugin_settings[ $option ] ) ) {
368 - return self::$plugin_settings[ $option ];
369 - } elseif ( $default !== null ) {
370 - return $default;
371 - }
372 -
373 - return false;
309 + public function get_slug() {
310 + return $this->plugin_slug;
374 311 }
375 312
376 313 /**
377 314 * Fired when the plugin is activated.
@@ -379,9 +316,9 @@
379 316 *
380 317 * @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.
381 318 */
382 319 public static function activate( $network_wide ) {
383 -
320 + //@todo Define activation functionality here
384 321 }
385 322
386 323 /**
387 324 * Fired when the plugin is deactivated.
@@ -389,9 +326,9 @@
389 326 *
390 327 * @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.
391 328 */
392 329 static function deactivate( $network_wide ) {
393 - // TODO: Define deactivation functionality here
330 + //@todo Define deactivation functionality here
394 331 }
395 332
396 333 /**
397 334 * Load the plugin text domain for translation.
@@ -397,59 +334,79 @@
397 334 * Load the plugin text domain for translation.
398 335 * @since 1.0.0
399 336 */
400 337 function load_plugin_textdomain() {
401 -
402 338 $domain = $this->plugin_slug;
403 - $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
404 -
405 - load_textdomain( $domain, WP_LANG_DIR . '/' . $domain . '/' . $domain . '-' . $locale . '.mo' );
406 - load_plugin_textdomain( $domain, false, basename( dirname( __FILE__ ) ) . '/lang/' );
339 + load_plugin_textdomain( $domain, false, basename( dirname( $this->file ) ) . '/languages/' );
407 340 }
408 341
409 342 /** === RESOURCES === **/
410 343
411 344 /**
412 - * Customizer admin styles
345 + * Register Customizer admin styles
413 346 */
347 + function register_admin_customizer_styles() {
348 + wp_register_style( 'customify_select2', plugins_url( 'js/select2/css/select2.css', $this->file ), array(), $this->_version );
349 + wp_register_style( 'customify_style', plugins_url( 'css/customizer.css', $this->file ), array( 'customify_select2' ), $this->_version );
350 + }
351 +
352 + /**
353 + * Enqueue Customizer admin styles
354 + */
414 355 function enqueue_admin_customizer_styles() {
415 - wp_enqueue_style( 'select2', plugins_url( 'js/select2/select2.css', __FILE__ ), array(), $this->version );
416 - wp_enqueue_style( 'customify_style', plugins_url( 'css/customizer.css', __FILE__ ), array(), $this->version );
356 + wp_enqueue_style( 'customify_style' );
417 357 }
418 358
419 359 /**
420 - * Customizer admin scripts
360 + * Register Customizer admin scripts
421 361 */
422 - function enqueue_admin_customizer_scripts() {
362 + function register_admin_customizer_scripts() {
423 363
424 - wp_enqueue_script( 'select2', plugins_url( 'js/select2/select2.js', __FILE__ ), array( 'jquery' ), $this->version );
425 - wp_enqueue_script( 'jquery-react', plugins_url( 'js/jquery-react.js', __FILE__ ), array( 'jquery' ), $this->version );
426 - wp_enqueue_script( $this->plugin_slug . '-customizer-scripts', plugins_url( 'js/customizer.js', __FILE__ ), array(
364 + wp_register_script( 'customify_select2', plugins_url( 'js/select2/js/select2.js', $this->file ), array( 'jquery' ), $this->_version );
365 + wp_register_script( 'jquery-react', plugins_url( 'js/jquery-react.js', $this->file ), array( 'jquery' ), $this->_version );
366 +
367 + wp_register_script( 'customify-scale', plugins_url( 'js/customizer/customify-scale.js', $this->file ), array( 'jquery' ), $this->_version );
368 +
369 + wp_register_script( $this->plugin_slug . '-customizer-scripts', plugins_url( 'js/customizer.js', $this->file ), array(
427 370 'jquery',
428 - 'select2',
371 + 'customify_select2',
429 372 'underscore',
430 - ), $this->version );
373 + 'customize-controls',
431 374
432 - wp_localize_script( $this->plugin_slug . '-customizer-scripts', 'customify_settings', self::$localized );
433 -
375 + 'customify-scale',
376 + ), $this->_version );
434 377 }
435 378
379 + /**
380 + * Enqueue Customizer admin scripts
381 + */
382 + function enqueue_admin_customizer_scripts() {
383 + wp_enqueue_script( 'jquery-react' );
384 + wp_enqueue_script( $this->plugin_slug . '-customizer-scripts' );
436 385
437 - /** Customizer scripts loaded only on previewer page */
438 - function customizer_live_preview_enqueue_scripts() {
386 + wp_localize_script( $this->plugin_slug . '-customizer-scripts', 'customify_settings', $this->localized );
387 + }
439 388
440 - wp_register_script( $this->plugin_slug . 'CSSOM', plugins_url( 'js/CSSOM.js', __FILE__ ), array( 'jquery' ), $this->version, true );
441 - wp_register_script( $this->plugin_slug . 'cssUpdate', plugins_url( 'js/jquery.cssUpdate.js', __FILE__ ), array(), $this->version, true );
442 - wp_enqueue_script( $this->plugin_slug . '-previewer-scripts', plugins_url( 'js/customizer_preview.js', __FILE__ ), array(
389 + /** Register Customizer scripts loaded only on previewer page */
390 + function customizer_live_preview_register_scripts() {
391 + wp_register_script( $this->plugin_slug . 'CSSOM', plugins_url( 'js/CSSOM.js', $this->file ), array( 'jquery' ), $this->_version, true );
392 + wp_register_script( $this->plugin_slug . 'cssUpdate', plugins_url( 'js/jquery.cssUpdate.js', $this->file ), array(), $this->_version, true );
393 + wp_register_script( $this->plugin_slug . '-previewer-scripts', plugins_url( 'js/customizer_preview.js', $this->file ), array(
443 394 'jquery',
395 + 'customize-preview',
444 396 $this->plugin_slug . 'CSSOM',
445 397 $this->plugin_slug . 'cssUpdate'
446 - ), $this->version, true );
398 + ), $this->_version, true );
399 + }
447 400
401 + /** Enqueue Customizer scripts loaded only on previewer page */
402 + function customizer_live_preview_enqueue_scripts() {
403 + wp_enqueue_script( $this->plugin_slug . '-previewer-scripts' );
404 +
448 405 // when a live preview field is in action we need to know which props need 'px' as defaults
449 - self::$localized['px_dependent_css_props'] = self::$pixel_dependent_css_properties;
406 + $this->localized['px_dependent_css_props'] = self::$pixel_dependent_css_properties;
450 407
451 - wp_localize_script( $this->plugin_slug . '-previewer-scripts', 'customify_settings', self::$localized );
408 + wp_localize_script( $this->plugin_slug . '-previewer-scripts', 'customify_settings', $this->localized );
452 409 }
453 410
454 411 /**
455 412 * Add dynamic style only on the previewer page
@@ -465,9 +422,9 @@
465 422 }
466 423
467 424 $screen = get_current_screen();
468 425 if ( $screen->id == $this->plugin_screen_hook_suffix ) {
469 - wp_enqueue_style( $this->plugin_slug . '-admin-styles', plugins_url( 'css/admin.css', __FILE__ ), array(), $this->version );
426 + wp_enqueue_style( $this->plugin_slug . '-admin-styles', plugins_url( 'css/admin.css', $this->file ), array(), $this->_version );
470 427 }
471 428 }
472 429
473 430 /**
@@ -480,35 +437,65 @@
480 437 }
481 438
482 439 $screen = get_current_screen();
483 440 if ( $screen->id == $this->plugin_screen_hook_suffix ) {
484 - wp_enqueue_script( $this->plugin_slug . '-admin-script', plugins_url( 'js/admin.js', __FILE__ ), array( 'jquery' ), $this->version );
485 - wp_localize_script( $this->plugin_slug . '-admin-script', 'locals', array(
486 - 'ajax_url' => admin_url( 'admin-ajax.php' )
441 + wp_enqueue_script( $this->plugin_slug . '-admin-script', plugins_url( 'js/admin.js', $this->file ), array( 'jquery' ), $this->_version );
442 + wp_localize_script( $this->plugin_slug . '-admin-script', 'customify_settings', array(
443 + 'ajax_url' => admin_url( 'admin-ajax.php' ),
444 + 'wp_rest' => array(
445 + 'root' => esc_url_raw( rest_url() ),
446 + 'nonce' => wp_create_nonce( 'wp_rest' ),
447 + 'customify_settings_nonce' => wp_create_nonce( 'customify_settings_nonce' )
448 + ),
487 449 ) );
488 450 }
489 451
452 + wp_localize_script( $this->plugin_slug . '-customizer-scripts', 'WP_API_Settings', array(
453 + 'root' => esc_url_raw( rest_url() ),
454 + 'nonce' => wp_create_nonce( 'wp_rest' )
455 + ) );
456 + }
490 457
491 - wp_localize_script( $this->plugin_slug . '-customizer-scripts', 'WP_API_Settings', array( 'root' => esc_url_raw( rest_url() ), 'nonce' => wp_create_nonce( 'wp_rest' ) ) );
458 + function add_rest_routes_api(){
459 + register_rest_route( 'customify/v1', '/delete_theme_mod', array(
460 + 'methods' => 'POST',
461 + 'callback' => array( $this, 'delete_theme_mod' ),
462 + 'permission_callback' => array( $this, 'permission_nonce_callback' ),
463 + ) );
492 464 }
493 465
494 - /**
495 - * Register and enqueue public-facing style sheet.
496 - * @since 1.0.0
497 - */
498 - function enqueue_styles() {
499 - // wp_enqueue_style( $this->plugin_slug . '-plugin-styles', plugins_url( 'css/public.css', __FILE__ ), array(), $this->version );
466 + function delete_theme_mod(){
467 + if ( ! current_user_can( 'manage_options' ) ) {
468 + wp_send_json_error('You don\'t have admin privileges.');
469 + }
470 +
471 + $config = apply_filters('customify_filter_fields', array() );
472 +
473 + if ( empty( $config['opt-name'] ) ) {
474 + wp_send_json_error('no option key');
475 + }
476 +
477 + $key = $config['opt-name'];
478 +
479 + remove_theme_mod( $key );
480 +
481 + wp_send_json_success('Deleted ' . $key . ' theme mod!');
500 482 }
501 483
502 - /**
503 - * Register and enqueues public-facing JavaScript files.
504 - * @since 1.0.0
505 - */
506 - public function enqueue_scripts() {
507 - //wp_enqueue_script( $this->plugin_slug . '-plugin-script', plugins_url( 'js/public.js', __FILE__ ), array( 'jquery' ), $this->version, true );
484 + function permission_nonce_callback() {
485 + return wp_verify_nonce( $this->get_nonce(), 'customify_settings_nonce' );
486 + }
508 487
509 - // quit adding google fonts as a static resource ... we will add it dynamically as a fallback when the typekit library isn't used
510 - // wp_enqueue_script( 'google-fonts', '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js' );
488 + private function get_nonce() {
489 + $nonce = null;
490 +
491 + if ( isset( $_REQUEST['customify_settings_nonce'] ) ) {
492 + $nonce = wp_unslash( $_REQUEST['customify_settings_nonce'] );
493 + } elseif ( isset( $_POST['customify_settings_nonce'] ) ) {
494 + $nonce = wp_unslash( $_POST['customify_settings_nonce'] );
495 + }
496 +
497 + return $nonce;
511 498 }
512 499
513 500 /**
514 501 * Public style generated by customizer
@@ -513,11 +500,11 @@
513 500 /**
514 501 * Public style generated by customizer
515 502 */
516 503 function output_dynamic_style() {
517 - $custom_css = "\n";
504 + $custom_css = '';
518 505
519 - foreach ( self::$options_list as $option_id => $option ) {
506 + foreach ( $this->options_list as $option_id => $option ) {
520 507
521 508 if ( isset( $option['css'] ) && ! empty( $option['css'] ) ) {
522 509 // now process each
523 510 $custom_css .= $this->convert_setting_to_css( $option_id, $option['css'] );
@@ -522,43 +509,39 @@
522 509 // now process each
523 510 $custom_css .= $this->convert_setting_to_css( $option_id, $option['css'] );
524 511 }
525 512
526 - if ( $option['type'] === 'custom_background' ) {
527 - $custom_css .= $this->process_custom_background_field_output( $option_id, $option );
513 + if ( isset( $option['type'] ) && $option['type'] === 'custom_background' ) {
514 + $option['value'] = $this->get_option( $option_id );
515 + $custom_css .= $this->process_custom_background_field_output( $option_id, $option ) . PHP_EOL;
528 516 }
529 517 }
530 518
531 - if ( ! empty( self::$media_queries ) ) {
519 + if ( ! empty( $this->media_queries ) ) {
532 520
533 - foreach ( self::$media_queries as $media_query => $properties ) {
521 + foreach ( $this->media_queries as $media_query => $properties ) {
534 522
535 523 if ( empty( $properties ) ) {
536 524 continue;
537 525 }
538 526
539 - $custom_css .= '@media ' . $media_query . " {\n";
527 + $custom_css .= PHP_EOL . '@media ' . $media_query . " { " . PHP_EOL . PHP_EOL;
540 528
541 529 foreach ( $properties as $key => $property ) {
542 530 $property_settings = $property['property'];
543 531 $property_value = $property['value'];
544 - $custom_css .= "\t" . self::proccess_css_property( $property_settings, $property_value );
532 + $custom_css .= "\t" . $this->proccess_css_property( $property_settings, $property_value ) . PHP_EOL;
545 533 }
546 534
547 - $custom_css .= "\n}\n";
535 + $custom_css .= "}" . PHP_EOL;
548 536
549 537 }
550 538 }
551 -
552 - $custom_css .= "\n";
553 -
554 - //@todo maybe add a filter to this output ?>
539 + ?>
555 540 <style id="customify_output_style">
556 - <?php echo( $custom_css ); ?>
557 - </style>
558 - <?php
541 + <?php echo apply_filters( 'customify_dynamic_style', $custom_css ); ?>
542 + </style><?php
559 543
560 -
561 544 /**
562 545 * from now on we output only style tags only for the preview purpose
563 546 * so don't cry if you see 30+ style tags for each section
564 547 */
@@ -565,15 +548,15 @@
565 548 if ( ! isset( $GLOBALS['wp_customize'] ) ) {
566 549 return;
567 550 }
568 551
569 - foreach ( self::$options_list as $option_id => $options ) {
552 + foreach ( $this->options_list as $option_id => $options ) {
570 553
571 - if ( $options['type'] === 'custom_background' ) {
572 - $options['value'] = self::get_option( $option_id );
554 + if ( isset( $options['type'] ) && $options['type'] === 'custom_background' ) {
555 + $options['value'] = $this->get_option( $option_id );
573 556 $custom_background_output = $this->process_custom_background_field_output( $option_id, $options ); ?>
574 557
575 - <style id="custom_backgorund_output_for_<?php echo $option_id; ?>">
558 + <style id="custom_background_output_for_<?php echo sanitize_html_class( $option_id ); ?>">
576 559 <?php
577 560 if ( isset( $custom_background_output ) && ! empty( $custom_background_output )) {
578 561 echo $custom_background_output;
579 562 } ?>
@@ -583,71 +566,43 @@
583 566 if ( ! isset( $options['live'] ) || $options['live'] !== true ) {
584 567 continue;
585 568 }
586 569
587 - $this_value = self::get_option( $option_id );
588 - foreach ( $options['css'] as $key => $properties_set ) { ?>
589 - <style id="dynamic_setting_<?php echo $option_id . '_property_' . str_replace( '-', '_', $properties_set['property'] ); ?>" type="text/css"><?php
570 + $this_value = $this->get_option( $option_id );
571 + if ( ! empty( $options['css'] ) ) {
572 + foreach ( $options['css'] as $key => $properties_set ) {
573 + // We need to use a class because we may have multiple <style>s with the same "ID" for example
574 + // when targeting the same property but with different selectors.
575 + ?>
576 + <style class="dynamic_setting_<?php echo sanitize_html_class( $option_id ) . '_property_' . str_replace( '-', '_', $properties_set['property'] ) . '_' . $key; ?>"
577 + type="text/css"><?php
590 578
591 579 if ( isset( $properties_set['media'] ) && ! empty( $properties_set['media'] ) ) {
592 - echo '@media '. $properties_set['media'] . " {\n";
580 + echo '@media '. $properties_set['media'] . " {" . PHP_EOL;
593 581 }
594 582
595 583 if ( isset( $properties_set['selector'] ) && isset( $properties_set['property'] ) ) {
596 - echo self::proccess_css_property($properties_set, $this_value);
584 + echo $this->proccess_css_property($properties_set, $this_value) . PHP_EOL;
597 585 }
598 586
599 587 if ( isset( $properties_set['media'] ) && ! empty( $properties_set['media'] ) ) {
600 - echo "}\n";
588 + echo "}" . PHP_EOL;
601 589 } ?>
602 - </style>
603 - <?php }
604 - }
605 -
606 - if ( ! empty( self::$media_queries ) ) {
607 -
608 - foreach ( self::$media_queries as $media_query => $properties ) {
609 -
610 - if ( empty( $properties ) ) {
611 - continue;
612 - }
613 -
614 - $display = false;
615 - $media_q = '@media ' . $media_query . " {\n";
616 -
617 - foreach ( $properties as $key => $property ) {
618 -
619 - if ( ! isset( $options['live'] ) || $options['live'] !== true ) {
620 - continue;
621 - }
622 -
623 - $display = true; ?>
624 - <style id="dynamic_setting_<?php echo $key; ?>" type="text/css"><?php
625 - $property_settings = $property['property'];
626 - $property_value = $property['value'];
627 - $media_q .= "\t" . self::proccess_css_property( $property_settings, $property_value );?>
628 590 </style>
629 591 <?php }
630 -
631 - $media_q .= "\n}\n";
632 -
633 - if ( $display ) {
634 - $custom_css .= $media_q;
635 - }
636 592 }
637 593 }
638 594 }
639 595
640 596 protected function load_google_fonts() {
597 + $fonts_path = plugin_dir_path( $this->file ) . 'features/customizer/controls/resources/google.fonts.php';
641 598
642 - $fonts_path = plugin_dir_path( __FILE__ ) . 'features/customizer/controls/resources/google.fonts.php';
643 -
644 599 if ( file_exists( $fonts_path ) ) {
645 - self::$google_fonts = require( $fonts_path );
600 + $this->google_fonts = require( $fonts_path );
646 601 }
647 602
648 - if ( ! empty( self::$google_fonts ) ) {
649 - return self::$google_fonts;
603 + if ( ! empty( $this->google_fonts ) ) {
604 + return $this->google_fonts;
650 605 }
651 606
652 607 return false;
653 608 }
@@ -652,67 +607,56 @@
652 607 return false;
653 608 }
654 609
655 610 function output_typography_dynamic_style() {
611 + $this->get_typography_fields( $this->options_list, 'type', 'typography', $this->typo_settings );
656 612
657 - self::get_typography_fields( self::$options_list, 'type', 'typography', self::$typo_settings );
658 -
659 - if ( empty( self::$typo_settings ) ) {
613 + if ( empty( $this->typo_settings ) ) {
660 614 return;
661 615 }
662 616
663 617 $families = '';
664 618
665 - foreach ( self::$typo_settings as $id => $font ) {
619 + foreach ( $this->typo_settings as $id => $font ) {
666 620 if ( isset ( $font['value'] ) ) {
667 621
668 622 $load_all_weights = false;
669 -
670 623 if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
671 624 $load_all_weights = true;
672 625 }
673 626
674 627 // shim the time when this was an array
628 + // @todo Is this really needed? Or does it make sense?
675 629 if ( is_array( $font['value'] ) ) {
676 -// $font['value']['font_family'] = $font['value']['font-family'];
677 -// unset( $font['value']['font-family'] );
678 -//
679 -// if ( isset( $font['value']['google'] ) && $font['value']['google'] ) {
680 -// $font['value']['type'] = 'google';
681 -// unset($font['value']['type']);
682 -// }
683 -//
684 -// foreach ($font['value']['font-options']['variants'] as $variant ) {
685 -// $font['value']['variants'][$variant['id']] = $variant['name'];
686 -// }
687 -//
688 -// foreach ($font['value']['font-options']['subsets'] as $subsets ) {
689 -// $font['value']['subsets'][$subsets['id']] = $subsets['name'];
690 -// }
691 -//
692 -// unset( $font['value']['font-options'] );
693 -
694 630 $font['value'] = stripslashes_deep( $font['value'] );
695 631 $font['value'] = json_encode( $font['value'] );
696 632 }
697 633
698 - $value = json_decode( wp_unslash( PixCustomifyPlugin::decodeURIComponent( $font['value'] ) ), true );
634 + $value = wp_unslash( PixCustomifyPlugin::decodeURIComponent( $font['value'] ) );
635 + if ( is_string( $value ) ) {
636 + $value = json_decode( $value, true );
637 + }
699 638
700 - // in case the value is still null, try default value(mostly for google fonts)
701 - if ( ! is_array( $value ) || $value === null ) {
639 + // In case the value is still null, try default value (mostly for google fonts)
640 + if ( $value === null || ! is_array( $value ) ) {
702 641 $value = $this->get_font_defaults_value( str_replace( '"', '', $font['value'] ) );
703 642 }
704 643
705 - //bail if by this time we don't have a value of some sort
644 + // Bail if by this time we don't have a value of some sort
706 645 if ( empty( $value ) ) {
707 646 continue;
708 647 }
709 648
710 - //Handle special logic for when the $value array is not an associative array
711 - if ( ! self::is_assoc( $value ) ) {
712 - $value = $this->process_a_not_associative_font_default( $value );
649 + // Handle special logic for when the $value array is not an associative array
650 + if ( ! $this->is_assoc( $value ) ) {
651 + $value = $this->standardize_non_associative_font_default( $value );
713 652 }
714 653
654 + // Bail if empty or we don't have an array
655 + if ( empty( $value ) || ! is_array( $value ) ) {
656 + continue;
657 + }
658 +
715 659 if ( isset( $value['font_family'] ) && isset( $value['type'] ) && $value['type'] == 'google' ) {
716 660 $families .= "'" . $value['font_family'];
717 661
718 662 if ( $load_all_weights && is_array( $value['variants'] ) ) {
@@ -749,39 +693,38 @@
749 693 }
750 694 }
751 695 }
752 696
753 -
754 - if ( ! empty ( $families ) && self::get_plugin_option( 'typography', '1' ) && self::get_plugin_option( 'typography_google_fonts', 1 ) ) { ?>
697 + if ( ! empty ( $families ) && $this->get_plugin_setting( 'typography', '1' ) && $this->get_plugin_setting( 'typography_google_fonts', 1 ) ) { ?>
755 698 <script type="text/javascript">
756 - if ( typeof WebFont !== 'undefined' ) {<?php // if there is a WebFont object, use it ?>
757 - WebFont.load( {
699 + if (typeof WebFont !== 'undefined') {<?php // if there is a WebFont object, use it ?>
700 + WebFont.load({
758 701 google: {families: [<?php echo( rtrim( $families, ',' ) ); ?>]},
759 702 classes: false,
760 703 events: false
761 - } );
704 + });
762 705 } else {<?php // basically when we don't have the WebFont object we create the google script dynamically ?>
763 706
764 - var tk = document.createElement( 'script' );
707 + var tk = document.createElement('script');
765 708 tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
766 709 tk.type = 'text/javascript';
767 710
768 - tk.onload = tk.onreadystatechange = function() {
769 - WebFont.load( {
711 + tk.onload = tk.onreadystatechange = function () {
712 + WebFont.load({
770 713 google: {families: [<?php echo( rtrim( $families, ',' ) ); ?>]},
771 714 classes: false,
772 715 events: false
773 - } );
716 + });
774 717 };
775 718
776 - var s = document.getElementsByTagName( 'script' )[0];
777 - s.parentNode.insertBefore( tk, s );
719 + var s = document.getElementsByTagName('script')[0];
720 + s.parentNode.insertBefore(tk, s);
778 721 }
779 722 </script>
780 723 <?php } ?>
781 724 <style id="customify_typography_output_style">
782 725 <?php
783 - foreach ( self::$typo_settings as $key => $font ) {
726 + foreach ( $this->typo_settings as $key => $font ) {
784 727 $load_all_weights = false;
785 728 if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
786 729 $load_all_weights = true;
787 730 }
@@ -786,25 +729,35 @@
786 729 $load_all_weights = true;
787 730 }
788 731
789 732 if ( isset( $font['selector'] ) && isset( $font['value'] ) && ! empty( $font['value'] ) ) {
733 + // Make sure that the value is in the proper format
734 + $value = PixCustomifyPlugin::decodeURIComponent( $font['value'] );
735 + if ( is_string( $value ) ) {
736 + $value = json_decode( $value, true );
737 + }
790 738
791 - $value = json_decode( PixCustomifyPlugin::decodeURIComponent( $font['value'] ), true );
792 - // in case the value is still null, try default value(mostly for google fonts)
739 + // In case the value is null (most probably because the json_decode failed),
740 + // try the default value (mostly for google fonts)
793 741 if ( $value === null ) {
794 742 $value = $this->get_font_defaults_value( $font['value'] );
795 743 }
796 744
797 - // shim the old case when the default was only the font name
798 - if ( is_string( $value ) && ! empty( $value ) ) {
745 + // Shim the old case when the default was only the font name
746 + if ( ! empty( $value ) && is_string( $value ) ) {
799 747 $value = array( 'font_family' => $value );
800 748 }
801 749
802 - //Handle special logic for when the $value array is not an associative array
803 - if ( ! self::is_assoc( $value ) ) {
804 - $value = $this->process_a_not_associative_font_default( $value );
750 + // Handle special logic for when the $value array is not an associative array
751 + if ( ! $this->is_assoc( $value ) ) {
752 + $value = $this->standardize_non_associative_font_default( $value );
805 753 }
806 754
755 + // Bail if empty or we don't have an array
756 + if ( empty( $value ) || ! is_array( $value ) ) {
757 + continue;
758 + }
759 +
807 760 $selected_variant = '';
808 761 if ( ! empty( $value['selected_variants'] ) ) {
809 762 if ( is_array( $value['selected_variants'] ) ) {
810 763 $selected_variant = $value['selected_variants'][0];
@@ -814,13 +767,13 @@
814 767 }
815 768
816 769 // First handle the case where we have the font-family in the selected variant (usually this means a custom font from our Fonto plugin)
817 770 if ( ! empty( $selected_variant ) && is_array( $selected_variant ) && ! empty( $selected_variant['font-family'] ) ) {
818 - //the variant's font-family
771 + // The variant's font-family
819 772 echo $font['selector'] . " {\nfont-family: " . $selected_variant['font-family'] . ";\n";
820 773
821 774 if ( ! $load_all_weights ) {
822 - // if this is a custom font (like from our plugin Fonto) with individual styles & weights - i.e. the font-family says it all
775 + // If this is a custom font (like from our plugin Fonto) with individual styles & weights - i.e. the font-family says it all
823 776 // we need to "force" the font-weight and font-style
824 777 if ( ! empty( $value['type'] ) && 'custom_individual' == $value['type'] ) {
825 778 $selected_variant['font-weight'] = '400 !important';
826 779 $selected_variant['font-style'] = 'normal !important';
@@ -825,14 +778,14 @@
825 778 $selected_variant['font-weight'] = '400 !important';
826 779 $selected_variant['font-style'] = 'normal !important';
827 780 }
828 781
829 - // output the font weight, if available
782 + // Output the font weight, if available
830 783 if ( ! empty( $selected_variant['font-weight'] ) ) {
831 784 echo "font-weight: " . $selected_variant['font-weight'] . ";\n";
832 785 }
833 786
834 - // output the font style, if available
787 + // Output the font style, if available
835 788 if ( ! empty( $selected_variant['font-style'] ) ) {
836 789 echo "font-style: " . $selected_variant['font-style'] . ";\n";
837 790 }
838 791 }
@@ -838,9 +791,9 @@
838 791 }
839 792
840 793 echo "}\n";
841 794 } elseif ( isset( $value['font_family'] ) ) {
842 - // the selected font family
795 + // The selected font family
843 796 echo $font['selector'] . " {\n font-family: " . $value['font_family'] . ";\n";
844 797
845 798 if ( ! empty( $selected_variant ) && ! $load_all_weights ) {
846 799 $weight_and_style = strtolower( $selected_variant );
@@ -876,14 +829,18 @@
876 829 /**
877 830 * Handle special logic for when the $value array is not an associative array
878 831 * Return a new associative array with proper keys
879 832 */
880 - protected function process_a_not_associative_font_default( $value ) {
833 + public function standardize_non_associative_font_default( $value ) {
834 + // If the value provided is not array, simply return it
835 + if ( ! is_array( $value ) ) {
836 + return $value;
837 + }
881 838
882 839 $new_value = array();
883 840
884 - //Let's determine some type of font
885 - if ( ! isset( $value[2] ) || ( isset( $value[2] ) && 'google' == $value[2] ) ) {
841 + // Let's determine some type of font
842 + if ( ! isset( $value[2] ) || 'google' == $value[2] ) {
886 843 $new_value = $this->get_font_defaults_value( $value[0] );
887 844 } else {
888 845 $new_value['type'] = $value[2];
889 846 }
@@ -891,15 +848,15 @@
891 848 if ( null == $new_value ) {
892 849 $new_value = array();
893 850 }
894 851
895 - //The first entry is the font-family
852 + // The first entry is the font-family
896 853 if ( isset( $value[0] ) ) {
897 854 $new_value['font_family'] = $value[0];
898 855 }
899 856
900 - //In case we don't have an associative array
901 - //The second entry is the variants
857 + // In case we don't have an associative array
858 + // The second entry is the variants
902 859 if ( isset( $value[1] ) ) {
903 860 $new_value['selected_variants'] = $value[1];
904 861 }
905 862
@@ -911,20 +868,27 @@
911 868 * @param $font_name
912 869 *
913 870 * @return null
914 871 */
915 - protected function get_font_defaults_value( $font_name ) {
872 + public function get_font_defaults_value( $font_name ) {
916 873
917 - if ( empty( self::$google_fonts ) ) {
874 + if ( empty( $this->google_fonts ) ) {
918 875 $this->load_google_fonts();
919 876 }
920 877
921 - if ( isset( self::$google_fonts[ $font_name ] ) ) {
922 - $value = self::$google_fonts[ $font_name ];
878 + if ( isset( $this->google_fonts[ $font_name ] ) ) {
879 + $value = $this->google_fonts[ $font_name ];
923 880 $value['font_family'] = $font_name;
924 881 $value['type'] = 'google';
925 882
926 883 return $value;
884 + } elseif ( isset( $this->theme_fonts[ $font_name ] ) ) {
885 + $value['type'] = 'theme_font';
886 + $value['src'] = $this->theme_fonts[ $font_name ]['src'];
887 + $value['variants'] = $this->theme_fonts[ $font_name ]['variants'];
888 + $value['font_family'] = $this->theme_fonts[ $font_name ]['family'];
889 +
890 + return $value;
927 891 }
928 892
929 893 return null;
930 894 }
@@ -939,9 +903,9 @@
939 903 */
940 904 protected function convert_setting_to_css( $option_id, $css_config = array() ) {
941 905 $output = '';
942 906
943 - $this_value = self::get_option( $option_id );
907 + $this_value = $this->get_option( $option_id );
944 908
945 909 if ( empty( $css_config ) ) {
946 910 return $output;
947 911 }
@@ -948,9 +912,9 @@
948 912
949 913 foreach ( $css_config as $css_property ) {
950 914
951 915 if ( isset( $css_property['media'] ) && ! empty( $css_property['media'] ) ) {
952 - self::$media_queries[ $css_property['media'] ][ $option_id ] = array(
916 + $this->media_queries[ $css_property['media'] ][ $option_id ] = array(
953 917 'property' => $css_property,
954 918 'value' => $this_value
955 919 );
956 920 continue;
@@ -955,10 +919,10 @@
955 919 );
956 920 continue;
957 921 }
958 922
959 - if ( ! isset( $css_property['selector'] ) || isset( $css_property['property'] ) ) {
960 - $output .= self::proccess_css_property( $css_property, $this_value );
923 + if ( isset( $css_property['selector'] ) && isset( $css_property['property'] ) ) {
924 + $output .= $this->proccess_css_property( $css_property, $this_value ) . PHP_EOL;
961 925 }
962 926 }
963 927
964 928 return $output;
@@ -974,12 +938,20 @@
974 938 // if the unit isn't specified but the property should have a unit force 'px' as it
975 939 if ( empty( $unit ) && in_array( $css_property['property'], self::$pixel_dependent_css_properties ) ) {
976 940 $unit = 'px';
977 941 }
942 + // lose the tons of tabs
943 + $css_property['selector'] = trim( preg_replace( '/\t+/', '', $css_property['selector'] ) );
978 944
979 - $this_property_output = $css_property['selector'] . ' { ' . $css_property['property'] . ': ' . $this_value . $unit . "; } \n";
945 + $this_property_output = $css_property['selector'] . ' { ' . $css_property['property'] . ': ' . $this_value . $unit . "; }" . PHP_EOL;
980 946
981 - if ( isset( $css_property['callback_filter'] ) && function_exists( $css_property['callback_filter'] ) ) {
947 + // Handle the value filter callback.
948 + if ( isset( $css_property['filter_value_cb'] ) ) {
949 + $this_value = $this->maybe_apply_filter( $css_property['filter_value_cb'], $this_value );
950 + }
951 +
952 + // Handle output callback.
953 + if ( isset( $css_property['callback_filter'] ) && is_callable( $css_property['callback_filter'] ) ) {
982 954 $this_property_output = call_user_func( $css_property['callback_filter'], $this_value, $css_property['selector'], $css_property['property'], $unit );
983 955 }
984 956
985 957 return $this_property_output;
@@ -984,15 +956,60 @@
984 956
985 957 return $this_property_output;
986 958 }
987 959
960 + /**
961 + * Apply a filter (config) to a value.
962 + *
963 + * We currently handle filters like these:
964 + * // Elaborate filter config
965 + * array(
966 + * 'callback' => 'is_post_type_archive',
967 + * // The arguments we should pass to the check function.
968 + * // Think post types, taxonomies, or nothing if that is the case.
969 + * // It can be an array of values or a single value.
970 + * 'args' => array(
971 + * 'jetpack-portfolio',
972 + * ),
973 + * ),
974 + * // Simple filter - just the function name
975 + * 'is_404',
976 + *
977 + * @param array|string $filter
978 + * @param mixed $value The value to apply the filter to.
979 + *
980 + * @return mixed The filtered value.
981 + */
982 + public function maybe_apply_filter( $filter, $value ) {
983 + // Let's get some obvious things off the table.
984 + // On invalid data, we just return what we've received.
985 + if ( empty( $filter ) ) {
986 + return $value;
987 + }
988 +
989 + // First, we handle the shorthand version: just a function name
990 + if ( is_string( $filter ) && is_callable( $filter ) ) {
991 + $value = call_user_func( $filter );
992 + } elseif ( is_array( $filter ) && ! empty( $filter['callback'] ) && is_callable( $filter['callback'] ) ) {
993 + if ( empty( $filter['args'] ) ) {
994 + $filter['args'] = array();
995 + }
996 + // The value is always the first argument.
997 + $filter['args'] = array( $value ) + $filter['args'];
998 +
999 + $value = call_user_func_array( $filter['callback'], $filter['args'] );
1000 + }
1001 +
1002 + return $value;
1003 + }
1004 +
988 1005 protected function process_custom_background_field_output( $option_id, $options ) {
989 - $selector = '';
1006 + $selector = $output = '';
990 1007
991 1008 if ( ! isset( $options['value'] ) ) {
992 1009 return false;
993 1010 }
994 - $value = $options['value'];
1011 + $value = $options['value'];
995 1012
996 1013 if ( ! isset( $options['output'] ) ) {
997 1014 return $selector;
998 1015 } elseif ( is_string( $options['output'] ) ) {
@@ -999,39 +1016,37 @@
999 1016 $selector = $options['output'];
1000 1017 } elseif ( is_array( $options['output'] ) ) {
1001 1018 $selector = implode( ' ', $options['output'] );
1002 1019 }
1003 - ob_start();
1004 1020
1005 - echo "\n" . $selector . " { \n";
1021 +
1022 + $output .= $selector . " {";
1006 1023 if ( isset( $value['background-image'] ) && ! empty( $value['background-image'] ) ) {
1007 - echo "background-image: url( " . $value['background-image'] . ");\n";
1024 + $output .= "background-image: url( " . $value['background-image'] . ");";
1008 1025 } else {
1009 - echo "background-image: none;\n";
1026 + $output .= "background-image: none;";
1010 1027 }
1011 1028
1012 1029 if ( isset( $value['background-repeat'] ) && ! empty( $value['background-repeat'] ) ) {
1013 - echo "background-repeat:" . $value['background-repeat'] . ";\n";
1030 + $output .= "background-repeat:" . $value['background-repeat'] . ";";
1014 1031 }
1015 1032
1016 1033 if ( isset( $value['background-position'] ) && ! empty( $value['background-position'] ) ) {
1017 - echo "background-position:" . $value['background-position'] . ";\n";
1034 + $output .= "background-position:" . $value['background-position'] . ";";
1018 1035 }
1019 1036
1020 1037 if ( isset( $value['background-size'] ) && ! empty( $value['background-size'] ) ) {
1021 - echo "background-size:" . $value['background-size'] . ";\n";
1038 + $output .= "background-size:" . $value['background-size'] . ";";
1022 1039 }
1023 1040
1024 1041 if ( isset( $value['background-attachment'] ) && ! empty( $value['background-attachment'] ) ) {
1025 - echo "background-attachment:" . $value['background-attachment'] . ";\n";
1042 + $output .= "background-attachment:" . $value['background-attachment'] . ";";
1026 1043 }
1027 - echo "\n}\n";
1044 + $output .= "}\n";
1028 1045
1029 - return ob_get_clean();
1046 + return $output;
1030 1047 }
1031 1048
1032 - // addd editor style
1033 -
1034 1049 /**
1035 1050 * add our customizer styling edits into the wp_editor
1036 1051 */
1037 1052 function add_customizer_settings_into_wp_editor() {
@@ -1042,61 +1057,58 @@
1042 1057
1043 1058 $custom_css = ob_get_clean(); ?>
1044 1059 <script type="text/javascript">
1045 1060 /* <![CDATA[ */
1046 - (function( $ ) {
1047 - $( window ).load( function() {
1061 + (function ($) {
1062 + $(window).load(function () {
1048 1063 /**
1049 - * @param iframe_id the id of the frame you whant to append the style
1064 + * @param iframe_id the id of the frame you want to append the style
1050 1065 * @param style_element the style element you want to append
1051 1066 */
1052 - var append_script_to_iframe = function( ifrm_id, scriptEl ) {
1053 - var myIframe = document.getElementById( ifrm_id );
1067 + var append_script_to_iframe = function (ifrm_id, scriptEl) {
1068 + var myIframe = document.getElementById(ifrm_id);
1054 1069
1055 - var script = myIframe.contentWindow.document.createElement( "script" );
1070 + var script = myIframe.contentWindow.document.createElement("script");
1056 1071 script.type = "text/javascript";
1057 1072 script.innerHTML = scriptEl.innerHTML;
1058 1073
1059 - myIframe.contentWindow.document.head.appendChild( script );
1074 + myIframe.contentWindow.document.head.appendChild(script);
1060 1075 };
1061 1076
1062 - var append_style_to_iframe = function( ifrm_id, styleElment ) {
1077 + var append_style_to_iframe = function (ifrm_id, styleElment) {
1063 1078 var ifrm = window.frames[ifrm_id];
1064 1079 ifrm = ( ifrm.contentDocument || ifrm.contentDocument || ifrm.document );
1065 - var head = ifrm.getElementsByTagName( 'head' )[0];
1080 + var head = ifrm.getElementsByTagName('head')[0];
1066 1081
1067 - if ( typeof styleElment !== "undefined" ) {
1068 - head.appendChild( styleElment );
1082 + if (typeof styleElment !== "undefined") {
1083 + head.appendChild(styleElment);
1069 1084 }
1070 1085 };
1071 1086
1072 1087 var xmlString = <?php echo json_encode( str_replace( "\n", "", $custom_css ) ); ?>,
1073 1088 parser = new DOMParser(),
1074 - doc = parser.parseFromString( xmlString, "text/html" );
1089 + doc = parser.parseFromString(xmlString, "text/html");
1075 1090
1076 - if ( typeof window.frames['content_ifr'] !== 'undefined' ) {
1091 + if (typeof window.frames['content_ifr'] !== 'undefined') {
1077 1092
1078 - $.each( doc.head.childNodes, function( key, el ) {
1093 + $.each(doc.head.childNodes, function (key, el) {
1094 + if (typeof el !== "undefined" && typeof el.tagName !== "undefined") {
1079 1095
1080 - if ( typeof el !== "undefined" && typeof el.tagName !== "undefined" ) {
1081 -
1082 - switch ( el.tagName ) {
1083 -
1096 + switch (el.tagName) {
1084 1097 case 'STYLE' :
1085 - append_style_to_iframe( 'content_ifr', el );
1098 + append_style_to_iframe('content_ifr', el);
1086 1099 break;
1087 -
1088 1100 case 'SCRIPT' :
1089 - append_script_to_iframe( 'content_ifr', el );
1101 + append_script_to_iframe('content_ifr', el);
1090 1102 break;
1091 1103 default:
1092 1104 break;
1093 1105 }
1094 1106 }
1095 - } );
1107 + });
1096 1108 }
1097 - } );
1098 - })( jQuery );
1109 + });
1110 + })(jQuery);
1099 1111 /* ]]> */
1100 1112 </script>
1101 1113 <?php }
1102 1114
@@ -1126,25 +1138,28 @@
1126 1138
1127 1139 protected function register_customizer_controls() {
1128 1140
1129 1141 // first get the base customizer extend class
1130 - require_once( self::get_base_path() . '/features/customizer/class-Pix_Customize_Control.php' );
1142 + require_once( $this->get_base_path() . '/features/customizer/class-Pix_Customize_Control.php' );
1131 1143
1132 1144 // now get all the controls
1133 - $path = self::get_base_path() . '/features/customizer/controls/';
1145 + $path = $this->get_base_path() . '/features/customizer/controls/';
1134 1146 pixcustomify::require_all( $path );
1135 1147 }
1136 1148
1149 + /**
1150 + * @param WP_Customize_Manager $wp_customize
1151 + */
1137 1152 function register_customizer( $wp_customize ) {
1138 1153
1139 1154 $this->register_customizer_controls();
1140 1155
1141 - $customizer_settings = self::$customizer_config;
1156 + $customizer_settings = $this->customizer_config;
1142 1157
1143 1158 if ( ! empty ( $customizer_settings ) ) {
1144 1159
1145 1160 // first check the very needed options name
1146 - if ( ! isset ( $customizer_settings['opt-name'] ) || empty( $customizer_settings['opt-name'] ) ) {
1161 + if ( empty( $customizer_settings['opt-name'] ) ) {
1147 1162 return;
1148 1163 }
1149 1164 $options_name = $customizer_settings['opt-name'];
1150 1165 $wp_customize->options_key = $options_name;
@@ -1151,37 +1166,43 @@
1151 1166
1152 1167 // let's check if we have sections or panels
1153 1168 if ( isset( $customizer_settings['panels'] ) && ! empty( $customizer_settings['panels'] ) ) {
1154 1169
1155 - foreach ( $customizer_settings['panels'] as $panel_id => $panel_settings ) {
1170 + foreach ( $customizer_settings['panels'] as $panel_id => $panel_config ) {
1156 1171
1157 - if ( ! empty( $panel_id ) && isset( $panel_settings['sections'] ) && ! empty( $panel_settings['sections'] ) ) {
1172 + if ( ! empty( $panel_id ) && isset( $panel_config['sections'] ) && ! empty( $panel_config['sections'] ) ) {
1158 1173
1159 - $panel_id = $options_name . '[' . $panel_id . ']';
1174 + // If we have been explicitly given a panel ID we will use that
1175 + if ( ! empty( $panel_config['panel_id'] ) ) {
1176 + $panel_id = $panel_config['panel_id'];
1177 + } else {
1178 + $panel_id = $options_name . '[' . $panel_id . ']';
1179 + }
1180 +
1160 1181 $panel_args = array(
1161 1182 'priority' => 10,
1162 1183 'capability' => 'edit_theme_options',
1163 - 'title' => __( 'Panel title is required', 'textdomain' ),
1164 - 'description' => __( 'Description of what this panel does.', 'textdomain' ),
1184 + 'title' => __( 'Panel title is required', 'pixcustomify' ),
1185 + 'description' => __( 'Description of what this panel does.', 'pixcustomify' ),
1165 1186 );
1166 1187
1167 - if ( isset( $panel_settings['priority'] ) && ! empty( $panel_settings['priority'] ) ) {
1168 - $panel_args['priority'] = $panel_settings['priority'];
1188 + if ( isset( $panel_config['priority'] ) && ! empty( $panel_config['priority'] ) ) {
1189 + $panel_args['priority'] = $panel_config['priority'];
1169 1190 }
1170 1191
1171 - if ( isset( $panel_settings['title'] ) && ! empty( $panel_settings['title'] ) ) {
1172 - $panel_args['title'] = $panel_settings['title'];
1192 + if ( isset( $panel_config['title'] ) && ! empty( $panel_config['title'] ) ) {
1193 + $panel_args['title'] = $panel_config['title'];
1173 1194 }
1174 1195
1175 - if ( isset( $panel_settings['description'] ) && ! empty( $panel_settings['description'] ) ) {
1176 - $panel_args[10] = $panel_settings['description'];
1196 + if ( isset( $panel_config['description'] ) && ! empty( $panel_config['description'] ) ) {
1197 + $panel_args['description'] = $panel_config['description'];
1177 1198 }
1178 1199
1179 1200 $wp_customize->add_panel( $panel_id, $panel_args );
1180 1201
1181 - foreach ( $panel_settings['sections'] as $section_id => $section_settings ) {
1182 - if ( ! empty( $section_id ) && isset( $section_settings['options'] ) && ! empty( $section_settings['options'] ) ) {
1183 - $this->register_section( $panel_id, $section_id, $options_name, $section_settings, $wp_customize );
1202 + foreach ( $panel_config['sections'] as $section_id => $section_config ) {
1203 + if ( ! empty( $section_id ) && isset( $section_config['options'] ) && ! empty( $section_config['options'] ) ) {
1204 + $this->register_section( $panel_id, $section_id, $options_name, $section_config, $wp_customize );
1184 1205 }
1185 1206 }
1186 1207 }
1187 1208 }
@@ -1188,19 +1209,21 @@
1188 1209 }
1189 1210
1190 1211 if ( isset( $customizer_settings['sections'] ) && ! empty( $customizer_settings['sections'] ) ) {
1191 1212
1192 - foreach ( $customizer_settings['sections'] as $section_id => $section_settings ) {
1193 - if ( ! empty( $section_id ) && isset( $section_settings['options'] ) && ! empty( $section_settings['options'] ) ) {
1194 - $this->register_section( $panel_id = false, $section_id, $options_name, $section_settings, $wp_customize );
1213 + foreach ( $customizer_settings['sections'] as $section_id => $section_config ) {
1214 + if ( ! empty( $section_id ) && isset( $section_config['options'] ) && ! empty( $section_config['options'] ) ) {
1215 + $this->register_section( $panel_id = false, $section_id, $options_name, $section_config, $wp_customize );
1195 1216 }
1196 1217 }
1197 1218 }
1198 1219
1199 - if ( self::$plugin_settings['enable_reset_buttons'] ) {
1220 + if ( $this->plugin_settings['enable_reset_buttons'] ) {
1200 1221 // create a toolbar section which will be present all the time
1201 1222 $reset_section_settings = array(
1202 - 'title' => 'Customify toolbar',
1223 + 'title' => 'Customify Toolbox',
1224 + 'capability' => 'manage_options',
1225 + 'priority' => 999999999,
1203 1226 'options' => array(
1204 1227 'reset_all_button' => array(
1205 1228 'type' => 'button',
1206 1229 'label' => 'Reset Customify',
@@ -1211,12 +1234,9 @@
1211 1234 );
1212 1235
1213 1236 $wp_customize->add_section(
1214 1237 'customify_toolbar',
1215 - array(
1216 - 'title' => '',
1217 - 'priority' => 999999999
1218 - )
1238 + $reset_section_settings
1219 1239 );
1220 1240
1221 1241 $wp_customize->add_setting(
1222 1242 'reset_customify',
@@ -1225,9 +1245,9 @@
1225 1245 $wp_customize->add_control( new Pix_Customize_Button_Control(
1226 1246 $wp_customize,
1227 1247 'reset_customify',
1228 1248 array(
1229 - 'label' => __( 'Reset Customify to Defaults', 'customify_txtd' ),
1249 + 'label' => __( 'Reset All Customify Options to Default', 'customify' ),
1230 1250 'section' => 'customify_toolbar',
1231 1251 'settings' => 'reset_customify',
1232 1252 'action' => 'reset_customify',
1233 1253 )
@@ -1257,54 +1277,81 @@
1257 1277
1258 1278 do_action( 'customify_create_custom_control', $wp_customize );
1259 1279 }
1260 1280
1261 - protected function register_section( $panel_id, $section_key, $options_name, $section_settings, $wp_customize ) {
1281 + /**
1282 + * @param string $panel_id
1283 + * @param string $section_key
1284 + * @param string $options_name
1285 + * @param array $section_config
1286 + * @param WP_Customize_Manager $wp_customize
1287 + */
1288 + protected function register_section( $panel_id, $section_key, $options_name, $section_config, $wp_customize ) {
1262 1289
1263 - if ( isset( self::$plugin_settings['disable_customify_sections'] ) && isset( self::$plugin_settings['disable_customify_sections'][ $section_key ] ) ) {
1290 + if ( isset( $this->plugin_settings['disable_customify_sections'] ) && isset( $this->plugin_settings['disable_customify_sections'][ $section_key ] ) ) {
1264 1291 return;
1265 1292 }
1266 1293
1267 - $section_args = array(
1294 + // Merge the section settings with the defaults
1295 + $section_args = wp_parse_args( $section_config, array(
1268 1296 'priority' => 10,
1297 + 'panel' => $panel_id,
1269 1298 'capability' => 'edit_theme_options',
1270 - 'title' => __( 'Title Section is required', 'textdomain' ),
1271 - 'panel' => $panel_id,
1272 - );
1273 - $section_id = $options_name . '[' . $section_key . ']';
1299 + 'theme_supports' => '',
1300 + 'title' => esc_html__( 'Title Section is required', 'customify' ),
1301 + 'description' => '',
1302 + 'type' => 'default',
1303 + 'description_hidden' => false,
1304 + ) );
1274 1305
1275 - if ( isset( $section_settings['priority'] ) && ! empty( $section_settings['priority'] ) ) {
1276 - $section_args['priority'] = $section_settings['priority'];
1306 + // If we have been explicitly given a section ID we will use that
1307 + if ( ! empty( $section_config['section_id'] ) ) {
1308 + $section_id = $section_config['section_id'];
1309 + } else {
1310 + $section_id = $options_name . '[' . $section_key . ']';
1277 1311 }
1278 1312
1279 - if ( isset( $section_settings['title'] ) && ! empty( $section_settings['title'] ) ) {
1280 - $section_args['title'] = $section_settings['title'];
1281 - }
1282 -
1283 - if ( isset( $section_settings['theme_supports'] ) && ! empty( $section_settings['theme_supports'] ) ) {
1284 - $section_args['theme_supports'] = $section_settings['theme_supports'];
1285 - }
1286 -
1287 - if ( isset( $section_settings['description'] ) && ! empty( $section_settings['description'] ) ) {
1288 - $section_args['description'] = $section_settings['description'];
1289 - }
1290 -
1313 + // Add the new section to the Customizer
1291 1314 $wp_customize->add_section( $section_id, $section_args );
1292 1315
1293 - foreach ( $section_settings['options'] as $option_id => $option_config ) {
1316 + // Now go through each section option and add the fields
1317 + foreach ( $section_config['options'] as $option_id => $option_config ) {
1294 1318
1295 1319 if ( empty( $option_id ) || ! isset( $option_config['type'] ) ) {
1296 1320 continue;
1297 1321 }
1298 1322
1299 - $option_id = $options_name . '[' . $option_id . ']';
1323 + // If we have been explicitly given a setting ID we will use that
1324 + if ( ! empty( $option_config['setting_id'] ) ) {
1325 + $setting_id = $option_config['setting_id'];
1326 + } else {
1327 + $setting_id = $options_name . '[' . $option_id . ']';
1328 + }
1300 1329
1301 - $this->register_field( $section_id, $option_id, $option_config, $wp_customize );
1330 + // Add the option config to the localized array so we can pass the info to JS.
1331 + // @todo Maybe we should ensure that the connected_fields configs passed here follow the same format and logic as the ones in ::customize_pane_settings_additional_data() thus maybe having the data in the same place.
1332 + $this->localized['settings'][ $setting_id ] = $option_config;
1333 +
1334 + // Generate a safe option ID (not the final setting ID) to us in HTML attributes like ID or class
1335 + $this->localized['settings'][ $setting_id ]['html_safe_option_id'] = sanitize_html_class( $option_id );
1336 +
1337 + $this->register_field( $section_id, $setting_id, $option_config, $wp_customize );
1302 1338 }
1303 1339
1304 1340 }
1305 1341
1306 - protected function register_field( $section_id, $setting_id, $setting_config, $wp_customize ) {
1342 + /**
1343 + * Register a Customizer field (setting and control).
1344 + *
1345 + * @see WP_Customize_Setting
1346 + * @see WP_Customize_Control
1347 + *
1348 + * @param string $section_id
1349 + * @param string $setting_id
1350 + * @param array $field_config
1351 + * @param WP_Customize_Manager $wp_customize
1352 + */
1353 + protected function register_field( $section_id, $setting_id, $field_config, $wp_customize ) {
1307 1354
1308 1355 $add_control = true;
1309 1356 // defaults
1310 1357 $setting_args = array(
@@ -1312,34 +1359,38 @@
1312 1359 'capability' => 'edit_theme_options',
1313 1360 'transport' => 'refresh',
1314 1361 );
1315 1362 $control_args = array(
1363 + 'priority' => 10,
1316 1364 'label' => '',
1317 1365 'section' => $section_id,
1318 1366 'settings' => $setting_id,
1319 1367 );
1320 1368
1321 - self::$localized['settings'][ $setting_id ] = $setting_config;
1322 -
1323 1369 // sanitize settings
1324 - if ( isset( $setting_config['live'] ) && $setting_config['live'] ) {
1370 + if ( ! empty( $field_config['live'] ) || $field_config['type'] === 'font' ) {
1325 1371 $setting_args['transport'] = 'postMessage';
1326 1372 }
1327 1373
1328 - if ( isset( $setting_config['default'] ) ) {
1329 - $setting_args['default'] = $setting_config['default'];
1374 + if ( isset( $field_config['default'] ) ) {
1375 + $setting_args['default'] = $field_config['default'];
1330 1376 }
1331 1377
1332 - if ( isset( $setting_config['capability'] ) && ! empty( $setting_config['capability'] ) ) {
1333 - $setting_args['capability'] = $setting_config['capability'];
1378 + if ( ! empty( $field_config['capability'] ) ) {
1379 + $setting_args['capability'] = $field_config['capability'];
1334 1380 }
1335 1381
1336 - if ( self::$plugin_settings['values_store_mod'] == 'option' ) {
1382 + // If the setting defines it's own type we will respect that, otherwise we will follow the global plugin setting.
1383 + if ( ! empty( $field_config['setting_type'] ) ) {
1384 + if ( 'option' === $field_config['setting_type'] ) {
1385 + $setting_args['type'] = 'option';
1386 + }
1387 + } elseif ( $this->plugin_settings['values_store_mod'] === 'option' ) {
1337 1388 $setting_args['type'] = 'option';
1338 1389 }
1339 1390
1340 1391 // if we arrive here this means we have a custom field control
1341 - switch ( $setting_config['type'] ) {
1392 + switch ( $field_config['type'] ) {
1342 1393
1343 1394 case 'checkbox':
1344 1395
1345 1396 $setting_args['sanitize_callback'] = array( $this, 'setting_sanitize_checkbox' );
@@ -1348,37 +1399,41 @@
1348 1399 default:
1349 1400 break;
1350 1401 }
1351 1402
1352 - if ( isset( $setting_config['sanitize_callback'] ) && ! empty( $setting_config['sanitize_callback'] ) && function_exists( $setting_config['sanitize_callback'] ) ) {
1353 - $setting_args['sanitize_callback'] = $setting_config['sanitize_callback'];
1403 + if ( ! empty( $field_config['sanitize_callback'] ) && is_callable( $field_config['sanitize_callback'] ) ) {
1404 + $setting_args['sanitize_callback'] = $field_config['sanitize_callback'];
1354 1405 }
1355 1406
1356 - // and add it
1407 + // Add the setting
1357 1408 $wp_customize->add_setting( $setting_id, $setting_args );
1358 1409
1359 1410 // now sanitize the control
1360 - if ( isset( $setting_config['label'] ) && ! empty( $setting_config['label'] ) ) {
1361 - $control_args['label'] = $setting_config['label'];
1411 + if ( ! empty( $field_config['label'] ) ) {
1412 + $control_args['label'] = $field_config['label'];
1362 1413 }
1363 1414
1364 - if ( isset( $setting_config['priority'] ) && ! empty( $setting_config['priority'] ) ) {
1365 - $control_args['priority'] = $setting_config['priority'];
1415 + if ( ! empty( $field_config['priority'] ) ) {
1416 + $control_args['priority'] = $field_config['priority'];
1366 1417 }
1367 1418
1368 - if ( isset( $setting_config['desc'] ) && ! empty( $setting_config['desc'] ) ) {
1369 - $control_args['description'] = $setting_config['desc'];
1419 + if ( ! empty( $field_config['desc'] ) ) {
1420 + $control_args['description'] = $field_config['desc'];
1370 1421 }
1371 1422
1423 + if ( ! empty( $field_config['active_callback'] ) ) {
1424 + $control_args['active_callback'] = $field_config['active_callback'];
1425 + }
1372 1426
1373 - $control_args['type'] = $setting_config['type'];
1374 1427
1428 + $control_args['type'] = $field_config['type'];
1429 +
1375 1430 // select the control type
1376 1431 // but first init a default
1377 1432 $control_class_name = 'Pix_Customize_Text_Control';
1378 1433
1379 - // if is a standard wp field type call it here and skip the rest
1380 - if ( in_array( $setting_config['type'], array(
1434 + // If is a standard wp field type call it here and skip the rest.
1435 + if ( in_array( $field_config['type'], array(
1381 1436 'checkbox',
1382 1437 'dropdown-pages',
1383 1438 'url',
1384 1439 'date',
@@ -1389,31 +1444,30 @@
1389 1444 ) ) ) {
1390 1445 $wp_customize->add_control( $setting_id . '_control', $control_args );
1391 1446
1392 1447 return;
1393 - } elseif ( in_array( $setting_config['type'], array(
1448 + } elseif ( in_array( $field_config['type'], array(
1394 1449 'radio',
1395 1450 'select'
1396 - ) ) && isset( $setting_config['choices'] ) && ! empty( $setting_config['choices'] )
1451 + ) ) && ! empty( $field_config['choices'] )
1397 1452 ) {
1398 - $control_args['choices'] = $setting_config['choices'];
1453 + $control_args['choices'] = $field_config['choices'];
1399 1454 $wp_customize->add_control( $setting_id . '_control', $control_args );
1400 1455
1401 1456 return;
1402 - } elseif ( in_array( $setting_config['type'], array( 'range' ) ) && isset( $setting_config['input_attrs'] ) && ! empty( $setting_config['input_attrs'] ) ) {
1457 + } elseif ( in_array( $field_config['type'], array( 'range' ) ) && ! empty( $field_config['input_attrs'] ) ) {
1403 1458
1404 - $control_args['input_attrs'] = $setting_config['input_attrs'];
1459 + $control_args['input_attrs'] = $field_config['input_attrs'];
1405 1460
1406 1461 $wp_customize->add_control( $setting_id . '_control', $control_args );
1407 1462 }
1408 1463
1409 - // if we arrive here this means we have a custom field control
1410 - switch ( $setting_config['type'] ) {
1464 + // If we arrive here this means we have a custom field control.
1465 + switch ( $field_config['type'] ) {
1411 1466
1412 1467 case 'text':
1413 -
1414 - if ( isset( $setting_config['live'] ) ) {
1415 - $control_args['live'] = $setting_config['live'];
1468 + if ( isset( $field_config['live'] ) ) {
1469 + $control_args['live'] = $field_config['live'];
1416 1470 }
1417 1471
1418 1472 $control_class_name = 'Pix_Customize_Text_Control';
1419 1473 break;
@@ -1418,11 +1472,10 @@
1418 1472 $control_class_name = 'Pix_Customize_Text_Control';
1419 1473 break;
1420 1474
1421 1475 case 'textarea':
1422 -
1423 - if ( isset( $setting_config['live'] ) ) {
1424 - $control_args['live'] = $setting_config['live'];
1476 + if ( isset( $field_config['live'] ) ) {
1477 + $control_args['live'] = $field_config['live'];
1425 1478 }
1426 1479
1427 1480 $control_class_name = 'Pix_Customize_Textarea_Control';
1428 1481 break;
@@ -1427,25 +1480,22 @@
1427 1480 $control_class_name = 'Pix_Customize_Textarea_Control';
1428 1481 break;
1429 1482
1430 1483 case 'color':
1431 -
1432 1484 $control_class_name = 'WP_Customize_Color_Control';
1433 1485 break;
1434 1486
1435 1487 case 'color_drop':
1436 -
1437 1488 $control_class_name = 'Pix_Customize_Color_Drop_Control';
1438 1489 break;
1439 1490
1440 1491 case 'ace_editor':
1441 -
1442 - if ( isset( $setting_config['live'] ) ) {
1443 - $control_args['live'] = $setting_config['live'];
1492 + if ( isset( $field_config['live'] ) ) {
1493 + $control_args['live'] = $field_config['live'];
1444 1494 }
1445 1495
1446 - if ( isset( $setting_config['editor_type'] ) ) {
1447 - $control_args['editor_type'] = $setting_config['editor_type'];
1496 + if ( isset( $field_config['editor_type'] ) ) {
1497 + $control_args['editor_type'] = $field_config['editor_type'];
1448 1498 }
1449 1499
1450 1500 $control_class_name = 'Pix_Customize_Ace_Editor_Control';
1451 1501 break;
@@ -1450,25 +1500,22 @@
1450 1500 $control_class_name = 'Pix_Customize_Ace_Editor_Control';
1451 1501 break;
1452 1502
1453 1503 case 'upload':
1454 -
1455 1504 $control_class_name = 'WP_Customize_Upload_Control';
1456 1505 break;
1457 1506
1458 1507 case 'image':
1459 -
1460 1508 $control_class_name = 'WP_Customize_Image_Control';
1461 1509 break;
1462 1510
1463 1511 case 'media':
1464 -
1465 1512 $control_class_name = 'WP_Customize_Media_Control';
1466 1513 break;
1467 1514
1468 1515 case 'custom_background':
1469 - if ( isset( $setting_config['field'] ) ) {
1470 - $control_args['field'] = $setting_config['field'];
1516 + if ( isset( $field_config['field'] ) ) {
1517 + $control_args['field'] = $field_config['field'];
1471 1518 }
1472 1519
1473 1520 $control_class_name = 'Pix_Customize_Background_Control';
1474 1521 break;
@@ -1473,23 +1520,22 @@
1473 1520 $control_class_name = 'Pix_Customize_Background_Control';
1474 1521 break;
1475 1522
1476 1523 case 'cropped_media':
1477 -
1478 - if ( isset( $setting_config['width'] ) ) {
1479 - $control_args['width'] = $setting_config['width'];
1524 + if ( isset( $field_config['width'] ) ) {
1525 + $control_args['width'] = $field_config['width'];
1480 1526 }
1481 1527
1482 - if ( isset( $setting_config['height'] ) ) {
1483 - $control_args['height'] = $setting_config['height'];
1528 + if ( isset( $field_config['height'] ) ) {
1529 + $control_args['height'] = $field_config['height'];
1484 1530 }
1485 1531
1486 - if ( isset( $setting_config['flex_width'] ) ) {
1487 - $control_args['flex_width'] = $setting_config['flex_width'];
1532 + if ( isset( $field_config['flex_width'] ) ) {
1533 + $control_args['flex_width'] = $field_config['flex_width'];
1488 1534 }
1489 1535
1490 - if ( isset( $setting_config['flex_height'] ) ) {
1491 - $control_args['flex_height'] = $setting_config['flex_height'];
1536 + if ( isset( $field_config['flex_height'] ) ) {
1537 + $control_args['flex_height'] = $field_config['flex_height'];
1492 1538 }
1493 1539
1494 1540 $control_class_name = 'WP_Customize_Cropped_Image_Control';
1495 1541 break;
@@ -1495,69 +1541,107 @@
1495 1541 break;
1496 1542
1497 1543 // Custom types
1498 1544 case 'typography' :
1545 + $use_typography = $this->get_plugin_setting( 'typography', '1' );
1499 1546
1500 - $use_typography = self::get_plugin_option( 'typography', '1' );
1547 + if ( $use_typography === false ) {
1548 + $add_control = false;
1549 + continue;
1550 + }
1501 1551
1552 + $control_class_name = 'Pix_Customize_Typography_Control';
1553 +
1554 + if ( isset( $field_config['backup'] ) ) {
1555 + $control_args['backup'] = $field_config['backup'];
1556 + }
1557 +
1558 + if ( isset( $field_config['font_weight'] ) ) {
1559 + $control_args['font_weight'] = $field_config['font_weight'];
1560 + }
1561 +
1562 + if ( isset( $field_config['subsets'] ) ) {
1563 + $control_args['subsets'] = $field_config['subsets'];
1564 + }
1565 +
1566 + if ( isset( $field_config['recommended'] ) ) {
1567 + $control_args['recommended'] = array_flip( $field_config['recommended'] );
1568 + }
1569 +
1570 + if ( isset( $field_config['load_all_weights'] ) ) {
1571 + $control_args['load_all_weights'] = $field_config['load_all_weights'];
1572 + }
1573 +
1574 + if ( isset( $field_config['default'] ) ) {
1575 + $control_args['default'] = $field_config['default'];
1576 + }
1577 +
1578 + break;
1579 +
1580 + case 'font' :
1581 + $use_typography = $this->get_plugin_setting( 'typography', '1' );
1582 +
1502 1583 if ( $use_typography === false ) {
1503 1584 $add_control = false;
1504 1585 continue;
1505 1586 }
1506 1587
1507 - $control_class_name = 'Pix_Customize_Typography_Control';
1588 + $control_class_name = 'Pix_Customize_Font_Control';
1508 1589
1509 - if ( isset( $setting_config['backup'] ) ) {
1510 - $control_args['backup'] = $setting_config['backup'];
1590 + if ( isset( $field_config['backup'] ) ) {
1591 + $control_args['backup'] = $field_config['backup'];
1511 1592 }
1512 1593
1513 - if ( isset( $setting_config['font_weight'] ) ) {
1514 - $control_args['font_weight'] = $setting_config['font_weight'];
1594 + if ( isset( $field_config['font_weight'] ) ) {
1595 + $control_args['font_weight'] = $field_config['font_weight'];
1515 1596 }
1516 1597
1517 - if ( isset( $setting_config['subsets'] ) ) {
1518 - $control_args['subsets'] = $setting_config['subsets'];
1598 + if ( isset( $field_config['subsets'] ) ) {
1599 + $control_args['subsets'] = $field_config['subsets'];
1519 1600 }
1520 1601
1521 - if ( isset( $setting_config['recommended'] ) ) {
1522 - $control_args['recommended'] = array_flip( $setting_config['recommended'] );
1602 + if ( isset( $field_config['recommended'] ) ) {
1603 + $control_args['recommended'] = array_flip( $field_config['recommended'] );
1523 1604 }
1524 1605
1525 - if ( isset( $setting_config['load_all_weights'] ) ) {
1526 - $control_args['load_all_weights'] = $setting_config['load_all_weights'];
1606 + if ( isset( $field_config['load_all_weights'] ) ) {
1607 + $control_args['load_all_weights'] = $field_config['load_all_weights'];
1527 1608 }
1528 1609
1529 - if ( isset( $setting_config['default'] ) ) {
1530 - $control_args['default'] = $setting_config['default'];
1610 + if ( isset( $field_config['default'] ) ) {
1611 + $control_args['default'] = $field_config['default'];
1531 1612 }
1532 1613
1614 + if ( isset( $field_config['fields'] ) ) {
1615 + $control_args['fields'] = $field_config['fields'];
1616 + }
1617 + $control_args['live'] = true;
1618 +
1533 1619 break;
1534 1620
1535 1621 case 'select2' :
1536 -
1537 - if ( ! isset( $setting_config['choices'] ) || empty( $setting_config['choices'] ) ) {
1622 + if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
1538 1623 return;
1539 1624 }
1540 1625
1541 - $control_args['choices'] = $setting_config['choices'];
1626 + $control_args['choices'] = $field_config['choices'];
1542 1627
1543 1628 $control_class_name = 'Pix_Customize_Select2_Control';
1544 1629 break;
1545 1630
1546 1631 case 'preset' :
1547 -
1548 - if ( ! isset( $setting_config['choices'] ) || empty( $setting_config['choices'] ) ) {
1632 + if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
1549 1633 return;
1550 1634 }
1551 1635
1552 - $control_args['choices'] = $setting_config['choices'];
1636 + $control_args['choices'] = $field_config['choices'];
1553 1637
1554 - if ( isset( $setting_config['choices_type'] ) || ! empty( $setting_config['choices_type'] ) ) {
1555 - $control_args['choices_type'] = $setting_config['choices_type'];
1638 + if ( isset( $field_config['choices_type'] ) || ! empty( $field_config['choices_type'] ) ) {
1639 + $control_args['choices_type'] = $field_config['choices_type'];
1556 1640 }
1557 1641
1558 - if ( isset( $setting_config['desc'] ) || ! empty( $setting_config['desc'] ) ) {
1559 - $control_args['description'] = $setting_config['desc'];
1642 + if ( isset( $field_config['desc'] ) || ! empty( $field_config['desc'] ) ) {
1643 + $control_args['description'] = $field_config['desc'];
1560 1644 }
1561 1645
1562 1646
1563 1647 $control_class_name = 'Pix_Customize_Preset_Control';
@@ -1563,21 +1647,20 @@
1563 1647 $control_class_name = 'Pix_Customize_Preset_Control';
1564 1648 break;
1565 1649
1566 1650 case 'radio_image' :
1567 -
1568 - if ( ! isset( $setting_config['choices'] ) || empty( $setting_config['choices'] ) ) {
1651 + if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
1569 1652 return;
1570 1653 }
1571 1654
1572 - $control_args['choices'] = $setting_config['choices'];
1655 + $control_args['choices'] = $field_config['choices'];
1573 1656
1574 - if ( isset( $setting_config['choices_type'] ) || ! empty( $setting_config['choices_type'] ) ) {
1575 - $control_args['choices_type'] = $setting_config['choices_type'];
1657 + if ( isset( $field_config['choices_type'] ) || ! empty( $field_config['choices_type'] ) ) {
1658 + $control_args['choices_type'] = $field_config['choices_type'];
1576 1659 }
1577 1660
1578 - if ( isset( $setting_config['desc'] ) || ! empty( $setting_config['desc'] ) ) {
1579 - $control_args['description'] = $setting_config['desc'];
1661 + if ( isset( $field_config['desc'] ) || ! empty( $field_config['desc'] ) ) {
1662 + $control_args['description'] = $field_config['desc'];
1580 1663 }
1581 1664
1582 1665
1583 1666 $control_class_name = 'Pix_Customize_Radio_Image_Control';
@@ -1583,14 +1666,13 @@
1583 1666 $control_class_name = 'Pix_Customize_Radio_Image_Control';
1584 1667 break;
1585 1668
1586 1669 case 'button' :
1587 -
1588 - if ( ! isset( $setting_config['action'] ) || empty( $setting_config['action'] ) ) {
1670 + if ( ! isset( $field_config['action'] ) || empty( $field_config['action'] ) ) {
1589 1671 return;
1590 1672 }
1591 1673
1592 - $control_args['action'] = $setting_config['action'];
1674 + $control_args['action'] = $field_config['action'];
1593 1675
1594 1676 $control_class_name = 'Pix_Customize_Button_Control';
1595 1677
1596 1678 break;
@@ -1595,11 +1677,10 @@
1595 1677
1596 1678 break;
1597 1679
1598 1680 case 'html' :
1599 -
1600 - if ( isset( $setting_config['html'] ) || ! empty( $setting_config['html'] ) ) {
1601 - $control_args['html'] = $setting_config['html'];
1681 + if ( isset( $field_config['html'] ) || ! empty( $field_config['html'] ) ) {
1682 + $control_args['html'] = $field_config['html'];
1602 1683 }
1603 1684
1604 1685 $control_class_name = 'Pix_Customize_HTML_Control';
1605 1686 break;
@@ -1604,21 +1685,20 @@
1604 1685 $control_class_name = 'Pix_Customize_HTML_Control';
1605 1686 break;
1606 1687
1607 1688 case 'import_demo_data' :
1608 -
1609 - if ( isset( $setting_config['html'] ) || ! empty( $setting_config['html'] ) ) {
1610 - $control_args['html'] = $setting_config['html'];
1689 + if ( isset( $field_config['html'] ) || ! empty( $field_config['html'] ) ) {
1690 + $control_args['html'] = $field_config['html'];
1611 1691 }
1612 1692
1613 - if ( ! isset( $setting_config['label'] ) || empty( $setting_config['label'] ) ) {
1693 + if ( ! isset( $field_config['label'] ) || empty( $field_config['label'] ) ) {
1614 1694 $control_args['label'] = esc_html__( 'Import', 'customify' );
1615 1695 } else {
1616 - $control_args['label'] = $setting_config['label'];
1696 + $control_args['label'] = $field_config['label'];
1617 1697 }
1618 1698
1619 - if ( isset( $setting_config['notices'] ) && ! empty( $setting_config['notices'] ) ) {
1620 - $control_args['notices'] = $setting_config['notices'];
1699 + if ( isset( $field_config['notices'] ) && ! empty( $field_config['notices'] ) ) {
1700 + $control_args['notices'] = $field_config['notices'];
1621 1701 }
1622 1702
1623 1703 $control_class_name = 'Pix_Customize_Import_Demo_Data_Control';
1624 1704 break;
@@ -1639,21 +1719,17 @@
1639 1719 $wp_customize->add_control( $this_control );
1640 1720 }
1641 1721 }
1642 1722
1643 - function do_nothing_jon_snow() {
1644 - echo '1';
1645 - }
1646 -
1647 1723 /**
1648 1724 * Remove the sections selected by user
1649 1725 *
1650 - * @param $wp_customize
1726 + * @param WP_Customize_Manager $wp_customize
1651 1727 */
1652 1728 function remove_default_sections( $wp_customize ) {
1653 1729 global $wp_registered_sidebars;
1654 1730
1655 - $to_remove = self::get_plugin_option( 'disable_default_sections' );
1731 + $to_remove = $this->get_plugin_setting( 'disable_default_sections' );
1656 1732
1657 1733 if ( ! empty( $to_remove ) ) {
1658 1734 foreach ( $to_remove as $section => $nothing ) {
1659 1735
@@ -1668,13 +1744,100 @@
1668 1744 }
1669 1745 }
1670 1746 }
1671 1747
1672 - static function get_base_path() {
1673 - return plugin_dir_path( __FILE__ );
1748 + /**
1749 + * Print JavaScript for adding additional data to _wpCustomizeSettings.settings object of the main window (not the preview window).
1750 + */
1751 + public function customize_pane_settings_additional_data() {
1752 + /**
1753 + * @global WP_Customize_Manager $wp_customize
1754 + */
1755 + global $wp_customize;
1756 +
1757 + // Without an options name we can't do much.
1758 + if ( empty( $this->customizer_config['opt-name'] ) ) {
1759 + return;
1760 + }
1761 +
1762 + $options_name = $this->customizer_config['opt-name'];
1763 + $customizer_settings = $wp_customize->settings();
1764 + ?>
1765 + <script type="text/javascript">
1766 + if ( 'undefined' === typeof _wpCustomizeSettings.settings ) {
1767 + _wpCustomizeSettings.settings = {};
1768 + }
1769 +
1770 + <?php
1771 + echo "(function ( sAdditional ){\n";
1772 +
1773 + $options = $this->get_options();
1774 + foreach ( $options as $option_id => $option_config ) {
1775 + // If we have been explicitly given a setting ID we will use that
1776 + if ( ! empty( $option_config['setting_id'] ) ) {
1777 + $setting_id = $option_config['setting_id'];
1778 + } else {
1779 + $setting_id = $options_name . '[' . $option_id . ']';
1780 + }
1781 + // @todo Right now we only handle the connected_fields key - make this more dynamic by adding the keys that are not returned by WP_Customize_Setting->json()
1782 + if ( ! empty( $customizer_settings[ $setting_id ] ) && ! empty( $option_config['connected_fields'] ) ) {
1783 + // Pass through all the connected fields and make sure the id is in the final format
1784 + $connected_fields = array();
1785 + foreach ( $option_config['connected_fields'] as $key => $connected_field_config ) {
1786 + $connected_field_data = array();
1787 +
1788 + if ( is_string( $connected_field_config ) ) {
1789 + $connected_field_id = $connected_field_config;
1790 + } elseif ( is_array( $connected_field_config ) ) {
1791 + // We have a full blown connected field config
1792 + if ( is_string( $key ) ) {
1793 + $connected_field_id = $key;
1794 + } else {
1795 + continue;
1796 + }
1797 +
1798 + // We will pass to JS all the configured connected field details.
1799 + $connected_field_data = $connected_field_config;
1800 + }
1801 +
1802 + // Continue if we don't have a connected field ID to work with.
1803 + if ( empty( $connected_field_id ) ) {
1804 + continue;
1805 + }
1806 +
1807 + // If the connected setting is not one of our's, we will use it's ID as it is.
1808 + if ( ! array_key_exists( $connected_field_id, $options ) ) {
1809 + $connected_field_data['setting_id'] = $connected_field_id;
1810 + }
1811 + // If the connected setting specifies a setting ID, we will not prefix it and use it as it is.
1812 + elseif ( ! empty( $options[ $connected_field_id ] ) && ! empty( $options[ $connected_field_id ]['setting_id'] ) ) {
1813 + $connected_field_data['setting_id'] = $options[ $connected_field_id ]['setting_id'];
1814 + } else {
1815 + $connected_field_data['setting_id'] = $options_name . '[' . $connected_field_id . ']';
1816 + }
1817 +
1818 + $connected_fields[] = $connected_field_data;
1819 + }
1820 +
1821 + printf(
1822 + "sAdditional[%s].%s = %s;\n",
1823 + wp_json_encode( $setting_id ),
1824 + 'connected_fields',
1825 + wp_json_encode( $connected_fields, JSON_FORCE_OBJECT )
1826 + );
1827 + }
1828 + }
1829 + echo "})( _wpCustomizeSettings.settings );\n";
1830 + ?>
1831 + </script>
1832 + <?php
1674 1833 }
1675 1834
1676 - protected static function get_typography_fields( $array, $key, $value, &$results, $input_key = 0 ) {
1835 + public function get_base_path() {
1836 + return plugin_dir_path( $this->file );
1837 + }
1838 +
1839 + public function get_typography_fields( $array, $key, $value, &$results, $input_key = 0 ) {
1677 1840 if ( ! is_array( $array ) ) {
1678 1841 return;
1679 1842 }
1680 1843
@@ -1686,19 +1849,19 @@
1686 1849 if ( isset( $array['default'] ) && is_array( $array['default'] ) ) {
1687 1850 $default = json_encode( $array['default'] );
1688 1851 }
1689 1852
1690 - $results[ $input_key ]['value'] = self::get_option( $input_key, $default );
1853 + $results[ $input_key ]['value'] = $this->get_option( $input_key, $default );
1691 1854 }
1692 1855
1693 1856 foreach ( $array as $i => $subarray ) {
1694 - self::get_typography_fields( $subarray, $key, $value, $results, $i );
1857 + $this->get_typography_fields( $subarray, $key, $value, $results, $i );
1695 1858 }
1696 1859 }
1697 1860
1698 1861 function get_options_key() {
1699 - if ( ! empty( self::$opt_name ) ) {
1700 - return self::$opt_name;
1862 + if ( ! empty( $this->opt_name ) ) {
1863 + return $this->opt_name;
1701 1864 }
1702 1865
1703 1866 return false;
1704 1867 }
@@ -1708,13 +1871,13 @@
1708 1871 * @return bool
1709 1872 */
1710 1873 function import_button_exists() {
1711 1874
1712 - if ( empty( self::$options_list ) ) {
1713 - self::$options_list = $this->get_options();
1875 + if ( empty( $this->options_list ) ) {
1876 + $this->options_list = $this->get_options();
1714 1877 }
1715 1878
1716 - foreach ( self::$options_list as $option ) {
1879 + foreach ( $this->options_list as $option ) {
1717 1880 if ( isset( $option['type'] ) && 'import_demo_data' === $option['type'] ) {
1718 1881 return true;
1719 1882 break;
1720 1883 }
@@ -1722,9 +1885,230 @@
1722 1885
1723 1886 return false;
1724 1887 }
1725 1888
1889 + /** == Helpers == */
1890 +
1891 + protected function get_current_values( $opt_name = null ) {
1892 + // Fallback to the global $opt_name
1893 + if ( empty( $opt_name ) ) {
1894 + $opt_name = $this->opt_name;
1895 + }
1896 +
1897 + // Bail as we have nothing to work with
1898 + if ( empty( $opt_name ) ) {
1899 + return false;
1900 + }
1901 +
1902 + $store_type = $this->get_plugin_setting( 'values_store_mod', 'option' );
1903 + if ( $store_type === 'option' ) {
1904 + return get_option( $opt_name );
1905 + } elseif ( $store_type === 'theme_mod' ) {
1906 + return get_theme_mod( $opt_name );
1907 + }
1908 +
1909 + return false;
1910 + }
1911 +
1912 + public function get_options() {
1913 +
1914 + $settings = array();
1915 +
1916 + if ( isset ( $this->customizer_config['panels'] ) ) {
1917 +
1918 + foreach ( $this->customizer_config['panels'] as $pane_id => $panel_settings ) {
1919 +
1920 + if ( isset( $panel_settings['sections'] ) ) {
1921 + foreach ( $panel_settings['sections'] as $section_id => $section_settings ) {
1922 + if ( isset( $section_settings['options'] ) ) {
1923 + foreach ( $section_settings['options'] as $option_id => $option ) {
1924 + $settings[ $option_id ] = $option;
1925 + if ( isset( $this->current_values[ $option_id ] ) ) {
1926 + $settings[ $option_id ]['value'] = $this->current_values[ $option_id ];
1927 + }
1928 + }
1929 + }
1930 + }
1931 + }
1932 + }
1933 + }
1934 +
1935 + if ( isset ( $this->customizer_config['sections'] ) ) {
1936 + foreach ( $this->customizer_config['sections'] as $section_id => $section_settings ) {
1937 + if ( isset( $section_settings['options'] ) ) {
1938 + foreach ( $section_settings['options'] as $option_id => $option ) {
1939 + $settings[ $option_id ] = $option;
1940 + if ( isset( $this->current_values[ $option_id ] ) ) {
1941 + $settings[ $option_id ]['value'] = $this->current_values[ $option_id ];
1942 + }
1943 + }
1944 + }
1945 + }
1946 + }
1947 +
1948 + return $settings;
1949 + }
1950 +
1951 + protected function get_value( $option, $alt_opt_name ) {
1952 + global $wp_customize;
1953 +
1954 + $opt_name = $this->opt_name;
1955 + $values = $this->current_values;
1956 +
1957 + // In case someone asked for a DB value too early but it has given us the opt_name under which to search, let's do it
1958 + if ( empty( $opt_name ) && ! empty( $alt_opt_name ) ) {
1959 + $opt_name = $alt_opt_name;
1960 + $values = $this->get_current_values( $opt_name );
1961 + }
1962 +
1963 + if ( ! empty( $wp_customize ) && method_exists( $wp_customize, 'get_setting' ) ) {
1964 +
1965 + $option_key = $opt_name . '[' . $option . ']';
1966 + $setting = $wp_customize->get_setting( $option_key );
1967 + if ( ! empty( $setting ) ) {
1968 + $value = $setting->value();
1969 +
1970 + return $value;
1971 + }
1972 + }
1973 +
1974 + // shim
1975 + if ( strpos( $option, $opt_name . '[' ) !== false ) {
1976 + // get only the setting id
1977 + $option = explode( '[', $option );
1978 + $option = rtrim( $option[1], ']' );
1979 + }
1980 +
1981 + if ( isset( $values[ $option ] ) ) {
1982 + return $values[ $option ];
1983 + }
1984 +
1985 + return null;
1986 + }
1987 +
1726 1988 /**
1989 + * A public function to get an option's value.
1990 + * If there is a value and return it.
1991 + * Otherwise try to get the default parameter or the default from config.
1992 + *
1993 + * @param $option
1994 + * @param mixed $default Optional.
1995 + * @param string $alt_opt_name Optional. We can use this to bypass the fact that the DB values are loaded on after_setup_theme, if we know what to look for.
1996 + *
1997 + * @return bool|null|string
1998 + */
1999 + public function get_option( $option, $default = null, $alt_opt_name = null ) {
2000 + // If the development constant CUSTOMIFY_DEV_FORCE_DEFAULTS has been defined we will not retrieve anything from the database
2001 + // Always go with the default
2002 + if ( defined( 'CUSTOMIFY_DEV_FORCE_DEFAULTS' ) && true === CUSTOMIFY_DEV_FORCE_DEFAULTS ) {
2003 + $return = null;
2004 + } else {
2005 + $return = $this->get_value( $option, $alt_opt_name );
2006 + }
2007 +
2008 + if ( $return !== null ) {
2009 + return $return;
2010 + } elseif ( $default !== null ) {
2011 + return $default;
2012 + } elseif ( isset( $this->options_list[ $option ] ) && isset( $this->options_list[ $option ]['default'] ) ) {
2013 + return $this->options_list[ $option ]['default'];
2014 + }
2015 +
2016 + return null;
2017 + }
2018 +
2019 + public function has_option( $option ) {
2020 +
2021 + if ( isset( $this->options_list[ $option ] ) ) {
2022 + return true;
2023 + }
2024 +
2025 + return false;
2026 + }
2027 +
2028 + public function get_customizer_config() {
2029 + return $this->customizer_config;
2030 + }
2031 +
2032 + /**
2033 + * Get the Customify configuration of a certain option.
2034 + *
2035 + * @param string $option_id
2036 + *
2037 + * @return array|false The option config or false on failure.
2038 + */
2039 + public function get_option_customizer_config( $option_id ) {
2040 + // We need to search for the option configured under the given id (the array key)
2041 + if ( isset ( $this->customizer_config['panels'] ) ) {
2042 + foreach ( $this->customizer_config['panels'] as $panel_id => $panel_settings ) {
2043 + if ( isset( $panel_settings['sections'] ) ) {
2044 + foreach ( $panel_settings['sections'] as $section_id => $section_settings ) {
2045 + if ( isset( $section_settings['options'] ) ) {
2046 + foreach ( $section_settings['options'] as $id => $option_config ) {
2047 + if ( $id === $option_id ) {
2048 + return $option_config;
2049 + }
2050 + }
2051 + }
2052 + }
2053 + }
2054 + }
2055 + }
2056 +
2057 + if ( isset ( $this->customizer_config['sections'] ) ) {
2058 + foreach ( $this->customizer_config['sections'] as $section_id => $section_settings ) {
2059 + if ( isset( $section_settings['options'] ) ) {
2060 + foreach ( $section_settings['options'] as $id => $option_config ) {
2061 + if ( $id === $option_id ) {
2062 + return $option_config;
2063 + }
2064 + }
2065 + }
2066 + }
2067 + }
2068 +
2069 + return false;
2070 + }
2071 +
2072 + protected function get_config() {
2073 + if ( file_exists( $this->get_base_path() . 'plugin-config.php' ) ) {
2074 + return include( $this->get_base_path() . 'plugin-config.php' );
2075 + }
2076 +
2077 + return false;
2078 + }
2079 +
2080 + /**
2081 + * Get an option's value from the config file
2082 + *
2083 + * @param $option
2084 + * @param null $default
2085 + *
2086 + * @return bool|null
2087 + */
2088 + public function get_config_option( $option, $default = null ) {
2089 +
2090 + if ( isset( $this->config[ $option ] ) ) {
2091 + return $this->config[ $option ];
2092 + } elseif ( $default !== null ) {
2093 + return $default;
2094 + }
2095 +
2096 + return false;
2097 + }
2098 +
2099 + public function get_plugin_setting( $option, $default = null ) {
2100 +
2101 + if ( isset( $this->plugin_settings[ $option ] ) ) {
2102 + return $this->plugin_settings[ $option ];
2103 + } elseif ( $default !== null ) {
2104 + return $default;
2105 + }
2106 +
2107 + return false;
2108 + }
2109 +
2110 + /**
1727 2111 * Sanitize functions
1728 2112 */
1729 2113
1730 2114 /**
@@ -1748,9 +2132,9 @@
1748 2132 * @param array $array
1749 2133 *
1750 2134 * @return bool
1751 2135 */
1752 - public static function is_assoc( $array ) {
2136 + public function is_assoc( $array ) {
1753 2137
1754 2138 if ( ! is_array( $array ) ) {
1755 2139 return false;
1756 2140 }
@@ -1762,17 +2146,17 @@
1762 2146 // not be associative (e.g. the keys array looked like {0:0, 1:1...}).
1763 2147 return array_keys( $keys ) !== $keys;
1764 2148 }
1765 2149
1766 - function register_import_api(){
2150 + function register_import_api() {
1767 2151
1768 - include_once( self::get_base_path() . '/features/class-Customify_Importer.php' );
2152 + include_once( $this->get_base_path() . '/features/class-Customify_Importer.php' );
1769 2153 $controller = new Customify_Importer_Controller();
1770 2154 $controller->init();
1771 2155 }
1772 2156
1773 - function get_options_configs () {
1774 - return self::$options_list;
2157 + function get_options_configs() {
2158 + return $this->options_list;
1775 2159 }
1776 2160
1777 2161 /**
1778 2162 * Does the same thing the JS encodeURIComponent() does
@@ -1787,9 +2171,10 @@
1787 2171 $revert = array( '%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')' );
1788 2172
1789 2173 $str = strtr( rawurlencode( $str ), $revert );
1790 2174 } else {
1791 - var_dump('boooom');die;
2175 + var_dump( 'boooom' );
2176 + die;
1792 2177 }
1793 2178
1794 2179 return $str;
1795 2180 }
@@ -1801,13 +2186,116 @@
1801 2186 *
1802 2187 * @return string
1803 2188 */
1804 2189 public static function decodeURIComponent( $str ) {
1805 - //if we get an array we just let it be
2190 + // If we get an array we just let it be
1806 2191 if ( is_string( $str ) ) {
1807 2192 $revert = array( '!' => '%21', '*' => '%2A', "'" => '%27', '(' => '%28', ')' => '%29' );
1808 - $str = rawurldecode( strtr( $str, $revert ) );
2193 + $str = rawurldecode( strtr( $str, $revert ) );
1809 2194 }
1810 2195
1811 2196 return $str;
1812 2197 }
1813 -}
2198 +
2199 + /**
2200 + * PHP version check
2201 + */
2202 + protected function php_version_check() {
2203 +
2204 + if ( version_compare( phpversion(), $this->minimalRequiredPhpVersion ) < 0 ) {
2205 + add_action( 'admin_notices', array( $this, 'notice_php_version_wrong' ) );
2206 +
2207 + return false;
2208 + }
2209 +
2210 + return true;
2211 + }
2212 +
2213 + /**
2214 + * Prevent saving of plugin options in the Customizer
2215 + *
2216 + * @param array $data The data to save
2217 + * @param array $filter_context
2218 + *
2219 + * @return array
2220 + */
2221 + public function prevent_changeset_save_in_devmode( $data, $filter_context ) {
2222 + // Get the options key
2223 + $options_key = $this->customizer_config['opt-name'];
2224 + if ( ! empty( $options_key ) ) {
2225 + // Remove any Customify data thus preventing it from saving
2226 + foreach ( $data as $key => $value ) {
2227 + if ( false !== strpos( $key, $options_key ) ) {
2228 + unset( $data[$key] );
2229 + }
2230 + }
2231 + }
2232 +
2233 + return $data;
2234 + }
2235 +
2236 + public function prevent_changeset_save_in_devmode_notification() { ?>
2237 + <script type="application/javascript">
2238 + (function ( $, exports, wp ) {
2239 + 'use strict';
2240 + // when the customizer is ready add our notification
2241 + wp.customize.bind('ready', function () {
2242 + wp.customize.notifications.add( 'customify_force_defaults', new wp.customize.Notification(
2243 + 'customify_force_defaults',
2244 + {
2245 + type: 'warning',
2246 + message: '<strong style="margin-bottom: ">Customify: Development Mode</strong><p>All the options are switched to default. While they are changing in the live preview, they will not be kept when publish.</p>'
2247 + }
2248 + ) );
2249 + });
2250 + })(jQuery, window, wp);
2251 + </script>
2252 + <?php }
2253 +
2254 + /**
2255 + * Return an instance of this class.
2256 + * @since 1.0.0
2257 + * @return PixCustomifyPlugin A single instance of this class.
2258 + */
2259 + /**
2260 + * Main PixCustomifyPlugin Instance
2261 + *
2262 + * Ensures only one instance of PixCustomifyPlugin is loaded or can be loaded.
2263 + *
2264 + * @since 1.0.0
2265 + * @static
2266 + *
2267 + * @param string $file File.
2268 + * @param string $version Version.
2269 + *
2270 + * @see PixCustomifyPlugin()
2271 + * @return PixCustomifyPlugin Main PixCustomifyPlugin instance
2272 + */
2273 + public static function instance( $file = '', $version = '1.0.0' ) {
2274 + // If the single instance hasn't been set, set it now.
2275 + if ( is_null( self::$_instance ) ) {
2276 + self::$_instance = new self( $file, $version );
2277 + }
2278 +
2279 + return self::$_instance;
2280 + }
2281 +
2282 + /**
2283 + * Cloning is forbidden.
2284 + *
2285 + * @since 1.5.0
2286 + */
2287 + public function __clone() {
2288 +
2289 + _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), esc_html( $this->_version ) );
2290 + } // End __clone ()
2291 +
2292 + /**
2293 + * Unserializing instances of this class is forbidden.
2294 + *
2295 + * @since 1.5.0
2296 + */
2297 + public function __wakeup() {
2298 +
2299 + _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), esc_html( $this->_version ) );
2300 + } // End __wakeup ()
2301 +}