Version Description
- Fixed warnings that were appearing when PHP has version 7.2.0+.
Download this release
Release Info
Developer | babbardel |
Plugin | Customify – A Theme Customizer Booster |
Version | 2.3.4 |
Comparing to | |
See all releases |
Code changes from version 2.3.3 to 2.3.4
- customify.php +8 -44
- features/class-Customify_Importer.php +4 -8
- features/class-Font_Selector.php +18 -16
- features/customizer/controls/class-Pix_Customize_Font_Control.php +5 -5
- features/customizer/controls/class-Pix_Customize_Preset_Control.php +6 -4
- features/customizer/controls/class-Pix_Customize_Typography_Control.php +3 -3
- features/index.php +3 -0
- includes/admin-notifications-manager/class-admin-notifications-manager.php +2 -2
- includes/admin-notifications-manager/index.php +3 -0
- includes/admin-settings/core/README.md +33 -0
- includes/admin-settings/core/bootstrap.php +22 -0
- includes/admin-settings/core/callbacks/cleanup/switch_not_available.php +5 -0
- includes/admin-settings/core/callbacks/validation/is_numeric.php +5 -0
- includes/admin-settings/core/callbacks/validation/not_empty.php +5 -0
- includes/admin-settings/core/classes/HTMLElement.php +106 -0
- includes/admin-settings/core/classes/HTMLTag.php +75 -0
- includes/admin-settings/core/classes/Meta.php +115 -0
- includes/admin-settings/core/classes/Processor.php +331 -0
- includes/admin-settings/core/classes/Validator.php +118 -0
- includes/admin-settings/core/classes/forms/Form.php +190 -0
- includes/admin-settings/core/classes/forms/FormField.php +110 -0
- includes/admin-settings/core/core.php +293 -0
- includes/admin-settings/core/defaults.php +44 -0
- includes/admin-settings/core/index.php +3 -0
- includes/admin-settings/core/interfaces/HTMLElement.php +50 -0
- includes/admin-settings/core/interfaces/HTMLTag.php +30 -0
- includes/admin-settings/core/interfaces/Meta.php +57 -0
- includes/admin-settings/core/interfaces/Processor.php +45 -0
- includes/admin-settings/core/interfaces/Validator.php +22 -0
- includes/admin-settings/core/interfaces/extended/Form.php +69 -0
- includes/admin-settings/core/interfaces/extended/FormField.php +29 -0
- includes/admin-settings/core/tests/bootstrap.php +11 -0
- includes/admin-settings/core/tests/sample-config.php +13 -0
- includes/admin-settings/core/views/form-partials/fields/color.php +13 -0
- includes/admin-settings/core/views/form-partials/fields/counter.php +43 -0
- includes/admin-settings/core/views/form-partials/fields/group.php +32 -0
- includes/admin-settings/core/views/form-partials/fields/hidden.php +22 -0
- includes/admin-settings/core/views/form-partials/fields/postbox.php +38 -0
- includes/admin-settings/core/views/form-partials/fields/select.php +41 -0
- includes/admin-settings/core/views/form-partials/fields/switch.php +64 -0
- includes/admin-settings/core/views/form-partials/fields/tabular-group.php +36 -0
- includes/admin-settings/core/views/form-partials/fields/text.php +38 -0
- includes/admin-settings/core/views/form-partials/linear.php +15 -0
- includes/admin-settings/views/admin.php +65 -0
- includes/admin-settings/views/form-partials/fields/multicheckbox.php +36 -0
- includes/admin-settings/views/form-partials/fields/reset_theme_mod.php +64 -0
- includes/admin-settings/views/index.php +1 -0
- includes/class-customify-color-palettes.php +17 -19
- includes/class-customify-customizer.php +1953 -0
- includes/class-customify-gutenberg.php +13 -12
- includes/class-customify-settings.php +430 -0
- includes/class-pixcustomify.php +830 -0
- includes/extras.php +354 -0
- includes/index.php +3 -0
- includes/lib/index.php +3 -0
- js/admin.js +38 -38
- js/customizer.js +1261 -1261
- js/customizer/style-manager.js +126 -127
- js/customizer_preview.js +332 -332
- readme.txt +11 -5
customify.php
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
/*
|
3 |
Plugin Name: Customify
|
4 |
Plugin URI: https://wordpress.org/plugins/customify/
|
5 |
-
Description: A Theme Customizer Booster
|
6 |
-
Version: 2.3.
|
7 |
Author: Pixelgrade
|
8 |
Author URI: https://pixelgrade.com
|
9 |
Author Email: contact@pixelgrade.com
|
@@ -11,8 +11,8 @@ Text Domain: customify
|
|
11 |
License: GPL-2.0+
|
12 |
License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
13 |
Domain Path: /languages/
|
14 |
-
Requires at least: 4.9
|
15 |
-
Tested up to: 5.0
|
16 |
*/
|
17 |
|
18 |
// If this file is called directly, abort.
|
@@ -20,35 +20,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
20 |
die;
|
21 |
}
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
define('EXT', '.php');
|
26 |
-
}
|
27 |
-
|
28 |
-
require 'core/bootstrap.php';
|
29 |
-
|
30 |
-
// Include our helper array class.
|
31 |
-
require 'includes/lib/class-customify-array.php';
|
32 |
-
|
33 |
-
$config = include 'plugin-config.php';
|
34 |
-
|
35 |
-
// set textdomain
|
36 |
-
pixcustomify::settextdomain( 'customify' );
|
37 |
-
|
38 |
-
// Ensure Test Data
|
39 |
-
// ----------------
|
40 |
-
|
41 |
-
$defaults = include 'plugin-defaults.php';
|
42 |
-
|
43 |
-
$current_data = get_option( $config['settings-key'] );
|
44 |
-
|
45 |
-
if ( $current_data === false ) {
|
46 |
-
add_option( $config['settings-key'], $defaults );
|
47 |
-
} elseif ( count( array_diff_key( $defaults, $current_data ) ) != 0) {
|
48 |
-
$plugindata = array_merge( $defaults, $current_data );
|
49 |
-
update_option( $config['settings-key'], $plugindata );
|
50 |
-
}
|
51 |
-
# else: data is available; do nothing
|
52 |
|
53 |
/**
|
54 |
* Returns the main instance of PixCustomifyPlugin to prevent the need to use globals.
|
@@ -57,20 +30,11 @@ if ( $current_data === false ) {
|
|
57 |
* @return PixCustomifyPlugin
|
58 |
*/
|
59 |
function PixCustomifyPlugin() {
|
60 |
-
|
61 |
-
* The core plugin class that is used to define internationalization,
|
62 |
-
* admin-specific hooks, and public-facing site hooks.
|
63 |
-
*/
|
64 |
-
require_once plugin_dir_path( __FILE__ ) . 'class-pixcustomify.php';
|
65 |
-
|
66 |
-
$instance = PixCustomifyPlugin::instance( __FILE__, '2.3.3' );
|
67 |
|
68 |
-
return
|
69 |
}
|
70 |
|
71 |
// Now get the party started
|
72 |
// We will keep this global variable for legacy
|
73 |
$pixcustomify_plugin = PixCustomifyPlugin();
|
74 |
-
|
75 |
-
// Load custom modules
|
76 |
-
require_once( 'features/class-Font_Selector.php' );
|
2 |
/*
|
3 |
Plugin Name: Customify
|
4 |
Plugin URI: https://wordpress.org/plugins/customify/
|
5 |
+
Description: A Theme Customizer Booster to easily customize Fonts, Colors, and other options for your site.
|
6 |
+
Version: 2.3.4
|
7 |
Author: Pixelgrade
|
8 |
Author URI: https://pixelgrade.com
|
9 |
Author Email: contact@pixelgrade.com
|
11 |
License: GPL-2.0+
|
12 |
License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
13 |
Domain Path: /languages/
|
14 |
+
Requires at least: 4.9.9
|
15 |
+
Tested up to: 5.2.0
|
16 |
*/
|
17 |
|
18 |
// If this file is called directly, abort.
|
20 |
die;
|
21 |
}
|
22 |
|
23 |
+
require_once 'includes/lib/class-customify-array.php';
|
24 |
+
require_once 'includes/extras.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
/**
|
27 |
* Returns the main instance of PixCustomifyPlugin to prevent the need to use globals.
|
30 |
* @return PixCustomifyPlugin
|
31 |
*/
|
32 |
function PixCustomifyPlugin() {
|
33 |
+
require_once plugin_dir_path( __FILE__ ) . 'includes/class-pixcustomify.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
+
return PixCustomifyPlugin::instance( __FILE__, '2.3.4' );
|
36 |
}
|
37 |
|
38 |
// Now get the party started
|
39 |
// We will keep this global variable for legacy
|
40 |
$pixcustomify_plugin = PixCustomifyPlugin();
|
|
|
|
|
|
features/class-Customify_Importer.php
CHANGED
@@ -144,7 +144,7 @@ final class Customify_Importer_Controller {
|
|
144 |
wp_send_json_error( 'i don\'t evan kno\'' );
|
145 |
}
|
146 |
|
147 |
-
$
|
148 |
break;
|
149 |
}
|
150 |
|
@@ -193,7 +193,7 @@ final class Customify_Importer_Controller {
|
|
193 |
continue;
|
194 |
}
|
195 |
|
196 |
-
|
197 |
}
|
198 |
}
|
199 |
|
@@ -382,8 +382,6 @@ final class Customify_Importer_Controller {
|
|
382 |
$this->add_step( 'widgets', 'widgets', $data['widgets'] );
|
383 |
}
|
384 |
|
385 |
-
if ( isset( $data['widgets'] ) && ! empty( $data['widgets'] ) ) {}
|
386 |
-
|
387 |
// select what you can get from the export
|
388 |
if ( isset( $data['taxonomies'] ) && ! empty( $data['taxonomies'] ) ) {
|
389 |
|
@@ -471,11 +469,9 @@ final class Customify_Importer_Controller {
|
|
471 |
$options = PixCustomifyPlugin()->get_options_configs();
|
472 |
|
473 |
if ( ! isset( $options[ $option_key ] ) ) {
|
474 |
-
wp_send_json_error( '
|
475 |
}
|
476 |
|
477 |
-
$option_config = $options[ $option_key ];
|
478 |
-
|
479 |
if ( ! isset( $options[ $option_key ]['imports'] ) ) {
|
480 |
wp_send_json_error( 'where is imports????' );
|
481 |
}
|
@@ -618,4 +614,4 @@ final class Customify_Importer_Controller {
|
|
618 |
|
619 |
return $new_widget_name;
|
620 |
}
|
621 |
-
}
|
144 |
wp_send_json_error( 'i don\'t evan kno\'' );
|
145 |
}
|
146 |
|
147 |
+
$this->process_remote_data( $data );
|
148 |
break;
|
149 |
}
|
150 |
|
193 |
continue;
|
194 |
}
|
195 |
|
196 |
+
update_option( $step_id, $value );
|
197 |
}
|
198 |
}
|
199 |
|
382 |
$this->add_step( 'widgets', 'widgets', $data['widgets'] );
|
383 |
}
|
384 |
|
|
|
|
|
385 |
// select what you can get from the export
|
386 |
if ( isset( $data['taxonomies'] ) && ! empty( $data['taxonomies'] ) ) {
|
387 |
|
469 |
$options = PixCustomifyPlugin()->get_options_configs();
|
470 |
|
471 |
if ( ! isset( $options[ $option_key ] ) ) {
|
472 |
+
wp_send_json_error( 'nonexistent key' );
|
473 |
}
|
474 |
|
|
|
|
|
475 |
if ( ! isset( $options[ $option_key ]['imports'] ) ) {
|
476 |
wp_send_json_error( 'where is imports????' );
|
477 |
}
|
614 |
|
615 |
return $new_widget_name;
|
616 |
}
|
617 |
+
}
|
features/class-Font_Selector.php
CHANGED
@@ -18,12 +18,12 @@ class Customify_Font_Selector {
|
|
18 |
function __construct() {
|
19 |
$this->theme_fonts = apply_filters( 'customify_theme_fonts', array() );
|
20 |
|
21 |
-
$load_location = PixCustomifyPlugin()->get_plugin_setting( 'style_resources_location', 'wp_head' );
|
22 |
add_action( $load_location, array( $this, 'output_webfont_script' ), 99 );
|
23 |
add_action( $load_location, array( $this, 'output_fonts_dynamic_style' ), 100 );
|
24 |
-
add_action( 'customify_font_family_before_options', array( $this, 'add_customify_theme_fonts' ), 11,
|
25 |
|
26 |
-
if ( PixCustomifyPlugin()->get_plugin_setting( 'enable_editor_style', true ) ) {
|
27 |
add_action( 'admin_head', array( $this, 'script_to_add_customizer_settings_into_wp_editor' ) );
|
28 |
}
|
29 |
|
@@ -99,7 +99,7 @@ class Customify_Font_Selector {
|
|
99 |
return $this->theme_fonts;
|
100 |
}
|
101 |
|
102 |
-
function add_customify_theme_fonts( $active_font_family
|
103 |
//first get all the published custom fonts
|
104 |
if ( empty( $this->theme_fonts ) ) {
|
105 |
return;
|
@@ -136,9 +136,9 @@ class Customify_Font_Selector {
|
|
136 |
/** @var PixCustomifyPlugin $local_plugin */
|
137 |
$local_plugin = PixCustomifyPlugin();
|
138 |
|
139 |
-
self::$options_list = $local_plugin->
|
140 |
|
141 |
-
$local_plugin->get_typography_fields( self::$options_list, 'type', 'font', self::$typo_settings );
|
142 |
|
143 |
if ( empty( self::$typo_settings ) ) {
|
144 |
return $args;
|
@@ -158,7 +158,7 @@ class Customify_Font_Selector {
|
|
158 |
|
159 |
// in case the value is still null, try default value (mostly for google fonts)
|
160 |
if ( ! is_array( $value ) || $value === null ) {
|
161 |
-
$value = $local_plugin->get_font_defaults_value( str_replace( '"', '', $font['value'] ) );
|
162 |
}
|
163 |
|
164 |
//bail if by this time we don't have a value of some sort
|
@@ -168,7 +168,7 @@ class Customify_Font_Selector {
|
|
168 |
|
169 |
// Handle special logic for when the $value array is not an associative array
|
170 |
if ( ! $local_plugin->is_assoc( $value ) ) {
|
171 |
-
$value = $local_plugin->standardize_non_associative_font_default( $value );
|
172 |
}
|
173 |
|
174 |
// If we have reached this far and we don't have a type, we will assume it's a google font.
|
@@ -243,8 +243,8 @@ class Customify_Font_Selector {
|
|
243 |
/** @var PixCustomifyPlugin $local_plugin */
|
244 |
$local_plugin = PixCustomifyPlugin();
|
245 |
|
246 |
-
self::$options_list = $local_plugin->
|
247 |
-
$local_plugin->get_typography_fields( self::$options_list, 'type', 'font', self::$typo_settings );
|
248 |
|
249 |
if ( empty( self::$typo_settings ) ) {
|
250 |
return;
|
@@ -284,8 +284,8 @@ class Customify_Font_Selector {
|
|
284 |
/** @var PixCustomifyPlugin $local_plugin */
|
285 |
$local_plugin = PixCustomifyPlugin();
|
286 |
|
287 |
-
self::$options_list = $local_plugin->
|
288 |
-
$local_plugin->get_typography_fields( self::$options_list, 'type', 'font', self::$typo_settings );
|
289 |
|
290 |
if ( empty( self::$typo_settings ) ) {
|
291 |
return $output;
|
@@ -322,7 +322,7 @@ class Customify_Font_Selector {
|
|
322 |
$value = $this->maybe_decode_value( $font['value'] );
|
323 |
|
324 |
if ( $value === null ) {
|
325 |
-
$value = $local_plugin->get_font_defaults_value( $font['value'] );
|
326 |
}
|
327 |
|
328 |
// shim the old case when the default was only the font name
|
@@ -332,7 +332,7 @@ class Customify_Font_Selector {
|
|
332 |
|
333 |
// Handle special logic for when the $value array is not an associative array
|
334 |
if ( ! $local_plugin->is_assoc( $value ) ) {
|
335 |
-
$value = $local_plugin->standardize_non_associative_font_default( $value );
|
336 |
}
|
337 |
|
338 |
$value = $this->validate_font_values( $value );
|
@@ -412,7 +412,7 @@ class Customify_Font_Selector {
|
|
412 |
}
|
413 |
|
414 |
if ( ! empty( $value['font_weight'] ) ) {
|
415 |
-
$
|
416 |
}
|
417 |
|
418 |
if ( ! empty( $value['font_size'] ) ) {
|
@@ -510,7 +510,9 @@ class Customify_Font_Selector {
|
|
510 |
function get_fonts_dynamic_script() {
|
511 |
$args = $this->get_fonts_args();
|
512 |
|
513 |
-
if ( ( empty ( $args['local_families'] ) && empty ( $args['google_families'] ) )
|
|
|
|
|
514 |
return '';
|
515 |
}
|
516 |
|
18 |
function __construct() {
|
19 |
$this->theme_fonts = apply_filters( 'customify_theme_fonts', array() );
|
20 |
|
21 |
+
$load_location = PixCustomifyPlugin()->settings->get_plugin_setting( 'style_resources_location', 'wp_head' );
|
22 |
add_action( $load_location, array( $this, 'output_webfont_script' ), 99 );
|
23 |
add_action( $load_location, array( $this, 'output_fonts_dynamic_style' ), 100 );
|
24 |
+
add_action( 'customify_font_family_before_options', array( $this, 'add_customify_theme_fonts' ), 11, 1 );
|
25 |
|
26 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'enable_editor_style', true ) ) {
|
27 |
add_action( 'admin_head', array( $this, 'script_to_add_customizer_settings_into_wp_editor' ) );
|
28 |
}
|
29 |
|
99 |
return $this->theme_fonts;
|
100 |
}
|
101 |
|
102 |
+
function add_customify_theme_fonts( $active_font_family ) {
|
103 |
//first get all the published custom fonts
|
104 |
if ( empty( $this->theme_fonts ) ) {
|
105 |
return;
|
136 |
/** @var PixCustomifyPlugin $local_plugin */
|
137 |
$local_plugin = PixCustomifyPlugin();
|
138 |
|
139 |
+
self::$options_list = $local_plugin->get_options_details();
|
140 |
|
141 |
+
$local_plugin->customizer->get_typography_fields( self::$options_list, 'type', 'font', self::$typo_settings );
|
142 |
|
143 |
if ( empty( self::$typo_settings ) ) {
|
144 |
return $args;
|
158 |
|
159 |
// in case the value is still null, try default value (mostly for google fonts)
|
160 |
if ( ! is_array( $value ) || $value === null ) {
|
161 |
+
$value = $local_plugin->customizer->get_font_defaults_value( str_replace( '"', '', $font['value'] ) );
|
162 |
}
|
163 |
|
164 |
//bail if by this time we don't have a value of some sort
|
168 |
|
169 |
// Handle special logic for when the $value array is not an associative array
|
170 |
if ( ! $local_plugin->is_assoc( $value ) ) {
|
171 |
+
$value = $local_plugin->customizer->standardize_non_associative_font_default( $value );
|
172 |
}
|
173 |
|
174 |
// If we have reached this far and we don't have a type, we will assume it's a google font.
|
243 |
/** @var PixCustomifyPlugin $local_plugin */
|
244 |
$local_plugin = PixCustomifyPlugin();
|
245 |
|
246 |
+
self::$options_list = $local_plugin->get_options_details();
|
247 |
+
$local_plugin->customizer->get_typography_fields( self::$options_list, 'type', 'font', self::$typo_settings );
|
248 |
|
249 |
if ( empty( self::$typo_settings ) ) {
|
250 |
return;
|
284 |
/** @var PixCustomifyPlugin $local_plugin */
|
285 |
$local_plugin = PixCustomifyPlugin();
|
286 |
|
287 |
+
self::$options_list = $local_plugin->get_options_details();
|
288 |
+
$local_plugin->customizer->get_typography_fields( self::$options_list, 'type', 'font', self::$typo_settings );
|
289 |
|
290 |
if ( empty( self::$typo_settings ) ) {
|
291 |
return $output;
|
322 |
$value = $this->maybe_decode_value( $font['value'] );
|
323 |
|
324 |
if ( $value === null ) {
|
325 |
+
$value = $local_plugin->customizer->get_font_defaults_value( $font['value'] );
|
326 |
}
|
327 |
|
328 |
// shim the old case when the default was only the font name
|
332 |
|
333 |
// Handle special logic for when the $value array is not an associative array
|
334 |
if ( ! $local_plugin->is_assoc( $value ) ) {
|
335 |
+
$value = $local_plugin->customizer->standardize_non_associative_font_default( $value );
|
336 |
}
|
337 |
|
338 |
$value = $this->validate_font_values( $value );
|
412 |
}
|
413 |
|
414 |
if ( ! empty( $value['font_weight'] ) ) {
|
415 |
+
$this->display_weight_property( $value['font_weight'] );
|
416 |
}
|
417 |
|
418 |
if ( ! empty( $value['font_size'] ) ) {
|
510 |
function get_fonts_dynamic_script() {
|
511 |
$args = $this->get_fonts_args();
|
512 |
|
513 |
+
if ( ( empty ( $args['local_families'] ) && empty ( $args['google_families'] ) )
|
514 |
+
|| ! PixCustomifyPlugin()->settings->get_plugin_setting( 'typography', '1' )
|
515 |
+
|| ! PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_google_fonts', 1 ) ) {
|
516 |
return '';
|
517 |
}
|
518 |
|
features/customizer/controls/class-Pix_Customize_Font_Control.php
CHANGED
@@ -159,7 +159,7 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
|
|
159 |
|
160 |
do_action( 'customify_font_family_before_google_fonts_options' );
|
161 |
|
162 |
-
if ( PixCustomifyPlugin()->get_plugin_setting( 'typography_google_fonts' ) ) {
|
163 |
|
164 |
echo '<optgroup class="google-fonts-opts-placeholder" label="' . __( 'Google fonts', 'customify' ) . '"></optgroup>';
|
165 |
} ?>
|
@@ -200,12 +200,12 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
|
|
200 |
|
201 |
public function get_google_fonts_opts_html() {
|
202 |
$html = '';
|
203 |
-
if ( ! PixCustomifyPlugin()->get_plugin_setting( 'typography_google_fonts' ) ) {
|
204 |
return $html;
|
205 |
}
|
206 |
|
207 |
ob_start();
|
208 |
-
if ( PixCustomifyPlugin()->get_plugin_setting( 'typography_group_google_fonts' ) ) {
|
209 |
|
210 |
$grouped_google_fonts = array();
|
211 |
foreach ( self::$google_fonts as $key => $font ) {
|
@@ -236,7 +236,7 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
|
|
236 |
}
|
237 |
|
238 |
public function customize_pane_settings_google_fonts_options() {
|
239 |
-
if ( ! PixCustomifyPlugin()->get_plugin_setting( 'typography_google_fonts' ) ) {
|
240 |
return;
|
241 |
}
|
242 |
|
@@ -305,7 +305,7 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
|
|
305 |
// Allow others to add options here
|
306 |
do_action( 'customify_font_family_before_standard_fonts_options', $font_family, $current_value );
|
307 |
|
308 |
-
if ( PixCustomifyPlugin()->get_plugin_setting( 'typography_standard_fonts' ) ) {
|
309 |
|
310 |
echo '<optgroup label="' . __( 'Standard fonts', 'customify' ) . '">';
|
311 |
foreach ( self::$std_fonts as $key => $font ) {
|
159 |
|
160 |
do_action( 'customify_font_family_before_google_fonts_options' );
|
161 |
|
162 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_google_fonts' ) ) {
|
163 |
|
164 |
echo '<optgroup class="google-fonts-opts-placeholder" label="' . __( 'Google fonts', 'customify' ) . '"></optgroup>';
|
165 |
} ?>
|
200 |
|
201 |
public function get_google_fonts_opts_html() {
|
202 |
$html = '';
|
203 |
+
if ( ! PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_google_fonts' ) ) {
|
204 |
return $html;
|
205 |
}
|
206 |
|
207 |
ob_start();
|
208 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_group_google_fonts' ) ) {
|
209 |
|
210 |
$grouped_google_fonts = array();
|
211 |
foreach ( self::$google_fonts as $key => $font ) {
|
236 |
}
|
237 |
|
238 |
public function customize_pane_settings_google_fonts_options() {
|
239 |
+
if ( ! PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_google_fonts' ) ) {
|
240 |
return;
|
241 |
}
|
242 |
|
305 |
// Allow others to add options here
|
306 |
do_action( 'customify_font_family_before_standard_fonts_options', $font_family, $current_value );
|
307 |
|
308 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_standard_fonts' ) ) {
|
309 |
|
310 |
echo '<optgroup label="' . __( 'Standard fonts', 'customify' ) . '">';
|
311 |
foreach ( self::$std_fonts as $key => $font ) {
|
features/customizer/controls/class-Pix_Customize_Preset_Control.php
CHANGED
@@ -204,7 +204,7 @@ class Pix_Customize_Preset_Control extends Pix_Customize_Control {
|
|
204 |
</label>
|
205 |
<div class="palette">
|
206 |
<?php foreach ( $choice_config['options'] as $color_setting_id => $color_value ) {
|
207 |
-
$field_config = PixCustomifyPlugin()->
|
208 |
echo '<div class="palette__item ' . esc_attr( $color_setting_id ) . '" style="background: ' . esc_attr( $color_value ) . '"></div>' . PHP_EOL;
|
209 |
} ?>
|
210 |
</div>
|
@@ -386,8 +386,10 @@ class Pix_Customize_Preset_Control extends Pix_Customize_Control {
|
|
386 |
* @return boolean
|
387 |
*/
|
388 |
public function isLight( $color = FALSE ){
|
389 |
-
|
390 |
-
|
|
|
|
|
391 |
// Calculate straight from rbg
|
392 |
$r = hexdec($color[0].$color[1]);
|
393 |
$g = hexdec($color[2].$color[3]);
|
@@ -450,7 +452,7 @@ class Pix_Customize_Preset_Control extends Pix_Customize_Control {
|
|
450 |
}
|
451 |
|
452 |
foreach ( $options as $option_id => $option_value ) {
|
453 |
-
$option_config = $localPlugin->
|
454 |
if ( empty( $option_config ) ) {
|
455 |
continue;
|
456 |
}
|
204 |
</label>
|
205 |
<div class="palette">
|
206 |
<?php foreach ( $choice_config['options'] as $color_setting_id => $color_value ) {
|
207 |
+
$field_config = PixCustomifyPlugin()->get_option_details( $color_setting_id );
|
208 |
echo '<div class="palette__item ' . esc_attr( $color_setting_id ) . '" style="background: ' . esc_attr( $color_value ) . '"></div>' . PHP_EOL;
|
209 |
} ?>
|
210 |
</div>
|
386 |
* @return boolean
|
387 |
*/
|
388 |
public function isLight( $color = FALSE ){
|
389 |
+
if ( false === $color ) {
|
390 |
+
return false;
|
391 |
+
}
|
392 |
+
|
393 |
// Calculate straight from rbg
|
394 |
$r = hexdec($color[0].$color[1]);
|
395 |
$g = hexdec($color[2].$color[3]);
|
452 |
}
|
453 |
|
454 |
foreach ( $options as $option_id => $option_value ) {
|
455 |
+
$option_config = $localPlugin->get_option_details( $option_id );
|
456 |
if ( empty( $option_config ) ) {
|
457 |
continue;
|
458 |
}
|
features/customizer/controls/class-Pix_Customize_Typography_Control.php
CHANGED
@@ -188,7 +188,7 @@ class Pix_Customize_Typography_Control extends Pix_Customize_Control {
|
|
188 |
// Allow others to add options here
|
189 |
do_action( 'customify_typography_font_family_before_standard_fonts_options', $font_family, $current_value );
|
190 |
|
191 |
-
if ( PixCustomifyPlugin()->get_plugin_setting( 'typography_standard_fonts' ) ) {
|
192 |
|
193 |
echo '<optgroup label="' . __( 'Standard fonts', 'customify' ) . '">';
|
194 |
foreach ( self::$std_fonts as $key => $font ) {
|
@@ -200,9 +200,9 @@ class Pix_Customize_Typography_Control extends Pix_Customize_Control {
|
|
200 |
// Allow others to add options here
|
201 |
do_action( 'customify_typography_font_family_before_google_fonts_options' );
|
202 |
|
203 |
-
if ( PixCustomifyPlugin()->get_plugin_setting( 'typography_google_fonts' ) ) {
|
204 |
|
205 |
-
if ( PixCustomifyPlugin()->get_plugin_setting( 'typography_group_google_fonts' ) ) {
|
206 |
|
207 |
$grouped_google_fonts = array();
|
208 |
foreach ( self::$google_fonts as $key => $font ) {
|
188 |
// Allow others to add options here
|
189 |
do_action( 'customify_typography_font_family_before_standard_fonts_options', $font_family, $current_value );
|
190 |
|
191 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_standard_fonts' ) ) {
|
192 |
|
193 |
echo '<optgroup label="' . __( 'Standard fonts', 'customify' ) . '">';
|
194 |
foreach ( self::$std_fonts as $key => $font ) {
|
200 |
// Allow others to add options here
|
201 |
do_action( 'customify_typography_font_family_before_google_fonts_options' );
|
202 |
|
203 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_google_fonts' ) ) {
|
204 |
|
205 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_group_google_fonts' ) ) {
|
206 |
|
207 |
$grouped_google_fonts = array();
|
208 |
foreach ( self::$google_fonts as $key => $font ) {
|
features/index.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden
|
3 |
+
// Golden is deprecated
|
includes/admin-notifications-manager/class-admin-notifications-manager.php
CHANGED
@@ -1167,7 +1167,7 @@ class Pixcloud_Admin_Notifications_Manager {
|
|
1167 |
* @param int $user_id User ID from whom to remove dismissals. Set to 0 for all users.
|
1168 |
* @param array $notice_ids Array of notice ids to remove
|
1169 |
*/
|
1170 |
-
public function remove_user_notifications_data( $user_id = 0,
|
1171 |
|
1172 |
if ( ! empty( $notice_ids ) ) {
|
1173 |
|
@@ -1297,4 +1297,4 @@ class Pixcloud_Admin_Notifications_Manager {
|
|
1297 |
_doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin’ huh?' ) ), null );
|
1298 |
} // End __wakeup ()
|
1299 |
|
1300 |
-
}
|
1167 |
* @param int $user_id User ID from whom to remove dismissals. Set to 0 for all users.
|
1168 |
* @param array $notice_ids Array of notice ids to remove
|
1169 |
*/
|
1170 |
+
public function remove_user_notifications_data( $user_id = 0, $notice_ids = array() ) {
|
1171 |
|
1172 |
if ( ! empty( $notice_ids ) ) {
|
1173 |
|
1297 |
_doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin’ huh?' ) ), null );
|
1298 |
} // End __wakeup ()
|
1299 |
|
1300 |
+
}
|
includes/admin-notifications-manager/index.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden
|
3 |
+
// Golden is deprecated
|
includes/admin-settings/core/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
Field Configuration Spec
|
3 |
+
========================
|
4 |
+
|
5 |
+
The following are system reserved field metadata keys:
|
6 |
+
|
7 |
+
- type
|
8 |
+
- name (optional)
|
9 |
+
- idname (auto-generated based on name)
|
10 |
+
- default (optional)
|
11 |
+
- label (optional)
|
12 |
+
- desc (optional)
|
13 |
+
- form (internal)
|
14 |
+
- cleanup (optional)
|
15 |
+
- checks (optional)
|
16 |
+
- rendering (optional)
|
17 |
+
|
18 |
+
Field detection
|
19 |
+
---------------
|
20 |
+
|
21 |
+
If an array inside the dedicated fields configuration block has the "type"
|
22 |
+
key it is considered to be a field configuration regardless of where it is
|
23 |
+
inside the configuration (since fields may have other fields as children
|
24 |
+
that themselves have other fields, etc).
|
25 |
+
|
26 |
+
Field name
|
27 |
+
----------
|
28 |
+
|
29 |
+
The key pointing to a field configuration is considered the name of the
|
30 |
+
field unless a the optional key "name" is provided. If neither is available
|
31 |
+
or the name key is empty the field is considered esthetic and while it will
|
32 |
+
be processed by the rendering routines it won't be processed by the data
|
33 |
+
handling routines (since it's not a named entity).
|
includes/admin-settings/core/bootstrap.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined( 'ABSPATH' ) or die;
|
2 |
+
|
3 |
+
// ensure EXT is defined
|
4 |
+
if ( ! defined( 'EXT' ) ) {
|
5 |
+
define( 'EXT', '.php' );
|
6 |
+
}
|
7 |
+
|
8 |
+
$basepath = dirname( __FILE__ ) . DIRECTORY_SEPARATOR;
|
9 |
+
require $basepath . 'core' . EXT;
|
10 |
+
|
11 |
+
// load classes
|
12 |
+
|
13 |
+
$interfacepath = $basepath . 'interfaces' . DIRECTORY_SEPARATOR;
|
14 |
+
pixcustomify::require_all( $interfacepath );
|
15 |
+
|
16 |
+
$classpath = $basepath . 'classes' . DIRECTORY_SEPARATOR;
|
17 |
+
pixcustomify::require_all( $classpath );
|
18 |
+
|
19 |
+
// load callbacks
|
20 |
+
|
21 |
+
$callbackpath = $basepath . 'callbacks' . DIRECTORY_SEPARATOR;
|
22 |
+
pixcustomify::require_all( $callbackpath );
|
includes/admin-settings/core/callbacks/cleanup/switch_not_available.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
function pixcustomify_cleanup_switch_not_available($fieldvalue, $meta, $processor) {
|
4 |
+
return $fieldvalue !== null ? $fieldvalue : false;
|
5 |
+
}
|
includes/admin-settings/core/callbacks/validation/is_numeric.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
function pixcustomify_validate_is_numeric($fieldvalue, $validator) {
|
4 |
+
return is_int($fieldvalue) || preg_match('/^[0-9\.]+$/', $fieldvalue);
|
5 |
+
}
|
includes/admin-settings/core/callbacks/validation/not_empty.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
function pixcustomify_validate_not_empty($fieldvalue, $processor) {
|
4 |
+
return ! empty($fieldvalue);
|
5 |
+
}
|
includes/admin-settings/core/classes/HTMLElement.php
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A HTMLElement is a HTMLTag with meta support integrated into it. A normal
|
5 |
+
* HTMLTag only cares for it's attributes meta and nothing else, but more
|
6 |
+
* specialized tags such as forms or form fields require misc metadata to be
|
7 |
+
* attached on the object itself.
|
8 |
+
*
|
9 |
+
* @package pixcustomify
|
10 |
+
* @category core
|
11 |
+
* @author Pixelgrade Team
|
12 |
+
* @copyright (c) 2013, Pixelgrade
|
13 |
+
*/
|
14 |
+
class PixCustomifyHTMLElementImpl extends PixCustomifyHTMLTagImpl implements PixCustomifyHTMLElement {
|
15 |
+
|
16 |
+
/** @var array configuration values */
|
17 |
+
protected $meta = null;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param array config
|
21 |
+
*/
|
22 |
+
static function instance($config = null) {
|
23 |
+
$i = new self;
|
24 |
+
$i->configure($config);
|
25 |
+
return $i;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Apply configuration.
|
30 |
+
*/
|
31 |
+
protected function configure($config = null) {
|
32 |
+
// gurantee configuration
|
33 |
+
$config !== null or $config = array();
|
34 |
+
|
35 |
+
// invoke htmltag instance configuration
|
36 |
+
if (isset($config['attrs'])) {
|
37 |
+
parent::configure($config['attrs']);
|
38 |
+
unset($config['attrs']);
|
39 |
+
}
|
40 |
+
else { // no html attributes set
|
41 |
+
parent::configure(array());
|
42 |
+
}
|
43 |
+
|
44 |
+
// setup meta fields
|
45 |
+
$this->meta = pixcustomify::instance('PixCustomifyMeta', $config);
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
// Meta
|
50 |
+
// ------------------------------------------------------------------------
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @param string meta key
|
54 |
+
* @return boolean true if key exists, false otherwise
|
55 |
+
*/
|
56 |
+
function hasmeta($key) {
|
57 |
+
return $this->meta->has($key);
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @return mixed value or default
|
62 |
+
*/
|
63 |
+
function getmeta($key, $default = null) {
|
64 |
+
return $this->meta->get($key, $default);
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @return static $this
|
69 |
+
*/
|
70 |
+
function setmeta($key, $value) {
|
71 |
+
$this->meta->set($key, $value);
|
72 |
+
return $this;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Set the key if it's not already set.
|
77 |
+
*
|
78 |
+
* @param string key
|
79 |
+
* @param string value
|
80 |
+
*/
|
81 |
+
function ensuremeta($key, $value) {
|
82 |
+
$this->meta->ensure($key, $value);
|
83 |
+
return $this;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* If the key is currently a non-array value it will be converted to an
|
88 |
+
* array maintaning the previous value (along with the new one).
|
89 |
+
*
|
90 |
+
* @param string name
|
91 |
+
* @param mixed value
|
92 |
+
* @return static $this
|
93 |
+
*/
|
94 |
+
function addmeta($name, $value) {
|
95 |
+
$this->meta->add($name, $value);
|
96 |
+
return $this;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @return PixCustomifyMeta
|
101 |
+
*/
|
102 |
+
function meta() {
|
103 |
+
return $this->meta;
|
104 |
+
}
|
105 |
+
|
106 |
+
} # class
|
includes/admin-settings/core/classes/HTMLTag.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
class PixCustomifyHTMLTagImpl implements PixCustomifyHTMLTag {
|
10 |
+
|
11 |
+
/** @var array html attributes */
|
12 |
+
protected $attrs = null;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param array config
|
16 |
+
*/
|
17 |
+
static function instance($config = null) {
|
18 |
+
$i = new self;
|
19 |
+
$i->configure($config);
|
20 |
+
return $i;
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Apply configuration.
|
25 |
+
*/
|
26 |
+
protected function configure($config = null) {
|
27 |
+
$this->attrs = pixcustomify::instance('PixCustomifyMeta', $config);
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @param string key
|
32 |
+
* @param mixed default
|
33 |
+
* @return mixed
|
34 |
+
*/
|
35 |
+
function get($key, $default = null) {
|
36 |
+
return $this->attrs->get($key, $default);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param string key
|
41 |
+
* @param mixed value
|
42 |
+
* @return static $this
|
43 |
+
*/
|
44 |
+
function set($key, $value) {
|
45 |
+
$this->attrs->set($key, $value);
|
46 |
+
return $this;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @return string attributes
|
51 |
+
*/
|
52 |
+
function htmlattributes(array $extra = array()) {
|
53 |
+
$attr_segments = array();
|
54 |
+
$attributes = pixcustomify::merge($this->attrs->metadata_array(), $extra);
|
55 |
+
foreach ($attributes as $key => $value) {
|
56 |
+
if ($value !== false && $value !== null) {
|
57 |
+
if ( ! empty($value)) {
|
58 |
+
if (is_array($value)) {
|
59 |
+
$htmlvalue = implode(' ', $value);
|
60 |
+
$attr_segments[] = "$key=\"$htmlvalue\"";
|
61 |
+
}
|
62 |
+
else { // value is not an array
|
63 |
+
$attr_segments[] = "$key=\"$value\"";
|
64 |
+
}
|
65 |
+
}
|
66 |
+
else { // empty html tag; ie. no value html tag
|
67 |
+
$attr_segments[] = $key;
|
68 |
+
}
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
return implode(' ', $attr_segments);
|
73 |
+
}
|
74 |
+
|
75 |
+
} # class
|
includes/admin-settings/core/classes/Meta.php
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
class PixCustomifyMetaImpl implements PixCustomifyMeta {
|
10 |
+
|
11 |
+
/** @var array metadat */
|
12 |
+
protected $metadata = array();
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param array metadata
|
16 |
+
* @return PixCustomifyMeta
|
17 |
+
*/
|
18 |
+
static function instance($metadata) {
|
19 |
+
$i = new self;
|
20 |
+
$i->metadata = $metadata;
|
21 |
+
return $i;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @param string meta key
|
26 |
+
* @return boolean true if key exists, false otherwise
|
27 |
+
*/
|
28 |
+
function has($key) {
|
29 |
+
return isset($this->metadata[$key]);
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param string key
|
34 |
+
* @param mixed default
|
35 |
+
* @return mixed
|
36 |
+
*/
|
37 |
+
function get($key, $default = null) {
|
38 |
+
return $this->has($key) ? $this->metadata[$key] : $default;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param string key
|
43 |
+
* @param mixed value
|
44 |
+
* @return static $this
|
45 |
+
*/
|
46 |
+
function set($key, $value) {
|
47 |
+
$this->metadata[$key] = $value;
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Set the key if it's not already set.
|
53 |
+
*
|
54 |
+
* @param string key
|
55 |
+
* @param string value
|
56 |
+
*/
|
57 |
+
function ensure($key, $value) {
|
58 |
+
if ( ! $this->has($key)) {
|
59 |
+
$this->set($key, $value);
|
60 |
+
}
|
61 |
+
|
62 |
+
return $this;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* If the key is currently a non-array value it will be converted to an
|
67 |
+
* array maintaning the previous value (along with the new one).
|
68 |
+
*
|
69 |
+
* @param string name
|
70 |
+
* @param mixed value
|
71 |
+
* @return static $this
|
72 |
+
*/
|
73 |
+
function add($name, $value) {
|
74 |
+
|
75 |
+
// Cleanup
|
76 |
+
// -------
|
77 |
+
|
78 |
+
if ( ! isset($this->metadata[$name])) {
|
79 |
+
$this->metadata[$name] = array();
|
80 |
+
}
|
81 |
+
else if ( ! is_array($this->metadata[$name]))
|
82 |
+
{
|
83 |
+
$this->metadata[$name] = array($this->metadata[$name]);
|
84 |
+
}
|
85 |
+
# else: array, no cleanup required
|
86 |
+
|
87 |
+
// Register new value
|
88 |
+
// ------------------
|
89 |
+
|
90 |
+
$this->metadata[$name][] = $value;
|
91 |
+
|
92 |
+
return $this;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @return array all metadata as array
|
97 |
+
*/
|
98 |
+
function metadata_array() {
|
99 |
+
return $this->metadata;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Shorthand for a calling set on multiple keys.
|
104 |
+
*
|
105 |
+
* @return static $this
|
106 |
+
*/
|
107 |
+
function overwritemeta($overwrites) {
|
108 |
+
foreach ($overwrites as $key => $value) {
|
109 |
+
$this->set($key, $value);
|
110 |
+
}
|
111 |
+
|
112 |
+
return $this;
|
113 |
+
}
|
114 |
+
|
115 |
+
} # class
|
includes/admin-settings/core/classes/Processor.php
ADDED
@@ -0,0 +1,331 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
class PixCustomifyProcessorImpl implements PixCustomifyProcessor {
|
10 |
+
|
11 |
+
/** @var PixCustomifyMeta plugin configuration */
|
12 |
+
protected $meta = null;
|
13 |
+
|
14 |
+
/** @var PixCustomifyMeta field information */
|
15 |
+
protected $fields = null;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param array config
|
19 |
+
*/
|
20 |
+
static function instance($config = null) {
|
21 |
+
$i = new self;
|
22 |
+
$i->configure($config);
|
23 |
+
return $i;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Apply configuration.
|
28 |
+
*/
|
29 |
+
protected function configure($config = null) {
|
30 |
+
$this->meta = pixcustomify::instance('PixCustomifyMeta', $config);
|
31 |
+
|
32 |
+
// extract fields from configuration
|
33 |
+
$fields = $this->extract($this->meta->get('fields', array()));
|
34 |
+
$this->fields = pixcustomify::instance('PixCustomifyMeta', $fields);
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Extracts fields from raw fields configuration returning an array with
|
39 |
+
* the fields in a flat plain.
|
40 |
+
*
|
41 |
+
* Fields are extracted as follows: if an array has the key "type" it's a
|
42 |
+
* field configuration and the key above it is considered the field name
|
43 |
+
* unless a "name" key is also available.
|
44 |
+
*
|
45 |
+
* @param array raw fields
|
46 |
+
* @return array flat field list
|
47 |
+
*/
|
48 |
+
protected function extract($rawfields) {
|
49 |
+
$fields = array();
|
50 |
+
|
51 |
+
foreach ($rawfields as $key => $value) {
|
52 |
+
if (is_array($value)) {
|
53 |
+
if (isset($value['type'])) {
|
54 |
+
if (is_string($key)) {
|
55 |
+
$fields[$key] = $value;
|
56 |
+
}
|
57 |
+
else if (isset($value['name'])) {
|
58 |
+
$fields[$value['name']] = $value;
|
59 |
+
}
|
60 |
+
# else: assume rendering sugar or other
|
61 |
+
}
|
62 |
+
|
63 |
+
// search deeper for embeded fields
|
64 |
+
$embeded_fields = $this->extract($value);
|
65 |
+
$fields = array_merge($fields, $embeded_fields);
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
return $fields;
|
70 |
+
}
|
71 |
+
|
72 |
+
/** @var array status */
|
73 |
+
protected $status = null;
|
74 |
+
|
75 |
+
/** @var PixCustomifyMeta current data; including submitted data */
|
76 |
+
protected $data = null;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @return static $this
|
80 |
+
*/
|
81 |
+
function run() {
|
82 |
+
// if the status has been generated we skip execution
|
83 |
+
if ($this->status !== null) {
|
84 |
+
return $this;
|
85 |
+
}
|
86 |
+
|
87 |
+
$this->status = array
|
88 |
+
(
|
89 |
+
'state' => 'nominal',
|
90 |
+
'errors' => array(),
|
91 |
+
'dataupdate' => false,
|
92 |
+
);
|
93 |
+
|
94 |
+
try {
|
95 |
+
$option_key = $this->meta->get('settings-key', null);
|
96 |
+
|
97 |
+
if ($option_key === null) {
|
98 |
+
throw new Exception('Missing option_key in plugin configuration.');
|
99 |
+
}
|
100 |
+
|
101 |
+
if ($this->form_was_submitted()) {
|
102 |
+
$input = $this->cleanup_input($_POST);
|
103 |
+
$errors = $this->validate_input($input);
|
104 |
+
|
105 |
+
if (empty($errors)) {
|
106 |
+
$this->preupdate($input);
|
107 |
+
$this->status['dataupdate'] = true;
|
108 |
+
$current_values = get_option($option_key);
|
109 |
+
$new_option = array_merge($current_values, $input);
|
110 |
+
update_option($option_key, $new_option);
|
111 |
+
$this->data = pixcustomify::instance('PixCustomifyMeta', $input);
|
112 |
+
$this->postupdate($input);
|
113 |
+
}
|
114 |
+
else { // got errors
|
115 |
+
$this->status['errors'] = $errors;
|
116 |
+
$this->load_data_from_database($option_key);
|
117 |
+
$this->data->overwritemeta($input);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
else { // GET request
|
121 |
+
$this->load_data_from_database($option_key);
|
122 |
+
}
|
123 |
+
}
|
124 |
+
catch (Exception $e) {
|
125 |
+
if ($this->meta->get('debug', false)) {
|
126 |
+
throw $e;
|
127 |
+
}
|
128 |
+
|
129 |
+
$this->status['state'] = 'error';
|
130 |
+
$this->status['message'] = $e->getMessage();
|
131 |
+
}
|
132 |
+
|
133 |
+
return $this;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @return static $this
|
138 |
+
*/
|
139 |
+
protected function load_data_from_database($option_key) {
|
140 |
+
$dbconfig = get_option($option_key);
|
141 |
+
|
142 |
+
if ($dbconfig === false) {
|
143 |
+
throw new Exception('Unable to retrieve options.');
|
144 |
+
}
|
145 |
+
|
146 |
+
$this->data = pixcustomify::instance('PixCustomifyMeta', $dbconfig);
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* @param array input
|
151 |
+
* @return array cleaned up input
|
152 |
+
*/
|
153 |
+
protected function cleanup_input($input) {
|
154 |
+
$defaults = pixcustomify::defaults();
|
155 |
+
$plugin_cleanup = $this->meta->get('cleanup', array());
|
156 |
+
|
157 |
+
foreach ($this->fields->metadata_array() as $key => $field) {
|
158 |
+
|
159 |
+
// ensure a value is present
|
160 |
+
if ( ! isset($input[$key])) {
|
161 |
+
$input[$key] = null;
|
162 |
+
}
|
163 |
+
|
164 |
+
// Calculate cleanup rules
|
165 |
+
// -----------------------
|
166 |
+
|
167 |
+
$cleanup = array();
|
168 |
+
// check pixcustomify defaults
|
169 |
+
if (isset($defaults['cleanup'][$field['type']])) {
|
170 |
+
$cleanup = $defaults['cleanup'][$field['type']];
|
171 |
+
}
|
172 |
+
// check plugin defaults
|
173 |
+
if (isset($plugin_cleanup[$field['type']])) {
|
174 |
+
$cleanup = array_merge($cleanup, $plugin_cleanup[$field['type']]);
|
175 |
+
}
|
176 |
+
// check field presets
|
177 |
+
if (isset($field['cleanup'])) {
|
178 |
+
$cleanup = array_merge($cleanup, $field['cleanup']);
|
179 |
+
}
|
180 |
+
|
181 |
+
// Perform Cleanup
|
182 |
+
// ---------------
|
183 |
+
|
184 |
+
foreach ($cleanup as $rule) {
|
185 |
+
$callback = pixcustomify::callback($rule, $this->meta);
|
186 |
+
$input[$key] = call_user_func($callback, $input[$key], $field, $this);
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
return $input;
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* @param array input
|
195 |
+
* @return array
|
196 |
+
*/
|
197 |
+
protected function validate_input($input) {
|
198 |
+
$validator = pixcustomify::instance('PixCustomifyValidator', $this->meta, $this->fields);
|
199 |
+
return $validator->validate($input);
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* @return boolean
|
204 |
+
*/
|
205 |
+
protected function form_was_submitted() {
|
206 |
+
return $_SERVER['REQUEST_METHOD'] === 'POST';
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* @return array
|
211 |
+
*/
|
212 |
+
function status() {
|
213 |
+
if ($this->status === null) {
|
214 |
+
$this->run();
|
215 |
+
}
|
216 |
+
|
217 |
+
return $this->status;
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* @return PixCustomifyMeta current data (influenced by user submitted data)
|
222 |
+
*/
|
223 |
+
function data() {
|
224 |
+
if ($this->status === null) {
|
225 |
+
$this->run();
|
226 |
+
}
|
227 |
+
|
228 |
+
return $this->data;
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Shorthand.
|
233 |
+
*
|
234 |
+
* @return array
|
235 |
+
*/
|
236 |
+
function errors() {
|
237 |
+
if ($this->status === null) {
|
238 |
+
$this->run();
|
239 |
+
}
|
240 |
+
|
241 |
+
return $this->status['errors'];
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Shorthand.
|
246 |
+
*
|
247 |
+
* @return boolean
|
248 |
+
*/
|
249 |
+
function performed_update() {
|
250 |
+
if ($this->status === null) {
|
251 |
+
$this->run();
|
252 |
+
}
|
253 |
+
|
254 |
+
return $this->status['dataupdate'];
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* @return boolean true if state is nominal
|
259 |
+
*/
|
260 |
+
function ok() {
|
261 |
+
if ($this->status === null) {
|
262 |
+
$this->run();
|
263 |
+
}
|
264 |
+
|
265 |
+
return $this->status['state'] == 'nominal';
|
266 |
+
}
|
267 |
+
|
268 |
+
// ------------------------------------------------------------------------
|
269 |
+
// Hooks
|
270 |
+
|
271 |
+
/**
|
272 |
+
* Execute preupdate hooks on input.
|
273 |
+
*/
|
274 |
+
protected function preupdate($input)
|
275 |
+
{
|
276 |
+
$defaults = pixcustomify::defaults();
|
277 |
+
$plugin_hooks = $this->meta->get('processor', array('preupdate' => array(), 'postupdate' => array()));
|
278 |
+
|
279 |
+
// Calculate hooks
|
280 |
+
// ---------------
|
281 |
+
|
282 |
+
$hooks = array();
|
283 |
+
// check pixcustomify defaults
|
284 |
+
if (isset($defaults['processor']['preupdate'])) {
|
285 |
+
$hooks = $defaults['processor']['preupdate'];
|
286 |
+
}
|
287 |
+
// check plugin defaults
|
288 |
+
if (isset($plugin_hooks['preupdate'])) {
|
289 |
+
$hooks = array_merge($hooks, $plugin_hooks['preupdate']);
|
290 |
+
}
|
291 |
+
|
292 |
+
// Execute hooks
|
293 |
+
// -------------
|
294 |
+
|
295 |
+
foreach ($hooks as $rule) {
|
296 |
+
$callback = pixcustomify::callback($rule, $this->meta);
|
297 |
+
call_user_func($callback, $input, $this);
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
/**
|
302 |
+
* Execute postupdate hooks on input.
|
303 |
+
*/
|
304 |
+
protected function postupdate($input)
|
305 |
+
{
|
306 |
+
$defaults = pixcustomify::defaults();
|
307 |
+
$plugin_hooks = $this->meta->get('processor', array('preupdate' => array(), 'postupdate' => array()));
|
308 |
+
|
309 |
+
// Calculate hooks
|
310 |
+
// ---------------
|
311 |
+
|
312 |
+
$hooks = array();
|
313 |
+
// check pixcustomify defaults
|
314 |
+
if (isset($defaults['processor']['postupdate'])) {
|
315 |
+
$hooks = $defaults['processor']['postupdate'];
|
316 |
+
}
|
317 |
+
// check plugin defaults
|
318 |
+
if (isset($plugin_hooks['postupdate'])) {
|
319 |
+
$hooks = array_merge($hooks, $plugin_hooks['postupdate']);
|
320 |
+
}
|
321 |
+
|
322 |
+
// Execute hooks
|
323 |
+
// -------------
|
324 |
+
|
325 |
+
foreach ($hooks as $rule) {
|
326 |
+
$callback = pixcustomify::callback($rule, $this->meta);
|
327 |
+
call_user_func($callback, $input, $this);
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
} # class
|
includes/admin-settings/core/classes/Validator.php
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
class PixCustomifyValidatorImpl implements PixCustomifyValidator {
|
10 |
+
|
11 |
+
/** @var PixCustomifyMeta plugin configuration */
|
12 |
+
protected $meta = null;
|
13 |
+
|
14 |
+
/** @var PixCustomifyMeta field information */
|
15 |
+
protected $fields = null;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param array config
|
19 |
+
*/
|
20 |
+
static function instance($config = null, $fields = null) {
|
21 |
+
$i = new self;
|
22 |
+
$i->configure($config, $fields);
|
23 |
+
return $i;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Apply configuration.
|
28 |
+
*
|
29 |
+
* Fields array is assumed to be flat. The class will not perform any field
|
30 |
+
* extraction itself.
|
31 |
+
*/
|
32 |
+
protected function configure($config = null, $fields = null) {
|
33 |
+
$config !== null or $config = array();
|
34 |
+
$fields !== null or $fields = array();
|
35 |
+
|
36 |
+
if (is_array($config)) {
|
37 |
+
$this->meta = pixcustomify::instance('PixCustomifyMeta', $config);
|
38 |
+
}
|
39 |
+
else { // non-array; assume meta object
|
40 |
+
$this->meta = $config;
|
41 |
+
}
|
42 |
+
|
43 |
+
if (is_array($fields)) {
|
44 |
+
$this->fields = pixcustomify::instance('PixCustomifyMeta', $fields);
|
45 |
+
}
|
46 |
+
else { // non-array; assume meta object
|
47 |
+
$this->fields = $fields;
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Validation will only be performed on input keys not on all field keys to
|
53 |
+
* allow for partial input validation.
|
54 |
+
*
|
55 |
+
* @param array input
|
56 |
+
* @return array errors (empty if no errors)
|
57 |
+
*/
|
58 |
+
function validate($input) {
|
59 |
+
$errors = array();
|
60 |
+
$defaults = pixcustomify::defaults();
|
61 |
+
$plugin_checks = $this->meta->get('checks', array());
|
62 |
+
|
63 |
+
foreach ($input as $key => $value) {
|
64 |
+
|
65 |
+
$field = $this->fields->get($key);
|
66 |
+
|
67 |
+
// Calculate validation rules
|
68 |
+
// --------------------------
|
69 |
+
|
70 |
+
$rules = array();
|
71 |
+
// check pixcustomify defaults
|
72 |
+
if (isset($defaults['checks'][$field['type']])) {
|
73 |
+
$rules = $defaults['checks'][$field['type']];
|
74 |
+
}
|
75 |
+
// check theme defaults
|
76 |
+
if (isset($plugin_checks[$field['type']])) {
|
77 |
+
$rules = array_merge($rules, $plugin_checks[$field['type']]);
|
78 |
+
}
|
79 |
+
// check field presets
|
80 |
+
if (isset($field['checks'])) {
|
81 |
+
$rules = array_merge($rules, $field['checks']);
|
82 |
+
}
|
83 |
+
|
84 |
+
// Perform validation
|
85 |
+
// ------------------
|
86 |
+
|
87 |
+
foreach ($rules as $rule) {
|
88 |
+
$callback = pixcustomify::callback($rule, $this->meta);
|
89 |
+
$valid = call_user_func($callback, $input[$key], $field, $this);
|
90 |
+
if ( ! $valid) {
|
91 |
+
isset($errors[$key]) or $errors[$key] = array();
|
92 |
+
$errors[$key][$rule] = $this->error_message($rule);
|
93 |
+
}
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
return $errors;
|
98 |
+
}
|
99 |
+
|
100 |
+
/** @var array error messages */
|
101 |
+
protected static $error_message_cache = null;
|
102 |
+
|
103 |
+
/**
|
104 |
+
* @param string rule
|
105 |
+
* @return string error message
|
106 |
+
*/
|
107 |
+
function error_message($rule) {
|
108 |
+
if (self::$error_message_cache === null) {
|
109 |
+
$defaults = pixcustomify::defaults();
|
110 |
+
$default_errors = $defaults['errors'];
|
111 |
+
$plugin_errors = $this->meta->get('errors', array());
|
112 |
+
self::$error_message_cache = array_merge($default_errors, $plugin_errors);
|
113 |
+
}
|
114 |
+
|
115 |
+
return self::$error_message_cache[$rule];
|
116 |
+
}
|
117 |
+
|
118 |
+
} # class
|
includes/admin-settings/core/classes/forms/Form.php
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
class PixCustomifyFormImpl extends PixCustomifyHTMLElementImpl implements PixCustomifyForm {
|
10 |
+
|
11 |
+
/** @var array templates */
|
12 |
+
protected $fields = null;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param array config
|
16 |
+
*/
|
17 |
+
static function instance($config = null) {
|
18 |
+
$i = new self;
|
19 |
+
$i->configure($config);
|
20 |
+
return $i;
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Apply configuration.
|
25 |
+
*/
|
26 |
+
protected function configure($config = null) {
|
27 |
+
if ($config === null) {
|
28 |
+
$config = array('template-paths' => array(), 'fields' => array());
|
29 |
+
}
|
30 |
+
|
31 |
+
// setup errors
|
32 |
+
$this->errors = array();
|
33 |
+
|
34 |
+
// setup default autocomplete
|
35 |
+
$this->autocomplete = pixcustomify::instance('PixCustomifyMeta', array());
|
36 |
+
|
37 |
+
// setup fields
|
38 |
+
$this->fields = pixcustomify::instance('PixCustomifyMeta', $config['fields']);
|
39 |
+
unset($config['fields']);
|
40 |
+
|
41 |
+
// invoke htmltag instance configuration
|
42 |
+
parent::configure($config);
|
43 |
+
|
44 |
+
// setup paths
|
45 |
+
$this->setmeta('template-paths', $config['template-paths']);
|
46 |
+
|
47 |
+
// @todo CLEANUP the empty action should redirect to the same page but
|
48 |
+
// it's probably wiser to explicitly provide the right page url
|
49 |
+
$this->set('action', '');
|
50 |
+
$this->set('method', 'POST');
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Shorthand.
|
55 |
+
*
|
56 |
+
* @return static $this
|
57 |
+
*/
|
58 |
+
function addtemplatepath($path) {
|
59 |
+
return $this->addmeta('template-paths', $path);
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Note: the field configuration parameter is indented for use when
|
64 |
+
* invoking fields as part of creating other fields (ie. embeded field
|
65 |
+
* configuration inside custom fields). It is not meant for overwriting
|
66 |
+
* configuration and will not accept partial configuration; albeit the
|
67 |
+
* minimal field configuration is fairly minimal.
|
68 |
+
*
|
69 |
+
* @param string field name
|
70 |
+
* @param array complete field configuration
|
71 |
+
* @return string
|
72 |
+
*/
|
73 |
+
function field($fieldname, $fieldconfig = null) {
|
74 |
+
if ($fieldconfig === null) {
|
75 |
+
$fieldconfig = $this->fields->get($fieldname);
|
76 |
+
}
|
77 |
+
|
78 |
+
return pixcustomify::instance('PixCustomifyFormField', $fieldconfig)
|
79 |
+
->setmeta('form', $this)
|
80 |
+
->setmeta('name', $fieldname);
|
81 |
+
}
|
82 |
+
|
83 |
+
// Errors
|
84 |
+
// ------------------------------------------------------------------------
|
85 |
+
|
86 |
+
/** @var array field errors */
|
87 |
+
protected $errors = null;
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @return static $this
|
91 |
+
*/
|
92 |
+
function errors($errors) {
|
93 |
+
$this->errors = $errors;
|
94 |
+
return $this;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* @param string field name
|
99 |
+
* @return array error keys with messages
|
100 |
+
*/
|
101 |
+
function errors_for($fieldname) {
|
102 |
+
if (isset($this->errors[$fieldname])) {
|
103 |
+
return $this->errors[$fieldname];
|
104 |
+
}
|
105 |
+
else { // no errors set
|
106 |
+
return array();
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
// Autocomplete
|
112 |
+
// ------------------------------------------------------------------------
|
113 |
+
|
114 |
+
/** @var PixCustomifyMeta autocomplete */
|
115 |
+
protected $autocomplete = null;
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Autocomplete meta object passed on by the processor.
|
119 |
+
*
|
120 |
+
* @param PixCustomifyMeta autocomplete values
|
121 |
+
* @return static $this
|
122 |
+
*/
|
123 |
+
function autocomplete(PixCustomifyMeta $autocomplete) {
|
124 |
+
$this->autocomplete = $autocomplete;
|
125 |
+
return $this;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Retrieves the value registered for auto-complete. This will not fallback
|
130 |
+
* to the default value set in the configuration since fields are
|
131 |
+
* responsible for managing their internal complexity.
|
132 |
+
*
|
133 |
+
* Typically the autocomplete values are what the processor passes on to
|
134 |
+
* the form.
|
135 |
+
*
|
136 |
+
* @return mixed
|
137 |
+
*/
|
138 |
+
function autovalue($key, $default = null) {
|
139 |
+
return $this->autocomplete->get($key, $default);
|
140 |
+
}
|
141 |
+
|
142 |
+
// Rendering
|
143 |
+
// ------------------------------------------------------------------------
|
144 |
+
|
145 |
+
/**
|
146 |
+
* @return string
|
147 |
+
*/
|
148 |
+
function __toString() {
|
149 |
+
return $this->startform();;
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* @return string
|
154 |
+
*/
|
155 |
+
function startform() {
|
156 |
+
return "<form {$this->htmlattributes()}>";
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @return string
|
161 |
+
*/
|
162 |
+
function endform() {
|
163 |
+
return '</form>';
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* @param string template path
|
168 |
+
* @param array configuration
|
169 |
+
* @return string
|
170 |
+
*/
|
171 |
+
function fieldtemplate($templatepath, $conf = array()) {
|
172 |
+
$config = pixcustomify::instance('PixCustomifyMeta', $conf);
|
173 |
+
return $this->fieldtemplate_render($templatepath, $config);
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* @param string template path
|
178 |
+
* @param PixCustomifyMeta configuration
|
179 |
+
* @return string
|
180 |
+
*/
|
181 |
+
protected function fieldtemplate_render($_template_path, PixCustomifyMeta $conf) {
|
182 |
+
// variables which we wish to expose to template
|
183 |
+
$form = $this; # $this will also work
|
184 |
+
|
185 |
+
ob_start();
|
186 |
+
include $_template_path;
|
187 |
+
return ob_get_clean();
|
188 |
+
}
|
189 |
+
|
190 |
+
} # class
|
includes/admin-settings/core/classes/forms/FormField.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
class PixCustomifyFormFieldImpl extends PixCustomifyHTMLElementImpl implements PixCustomifyFormField {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array config
|
13 |
+
*/
|
14 |
+
static function instance($config = null) {
|
15 |
+
$i = new self;
|
16 |
+
$i->configure($config);
|
17 |
+
return $i;
|
18 |
+
}
|
19 |
+
|
20 |
+
// Error Handling Helpers
|
21 |
+
// ------------------------------------------------------------------------
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @return boolean true if field has errors
|
25 |
+
*/
|
26 |
+
function has_errors() {
|
27 |
+
$form = $this->getmeta('form', null);
|
28 |
+
$errors = $form->errors_for($this->getmeta('name'));
|
29 |
+
return ! empty($errors);
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @return string first error message
|
34 |
+
*/
|
35 |
+
function one_error() {
|
36 |
+
$form = $this->getmeta('form', null);
|
37 |
+
$errors = $form->errors_for($this->getmeta('name'));
|
38 |
+
return array_shift($errors);
|
39 |
+
}
|
40 |
+
|
41 |
+
// Rendering
|
42 |
+
// ------------------------------------------------------------------------
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Render field emulates wordpress template behaviour. First searches for
|
46 |
+
* name, then searches field type and so on.
|
47 |
+
*
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
function render() {
|
51 |
+
$form = $this->getmeta('form');
|
52 |
+
|
53 |
+
// we reverse the order so that last added is first checked
|
54 |
+
$template_paths = array_reverse($form->getmeta('template-paths', array()));
|
55 |
+
|
56 |
+
if (empty($template_paths)) {
|
57 |
+
throw new Exception('Missing template paths.');
|
58 |
+
}
|
59 |
+
|
60 |
+
// the following are the file patterns we look for
|
61 |
+
$patterns = array
|
62 |
+
(
|
63 |
+
'fields/'.$this->getmeta('name'),
|
64 |
+
'fields/'.$this->getmeta('type'),
|
65 |
+
$this->getmeta('name'),
|
66 |
+
$this->getmeta('type')
|
67 |
+
);
|
68 |
+
|
69 |
+
foreach ($patterns as $pattern) {
|
70 |
+
foreach ($template_paths as $path) {
|
71 |
+
$dirpath = rtrim($path, '\\/').DIRECTORY_SEPARATOR;
|
72 |
+
if (file_exists($dirpath.$pattern.EXT)) {
|
73 |
+
return $this->render_template_file($dirpath.$pattern.EXT);
|
74 |
+
}
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
throw new Exception('Failed to match any pattern for field ['.$this->getmeta('name').'] of type '.$this->getmeta('type', '[unknown]'));
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @param string template path
|
83 |
+
* @return string rendered field
|
84 |
+
*/
|
85 |
+
protected function render_template_file($_template_filepath) {
|
86 |
+
// variables which we wish to expose to template
|
87 |
+
$field = $this; # $this will also work
|
88 |
+
$form = $this->getmeta('form');
|
89 |
+
$name = $this->getmeta('name', null);
|
90 |
+
$label = $this->getmeta('label', null);
|
91 |
+
$default = $this->getmeta('default', null);
|
92 |
+
$desc = $this->getmeta('desc', '');
|
93 |
+
$rendering = $this->getmeta('rendering', 'standard');
|
94 |
+
|
95 |
+
// cleaned name (names may be "something[]")
|
96 |
+
$idname = preg_replace('/[^a-zA-Z0-9_-]/', '', $name);
|
97 |
+
|
98 |
+
ob_start();
|
99 |
+
include $_template_filepath;
|
100 |
+
return ob_get_clean();
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* @return string
|
105 |
+
*/
|
106 |
+
function __toString() {
|
107 |
+
return $this->render();
|
108 |
+
}
|
109 |
+
|
110 |
+
} # class
|
includes/admin-settings/core/core.php
ADDED
@@ -0,0 +1,293 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixel Grade Team
|
7 |
+
* @copyright (c) 2013, Pixel Grade Media
|
8 |
+
*/
|
9 |
+
class pixcustomify {
|
10 |
+
|
11 |
+
/** @var array core defaults */
|
12 |
+
protected static $defaults = null;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return array
|
16 |
+
*/
|
17 |
+
static function defaults() {
|
18 |
+
if (self::$defaults === null) {
|
19 |
+
self::$defaults = include self::corepath().'defaults'.EXT;
|
20 |
+
}
|
21 |
+
|
22 |
+
return self::$defaults;
|
23 |
+
}
|
24 |
+
|
25 |
+
// Simple Dependency Injection Container
|
26 |
+
// ------------------------------------------------------------------------
|
27 |
+
|
28 |
+
/** @var array interface -> implementation mapping */
|
29 |
+
protected static $mapping = array();
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @return mixed instance of class registered for the given interface
|
33 |
+
*/
|
34 |
+
static function instance() {
|
35 |
+
$args = func_get_args();
|
36 |
+
$interface = array_shift($args);
|
37 |
+
|
38 |
+
if (isset(self::$mapping[$interface])) {
|
39 |
+
$class = self::$mapping[$interface];
|
40 |
+
}
|
41 |
+
else { // the interface isn't mapped to a class
|
42 |
+
// we fallback to interface name + "Impl" suffix
|
43 |
+
$class = $interface.'Impl';
|
44 |
+
}
|
45 |
+
|
46 |
+
return call_user_func_array(array($class, 'instance'), $args);
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Registers a class for the given interface. If no class is registered for
|
51 |
+
* an interface the interface name with a Impl suffix is used.
|
52 |
+
*/
|
53 |
+
static function use_impl($interface, $class) {
|
54 |
+
self::$mapping[$interface] = $class;
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
// Syntactic Sugar
|
59 |
+
// ------------------------------------------------------------------------
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @param array configuration
|
63 |
+
* @return PixCustomifyForm
|
64 |
+
*/
|
65 |
+
static function form($config, $processor) {
|
66 |
+
$form = self::instance('PixCustomifyForm', $config);
|
67 |
+
$form->autocomplete($processor->data());
|
68 |
+
$form->errors($processor->errors());
|
69 |
+
return $form;
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @param array configuration
|
74 |
+
* @return PixCustomifyProcessor
|
75 |
+
*/
|
76 |
+
static function processor($config) {
|
77 |
+
return self::instance('PixCustomifyProcessor', $config);
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
// Paths
|
82 |
+
// ------------------------------------------------------------------------
|
83 |
+
|
84 |
+
/**
|
85 |
+
* @return string root path for core
|
86 |
+
*/
|
87 |
+
static function corepath() {
|
88 |
+
return dirname(__FILE__).DIRECTORY_SEPARATOR;
|
89 |
+
}
|
90 |
+
|
91 |
+
/** @var string plugin path */
|
92 |
+
protected static $pluginpath = null;
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @return string path
|
96 |
+
*/
|
97 |
+
static function pluginpath() {
|
98 |
+
if (self::$pluginpath === null) {
|
99 |
+
self::$pluginpath = realpath(self::corepath().'..').DIRECTORY_SEPARATOR;
|
100 |
+
}
|
101 |
+
|
102 |
+
return self::$pluginpath;
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Sets a custom plugin path; required in non-standard plugin structures.
|
107 |
+
*/
|
108 |
+
static function setpluginpath($path) {
|
109 |
+
self::$pluginpath = $path;
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
// Helpers
|
114 |
+
// ------------------------------------------------------------------------
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Hirarchical array merge. Will always return an array.
|
118 |
+
*
|
119 |
+
* @param ... arrays
|
120 |
+
* @return array
|
121 |
+
*/
|
122 |
+
static function merge() {
|
123 |
+
$base = array();
|
124 |
+
$args = func_get_args();
|
125 |
+
|
126 |
+
foreach ($args as $arg) {
|
127 |
+
self::array_merge($base, $arg);
|
128 |
+
}
|
129 |
+
|
130 |
+
return $base;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Overwrites base array with overwrite array.
|
135 |
+
*
|
136 |
+
* @param array base
|
137 |
+
* @param array overwrite
|
138 |
+
*/
|
139 |
+
protected static function array_merge(array &$base, array $overwrite) {
|
140 |
+
foreach ($overwrite as $key => &$value)
|
141 |
+
{
|
142 |
+
if (is_int($key))
|
143 |
+
{
|
144 |
+
// add only if it doesn't exist
|
145 |
+
if ( ! in_array($overwrite[$key], $base))
|
146 |
+
{
|
147 |
+
$base[] = $overwrite[$key];
|
148 |
+
}
|
149 |
+
}
|
150 |
+
// non-int key
|
151 |
+
else if (is_array($value))
|
152 |
+
{
|
153 |
+
if (isset($base[$key]) && is_array($base[$key]))
|
154 |
+
{
|
155 |
+
self::array_merge($base[$key], $value);
|
156 |
+
}
|
157 |
+
else # does not exist or it's a non-array
|
158 |
+
{
|
159 |
+
$base[$key] = $value;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
else # not an array and not numeric key
|
163 |
+
{
|
164 |
+
$base[$key] = $value;
|
165 |
+
}
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* @param string callback key
|
171 |
+
* @return string callback function name
|
172 |
+
* @throws Exception
|
173 |
+
*/
|
174 |
+
static function callback($key, PixCustomifyMeta $meta) {
|
175 |
+
$defaults = pixcustomify::defaults();
|
176 |
+
$default_callbacks = $defaults['callbacks'];
|
177 |
+
$plugin_callbacks = $meta->get('callbacks', array());
|
178 |
+
|
179 |
+
$callbacks = array_merge($default_callbacks, $plugin_callbacks);
|
180 |
+
|
181 |
+
if (isset($callbacks[$key])) {
|
182 |
+
return $callbacks[$key];
|
183 |
+
}
|
184 |
+
else { // missing callback
|
185 |
+
throw new Exception('Missing callback for ['.$key.'].');
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
/** @var string the translation text domain */
|
190 |
+
protected static $textdomain = 'customify';
|
191 |
+
|
192 |
+
/**
|
193 |
+
* @return string text domain
|
194 |
+
*/
|
195 |
+
static function textdomain() {
|
196 |
+
return self::$textdomain;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Sets a custom text domain; if null is passed the text domain will revert
|
201 |
+
* to the default text domain.
|
202 |
+
*/
|
203 |
+
static function settextdomain($textdomain) {
|
204 |
+
if ( ! empty($textdomain)) {
|
205 |
+
self::$textdomain = $textdomain;
|
206 |
+
}
|
207 |
+
else { // null or otherwise empty value
|
208 |
+
// revert to default
|
209 |
+
self::$textdomain = 'customify';
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Recursively finds all files in a directory.
|
215 |
+
*
|
216 |
+
* @param string directory to search
|
217 |
+
* @return array found files
|
218 |
+
*/
|
219 |
+
static function find_files($dir)
|
220 |
+
{
|
221 |
+
$found_files = array();
|
222 |
+
$files = scandir($dir);
|
223 |
+
|
224 |
+
foreach ($files as $value) {
|
225 |
+
// skip special dot files and directories
|
226 |
+
if (strpos($value,'.') === 0) {
|
227 |
+
continue;
|
228 |
+
}
|
229 |
+
|
230 |
+
// is it a file?
|
231 |
+
if (is_file("$dir/$value")) {
|
232 |
+
$found_files []= "$dir/$value";
|
233 |
+
continue;
|
234 |
+
}
|
235 |
+
else { // it's a directory
|
236 |
+
foreach (self::find_files("$dir/$value") as $value) {
|
237 |
+
$found_files []= $value;
|
238 |
+
}
|
239 |
+
}
|
240 |
+
}
|
241 |
+
|
242 |
+
return $found_files;
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Requires all PHP files in a directory.
|
247 |
+
* Use case: callback directory, removes the need to manage callbacks.
|
248 |
+
*
|
249 |
+
* Should be used on a small directory chunks with no sub directories to
|
250 |
+
* keep code clear.
|
251 |
+
*
|
252 |
+
* @param string path
|
253 |
+
*/
|
254 |
+
static function require_all($path)
|
255 |
+
{
|
256 |
+
$files = self::find_files(rtrim($path, '\\/'));
|
257 |
+
|
258 |
+
$priority_list = array();
|
259 |
+
foreach ($files as $file) {
|
260 |
+
$priority_list[$file] = self::file_priority($file);
|
261 |
+
}
|
262 |
+
|
263 |
+
asort($priority_list, SORT_ASC);
|
264 |
+
|
265 |
+
foreach ($priority_list as $file => $priority) {
|
266 |
+
if (strpos($file, EXT)) {
|
267 |
+
require_once $file;
|
268 |
+
}
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Priority based on path length and number of directories. Files in the
|
274 |
+
* same directory have higher priority if their path is shorter; files in
|
275 |
+
* directories have +100 priority bonus for every directory.
|
276 |
+
*
|
277 |
+
* @param string file path
|
278 |
+
* @return int
|
279 |
+
*/
|
280 |
+
protected static function file_priority($path) {
|
281 |
+
$path = str_replace('\\', '/', $path);
|
282 |
+
return strlen($path) + substr_count($path, '/') * 100;
|
283 |
+
}
|
284 |
+
|
285 |
+
static function option( $option, $default = null ) {
|
286 |
+
/** @var PixCustomifyPlugin $local_plugin */
|
287 |
+
$local_plugin = PixCustomifyPlugin();
|
288 |
+
|
289 |
+
return $local_plugin->get_option($option, $default = null);
|
290 |
+
|
291 |
+
}
|
292 |
+
|
293 |
+
} # class
|
includes/admin-settings/core/defaults.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php return array
|
2 |
+
(
|
3 |
+
'cleanup' => array
|
4 |
+
(
|
5 |
+
'switch' => array('switch_not_available'),
|
6 |
+
),
|
7 |
+
|
8 |
+
'checks' => array
|
9 |
+
(
|
10 |
+
'counter' => array('is_numeric', 'not_empty'),
|
11 |
+
),
|
12 |
+
|
13 |
+
'processor' => array
|
14 |
+
(
|
15 |
+
// callback signature: (array $input, PixCustomifyProcessor $processor)
|
16 |
+
|
17 |
+
'preupdate' => array
|
18 |
+
(
|
19 |
+
// callbacks to run before update process
|
20 |
+
// cleanup and validation has been performed on data
|
21 |
+
),
|
22 |
+
'postupdate' => array
|
23 |
+
(
|
24 |
+
// callbacks to run post update
|
25 |
+
),
|
26 |
+
),
|
27 |
+
|
28 |
+
'errors' => array
|
29 |
+
(
|
30 |
+
'is_numeric' => __('Numberic value required.', 'customify' ),
|
31 |
+
'not_empty' => __('Field is required.', 'customify' ),
|
32 |
+
),
|
33 |
+
|
34 |
+
'callbacks' => array
|
35 |
+
(
|
36 |
+
// cleanup callbacks
|
37 |
+
'switch_not_available' => 'pixcustomify_cleanup_switch_not_available',
|
38 |
+
|
39 |
+
// validation callbacks
|
40 |
+
'is_numeric' => 'pixcustomify_validate_is_numeric',
|
41 |
+
'not_empty' => 'pixcustomify_validate_not_empty'
|
42 |
+
)
|
43 |
+
|
44 |
+
); # config
|
includes/admin-settings/core/index.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden
|
3 |
+
// Golden is deprecated
|
includes/admin-settings/core/interfaces/HTMLElement.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
interface PixCustomifyHTMLElement extends PixCustomifyHTMLTag {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param string meta key
|
13 |
+
* @return boolean true if key exists, false otherwise
|
14 |
+
*/
|
15 |
+
function hasmeta($key);
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @return mixed value or default
|
19 |
+
*/
|
20 |
+
function getmeta($key, $default = null);
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return static $this
|
24 |
+
*/
|
25 |
+
function setmeta($key, $value);
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Set the key if it's not already set.
|
29 |
+
*
|
30 |
+
* @param string key
|
31 |
+
* @param string value
|
32 |
+
*/
|
33 |
+
function ensuremeta($key, $value);
|
34 |
+
|
35 |
+
/**
|
36 |
+
* If the key is currently a non-array value it will be converted to an
|
37 |
+
* array maintaning the previous value (along with the new one).
|
38 |
+
*
|
39 |
+
* @param string name
|
40 |
+
* @param mixed value
|
41 |
+
* @return static $this
|
42 |
+
*/
|
43 |
+
function addmeta($name, $value);
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @return PixCustomifyMeta form meta
|
47 |
+
*/
|
48 |
+
function meta();
|
49 |
+
|
50 |
+
} # interface
|
includes/admin-settings/core/interfaces/HTMLTag.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
interface PixCustomifyHTMLTag {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param string key
|
13 |
+
* @param mixed default
|
14 |
+
* @return mixed
|
15 |
+
*/
|
16 |
+
function get($key, $default = null);
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @param string key
|
20 |
+
* @param mixed value
|
21 |
+
* @return static $this
|
22 |
+
*/
|
23 |
+
function set($key, $value);
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @return string
|
27 |
+
*/
|
28 |
+
function htmlattributes(array $extra = array());
|
29 |
+
|
30 |
+
} # interface
|
includes/admin-settings/core/interfaces/Meta.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
interface PixCustomifyMeta {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param string meta key
|
13 |
+
* @return boolean true if key exists, false otherwise
|
14 |
+
*/
|
15 |
+
function has($key);
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @return mixed value or default
|
19 |
+
*/
|
20 |
+
function get($key, $default = null);
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return static $this
|
24 |
+
*/
|
25 |
+
function set($key, $value);
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Set the key if it's not already set.
|
29 |
+
*
|
30 |
+
* @param string key
|
31 |
+
* @param string value
|
32 |
+
*/
|
33 |
+
function ensure($key, $value);
|
34 |
+
|
35 |
+
/**
|
36 |
+
* If the key is currently a non-array value it will be converted to an
|
37 |
+
* array maintaning the previous value (along with the new one).
|
38 |
+
*
|
39 |
+
* @param string name
|
40 |
+
* @param mixed value
|
41 |
+
* @return static $this
|
42 |
+
*/
|
43 |
+
function add($name, $value);
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @return array all metadata as array
|
47 |
+
*/
|
48 |
+
function metadata_array();
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Shorthand for a calling set on multiple keys.
|
52 |
+
*
|
53 |
+
* @return static $this
|
54 |
+
*/
|
55 |
+
function overwritemeta($overwrites);
|
56 |
+
|
57 |
+
} # interface
|
includes/admin-settings/core/interfaces/Processor.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
interface PixCustomifyProcessor {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return static $this
|
13 |
+
*/
|
14 |
+
function run();
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return array
|
18 |
+
*/
|
19 |
+
function status();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @return PixCustomifyMeta current data (influenced by user submitted data)
|
23 |
+
*/
|
24 |
+
function data();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Shorthand.
|
28 |
+
*
|
29 |
+
* @return array
|
30 |
+
*/
|
31 |
+
function errors();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Shorthand.
|
35 |
+
*
|
36 |
+
* @return boolean
|
37 |
+
*/
|
38 |
+
function performed_update();
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return boolean true if state is nominal
|
42 |
+
*/
|
43 |
+
function ok();
|
44 |
+
|
45 |
+
} # interface
|
includes/admin-settings/core/interfaces/Validator.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
interface PixCustomifyValidator {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return array errors
|
13 |
+
*/
|
14 |
+
function validate($input);
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param string rule
|
18 |
+
* @return string error message
|
19 |
+
*/
|
20 |
+
function error_message($rule);
|
21 |
+
|
22 |
+
} # interface
|
includes/admin-settings/core/interfaces/extended/Form.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
interface PixCustomifyForm extends PixCustomifyHTMLElement {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return static $this
|
13 |
+
*/
|
14 |
+
function addtemplatepath($path);
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return PixCustomifyFormField
|
18 |
+
*/
|
19 |
+
function field($fieldname);
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @return static $this
|
23 |
+
*/
|
24 |
+
function errors($errors);
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @param string field name
|
28 |
+
* @return array error keys with messages
|
29 |
+
*/
|
30 |
+
function errors_for($fieldname);
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Autocomplete meta object passed on by the processor.
|
34 |
+
*
|
35 |
+
* @param PixCustomifyMeta autocomplete values
|
36 |
+
* @return static $this
|
37 |
+
*/
|
38 |
+
function autocomplete(PixCustomifyMeta $autocomplete);
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Retrieves the value registered for auto-complete. This will not fallback
|
42 |
+
* to the default value set in the configuration since fields are
|
43 |
+
* responsible for managing their internal complexity.
|
44 |
+
*
|
45 |
+
* Typically the autocomplete values are what the processor passes on to
|
46 |
+
* the form.
|
47 |
+
*
|
48 |
+
* @return mixed
|
49 |
+
*/
|
50 |
+
function autovalue($key, $default = null);
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @return string
|
54 |
+
*/
|
55 |
+
function startform();
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @return string
|
59 |
+
*/
|
60 |
+
function endform();
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @param string template path
|
64 |
+
* @param array configuration
|
65 |
+
* @return string
|
66 |
+
*/
|
67 |
+
function fieldtemplate($templatepath, $conf = array());
|
68 |
+
|
69 |
+
} # interface
|
includes/admin-settings/core/interfaces/extended/FormField.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package pixcustomify
|
5 |
+
* @category core
|
6 |
+
* @author Pixelgrade Team
|
7 |
+
* @copyright (c) 2013, Pixelgrade
|
8 |
+
*/
|
9 |
+
interface PixCustomifyFormField extends PixCustomifyHTMLElement {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return boolean true if field has errors
|
13 |
+
*/
|
14 |
+
function has_errors();
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return string first error message
|
18 |
+
*/
|
19 |
+
function one_error();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Render field emulates wordpress template behaviour. First searches for
|
23 |
+
* name, then searches field type and so on.
|
24 |
+
*
|
25 |
+
* @return string
|
26 |
+
*/
|
27 |
+
function render();
|
28 |
+
|
29 |
+
} # interface
|
includes/admin-settings/core/tests/bootstrap.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
|
3 |
+
// ensure EXT is defined
|
4 |
+
if ( ! defined('EXT')) {
|
5 |
+
define('EXT', '.php');
|
6 |
+
}
|
7 |
+
|
8 |
+
error_reporting(-1);
|
9 |
+
|
10 |
+
$basepath = realpath('..').DIRECTORY_SEPARATOR;
|
11 |
+
require $basepath.'bootstrap'.EXT;
|
includes/admin-settings/core/tests/sample-config.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php return array
|
2 |
+
(
|
3 |
+
'template-paths' => array
|
4 |
+
(
|
5 |
+
dirname(__FILE__).DIRECTORY_SEPARATOR.'sample-templates'
|
6 |
+
),
|
7 |
+
|
8 |
+
'fields' => array
|
9 |
+
(
|
10 |
+
// empty
|
11 |
+
),
|
12 |
+
|
13 |
+
); # config
|
includes/admin-settings/core/views/form-partials/fields/color.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
$type = 'color';
|
12 |
+
include 'text'.EXT;
|
13 |
+
|
includes/admin-settings/core/views/form-partials/fields/counter.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
// [!!] the counter field needs to be able to work inside other fields; if
|
12 |
+
// the field is in another field it will have a null label
|
13 |
+
|
14 |
+
$value = $form->autovalue($name, $default);
|
15 |
+
|
16 |
+
$attrs = array
|
17 |
+
(
|
18 |
+
'name' => $name,
|
19 |
+
'id' => $idname,
|
20 |
+
'type' => 'number',
|
21 |
+
'value' => $value,
|
22 |
+
'step' => 1,
|
23 |
+
'class' => array(),
|
24 |
+
);
|
25 |
+
|
26 |
+
$is_inline_field = empty($label) || $rendering == 'inline';
|
27 |
+
|
28 |
+
if ($field->has_errors()) {
|
29 |
+
$error_message = $field->one_error();
|
30 |
+
$attrs['class'][] = 'field-error';
|
31 |
+
$attrs['title'] = "Error: $error_message";
|
32 |
+
}
|
33 |
+
?>
|
34 |
+
|
35 |
+
<?php if ($is_inline_field): ?>
|
36 |
+
<?php $attrs['class'][] = 'small-text' ?>
|
37 |
+
<input <?php echo $field->htmlattributes($attrs) ?> class="small-text" />
|
38 |
+
<?php else: # standard field ?>
|
39 |
+
<label for="<?php echo $idname ?>">
|
40 |
+
<input <?php echo $field->htmlattributes($attrs) ?> />
|
41 |
+
<?php echo $label ?>
|
42 |
+
</label>
|
43 |
+
<?php endif; ?>
|
includes/admin-settings/core/views/form-partials/fields/group.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
/* @var string $show_on */
|
11 |
+
|
12 |
+
/* $show_on = $field->getmeta('show_on'); ?>
|
13 |
+
<div class="group" <?php if ( !empty($show_on) ) echo 'show_on="'. $show_on .'"'; */ ?>
|
14 |
+
<div class="group">
|
15 |
+
<?php foreach ($field->getmeta('options', array()) as $fieldname => $fieldconfig):
|
16 |
+
|
17 |
+
$field = $form->field($fieldname, $fieldconfig);
|
18 |
+
// we set the fields to default to inline
|
19 |
+
$field->ensuremeta('rendering', 'blocks');
|
20 |
+
// export field meta for processing
|
21 |
+
$fielddesc = $field->getmeta('desc', null);
|
22 |
+
$fieldexample = $field->getmeta('group-example', null);
|
23 |
+
$fieldnote = $field->getmeta('group-note', null); ?>
|
24 |
+
<div class="field" <?php if ( $fieldconfig['type'] == 'group' ) echo 'id="' . $fieldname . '"'; ?> >
|
25 |
+
<?php echo $field->render();
|
26 |
+
if ( ! empty($fieldnote)): ?>
|
27 |
+
<span class="field-note"><?php echo $fieldnote ?></span>
|
28 |
+
<?php endif; ?>
|
29 |
+
</div>
|
30 |
+
<?php endforeach; ?>
|
31 |
+
</div>
|
32 |
+
<!--</div>-->
|
includes/admin-settings/core/views/form-partials/fields/hidden.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
isset($type) or $type = 'hidden';
|
12 |
+
|
13 |
+
$attrs = array
|
14 |
+
(
|
15 |
+
'name' => $name,
|
16 |
+
'id' => $idname,
|
17 |
+
'type' => 'hidden',
|
18 |
+
'value' => $form->autovalue($name)
|
19 |
+
);
|
20 |
+
?>
|
21 |
+
|
22 |
+
<input <?php echo $field->htmlattributes($attrs) ?>/>
|
includes/admin-settings/core/views/form-partials/fields/postbox.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
?>
|
12 |
+
<div class="postbox">
|
13 |
+
<div class="handlediv" title="Click to toggle"><br></div>
|
14 |
+
<h3 class="hndle"><span><?php echo $label ?></span></h3>
|
15 |
+
|
16 |
+
<div class="inside">
|
17 |
+
<?php foreach ($field->getmeta('options', array()) as $fieldname => $fieldconfig):
|
18 |
+
|
19 |
+
$field = $form->field($fieldname, $fieldconfig);
|
20 |
+
// we set the fields to default to inline
|
21 |
+
$field->ensuremeta('rendering', 'blocks');
|
22 |
+
// export field meta for processing
|
23 |
+
$fielddesc = $field->getmeta('desc', null);
|
24 |
+
$show_group = $field->getmeta('show_group', null); ?>
|
25 |
+
|
26 |
+
<div class="row" <?php if ( $fieldconfig['type'] == 'group' ) echo 'id="' . $fieldname . '"'; ?>>
|
27 |
+
<?php if ( ! empty($fielddesc)): ?>
|
28 |
+
<div class="field-desc"><?php echo $fielddesc ?></div>
|
29 |
+
<?php endif;
|
30 |
+
echo $field->render();
|
31 |
+
if ( ! empty($fieldnote)): ?>
|
32 |
+
<span class="note"><?php echo $fieldnote ?></span>
|
33 |
+
<?php endif; ?>
|
34 |
+
</div>
|
35 |
+
|
36 |
+
<?php endforeach; ?>
|
37 |
+
</div>
|
38 |
+
</div>
|
includes/admin-settings/core/views/form-partials/fields/select.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined( 'ABSPATH' ) or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
// [!!] the counter field needs to be able to work inside other fields; if
|
12 |
+
// the field is in another field it will have a null label
|
13 |
+
|
14 |
+
$selected = $form->autovalue( $name, $default );
|
15 |
+
|
16 |
+
$attrs = array
|
17 |
+
(
|
18 |
+
'name' => $name,
|
19 |
+
'id' => $idname,
|
20 |
+
);
|
21 |
+
|
22 |
+
// group show
|
23 |
+
|
24 |
+
if ($field->hasmeta('show_group')) {
|
25 |
+
$attrs['data-show_group'] = $field->getmeta('show_group');
|
26 |
+
}
|
27 |
+
|
28 |
+
if ($field->hasmeta('display_option')) {
|
29 |
+
$attrs['data-display_option'] = $field->getmeta('display_option');
|
30 |
+
}?>
|
31 |
+
<div class="select">
|
32 |
+
<label id="<?php echo $name ?>"><?php echo $label ?></label>
|
33 |
+
<select <?php echo $field->htmlattributes( $attrs ) ?>>
|
34 |
+
<?php foreach ( $this->getmeta( 'options', array() ) as $key => $label ): ?>
|
35 |
+
<option <?php if ($key == $selected): ?>selected<?php endif; ?>
|
36 |
+
value="<?php echo $key ?>">
|
37 |
+
<?php echo $label ?>
|
38 |
+
</option>
|
39 |
+
<?php endforeach; ?>
|
40 |
+
</select>
|
41 |
+
</div>
|
includes/admin-settings/core/views/form-partials/fields/switch.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
// [!!] a switch is a checkbox that is only ever either on or off; not to
|
12 |
+
// be confused with a fully functional checkbox which may be many values
|
13 |
+
|
14 |
+
$checked = $form->autovalue($name, $default);
|
15 |
+
|
16 |
+
$attrs = array
|
17 |
+
(
|
18 |
+
'name' => $name,
|
19 |
+
'type' => 'checkbox',
|
20 |
+
'id' => $idname,
|
21 |
+
'value' => 1,
|
22 |
+
);
|
23 |
+
|
24 |
+
// is the checkbox checked?
|
25 |
+
if ($checked) {
|
26 |
+
$attrs['checked'] = 'checked';
|
27 |
+
}
|
28 |
+
|
29 |
+
// Label Fillins
|
30 |
+
// -------------
|
31 |
+
|
32 |
+
if ($field->hasmeta('label-fillins')) {
|
33 |
+
$fillers = array();
|
34 |
+
foreach ($field->getmeta('label-fillins', array()) as $fieldname => $conf) {
|
35 |
+
$fillers[":$fieldname"] = $form->field($fieldname, $conf)->render();
|
36 |
+
}
|
37 |
+
|
38 |
+
$processed_label = strtr($label, $fillers);
|
39 |
+
}
|
40 |
+
else { // no fillins available
|
41 |
+
$processed_label = $label;
|
42 |
+
}
|
43 |
+
|
44 |
+
// group show
|
45 |
+
|
46 |
+
if ($field->hasmeta('show_group')) {
|
47 |
+
$attrs['data-show_group'] = $field->getmeta('show_group');
|
48 |
+
}
|
49 |
+
?>
|
50 |
+
|
51 |
+
<?php if ($rendering == 'inline'): ?>
|
52 |
+
<input <?php echo $field->htmlattributes($attrs) ?> />
|
53 |
+
|
54 |
+
<?php elseif ($rendering == 'blocks'): ?>
|
55 |
+
<div class="switch">
|
56 |
+
<input <?php echo $field->htmlattributes($attrs) ?> />
|
57 |
+
<label for="<?php echo $idname ?>"><?php echo $processed_label ?></label>
|
58 |
+
</div>
|
59 |
+
<?php else: # rendering != 'inline' ?>
|
60 |
+
<label for="<?php echo $idname ?>">
|
61 |
+
<input <?php echo $field->htmlattributes($attrs) ?> />
|
62 |
+
<?php echo $processed_label ?>
|
63 |
+
</label>
|
64 |
+
<?php endif; ?>
|
includes/admin-settings/core/views/form-partials/fields/tabular-group.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
?>
|
11 |
+
|
12 |
+
<tr valign="top">
|
13 |
+
<th scope="row">
|
14 |
+
<?php echo $label ?>
|
15 |
+
</th>
|
16 |
+
<td>
|
17 |
+
<fieldset>
|
18 |
+
|
19 |
+
<legend class="screen-reader-text">
|
20 |
+
<span><?php echo $label ?></span>
|
21 |
+
</legend>
|
22 |
+
|
23 |
+
<?php foreach ($field->getmeta('options', array()) as $fieldname => $conf): ?>
|
24 |
+
<?php echo $form->field($fieldname, $conf)->render() ?>
|
25 |
+
<br/>
|
26 |
+
<?php endforeach; ?>
|
27 |
+
|
28 |
+
<?php if ($field->hasmeta('note')): ?>
|
29 |
+
<small>
|
30 |
+
<em>(<?php echo $field->getmeta('note') ?>)</em>
|
31 |
+
</small>
|
32 |
+
<?php endif; ?>
|
33 |
+
|
34 |
+
</fieldset>
|
35 |
+
</td>
|
36 |
+
</tr>
|
includes/admin-settings/core/views/form-partials/fields/text.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
isset($type) or $type = 'text';
|
12 |
+
|
13 |
+
$attrs = array
|
14 |
+
(
|
15 |
+
'name' => $name,
|
16 |
+
'id' => $idname,
|
17 |
+
'type' => 'text',
|
18 |
+
'value' => $form->autovalue($name)
|
19 |
+
);
|
20 |
+
?>
|
21 |
+
|
22 |
+
<?php if ($rendering == 'inline'): ?>
|
23 |
+
<input <?php echo $field->htmlattributes($attrs) ?>/>
|
24 |
+
<?php elseif ($rendering == 'blocks'): ?>
|
25 |
+
<div class="text">
|
26 |
+
<label id="<?php echo $name ?>"><?php echo $label ?></label>
|
27 |
+
<input <?php echo $field->htmlattributes($attrs) ?> />
|
28 |
+
<span><?php echo $desc ?></span>
|
29 |
+
</div>
|
30 |
+
<?php else: # ?>
|
31 |
+
<div>
|
32 |
+
<p><?php echo $desc ?></p>
|
33 |
+
<label id="<?php echo $name ?>">
|
34 |
+
<?php echo $label ?>
|
35 |
+
<input <?php echo $field->htmlattributes($attrs) ?>/>
|
36 |
+
</label>
|
37 |
+
</div>
|
38 |
+
<?php endif; ?>
|
includes/admin-settings/core/views/form-partials/linear.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined('ABSPATH') or die;
|
2 |
+
/* @var $form PixCustomifyForm */
|
3 |
+
/* @var $conf PixCustomifyMeta */
|
4 |
+
|
5 |
+
/* @var $f PixCustomifyForm */
|
6 |
+
$f = &$form;
|
7 |
+
?>
|
8 |
+
|
9 |
+
<?php foreach ($conf->get('fields', array()) as $fieldname): ?>
|
10 |
+
|
11 |
+
<?php echo $f->field($fieldname)
|
12 |
+
->addmeta('special_sekrit_property', '!!')
|
13 |
+
->render() ?>
|
14 |
+
|
15 |
+
<?php endforeach; ?>
|
includes/admin-settings/views/admin.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Represents the view for the administration dashboard.
|
4 |
+
*
|
5 |
+
* This includes the header, options, and other information that should
|
6 |
+
* provide the user interface to the end user.
|
7 |
+
*
|
8 |
+
* @package customify
|
9 |
+
* @author Pixelgrade <contact@pixelgrade.com>
|
10 |
+
* @license GPL-2.0+
|
11 |
+
* @link http://pixelgrade.com
|
12 |
+
* @copyright 2013 Pixel Grade Media
|
13 |
+
*/
|
14 |
+
|
15 |
+
$config = Customify_Settings::get_plugin_config();
|
16 |
+
|
17 |
+
// invoke processor
|
18 |
+
$processor = pixcustomify::processor( $config );
|
19 |
+
$status = $processor->status();
|
20 |
+
$errors = $processor->errors(); ?>
|
21 |
+
|
22 |
+
<div class="wrap" id="pixcustomify_form">
|
23 |
+
|
24 |
+
<div id="icon-options-general" class="icon32"><br></div>
|
25 |
+
|
26 |
+
<h2><?php esc_html_e( 'PixCustomify', 'customify' ); ?></h2>
|
27 |
+
|
28 |
+
<?php if ( $processor->ok() ): ?>
|
29 |
+
|
30 |
+
<?php if ( ! empty( $errors ) ): ?>
|
31 |
+
<br/>
|
32 |
+
<p class="update-nag">
|
33 |
+
<strong><?php esc_html_e( 'Unable to save settings.', 'customify' ); ?></strong>
|
34 |
+
<?php esc_html_e( 'Please check the fields for errors and typos.', 'customify' ); ?>
|
35 |
+
</p>
|
36 |
+
<?php endif;
|
37 |
+
|
38 |
+
if ( $processor->performed_update() ): ?>
|
39 |
+
<br/>
|
40 |
+
<p class="update-nag">
|
41 |
+
<?php esc_html_e( 'Settings have been updated.', 'customify' ); ?>
|
42 |
+
</p>
|
43 |
+
<?php endif;
|
44 |
+
$f = pixcustomify::form( $config, $processor );
|
45 |
+
echo $f->startform();
|
46 |
+
|
47 |
+
echo $f->field( 'hiddens' )->render();
|
48 |
+
echo $f->field( 'general' )->render();
|
49 |
+
echo $f->field( 'output' )->render();
|
50 |
+
echo $f->field( 'typography' )->render();
|
51 |
+
echo $f->field( 'tools' )->render(); ?>
|
52 |
+
<button type="submit" class="button button-primary">
|
53 |
+
<?php esc_html_e( 'Save Changes', 'customify' ); ?>
|
54 |
+
</button>
|
55 |
+
|
56 |
+
<?php echo $f->endform();
|
57 |
+
|
58 |
+
elseif ( $status['state'] == 'error' ): ?>
|
59 |
+
|
60 |
+
<h3><?php esc_html_e( 'Critical Error', 'customify' ); ?></h3>
|
61 |
+
|
62 |
+
<p><?php echo $status['message'] ?></p>
|
63 |
+
|
64 |
+
<?php endif; ?>
|
65 |
+
</div>
|
includes/admin-settings/views/form-partials/fields/multicheckbox.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined( 'ABSPATH' ) or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
// [!!] the counter field needs to be able to work inside other fields; if
|
12 |
+
// the field is in another field it will have a null label
|
13 |
+
|
14 |
+
$selected = $form->autovalue( $name, $default );
|
15 |
+
|
16 |
+
$option = get_option( 'pixcustomify_settings' );
|
17 |
+
$attrs = array(
|
18 |
+
'type' => 'checkbox',
|
19 |
+
);
|
20 |
+
?>
|
21 |
+
<div class="multicheckbox">
|
22 |
+
<?php
|
23 |
+
foreach ( $this->getmeta( 'options', array() ) as $value => $label ) {
|
24 |
+
$attrs['name'] = $name . '[' . $value . ']';
|
25 |
+
|
26 |
+
if ( is_array($selected) && array_key_exists( $value, $selected) ) {
|
27 |
+
$attrs['checked'] = 'checked';
|
28 |
+
} else {
|
29 |
+
unset($attrs['checked']);
|
30 |
+
} ?>
|
31 |
+
<fieldset class="multicheckbox_option">
|
32 |
+
<input <?php echo $field->htmlattributes( $attrs ) ?>>
|
33 |
+
<label id="<?php echo $value ?>"><?php echo $label ?></label>
|
34 |
+
</fieldset>
|
35 |
+
<?php } ?>
|
36 |
+
</div>
|
includes/admin-settings/views/form-partials/fields/reset_theme_mod.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php defined( 'ABSPATH' ) or die;
|
2 |
+
/* @var PixCustomifyFormField $field */
|
3 |
+
/* @var PixCustomifyForm $form */
|
4 |
+
/* @var mixed $default */
|
5 |
+
/* @var string $name */
|
6 |
+
/* @var string $idname */
|
7 |
+
/* @var string $label */
|
8 |
+
/* @var string $desc */
|
9 |
+
/* @var string $rendering */
|
10 |
+
|
11 |
+
// [!!] the counter field needs to be able to work inside other fields; if
|
12 |
+
// the field is in another field it will have a null label
|
13 |
+
|
14 |
+
$selected = $form->autovalue( $name, $default );
|
15 |
+
|
16 |
+
$config = apply_filters('customify_filter_fields', array() );
|
17 |
+
|
18 |
+
$key = $config[ 'opt-name' ];
|
19 |
+
|
20 |
+
$mods = get_theme_mods();
|
21 |
+
|
22 |
+
$option = get_option( 'pixcustomify_settings' );
|
23 |
+
|
24 |
+
$attrs = array(
|
25 |
+
'type' => 'checkbox',
|
26 |
+
); ?>
|
27 |
+
<div class="reset_customify_theme_mod">
|
28 |
+
<div class="button" id="reset_theme_mods"><?php esc_html_e( 'Reset Theme Mods', 'customify' ); ?></div>
|
29 |
+
<script>
|
30 |
+
(function ($) {
|
31 |
+
$(document).ready(function () {
|
32 |
+
$('#reset_theme_mods').on('click', function () {
|
33 |
+
var confirm = window.confirm('Are you sure?');
|
34 |
+
|
35 |
+
if ( ! confirm ) {
|
36 |
+
return false;
|
37 |
+
}
|
38 |
+
|
39 |
+
$.ajax({
|
40 |
+
url: customify_settings.wp_rest.root + 'customify/v1/delete_theme_mod',
|
41 |
+
method: 'POST',
|
42 |
+
beforeSend: function (xhr) {
|
43 |
+
xhr.setRequestHeader('X-WP-Nonce', customify_settings.wp_rest.nonce);
|
44 |
+
},
|
45 |
+
data: {
|
46 |
+
'customify_settings_nonce': customify_settings.wp_rest.customify_settings_nonce
|
47 |
+
}
|
48 |
+
}).done(function (response) {
|
49 |
+
if ( response.success ) {
|
50 |
+
alert( 'Success: ' + response.data );
|
51 |
+
} else {
|
52 |
+
alert( 'No luck: ' + response.data );
|
53 |
+
}
|
54 |
+
}).error(function (e) {
|
55 |
+
console.log(e);
|
56 |
+
});
|
57 |
+
});
|
58 |
+
});
|
59 |
+
|
60 |
+
})(jQuery)
|
61 |
+
</script>
|
62 |
+
</div>
|
63 |
+
<br>
|
64 |
+
<div class="field-desc"><?php esc_html_e('Resets all the Customizer settings introduced by the plugin. It will NOT reset core Customizer settings or plugin settings.'); ?></div>
|
includes/admin-settings/views/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden
|
includes/class-customify-color-palettes.php
CHANGED
@@ -1049,25 +1049,25 @@ class Customify_Color_Palettes {
|
|
1049 |
/**
|
1050 |
* Get all the defined Style Manager master color field ids.
|
1051 |
*
|
1052 |
-
* @
|
1053 |
-
*
|
1054 |
-
* @param array $options
|
1055 |
*
|
1056 |
* @return array
|
|
|
|
|
1057 |
*/
|
1058 |
-
public function get_all_master_color_controls_ids( $
|
1059 |
$control_ids = array();
|
1060 |
|
1061 |
-
if ( empty( $
|
1062 |
-
$
|
1063 |
}
|
1064 |
|
1065 |
-
if ( empty( $
|
1066 |
return $control_ids;
|
1067 |
}
|
1068 |
|
1069 |
-
foreach ( $
|
1070 |
-
if ( ! empty( $
|
1071 |
$control_ids[] = $option_id;
|
1072 |
}
|
1073 |
}
|
@@ -1078,26 +1078,24 @@ class Customify_Color_Palettes {
|
|
1078 |
/**
|
1079 |
* Get all the defined Style Manager final (master) color field ids.
|
1080 |
*
|
1081 |
-
* @
|
1082 |
-
*
|
1083 |
-
* @param array $options
|
1084 |
*
|
1085 |
* @return array
|
1086 |
*/
|
1087 |
-
public function get_all_final_master_color_controls_ids( $
|
1088 |
$control_ids = array();
|
1089 |
|
1090 |
-
if ( empty( $
|
1091 |
-
$
|
1092 |
}
|
1093 |
|
1094 |
-
if ( empty( $
|
1095 |
return $control_ids;
|
1096 |
}
|
1097 |
|
1098 |
-
foreach ( $
|
1099 |
-
if ( ! empty( $
|
1100 |
-
&& 'hidden' === $
|
1101 |
&& 0 === strpos( $option_id, 'sm_' )
|
1102 |
&& '__final' === substr( $option_id, - strlen( '__final' ) ) ) {
|
1103 |
$control_ids[] = $option_id;
|
1049 |
/**
|
1050 |
* Get all the defined Style Manager master color field ids.
|
1051 |
*
|
1052 |
+
* @param array $options_details
|
|
|
|
|
1053 |
*
|
1054 |
* @return array
|
1055 |
+
*@since 1.7.4
|
1056 |
+
*
|
1057 |
*/
|
1058 |
+
public function get_all_master_color_controls_ids( $options_details = null ) {
|
1059 |
$control_ids = array();
|
1060 |
|
1061 |
+
if ( empty( $options_details ) ) {
|
1062 |
+
$options_details = PixCustomifyPlugin()->get_options_configs(true);
|
1063 |
}
|
1064 |
|
1065 |
+
if ( empty( $options_details ) ) {
|
1066 |
return $control_ids;
|
1067 |
}
|
1068 |
|
1069 |
+
foreach ( $options_details as $option_id => $option_details ) {
|
1070 |
+
if ( ! empty( $option_details['type'] ) && 'color' === $option_details['type'] && 0 === strpos( $option_id, 'sm_' ) ) {
|
1071 |
$control_ids[] = $option_id;
|
1072 |
}
|
1073 |
}
|
1078 |
/**
|
1079 |
* Get all the defined Style Manager final (master) color field ids.
|
1080 |
*
|
1081 |
+
* @param array $options_details
|
|
|
|
|
1082 |
*
|
1083 |
* @return array
|
1084 |
*/
|
1085 |
+
public function get_all_final_master_color_controls_ids( $options_details = null ) {
|
1086 |
$control_ids = array();
|
1087 |
|
1088 |
+
if ( empty( $options_details ) ) {
|
1089 |
+
$options_details = PixCustomifyPlugin()->get_options_configs(true);
|
1090 |
}
|
1091 |
|
1092 |
+
if ( empty( $options_details ) ) {
|
1093 |
return $control_ids;
|
1094 |
}
|
1095 |
|
1096 |
+
foreach ( $options_details as $option_id => $option_details ) {
|
1097 |
+
if ( ! empty( $option_details['type'] )
|
1098 |
+
&& 'hidden' === $option_details['type']
|
1099 |
&& 0 === strpos( $option_id, 'sm_' )
|
1100 |
&& '__final' === substr( $option_id, - strlen( '__final' ) ) ) {
|
1101 |
$control_ids[] = $option_id;
|
includes/class-customify-customizer.php
ADDED
@@ -0,0 +1,1953 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This is the class that handles the overall logic for the Customizer.
|
4 |
+
*
|
5 |
+
* @see https://pixelgrade.com
|
6 |
+
* @author Pixelgrade
|
7 |
+
* @since 2.4.0
|
8 |
+
*/
|
9 |
+
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit; // Exit if accessed directly
|
12 |
+
}
|
13 |
+
|
14 |
+
if ( ! class_exists( 'Customify_Customizer' ) ) :
|
15 |
+
|
16 |
+
class Customify_Customizer {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Holds the only instance of this class.
|
20 |
+
* @var null|Customify_Customizer
|
21 |
+
* @access protected
|
22 |
+
* @since 2.4.0
|
23 |
+
*/
|
24 |
+
protected static $_instance = null;
|
25 |
+
|
26 |
+
protected $localized = array();
|
27 |
+
|
28 |
+
protected $typo_settings;
|
29 |
+
|
30 |
+
protected $google_fonts = null;
|
31 |
+
|
32 |
+
protected $theme_fonts = null;
|
33 |
+
|
34 |
+
protected $media_queries = array();
|
35 |
+
|
36 |
+
// these properties will get 'px' as a default unit
|
37 |
+
public static $pixel_dependent_css_properties = array(
|
38 |
+
'width',
|
39 |
+
'max-width',
|
40 |
+
'min-width',
|
41 |
+
|
42 |
+
'height',
|
43 |
+
'max-height',
|
44 |
+
'min-height',
|
45 |
+
|
46 |
+
'padding',
|
47 |
+
'padding-left',
|
48 |
+
'padding-right',
|
49 |
+
'padding-top',
|
50 |
+
'padding-bottom',
|
51 |
+
|
52 |
+
'margin',
|
53 |
+
'margin-right',
|
54 |
+
'margin-left',
|
55 |
+
'margin-top',
|
56 |
+
'margin-bottom',
|
57 |
+
|
58 |
+
'right',
|
59 |
+
'left',
|
60 |
+
'top',
|
61 |
+
'bottom',
|
62 |
+
|
63 |
+
'font-size',
|
64 |
+
'letter-spacing',
|
65 |
+
|
66 |
+
'border-size',
|
67 |
+
'border-width',
|
68 |
+
'border-bottom-width',
|
69 |
+
'border-left-width',
|
70 |
+
'border-right-width',
|
71 |
+
'border-top-width'
|
72 |
+
);
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Constructor.
|
76 |
+
*
|
77 |
+
* @since 2.4.0
|
78 |
+
*/
|
79 |
+
protected function __construct() {
|
80 |
+
// We will initialize the Customizer logic after the plugin has finished with it's configuration (at priority 15).
|
81 |
+
add_action( 'init', array( $this, 'init' ), 15 );
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Initialize this module.
|
86 |
+
*
|
87 |
+
* @since 2.4.0
|
88 |
+
*/
|
89 |
+
public function init() {
|
90 |
+
|
91 |
+
$this->localized['options_name'] = PixCustomifyPlugin()->get_options_key();
|
92 |
+
|
93 |
+
if ( $this->import_button_exists() ) {
|
94 |
+
$this->localized['import_rest_url'] = get_rest_url( '/customify/1.0/' );
|
95 |
+
$this->localized['import_rest_nonce'] = wp_create_nonce( 'wp_rest' );
|
96 |
+
|
97 |
+
$this->register_import_api();
|
98 |
+
}
|
99 |
+
|
100 |
+
require_once( PixCustomifyPlugin()->get_base_path() . 'features/class-Font_Selector.php' );
|
101 |
+
$this->localized['theme_fonts'] = $this->theme_fonts = Customify_Font_Selector::instance()->get_theme_fonts();
|
102 |
+
|
103 |
+
$this->localized['ajax_url'] = admin_url( 'admin-ajax.php' );
|
104 |
+
$this->localized['style_manager_user_feedback_nonce'] = wp_create_nonce( 'customify_style_manager_user_feedback' );
|
105 |
+
$this->localized['style_manager_user_feedback_provided'] = get_option( 'style_manager_user_feedback_provided', false );
|
106 |
+
|
107 |
+
// Hook up.
|
108 |
+
$this->add_hooks();
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Use this function when you need to know if an import button is used
|
113 |
+
* @return bool
|
114 |
+
*/
|
115 |
+
protected function import_button_exists() {
|
116 |
+
$options_details = PixCustomifyPlugin()->get_options_details(true);
|
117 |
+
|
118 |
+
foreach ( $options_details as $option ) {
|
119 |
+
if ( isset( $option['type'] ) && 'import_demo_data' === $option['type'] ) {
|
120 |
+
return true;
|
121 |
+
break;
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
return false;
|
126 |
+
}
|
127 |
+
|
128 |
+
protected function register_import_api() {
|
129 |
+
|
130 |
+
include_once( PixCustomifyPlugin()->get_base_path() . 'features/class-Customify_Importer.php' );
|
131 |
+
$controller = new Customify_Importer_Controller();
|
132 |
+
$controller->init();
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Initiate our hooks
|
137 |
+
*
|
138 |
+
* @since 2.4.0
|
139 |
+
*/
|
140 |
+
public function add_hooks() {
|
141 |
+
|
142 |
+
// Styles for the Customizer
|
143 |
+
add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_styles' ), 10 );
|
144 |
+
add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_styles' ), 10 );
|
145 |
+
// Scripts enqueued in the Customizer
|
146 |
+
add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_scripts' ), 15 );
|
147 |
+
add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 15 );
|
148 |
+
|
149 |
+
// Scripts enqueued only in the theme preview
|
150 |
+
add_action( 'customize_preview_init', array( $this, 'customizer_live_preview_register_scripts' ), 10 );
|
151 |
+
add_action( 'customize_preview_init', array( $this, 'customizer_live_preview_enqueue_scripts' ), 99999 );
|
152 |
+
|
153 |
+
// Add extra settings data to _wpCustomizeSettings.settings of the parent window.
|
154 |
+
add_action( 'customize_controls_print_footer_scripts', array( $this, 'customize_pane_settings_additional_data' ), 10000 );
|
155 |
+
|
156 |
+
// The frontend effects of the Customizer controls
|
157 |
+
$load_location = PixCustomifyPlugin()->settings->get_plugin_setting( 'style_resources_location', 'wp_head' );
|
158 |
+
|
159 |
+
add_action( $load_location, array( $this, 'output_dynamic_style' ), 99 );
|
160 |
+
add_action( 'wp_head', array( $this, 'output_typography_dynamic_script' ), 10 );
|
161 |
+
add_action( 'wp_head', array( $this, 'output_typography_dynamic_style' ), 10 );
|
162 |
+
|
163 |
+
add_action( 'customize_register', array( $this, 'remove_default_sections' ), 11 );
|
164 |
+
add_action( 'customize_register', array( $this, 'register_customizer' ), 12 );
|
165 |
+
// Maybe the theme has instructed us to do things like removing sections or controls.
|
166 |
+
add_action( 'customize_register', array( $this, 'maybe_process_config_extras' ), 13 );
|
167 |
+
|
168 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'enable_editor_style', true ) ) {
|
169 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'script_to_add_customizer_settings_into_wp_editor' ), 10, 1 );
|
170 |
+
}
|
171 |
+
|
172 |
+
/*
|
173 |
+
* Development related
|
174 |
+
*/
|
175 |
+
if ( defined( 'CUSTOMIFY_DEV_FORCE_DEFAULTS' ) && true === CUSTOMIFY_DEV_FORCE_DEFAULTS ) {
|
176 |
+
// If the development constant CUSTOMIFY_DEV_FORCE_DEFAULTS has been defined we will not save anything in the database
|
177 |
+
// Always go with the default
|
178 |
+
add_filter( 'customize_changeset_save_data', array( $this, 'prevent_changeset_save_in_devmode' ), 50, 1 );
|
179 |
+
// Add a JS to display a notification
|
180 |
+
add_action( 'customize_controls_print_footer_scripts', array( $this, 'prevent_changeset_save_in_devmode_notification' ), 100 );
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Register Customizer admin styles
|
186 |
+
*/
|
187 |
+
function register_admin_customizer_styles() {
|
188 |
+
wp_register_style( 'customify_select2', plugins_url( 'js/select2/css/select2.css', PixCustomifyPlugin()->get_file() ), array(), PixCustomifyPlugin()->get_version() );
|
189 |
+
wp_register_style( 'customify_style', plugins_url( 'css/customizer.css', PixCustomifyPlugin()->get_file() ), array( 'customify_select2' ), PixCustomifyPlugin()->get_version() );
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Enqueue Customizer admin styles
|
194 |
+
*/
|
195 |
+
function enqueue_admin_customizer_styles() {
|
196 |
+
wp_enqueue_style( 'customify_style' );
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Register Customizer admin scripts
|
201 |
+
*/
|
202 |
+
function register_admin_customizer_scripts() {
|
203 |
+
|
204 |
+
wp_register_script( 'customify_select2', plugins_url( 'js/select2/js/select2.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
|
205 |
+
wp_register_script( 'jquery-react', plugins_url( 'js/jquery-react.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
|
206 |
+
|
207 |
+
wp_register_script( 'customify-scale', plugins_url( 'js/customizer/scale-iframe.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
|
208 |
+
wp_register_script( 'customify-fontselectfields', plugins_url( 'js/customizer/font-select-fields.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
|
209 |
+
|
210 |
+
wp_register_script( PixCustomifyPlugin()->get_slug() . '-customizer-scripts', plugins_url( 'js/customizer.js', PixCustomifyPlugin()->get_file() ), array(
|
211 |
+
'jquery',
|
212 |
+
'customify_select2',
|
213 |
+
'underscore',
|
214 |
+
'customize-controls',
|
215 |
+
'customify-fontselectfields',
|
216 |
+
|
217 |
+
'customify-scale',
|
218 |
+
), PixCustomifyPlugin()->get_version() );
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Enqueue Customizer admin scripts
|
223 |
+
*/
|
224 |
+
function enqueue_admin_customizer_scripts() {
|
225 |
+
wp_enqueue_script( 'jquery-react' );
|
226 |
+
wp_enqueue_script( PixCustomifyPlugin()->get_slug() . '-customizer-scripts' );
|
227 |
+
|
228 |
+
wp_localize_script( PixCustomifyPlugin()->get_slug() . '-customizer-scripts', 'customify_settings', apply_filters( 'customify_localized_js_settings', $this->localized ) );
|
229 |
+
}
|
230 |
+
|
231 |
+
/** Register Customizer scripts loaded only on previewer page */
|
232 |
+
function customizer_live_preview_register_scripts() {
|
233 |
+
wp_register_script( PixCustomifyPlugin()->get_slug() . 'CSSOM', plugins_url( 'js/CSSOM.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version(), true );
|
234 |
+
wp_register_script( PixCustomifyPlugin()->get_slug() . 'cssUpdate', plugins_url( 'js/jquery.cssUpdate.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version(), true );
|
235 |
+
wp_register_script( PixCustomifyPlugin()->get_slug() . '-previewer-scripts', plugins_url( 'js/customizer_preview.js', PixCustomifyPlugin()->get_file() ), array(
|
236 |
+
'jquery',
|
237 |
+
'customize-preview',
|
238 |
+
PixCustomifyPlugin()->get_slug() . 'CSSOM',
|
239 |
+
PixCustomifyPlugin()->get_slug() . 'cssUpdate'
|
240 |
+
), PixCustomifyPlugin()->get_version(), true );
|
241 |
+
}
|
242 |
+
|
243 |
+
/** Enqueue Customizer scripts loaded only on previewer page */
|
244 |
+
function customizer_live_preview_enqueue_scripts() {
|
245 |
+
wp_enqueue_script( PixCustomifyPlugin()->get_slug() . '-previewer-scripts' );
|
246 |
+
|
247 |
+
// when a live preview field is in action we need to know which props need 'px' as defaults
|
248 |
+
$this->localized['px_dependent_css_props'] = self::$pixel_dependent_css_properties;
|
249 |
+
|
250 |
+
wp_localize_script( PixCustomifyPlugin()->get_slug() . '-previewer-scripts', 'customify_settings', $this->localized );
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Prevent saving of plugin options in the Customizer
|
255 |
+
*
|
256 |
+
* @param array $data The data to save
|
257 |
+
*
|
258 |
+
* @return array
|
259 |
+
*/
|
260 |
+
public function prevent_changeset_save_in_devmode( $data ) {
|
261 |
+
// Get the options key
|
262 |
+
$options_key = PixCustomifyPlugin()->get_options_key();
|
263 |
+
if ( ! empty( $options_key ) ) {
|
264 |
+
// Remove any Customify data thus preventing it from saving
|
265 |
+
foreach ( $data as $option_id => $value ) {
|
266 |
+
if ( false !== strpos( $option_id, $options_key ) && ! PixCustomifyPlugin()->skip_dev_mode_force_defaults( $option_id ) ) {
|
267 |
+
unset( $data[ $option_id ] );
|
268 |
+
}
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
return $data;
|
273 |
+
}
|
274 |
+
|
275 |
+
public function prevent_changeset_save_in_devmode_notification() { ?>
|
276 |
+
<script type="application/javascript">
|
277 |
+
(function ( $, exports, wp ) {
|
278 |
+
'use strict';
|
279 |
+
// when the customizer is ready add our notification
|
280 |
+
wp.customize.bind('ready', function () {
|
281 |
+
wp.customize.notifications.add( 'customify_force_defaults', new wp.customize.Notification(
|
282 |
+
'customify_force_defaults',
|
283 |
+
{
|
284 |
+
type: 'warning',
|
285 |
+
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 you hit publish.</p>'
|
286 |
+
}
|
287 |
+
) );
|
288 |
+
});
|
289 |
+
})(jQuery, window, wp);
|
290 |
+
</script>
|
291 |
+
<?php }
|
292 |
+
|
293 |
+
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Output CSS style generated by customizer
|
297 |
+
*/
|
298 |
+
function output_dynamic_style() { ?>
|
299 |
+
<style id="customify_output_style">
|
300 |
+
<?php echo $this->get_dynamic_style(); ?>
|
301 |
+
</style>
|
302 |
+
<?php
|
303 |
+
|
304 |
+
/**
|
305 |
+
* from now on we output only style tags only for the preview purpose
|
306 |
+
* so don't cry if you see 30+ style tags for each section
|
307 |
+
*/
|
308 |
+
if ( ! isset( $GLOBALS['wp_customize'] ) ) {
|
309 |
+
return;
|
310 |
+
}
|
311 |
+
|
312 |
+
foreach ( PixCustomifyPlugin()->get_options_details( false, true) as $option_id => $option_details ) {
|
313 |
+
|
314 |
+
if ( isset( $option_details['type'] ) && $option_details['type'] === 'custom_background' ) {
|
315 |
+
$custom_background_output = $this->process_custom_background_field_output( $option_details ); ?>
|
316 |
+
|
317 |
+
<style id="custom_background_output_for_<?php echo sanitize_html_class( $option_id ); ?>">
|
318 |
+
<?php
|
319 |
+
if ( ! empty( $custom_background_output )) {
|
320 |
+
echo $custom_background_output;
|
321 |
+
} ?>
|
322 |
+
</style>
|
323 |
+
<?php }
|
324 |
+
|
325 |
+
if ( ! isset( $option_details['live'] ) || $option_details['live'] !== true ) {
|
326 |
+
continue;
|
327 |
+
}
|
328 |
+
|
329 |
+
if ( ! empty( $option_details['css'] ) ) {
|
330 |
+
foreach ( $option_details['css'] as $key => $properties_set ) {
|
331 |
+
// We need to use a class because we may have multiple <style>s with the same "ID" for example
|
332 |
+
// when targeting the same property but with different selectors.
|
333 |
+
$unique_class = 'dynamic_setting_' . $option_id . '_property_' . str_replace( '-', '_', $properties_set['property'] ) . '_' . $key;
|
334 |
+
|
335 |
+
$inline_style = '<style class="' . sanitize_html_class( $unique_class ) . '" type="text/css">';
|
336 |
+
|
337 |
+
if ( isset( $properties_set['media'] ) && ! empty( $properties_set['media'] ) ) {
|
338 |
+
$inline_style .= '@media '. $properties_set['media'] . ' {';
|
339 |
+
}
|
340 |
+
|
341 |
+
if ( isset( $properties_set['selector'] ) && isset( $properties_set['property'] ) ) {
|
342 |
+
$css_output = $this->process_css_property($properties_set, $option_details['value']);
|
343 |
+
if ( ! empty( $css_output ) ) {
|
344 |
+
$inline_style .= $css_output;
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
if ( isset( $properties_set['media'] ) && ! empty( $properties_set['media'] ) ) {
|
349 |
+
$inline_style .= '}';
|
350 |
+
}
|
351 |
+
$inline_style .= '</style>';
|
352 |
+
|
353 |
+
echo $inline_style;
|
354 |
+
}
|
355 |
+
}
|
356 |
+
}
|
357 |
+
}
|
358 |
+
|
359 |
+
function get_dynamic_style() {
|
360 |
+
$custom_css = '';
|
361 |
+
|
362 |
+
foreach ( PixCustomifyPlugin()->get_options_details(true) as $option_id => $option_details ) {
|
363 |
+
|
364 |
+
if ( isset( $option_details['css'] ) && ! empty( $option_details['css'] ) ) {
|
365 |
+
// now process each
|
366 |
+
$custom_css .= $this->convert_setting_to_css( $option_id, $option_details );
|
367 |
+
}
|
368 |
+
|
369 |
+
if ( isset( $option_details['type'] ) && $option_details['type'] === 'custom_background' ) {
|
370 |
+
$custom_css .= $this->process_custom_background_field_output( $option_details ) . PHP_EOL;
|
371 |
+
}
|
372 |
+
}
|
373 |
+
|
374 |
+
if ( ! empty( $this->media_queries ) ) {
|
375 |
+
|
376 |
+
foreach ( $this->media_queries as $media_query => $properties ) {
|
377 |
+
|
378 |
+
if ( empty( $properties ) ) {
|
379 |
+
continue;
|
380 |
+
}
|
381 |
+
|
382 |
+
$media_query_custom_css = '';
|
383 |
+
|
384 |
+
foreach ( $properties as $key => $property ) {
|
385 |
+
$property_settings = $property['property'];
|
386 |
+
$property_value = $property['value'];
|
387 |
+
$css_output = $this->process_css_property( $property_settings, $property_value );
|
388 |
+
if ( ! empty( $css_output ) ) {
|
389 |
+
$media_query_custom_css .= "\t" . $css_output . PHP_EOL;
|
390 |
+
}
|
391 |
+
}
|
392 |
+
|
393 |
+
if ( ! empty( $media_query_custom_css ) ) {
|
394 |
+
$media_query_custom_css = PHP_EOL . '@media ' . $media_query . " { " . PHP_EOL . PHP_EOL . $media_query_custom_css . "}" . PHP_EOL;
|
395 |
+
}
|
396 |
+
|
397 |
+
if ( ! empty( $media_query_custom_css ) ) {
|
398 |
+
$custom_css .= $media_query_custom_css;
|
399 |
+
}
|
400 |
+
|
401 |
+
}
|
402 |
+
}
|
403 |
+
|
404 |
+
return apply_filters( 'customify_dynamic_style', $custom_css );
|
405 |
+
}
|
406 |
+
|
407 |
+
protected function load_google_fonts() {
|
408 |
+
$fonts_path = PixCustomifyPlugin()->get_base_path() . 'features/customizer/controls/resources/google.fonts.php';
|
409 |
+
|
410 |
+
if ( file_exists( $fonts_path ) ) {
|
411 |
+
$this->google_fonts = require( $fonts_path );
|
412 |
+
}
|
413 |
+
|
414 |
+
if ( ! empty( $this->google_fonts ) ) {
|
415 |
+
return $this->google_fonts;
|
416 |
+
}
|
417 |
+
|
418 |
+
return false;
|
419 |
+
}
|
420 |
+
|
421 |
+
function output_typography_dynamic_style() {
|
422 |
+
$style = $this->get_typography_dynamic_style();
|
423 |
+
|
424 |
+
if ( ! empty( $style ) ) { ?>
|
425 |
+
<style id="customify_typography_output_style">
|
426 |
+
<?php echo $style; ?>
|
427 |
+
</style>
|
428 |
+
<?php }
|
429 |
+
}
|
430 |
+
|
431 |
+
function get_typography_dynamic_style() {
|
432 |
+
$output = '';
|
433 |
+
|
434 |
+
$this->get_typography_fields( PixCustomifyPlugin()->get_options_details(true), 'type', 'typography', $this->typo_settings );
|
435 |
+
|
436 |
+
if ( empty( $this->typo_settings ) ) {
|
437 |
+
return $output;
|
438 |
+
}
|
439 |
+
|
440 |
+
ob_start();
|
441 |
+
foreach ( $this->typo_settings as $font ) {
|
442 |
+
$selector = apply_filters( 'customify_typography_css_selector', $font['selector'], $font );
|
443 |
+
|
444 |
+
$load_all_weights = false;
|
445 |
+
if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
|
446 |
+
$load_all_weights = true;
|
447 |
+
}
|
448 |
+
|
449 |
+
if ( isset( $selector ) && isset( $font['value'] ) && ! empty( $font['value'] ) ) {
|
450 |
+
// Make sure that the value is in the proper format
|
451 |
+
$value = PixCustomifyPlugin::decodeURIComponent( $font['value'] );
|
452 |
+
if ( is_string( $value ) ) {
|
453 |
+
$value = json_decode( $value, true );
|
454 |
+
}
|
455 |
+
|
456 |
+
// In case the value is null (most probably because the json_decode failed),
|
457 |
+
// try the default value (mostly for google fonts)
|
458 |
+
if ( $value === null ) {
|
459 |
+
$value = $this->get_font_defaults_value( $font['value'] );
|
460 |
+
}
|
461 |
+
|
462 |
+
// Shim the old case when the default was only the font name
|
463 |
+
if ( ! empty( $value ) && is_string( $value ) ) {
|
464 |
+
$value = array( 'font_family' => $value );
|
465 |
+
}
|
466 |
+
|
467 |
+
// Handle special logic for when the $value array is not an associative array
|
468 |
+
if ( ! PixCustomifyPlugin()->is_assoc( $value ) ) {
|
469 |
+
$value = $this->standardize_non_associative_font_default( $value );
|
470 |
+
}
|
471 |
+
|
472 |
+
// Bail if empty or we don't have an array
|
473 |
+
if ( empty( $value ) || ! is_array( $value ) ) {
|
474 |
+
continue;
|
475 |
+
}
|
476 |
+
|
477 |
+
$selected_variant = '';
|
478 |
+
if ( ! empty( $value['selected_variants'] ) ) {
|
479 |
+
if ( is_array( $value['selected_variants'] ) ) {
|
480 |
+
$selected_variant = $value['selected_variants'][0];
|
481 |
+
} else {
|
482 |
+
$selected_variant = $value['selected_variants'];
|
483 |
+
}
|
484 |
+
}
|
485 |
+
|
486 |
+
// First handle the case where we have the font-family in the selected variant (usually this means a custom font from our Fonto plugin)
|
487 |
+
if ( ! empty( $selected_variant ) && is_array( $selected_variant ) && ! empty( $selected_variant['font-family'] ) ) {
|
488 |
+
// The variant's font-family
|
489 |
+
echo $selector . " {\nfont-family: " . $selected_variant['font-family'] . ";\n";
|
490 |
+
|
491 |
+
if ( ! $load_all_weights ) {
|
492 |
+
// If this is a custom font (like from our plugin Fonto) with individual styles & weights - i.e. the font-family says it all
|
493 |
+
// we need to "force" the font-weight and font-style
|
494 |
+
if ( ! empty( $value['type'] ) && 'custom_individual' == $value['type'] ) {
|
495 |
+
$selected_variant['font-weight'] = '400 !important';
|
496 |
+
$selected_variant['font-style'] = 'normal !important';
|
497 |
+
}
|
498 |
+
|
499 |
+
// Output the font weight, if available
|
500 |
+
if ( ! empty( $selected_variant['font-weight'] ) ) {
|
501 |
+
echo "font-weight: " . $selected_variant['font-weight'] . ";\n";
|
502 |
+
}
|
503 |
+
|
504 |
+
// Output the font style, if available
|
505 |
+
if ( ! empty( $selected_variant['font-style'] ) ) {
|
506 |
+
echo "font-style: " . $selected_variant['font-style'] . ";\n";
|
507 |
+
}
|
508 |
+
}
|
509 |
+
|
510 |
+
echo "}\n";
|
511 |
+
} elseif ( isset( $value['font_family'] ) ) {
|
512 |
+
// The selected font family
|
513 |
+
echo $selector . " {\n font-family: " . $value['font_family'] . ";\n";
|
514 |
+
|
515 |
+
if ( ! empty( $selected_variant ) && ! $load_all_weights ) {
|
516 |
+
$weight_and_style = strtolower( $selected_variant );
|
517 |
+
|
518 |
+
$italic_font = false;
|
519 |
+
|
520 |
+
//determine if this is an italic font (the $weight_and_style is usually like '400' or '400italic' )
|
521 |
+
if ( strpos( $weight_and_style, 'italic' ) !== false ) {
|
522 |
+
$weight_and_style = str_replace( 'italic', '', $weight_and_style);
|
523 |
+
$italic_font = true;
|
524 |
+
}
|
525 |
+
|
526 |
+
if ( ! empty( $weight_and_style ) ) {
|
527 |
+
//a little bit of sanity check - in case it's not a number
|
528 |
+
if( $weight_and_style === 'regular' ) {
|
529 |
+
$weight_and_style = 'normal';
|
530 |
+
}
|
531 |
+
echo "font-weight: " . $weight_and_style . ";\n";
|
532 |
+
}
|
533 |
+
|
534 |
+
if ( $italic_font ) {
|
535 |
+
echo "font-style: italic;\n";
|
536 |
+
}
|
537 |
+
}
|
538 |
+
|
539 |
+
echo "}\n";
|
540 |
+
}
|
541 |
+
}
|
542 |
+
}
|
543 |
+
|
544 |
+
$output = ob_get_clean();
|
545 |
+
|
546 |
+
return $output;
|
547 |
+
}
|
548 |
+
|
549 |
+
function output_typography_dynamic_script() {
|
550 |
+
|
551 |
+
$script = $this->get_typography_dynamic_script();
|
552 |
+
if ( ! empty ( $script ) ) { ?>
|
553 |
+
<script type="text/javascript">
|
554 |
+
<?php echo $script; ?>
|
555 |
+
</script>
|
556 |
+
<?php }
|
557 |
+
}
|
558 |
+
|
559 |
+
function get_typography_dynamic_script() {
|
560 |
+
$output = '';
|
561 |
+
|
562 |
+
$this->get_typography_fields( PixCustomifyPlugin()->get_options_details(true), 'type', 'typography', $this->typo_settings );
|
563 |
+
|
564 |
+
if ( empty( $this->typo_settings ) ) {
|
565 |
+
return $output;
|
566 |
+
}
|
567 |
+
|
568 |
+
$families = '';
|
569 |
+
|
570 |
+
foreach ( $this->typo_settings as $id => $font ) {
|
571 |
+
if ( isset ( $font['value'] ) ) {
|
572 |
+
|
573 |
+
$load_all_weights = false;
|
574 |
+
if ( isset( $font['load_all_weights'] ) && $font['load_all_weights'] == 'true' ) {
|
575 |
+
$load_all_weights = true;
|
576 |
+
}
|
577 |
+
|
578 |
+
// shim the time when this was an array
|
579 |
+
// @todo Is this really needed? Or does it make sense?
|
580 |
+
if ( is_array( $font['value'] ) ) {
|
581 |
+
$font['value'] = stripslashes_deep( $font['value'] );
|
582 |
+
$font['value'] = json_encode( $font['value'] );
|
583 |
+
}
|
584 |
+
|
585 |
+
$value = wp_unslash( PixCustomifyPlugin::decodeURIComponent( $font['value'] ) );
|
586 |
+
if ( is_string( $value ) ) {
|
587 |
+
$value = json_decode( $value, true );
|
588 |
+
}
|
589 |
+
|
590 |
+
// In case the value is still null, try default value (mostly for google fonts)
|
591 |
+
if ( $value === null || ! is_array( $value ) ) {
|
592 |
+
$value = $this->get_font_defaults_value( str_replace( '"', '', $font['value'] ) );
|
593 |
+
}
|
594 |
+
|
595 |
+
// Bail if by this time we don't have a value of some sort
|
596 |
+
if ( empty( $value ) ) {
|
597 |
+
continue;
|
598 |
+
}
|
599 |
+
|
600 |
+
// Handle special logic for when the $value array is not an associative array
|
601 |
+
if ( ! PixCustomifyPlugin()->is_assoc( $value ) ) {
|
602 |
+
$value = $this->standardize_non_associative_font_default( $value );
|
603 |
+
}
|
604 |
+
|
605 |
+
// Bail if empty or we don't have an array
|
606 |
+
if ( empty( $value ) || ! is_array( $value ) ) {
|
607 |
+
continue;
|
608 |
+
}
|
609 |
+
|
610 |
+
if ( isset( $value['font_family'] ) && isset( $value['type'] ) && $value['type'] == 'google' ) {
|
611 |
+
$families .= "'" . $value['font_family'];
|
612 |
+
|
613 |
+
if ( $load_all_weights && is_array( $value['variants'] ) ) {
|
614 |
+
$families .= ":" . implode( ',', $value['variants'] );
|
615 |
+
} elseif ( isset( $value['selected_variants'] ) && ! empty( $value['selected_variants'] ) ) {
|
616 |
+
if ( is_array( $value['selected_variants'] ) ) {
|
617 |
+
$families .= ":" . implode( ',', $value['selected_variants'] );
|
618 |
+
} elseif ( is_string( $value['selected_variants'] ) || is_numeric( $value['selected_variants'] ) ) {
|
619 |
+
$families .= ":" . $value['selected_variants'];
|
620 |
+
}
|
621 |
+
} elseif ( isset( $value['variants'] ) && ! empty( $value['variants'] ) ) {
|
622 |
+
if ( is_array( $value['variants'] ) ) {
|
623 |
+
$families .= ":" . implode( ',', $value['variants'] );
|
624 |
+
} else {
|
625 |
+
$families .= ":" . $value['variants'];
|
626 |
+
}
|
627 |
+
}
|
628 |
+
|
629 |
+
if ( isset( $value['selected_subsets'] ) && ! empty( $value['selected_subsets'] ) ) {
|
630 |
+
if ( is_array( $value['selected_subsets'] ) ) {
|
631 |
+
$families .= ":" . implode( ',', $value['selected_subsets'] );
|
632 |
+
} else {
|
633 |
+
$families .= ":" . $value['selected_subsets'];
|
634 |
+
}
|
635 |
+
} elseif ( isset( $value['subsets'] ) && ! empty( $value['subsets'] ) ) {
|
636 |
+
if ( is_array( $value['subsets'] ) ) {
|
637 |
+
$families .= ":" . implode( ',', $value['subsets'] );
|
638 |
+
} else {
|
639 |
+
$families .= ":" . $value['subsets'];
|
640 |
+
}
|
641 |
+
}
|
642 |
+
|
643 |
+
$families .= '\',';
|
644 |
+
}
|
645 |
+
}
|
646 |
+
}
|
647 |
+
|
648 |
+
if ( ! empty ( $families ) && PixCustomifyPlugin()->settings->get_plugin_setting( 'typography', '1' )
|
649 |
+
&& PixCustomifyPlugin()->settings->get_plugin_setting( 'typography_google_fonts', 1 ) ) {
|
650 |
+
ob_start();
|
651 |
+
?>
|
652 |
+
if (typeof WebFont !== 'undefined') {<?php // if there is a WebFont object, use it ?>
|
653 |
+
WebFont.load({
|
654 |
+
google: {families: [<?php echo( rtrim( $families, ',' ) ); ?>]},
|
655 |
+
classes: false,
|
656 |
+
events: false
|
657 |
+
});
|
658 |
+
} else {<?php // basically when we don't have the WebFont object we create the google script dynamically ?>
|
659 |
+
|
660 |
+
var tk = document.createElement('script');
|
661 |
+
tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
|
662 |
+
tk.type = 'text/javascript';
|
663 |
+
|
664 |
+
tk.onload = tk.onreadystatechange = function () {
|
665 |
+
WebFont.load({
|
666 |
+
google: {families: [<?php echo( rtrim( $families, ',' ) ); ?>]},
|
667 |
+
classes: false,
|
668 |
+
events: false
|
669 |
+
});
|
670 |
+
};
|
671 |
+
|
672 |
+
var s = document.getElementsByTagName('script')[0];
|
673 |
+
s.parentNode.insertBefore(tk, s);
|
674 |
+
}<?php
|
675 |
+
$output = ob_get_clean();
|
676 |
+
}
|
677 |
+
|
678 |
+
return $output;
|
679 |
+
}
|
680 |
+
|
681 |
+
/**
|
682 |
+
* Handle special logic for when the $value array is not an associative array
|
683 |
+
* Return a new associative array with proper keys
|
684 |
+
*/
|
685 |
+
public function standardize_non_associative_font_default( $value ) {
|
686 |
+
// If the value provided is not array, simply return it
|
687 |
+
if ( ! is_array( $value ) ) {
|
688 |
+
return $value;
|
689 |
+
}
|
690 |
+
|
691 |
+
$new_value = array();
|
692 |
+
|
693 |
+
// Let's determine some type of font
|
694 |
+
if ( ! isset( $value[2] ) || 'google' == $value[2] ) {
|
695 |
+
$new_value = $this->get_font_defaults_value( $value[0] );
|
696 |
+
} else {
|
697 |
+
$new_value['type'] = $value[2];
|
698 |
+
}
|
699 |
+
|
700 |
+
if ( null == $new_value ) {
|
701 |
+
$new_value = array();
|
702 |
+
}
|
703 |
+
|
704 |
+
// The first entry is the font-family
|
705 |
+
if ( isset( $value[0] ) ) {
|
706 |
+
$new_value['font_family'] = $value[0];
|
707 |
+
}
|
708 |
+
|
709 |
+
// In case we don't have an associative array
|
710 |
+
// The second entry is the variants
|
711 |
+
if ( isset( $value[1] ) ) {
|
712 |
+
$new_value['selected_variants'] = $value[1];
|
713 |
+
}
|
714 |
+
|
715 |
+
return $new_value;
|
716 |
+
}
|
717 |
+
|
718 |
+
/**
|
719 |
+
*
|
720 |
+
* @param $font_name
|
721 |
+
*
|
722 |
+
* @return null
|
723 |
+
*/
|
724 |
+
public function get_font_defaults_value( $font_name ) {
|
725 |
+
|
726 |
+
if ( empty( $this->google_fonts ) ) {
|
727 |
+
$this->load_google_fonts();
|
728 |
+
}
|
729 |
+
|
730 |
+
if ( isset( $this->google_fonts[ $font_name ] ) ) {
|
731 |
+
$value = $this->google_fonts[ $font_name ];
|
732 |
+
$value['font_family'] = $font_name;
|
733 |
+
$value['type'] = 'google';
|
734 |
+
|
735 |
+
return $value;
|
736 |
+
} elseif ( isset( $this->theme_fonts[ $font_name ] ) ) {
|
737 |
+
$value['type'] = 'theme_font';
|
738 |
+
$value['src'] = $this->theme_fonts[ $font_name ]['src'];
|
739 |
+
$value['variants'] = $this->theme_fonts[ $font_name ]['variants'];
|
740 |
+
$value['font_family'] = $this->theme_fonts[ $font_name ]['family'];
|
741 |
+
|
742 |
+
return $value;
|
743 |
+
}
|
744 |
+
|
745 |
+
return null;
|
746 |
+
}
|
747 |
+
|
748 |
+
/**
|
749 |
+
* Turn css options into a valid CSS output
|
750 |
+
*
|
751 |
+
* @param $option_id
|
752 |
+
* @param array $option_details
|
753 |
+
*
|
754 |
+
* @return string
|
755 |
+
*/
|
756 |
+
protected function convert_setting_to_css( $option_id, $option_details ) {
|
757 |
+
$output = '';
|
758 |
+
|
759 |
+
if ( empty( $option_details['css'] ) ) {
|
760 |
+
return $output;
|
761 |
+
}
|
762 |
+
|
763 |
+
foreach ( $option_details['css'] as $css_property ) {
|
764 |
+
|
765 |
+
if ( isset( $css_property['media'] ) && ! empty( $css_property['media'] ) ) {
|
766 |
+
$this->media_queries[ $css_property['media'] ][ $option_id ] = array(
|
767 |
+
'property' => $css_property,
|
768 |
+
'value' => $option_details['value']
|
769 |
+
);
|
770 |
+
continue;
|
771 |
+
}
|
772 |
+
|
773 |
+
if ( isset( $css_property['selector'] ) && isset( $css_property['property'] ) ) {
|
774 |
+
$output .= $this->process_css_property( $css_property, $option_details['value'] );
|
775 |
+
}
|
776 |
+
}
|
777 |
+
|
778 |
+
return $output;
|
779 |
+
}
|
780 |
+
|
781 |
+
protected function process_css_property( $css_property, $value ) {
|
782 |
+
$unit = '';
|
783 |
+
|
784 |
+
if ( isset( $css_property['unit'] ) ) {
|
785 |
+
$unit = $css_property['unit'];
|
786 |
+
}
|
787 |
+
|
788 |
+
// if the unit isn't specified but the property should have a unit force 'px' as it
|
789 |
+
if ( empty( $unit ) && in_array( $css_property['property'], self::$pixel_dependent_css_properties ) ) {
|
790 |
+
$unit = 'px';
|
791 |
+
}
|
792 |
+
|
793 |
+
// lose the tons of tabs
|
794 |
+
$css_property['selector'] = trim( preg_replace( '/\t+/', '', $css_property['selector'] ) );
|
795 |
+
|
796 |
+
$css_property['selector'] = apply_filters( 'customify_css_selector', $css_property['selector'], $css_property );
|
797 |
+
|
798 |
+
if ( empty( $css_property['selector'] ) ) {
|
799 |
+
return '';
|
800 |
+
}
|
801 |
+
$property_output = $css_property['selector'] . ' { ' . $css_property['property'] . ': ' . $value . $unit . "; }" . PHP_EOL;
|
802 |
+
|
803 |
+
// Handle the value filter callback.
|
804 |
+
if ( isset( $css_property['filter_value_cb'] ) ) {
|
805 |
+
$value = $this->maybe_apply_filter( $css_property['filter_value_cb'], $value );
|
806 |
+
}
|
807 |
+
|
808 |
+
// Handle output callback.
|
809 |
+
if ( isset( $css_property['callback_filter'] ) && is_callable( $css_property['callback_filter'] ) ) {
|
810 |
+
$property_output = call_user_func( $css_property['callback_filter'], $value, $css_property['selector'], $css_property['property'], $unit );
|
811 |
+
}
|
812 |
+
|
813 |
+
return $property_output;
|
814 |
+
}
|
815 |
+
|
816 |
+
/**
|
817 |
+
* Apply a filter (config) to a value.
|
818 |
+
*
|
819 |
+
* We currently handle filters like these:
|
820 |
+
* // Elaborate filter config
|
821 |
+
* array(
|
822 |
+
* 'callback' => 'is_post_type_archive',
|
823 |
+
* // The arguments we should pass to the check function.
|
824 |
+
* // Think post types, taxonomies, or nothing if that is the case.
|
825 |
+
* // It can be an array of values or a single value.
|
826 |
+
* 'args' => array(
|
827 |
+
* 'jetpack-portfolio',
|
828 |
+
* ),
|
829 |
+
* ),
|
830 |
+
* // Simple filter - just the function name
|
831 |
+
* 'is_404',
|
832 |
+
*
|
833 |
+
* @param array|string $filter
|
834 |
+
* @param mixed $value The value to apply the filter to.
|
835 |
+
*
|
836 |
+
* @return mixed The filtered value.
|
837 |
+
*/
|
838 |
+
public function maybe_apply_filter( $filter, $value ) {
|
839 |
+
// Let's get some obvious things off the table.
|
840 |
+
// On invalid data, we just return what we've received.
|
841 |
+
if ( empty( $filter ) ) {
|
842 |
+
return $value;
|
843 |
+
}
|
844 |
+
|
845 |
+
// First, we handle the shorthand version: just a function name
|
846 |
+
if ( is_string( $filter ) && is_callable( $filter ) ) {
|
847 |
+
$value = call_user_func( $filter );
|
848 |
+
} elseif ( is_array( $filter ) && ! empty( $filter['callback'] ) && is_callable( $filter['callback'] ) ) {
|
849 |
+
if ( empty( $filter['args'] ) ) {
|
850 |
+
$filter['args'] = array();
|
851 |
+
}
|
852 |
+
// The value is always the first argument.
|
853 |
+
$filter['args'] = array( $value ) + $filter['args'];
|
854 |
+
|
855 |
+
$value = call_user_func_array( $filter['callback'], $filter['args'] );
|
856 |
+
}
|
857 |
+
|
858 |
+
return $value;
|
859 |
+
}
|
860 |
+
|
861 |
+
protected function process_custom_background_field_output( $option_details ) {
|
862 |
+
$selector = $output = '';
|
863 |
+
|
864 |
+
if ( ! isset( $option_details['value'] ) ) {
|
865 |
+
return false;
|
866 |
+
}
|
867 |
+
$value = $option_details['value'];
|
868 |
+
|
869 |
+
if ( ! isset( $option_details['output'] ) ) {
|
870 |
+
return $selector;
|
871 |
+
} elseif ( is_string( $option_details['output'] ) ) {
|
872 |
+
$selector = $option_details['output'];
|
873 |
+
} elseif ( is_array( $option_details['output'] ) ) {
|
874 |
+
$selector = implode( ' ', $option_details['output'] );
|
875 |
+
}
|
876 |
+
|
877 |
+
// Loose the ton of tabs.
|
878 |
+
$selector = trim( preg_replace( '/\t+/', '', $selector ) );
|
879 |
+
|
880 |
+
$output .= $selector . " {";
|
881 |
+
if ( isset( $value['background-image'] ) && ! empty( $value['background-image'] ) ) {
|
882 |
+
$output .= "background-image: url( " . $value['background-image'] . ");";
|
883 |
+
} else {
|
884 |
+
$output .= "background-image: none;";
|
885 |
+
}
|
886 |
+
|
887 |
+
if ( isset( $value['background-repeat'] ) && ! empty( $value['background-repeat'] ) ) {
|
888 |
+
$output .= "background-repeat:" . $value['background-repeat'] . ";";
|
889 |
+
}
|
890 |
+
|
891 |
+
if ( isset( $value['background-position'] ) && ! empty( $value['background-position'] ) ) {
|
892 |
+
$output .= "background-position:" . $value['background-position'] . ";";
|
893 |
+
}
|
894 |
+
|
895 |
+
if ( isset( $value['background-size'] ) && ! empty( $value['background-size'] ) ) {
|
896 |
+
$output .= "background-size:" . $value['background-size'] . ";";
|
897 |
+
}
|
898 |
+
|
899 |
+
if ( isset( $value['background-attachment'] ) && ! empty( $value['background-attachment'] ) ) {
|
900 |
+
$output .= "background-attachment:" . $value['background-attachment'] . ";";
|
901 |
+
}
|
902 |
+
$output .= "}\n";
|
903 |
+
|
904 |
+
return $output;
|
905 |
+
}
|
906 |
+
|
907 |
+
/**
|
908 |
+
* add our customizer styling edits into the wp_editor
|
909 |
+
*/
|
910 |
+
function script_to_add_customizer_settings_into_wp_editor() {
|
911 |
+
|
912 |
+
ob_start();
|
913 |
+
$this->output_typography_dynamic_script();
|
914 |
+
$this->output_typography_dynamic_style();
|
915 |
+
$this->output_dynamic_style();
|
916 |
+
|
917 |
+
$custom_css = ob_get_clean();
|
918 |
+
|
919 |
+
ob_start(); ?>
|
920 |
+
(function ($) {
|
921 |
+
$(window).load(function () {
|
922 |
+
/**
|
923 |
+
* @param iframe_id the id of the frame you want to append the style
|
924 |
+
* @param style_element the style element you want to append - boooom
|
925 |
+
*/
|
926 |
+
var append_script_to_iframe = function (ifrm_id, scriptEl) {
|
927 |
+
var myIframe = document.getElementById(ifrm_id);
|
928 |
+
|
929 |
+
var script = myIframe.contentWindow.document.createElement("script");
|
930 |
+
script.type = "text/javascript";
|
931 |
+
script.innerHTML = scriptEl.innerHTML;
|
932 |
+
|
933 |
+
myIframe.contentWindow.document.head.appendChild(script);
|
934 |
+
};
|
935 |
+
|
936 |
+
var append_style_to_iframe = function (ifrm_id, styleElement) {
|
937 |
+
var ifrm = window.frames[ifrm_id];
|
938 |
+
if ( typeof ifrm === "undefined" ) {
|
939 |
+
return;
|
940 |
+
}
|
941 |
+
ifrm = ( ifrm.contentDocument || ifrm.contentDocument || ifrm.document );
|
942 |
+
var head = ifrm.getElementsByTagName('head')[0];
|
943 |
+
|
944 |
+
if (typeof styleElement !== "undefined") {
|
945 |
+
head.appendChild(styleElement);
|
946 |
+
}
|
947 |
+
};
|
948 |
+
|
949 |
+
var xmlString = <?php echo json_encode( str_replace( "\n", "", $custom_css ) ); ?>,
|
950 |
+
parser = new DOMParser(),
|
951 |
+
doc = parser.parseFromString(xmlString, "text/html");
|
952 |
+
|
953 |
+
if (typeof window.frames['content_ifr'] !== 'undefined') {
|
954 |
+
|
955 |
+
$.each(doc.head.childNodes, function (key, el) {
|
956 |
+
if (typeof el !== "undefined" && typeof el.tagName !== "undefined") {
|
957 |
+
|
958 |
+
switch (el.tagName) {
|
959 |
+
case 'STYLE' :
|
960 |
+
append_style_to_iframe('content_ifr', el);
|
961 |
+
break;
|
962 |
+
case 'SCRIPT' :
|
963 |
+
append_script_to_iframe('content_ifr', el);
|
964 |
+
break;
|
965 |
+
default:
|
966 |
+
break;
|
967 |
+
}
|
968 |
+
}
|
969 |
+
});
|
970 |
+
}
|
971 |
+
});
|
972 |
+
})(jQuery);
|
973 |
+
<?php
|
974 |
+
$script = ob_get_clean();
|
975 |
+
wp_add_inline_script( 'editor', $script );
|
976 |
+
|
977 |
+
}
|
978 |
+
|
979 |
+
protected function register_customizer_controls() {
|
980 |
+
|
981 |
+
// first get the base customizer extend class
|
982 |
+
require_once( PixCustomifyPlugin()->get_base_path() . 'features/customizer/class-Pix_Customize_Control.php' );
|
983 |
+
|
984 |
+
// now get all the controls
|
985 |
+
$path = PixCustomifyPlugin()->get_base_path() . 'features/customizer/controls/';
|
986 |
+
pixcustomify::require_all( $path );
|
987 |
+
}
|
988 |
+
|
989 |
+
/**
|
990 |
+
* Maybe process certain "commands" from the config.
|
991 |
+
*
|
992 |
+
* Mainly things like removing sections, controls, etc.
|
993 |
+
*
|
994 |
+
* @since 1.9.0
|
995 |
+
*
|
996 |
+
* @param WP_Customize_Manager $wp_customize
|
997 |
+
*/
|
998 |
+
public function maybe_process_config_extras( $wp_customize ) {
|
999 |
+
$customizer_config = PixCustomifyPlugin()->get_customizer_config();
|
1000 |
+
|
1001 |
+
// Bail if we have no external theme config data.
|
1002 |
+
if ( empty( $customizer_config ) || ! is_array( $customizer_config ) ) {
|
1003 |
+
return;
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
// Maybe remove panels
|
1007 |
+
if ( ! empty( $customizer_config['remove_panels'] ) ) {
|
1008 |
+
// Standardize it.
|
1009 |
+
if ( is_string( $customizer_config['remove_panels'] ) ) {
|
1010 |
+
$customizer_config['remove_panels'] = array( $customizer_config['remove_panels'] );
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
foreach ( $customizer_config['remove_panels'] as $panel_id ) {
|
1014 |
+
$wp_customize->remove_panel( $panel_id );
|
1015 |
+
}
|
1016 |
+
}
|
1017 |
+
|
1018 |
+
// Maybe change panel props.
|
1019 |
+
if ( ! empty( $customizer_config['change_panel_props'] ) ) {
|
1020 |
+
foreach ( $customizer_config['change_panel_props'] as $panel_id => $panel_props ) {
|
1021 |
+
if ( ! is_array( $panel_props ) ) {
|
1022 |
+
continue;
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
$panel = $wp_customize->get_panel( $panel_id );
|
1026 |
+
if ( empty( $panel ) || ! $panel instanceof WP_Customize_Panel ) {
|
1027 |
+
continue;
|
1028 |
+
}
|
1029 |
+
|
1030 |
+
$public_props = get_class_vars( get_class( $panel ) );
|
1031 |
+
foreach ( $panel_props as $prop_name => $prop_value ) {
|
1032 |
+
|
1033 |
+
if ( ! in_array( $prop_name, array_keys( $public_props ) ) ) {
|
1034 |
+
continue;
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
$panel->$prop_name = $prop_value;
|
1038 |
+
}
|
1039 |
+
}
|
1040 |
+
}
|
1041 |
+
|
1042 |
+
// Maybe remove sections
|
1043 |
+
if ( ! empty( $customizer_config['remove_sections'] ) ) {
|
1044 |
+
// Standardize it.
|
1045 |
+
if ( is_string( $customizer_config['remove_sections'] ) ) {
|
1046 |
+
$customizer_config['remove_sections'] = array( $customizer_config['remove_sections'] );
|
1047 |
+
}
|
1048 |
+
|
1049 |
+
foreach ( $customizer_config['remove_sections'] as $section_id ) {
|
1050 |
+
|
1051 |
+
if ( 'widgets' === $section_id ) {
|
1052 |
+
global $wp_registered_sidebars;
|
1053 |
+
|
1054 |
+
foreach ( $wp_registered_sidebars as $widget => $settings ) {
|
1055 |
+
$wp_customize->remove_section( 'sidebar-widgets-' . $widget );
|
1056 |
+
}
|
1057 |
+
continue;
|
1058 |
+
}
|
1059 |
+
|
1060 |
+
$wp_customize->remove_section( $section_id );
|
1061 |
+
}
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
// Maybe change section props.
|
1065 |
+
if ( ! empty( $customizer_config['change_section_props'] ) ) {
|
1066 |
+
foreach ( $customizer_config['change_section_props'] as $section_id => $section_props ) {
|
1067 |
+
if ( ! is_array( $section_props ) ) {
|
1068 |
+
continue;
|
1069 |
+
}
|
1070 |
+
|
1071 |
+
$section = $wp_customize->get_section( $section_id );
|
1072 |
+
if ( empty( $section ) || ! $section instanceof WP_Customize_Section ) {
|
1073 |
+
continue;
|
1074 |
+
}
|
1075 |
+
|
1076 |
+
$public_props = get_class_vars( get_class( $section ) );
|
1077 |
+
foreach ( $section_props as $prop_name => $prop_value ) {
|
1078 |
+
|
1079 |
+
if ( ! in_array( $prop_name, array_keys( $public_props ) ) ) {
|
1080 |
+
continue;
|
1081 |
+
}
|
1082 |
+
|
1083 |
+
$section->$prop_name = $prop_value;
|
1084 |
+
}
|
1085 |
+
}
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
// Maybe remove settings
|
1089 |
+
if ( ! empty( $customizer_config['remove_settings'] ) ) {
|
1090 |
+
// Standardize it.
|
1091 |
+
if ( is_string( $customizer_config['remove_settings'] ) ) {
|
1092 |
+
$customizer_config['remove_settings'] = array( $customizer_config['remove_settings'] );
|
1093 |
+
}
|
1094 |
+
|
1095 |
+
foreach ( $customizer_config['remove_settings'] as $setting_id ) {
|
1096 |
+
$wp_customize->remove_setting( $setting_id );
|
1097 |
+
}
|
1098 |
+
}
|
1099 |
+
|
1100 |
+
// Maybe change setting props.
|
1101 |
+
if ( ! empty( $customizer_config['change_setting_props'] ) ) {
|
1102 |
+
foreach ( $customizer_config['change_setting_props'] as $setting_id => $setting_props ) {
|
1103 |
+
if ( ! is_array( $setting_props ) ) {
|
1104 |
+
continue;
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
$setting = $wp_customize->get_setting( $setting_id );
|
1108 |
+
if ( empty( $setting ) || ! $setting instanceof WP_Customize_Setting ) {
|
1109 |
+
continue;
|
1110 |
+
}
|
1111 |
+
|
1112 |
+
$public_props = get_class_vars( get_class( $setting ) );
|
1113 |
+
foreach ( $setting_props as $prop_name => $prop_value ) {
|
1114 |
+
|
1115 |
+
if ( ! in_array( $prop_name, array_keys( $public_props ) ) ) {
|
1116 |
+
continue;
|
1117 |
+
}
|
1118 |
+
|
1119 |
+
$setting->$prop_name = $prop_value;
|
1120 |
+
}
|
1121 |
+
}
|
1122 |
+
}
|
1123 |
+
|
1124 |
+
// Maybe remove controls
|
1125 |
+
if ( ! empty( $customizer_config['remove_controls'] ) ) {
|
1126 |
+
// Standardize it.
|
1127 |
+
if ( is_string( $customizer_config['remove_controls'] ) ) {
|
1128 |
+
$customizer_config['remove_controls'] = array( $customizer_config['remove_controls'] );
|
1129 |
+
}
|
1130 |
+
|
1131 |
+
foreach ( $customizer_config['remove_controls'] as $control_id ) {
|
1132 |
+
$wp_customize->remove_control( $control_id );
|
1133 |
+
}
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
// Maybe change control props.
|
1137 |
+
if ( ! empty( $customizer_config['change_control_props'] ) ) {
|
1138 |
+
foreach ( $customizer_config['change_control_props'] as $control_id => $control_props ) {
|
1139 |
+
if ( ! is_array( $control_props ) ) {
|
1140 |
+
continue;
|
1141 |
+
}
|
1142 |
+
|
1143 |
+
$control = $wp_customize->get_control( $control_id );
|
1144 |
+
if ( empty( $control ) || ! $control instanceof WP_Customize_Control ) {
|
1145 |
+
continue;
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
$public_props = get_class_vars( get_class( $control ) );
|
1149 |
+
foreach ( $control_props as $prop_name => $prop_value ) {
|
1150 |
+
|
1151 |
+
if ( ! in_array( $prop_name, array_keys( $public_props ) ) ) {
|
1152 |
+
continue;
|
1153 |
+
}
|
1154 |
+
|
1155 |
+
$control->$prop_name = $prop_value;
|
1156 |
+
}
|
1157 |
+
}
|
1158 |
+
}
|
1159 |
+
}
|
1160 |
+
|
1161 |
+
/**
|
1162 |
+
* @param WP_Customize_Manager $wp_customize
|
1163 |
+
*/
|
1164 |
+
function register_customizer( $wp_customize ) {
|
1165 |
+
|
1166 |
+
$this->register_customizer_controls();
|
1167 |
+
|
1168 |
+
$customizer_settings = PixCustomifyPlugin()->get_customizer_config();
|
1169 |
+
|
1170 |
+
if ( ! empty ( $customizer_settings ) ) {
|
1171 |
+
|
1172 |
+
// first check the very needed options name
|
1173 |
+
if ( empty( $customizer_settings['opt-name'] ) ) {
|
1174 |
+
return;
|
1175 |
+
}
|
1176 |
+
$options_name = $customizer_settings['opt-name'];
|
1177 |
+
$wp_customize->options_key = $options_name;
|
1178 |
+
|
1179 |
+
// let's check if we have sections or panels
|
1180 |
+
if ( isset( $customizer_settings['panels'] ) && ! empty( $customizer_settings['panels'] ) ) {
|
1181 |
+
|
1182 |
+
foreach ( $customizer_settings['panels'] as $panel_id => $panel_config ) {
|
1183 |
+
|
1184 |
+
if ( ! empty( $panel_id ) && isset( $panel_config['sections'] ) && ! empty( $panel_config['sections'] ) ) {
|
1185 |
+
|
1186 |
+
// If we have been explicitly given a panel ID we will use that
|
1187 |
+
if ( ! empty( $panel_config['panel_id'] ) ) {
|
1188 |
+
$panel_id = $panel_config['panel_id'];
|
1189 |
+
} else {
|
1190 |
+
$panel_id = $options_name . '[' . $panel_id . ']';
|
1191 |
+
}
|
1192 |
+
|
1193 |
+
$panel_args = array(
|
1194 |
+
'priority' => 10,
|
1195 |
+
'capability' => 'edit_theme_options',
|
1196 |
+
'title' => __( 'Panel title is required', 'customify' ),
|
1197 |
+
'description' => __( 'Description of what this panel does.', 'customify' ),
|
1198 |
+
'auto_expand_sole_section' => false,
|
1199 |
+
);
|
1200 |
+
|
1201 |
+
if ( isset( $panel_config['priority'] ) && ! empty( $panel_config['priority'] ) ) {
|
1202 |
+
$panel_args['priority'] = $panel_config['priority'];
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
if ( isset( $panel_config['title'] ) && ! empty( $panel_config['title'] ) ) {
|
1206 |
+
$panel_args['title'] = $panel_config['title'];
|
1207 |
+
}
|
1208 |
+
|
1209 |
+
if ( isset( $panel_config['description'] ) && ! empty( $panel_config['description'] ) ) {
|
1210 |
+
$panel_args['description'] = $panel_config['description'];
|
1211 |
+
}
|
1212 |
+
|
1213 |
+
if ( isset( $panel_config['auto_expand_sole_section'] ) ) {
|
1214 |
+
$panel_args['auto_expand_sole_section'] = $panel_config['auto_expand_sole_section'];
|
1215 |
+
}
|
1216 |
+
|
1217 |
+
|
1218 |
+
$wp_customize->add_panel( $panel_id, $panel_args );
|
1219 |
+
|
1220 |
+
foreach ( $panel_config['sections'] as $section_id => $section_config ) {
|
1221 |
+
if ( ! empty( $section_id ) && isset( $section_config['options'] ) && ! empty( $section_config['options'] ) ) {
|
1222 |
+
$this->register_section( $panel_id, $section_id, $options_name, $section_config, $wp_customize );
|
1223 |
+
}
|
1224 |
+
}
|
1225 |
+
}
|
1226 |
+
}
|
1227 |
+
}
|
1228 |
+
|
1229 |
+
if ( isset( $customizer_settings['sections'] ) && ! empty( $customizer_settings['sections'] ) ) {
|
1230 |
+
|
1231 |
+
foreach ( $customizer_settings['sections'] as $section_id => $section_config ) {
|
1232 |
+
if ( ! empty( $section_id ) && isset( $section_config['options'] ) && ! empty( $section_config['options'] ) ) {
|
1233 |
+
$this->register_section( $panel_id = false, $section_id, $options_name, $section_config, $wp_customize );
|
1234 |
+
}
|
1235 |
+
}
|
1236 |
+
}
|
1237 |
+
|
1238 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting('enable_reset_buttons') ) {
|
1239 |
+
// create a toolbar section which will be present all the time
|
1240 |
+
$reset_section_settings = array(
|
1241 |
+
'title' => 'Customify Toolbox',
|
1242 |
+
'capability' => 'manage_options',
|
1243 |
+
'priority' => 999999999,
|
1244 |
+
'options' => array(
|
1245 |
+
'reset_all_button' => array(
|
1246 |
+
'type' => 'button',
|
1247 |
+
'label' => 'Reset Customify',
|
1248 |
+
'action' => 'reset_customify',
|
1249 |
+
'value' => 'Reset'
|
1250 |
+
),
|
1251 |
+
)
|
1252 |
+
);
|
1253 |
+
|
1254 |
+
$wp_customize->add_section(
|
1255 |
+
'customify_toolbar',
|
1256 |
+
$reset_section_settings
|
1257 |
+
);
|
1258 |
+
|
1259 |
+
$wp_customize->add_setting(
|
1260 |
+
'reset_customify',
|
1261 |
+
array()
|
1262 |
+
);
|
1263 |
+
$wp_customize->add_control( new Pix_Customize_Button_Control(
|
1264 |
+
$wp_customize,
|
1265 |
+
'reset_customify',
|
1266 |
+
array(
|
1267 |
+
'label' => __( 'Reset All Customify Options to Default', 'customify' ),
|
1268 |
+
'section' => 'customify_toolbar',
|
1269 |
+
'settings' => 'reset_customify',
|
1270 |
+
'action' => 'reset_customify',
|
1271 |
+
)
|
1272 |
+
) );
|
1273 |
+
}
|
1274 |
+
}
|
1275 |
+
|
1276 |
+
do_action( 'customify_create_custom_control', $wp_customize );
|
1277 |
+
}
|
1278 |
+
|
1279 |
+
/**
|
1280 |
+
* @param string $panel_id
|
1281 |
+
* @param string $section_key
|
1282 |
+
* @param string $options_name
|
1283 |
+
* @param array $section_config
|
1284 |
+
* @param WP_Customize_Manager $wp_customize
|
1285 |
+
*/
|
1286 |
+
protected function register_section( $panel_id, $section_key, $options_name, $section_config, $wp_customize ) {
|
1287 |
+
|
1288 |
+
// If we have been explicitly given a section ID we will use that
|
1289 |
+
if ( ! empty( $section_config['section_id'] ) ) {
|
1290 |
+
$section_id = $section_config['section_id'];
|
1291 |
+
} else {
|
1292 |
+
$section_id = $options_name . '[' . $section_key . ']';
|
1293 |
+
}
|
1294 |
+
|
1295 |
+
// Add the new section to the Customizer, but only if it is not already added.
|
1296 |
+
if ( ! $wp_customize->get_section( $section_id ) ) {
|
1297 |
+
// Merge the section settings with the defaults
|
1298 |
+
$section_args = wp_parse_args( $section_config, array(
|
1299 |
+
'priority' => 10,
|
1300 |
+
'panel' => $panel_id,
|
1301 |
+
'capability' => 'edit_theme_options',
|
1302 |
+
'theme_supports' => '',
|
1303 |
+
'title' => esc_html__( 'Title Section is required', 'customify' ),
|
1304 |
+
'description' => '',
|
1305 |
+
'type' => 'default',
|
1306 |
+
'description_hidden' => false,
|
1307 |
+
) );
|
1308 |
+
|
1309 |
+
$wp_customize->add_section( $section_id, $section_args );
|
1310 |
+
}
|
1311 |
+
|
1312 |
+
// Now go through each section option and add the fields
|
1313 |
+
foreach ( $section_config['options'] as $option_id => $option_config ) {
|
1314 |
+
|
1315 |
+
if ( empty( $option_id ) || ! isset( $option_config['type'] ) ) {
|
1316 |
+
continue;
|
1317 |
+
}
|
1318 |
+
|
1319 |
+
// If we have been explicitly given a setting ID we will use that
|
1320 |
+
if ( ! empty( $option_config['setting_id'] ) ) {
|
1321 |
+
$setting_id = $option_config['setting_id'];
|
1322 |
+
} else {
|
1323 |
+
$setting_id = $options_name . '[' . $option_id . ']';
|
1324 |
+
}
|
1325 |
+
|
1326 |
+
// Add the option config to the localized array so we can pass the info to JS.
|
1327 |
+
// @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.
|
1328 |
+
$this->localized['settings'][ $setting_id ] = $option_config;
|
1329 |
+
|
1330 |
+
// Generate a safe option ID (not the final setting ID) to us in HTML attributes like ID or class
|
1331 |
+
$this->localized['settings'][ $setting_id ]['html_safe_option_id'] = sanitize_html_class( $option_id );
|
1332 |
+
|
1333 |
+
$this->register_field( $section_id, $setting_id, $option_config, $wp_customize );
|
1334 |
+
}
|
1335 |
+
|
1336 |
+
}
|
1337 |
+
|
1338 |
+
/**
|
1339 |
+
* Register a Customizer field (setting and control).
|
1340 |
+
*
|
1341 |
+
* @see WP_Customize_Setting
|
1342 |
+
* @see WP_Customize_Control
|
1343 |
+
*
|
1344 |
+
* @param string $section_id
|
1345 |
+
* @param string $setting_id
|
1346 |
+
* @param array $field_config
|
1347 |
+
* @param WP_Customize_Manager $wp_customize
|
1348 |
+
*/
|
1349 |
+
protected function register_field( $section_id, $setting_id, $field_config, $wp_customize ) {
|
1350 |
+
|
1351 |
+
$add_control = true;
|
1352 |
+
// defaults
|
1353 |
+
$setting_args = array(
|
1354 |
+
'default' => '',
|
1355 |
+
'capability' => 'edit_theme_options',
|
1356 |
+
'transport' => 'refresh',
|
1357 |
+
);
|
1358 |
+
$control_args = array(
|
1359 |
+
'priority' => 10,
|
1360 |
+
'label' => '',
|
1361 |
+
'section' => $section_id,
|
1362 |
+
'settings' => $setting_id,
|
1363 |
+
);
|
1364 |
+
|
1365 |
+
// sanitize settings
|
1366 |
+
if ( ! empty( $field_config['live'] ) || $field_config['type'] === 'font' ) {
|
1367 |
+
$setting_args['transport'] = 'postMessage';
|
1368 |
+
}
|
1369 |
+
|
1370 |
+
if ( isset( $field_config['default'] ) ) {
|
1371 |
+
$setting_args['default'] = $field_config['default'];
|
1372 |
+
}
|
1373 |
+
|
1374 |
+
if ( ! empty( $field_config['capability'] ) ) {
|
1375 |
+
$setting_args['capability'] = $field_config['capability'];
|
1376 |
+
}
|
1377 |
+
|
1378 |
+
// If the setting defines it's own type we will respect that, otherwise we will follow the global plugin setting.
|
1379 |
+
if ( ! empty( $field_config['setting_type'] ) ) {
|
1380 |
+
if ( 'option' === $field_config['setting_type'] ) {
|
1381 |
+
$setting_args['type'] = 'option';
|
1382 |
+
} else {
|
1383 |
+
$setting_args['type'] = 'theme_mod';
|
1384 |
+
}
|
1385 |
+
} elseif ( PixCustomifyPlugin()->settings->get_plugin_setting('values_store_mod') === 'option' ) {
|
1386 |
+
$setting_args['type'] = 'option';
|
1387 |
+
}
|
1388 |
+
|
1389 |
+
// if we arrive here this means we have a custom field control
|
1390 |
+
switch ( $field_config['type'] ) {
|
1391 |
+
|
1392 |
+
case 'checkbox':
|
1393 |
+
|
1394 |
+
$setting_args['sanitize_callback'] = array( $this, 'setting_sanitize_checkbox' );
|
1395 |
+
break;
|
1396 |
+
|
1397 |
+
default:
|
1398 |
+
break;
|
1399 |
+
}
|
1400 |
+
|
1401 |
+
if ( ! empty( $field_config['sanitize_callback'] ) && is_callable( $field_config['sanitize_callback'] ) ) {
|
1402 |
+
$setting_args['sanitize_callback'] = $field_config['sanitize_callback'];
|
1403 |
+
}
|
1404 |
+
|
1405 |
+
// Add the setting
|
1406 |
+
$wp_customize->add_setting( $setting_id, $setting_args );
|
1407 |
+
|
1408 |
+
// Stop the control registration, if we are presented with the right type.
|
1409 |
+
if ( 'hidden_control' === $field_config['type'] ) {
|
1410 |
+
return;
|
1411 |
+
}
|
1412 |
+
|
1413 |
+
$control_args['type'] = $field_config['type'];
|
1414 |
+
|
1415 |
+
// now sanitize the control
|
1416 |
+
if ( ! empty( $field_config['label'] ) ) {
|
1417 |
+
$control_args['label'] = $field_config['label'];
|
1418 |
+
}
|
1419 |
+
|
1420 |
+
if ( ! empty( $field_config['priority'] ) ) {
|
1421 |
+
$control_args['priority'] = $field_config['priority'];
|
1422 |
+
}
|
1423 |
+
|
1424 |
+
if ( ! empty( $field_config['desc'] ) ) {
|
1425 |
+
$control_args['description'] = $field_config['desc'];
|
1426 |
+
}
|
1427 |
+
|
1428 |
+
if ( ! empty( $field_config['active_callback'] ) ) {
|
1429 |
+
$control_args['active_callback'] = $field_config['active_callback'];
|
1430 |
+
}
|
1431 |
+
|
1432 |
+
// select the control type
|
1433 |
+
// but first init a default
|
1434 |
+
$control_class_name = 'Pix_Customize_Text_Control';
|
1435 |
+
|
1436 |
+
// If is a standard wp field type call it here and skip the rest.
|
1437 |
+
if ( in_array( $field_config['type'], array(
|
1438 |
+
'checkbox',
|
1439 |
+
'dropdown-pages',
|
1440 |
+
'url',
|
1441 |
+
'date',
|
1442 |
+
'time',
|
1443 |
+
'datetime',
|
1444 |
+
'week',
|
1445 |
+
'search'
|
1446 |
+
) ) ) {
|
1447 |
+
$wp_customize->add_control( $setting_id . '_control', $control_args );
|
1448 |
+
|
1449 |
+
return;
|
1450 |
+
} elseif ( in_array( $field_config['type'], array(
|
1451 |
+
'radio',
|
1452 |
+
'select'
|
1453 |
+
) ) && ! empty( $field_config['choices'] )
|
1454 |
+
) {
|
1455 |
+
$control_args['choices'] = $field_config['choices'];
|
1456 |
+
$wp_customize->add_control( $setting_id . '_control', $control_args );
|
1457 |
+
|
1458 |
+
return;
|
1459 |
+
} elseif ( in_array( $field_config['type'], array( 'range' ) ) && ! empty( $field_config['input_attrs'] ) ) {
|
1460 |
+
|
1461 |
+
$control_args['input_attrs'] = $field_config['input_attrs'];
|
1462 |
+
|
1463 |
+
$wp_customize->add_control( $setting_id . '_control', $control_args );
|
1464 |
+
}
|
1465 |
+
|
1466 |
+
// If we arrive here this means we have a custom field control.
|
1467 |
+
switch ( $field_config['type'] ) {
|
1468 |
+
|
1469 |
+
case 'text':
|
1470 |
+
if ( isset( $field_config['live'] ) ) {
|
1471 |
+
$control_args['live'] = $field_config['live'];
|
1472 |
+
}
|
1473 |
+
|
1474 |
+
$control_class_name = 'Pix_Customize_Text_Control';
|
1475 |
+
break;
|
1476 |
+
|
1477 |
+
case 'textarea':
|
1478 |
+
if ( isset( $field_config['live'] ) ) {
|
1479 |
+
$control_args['live'] = $field_config['live'];
|
1480 |
+
}
|
1481 |
+
|
1482 |
+
$control_class_name = 'Pix_Customize_Textarea_Control';
|
1483 |
+
break;
|
1484 |
+
|
1485 |
+
case 'color':
|
1486 |
+
$control_class_name = 'WP_Customize_Color_Control';
|
1487 |
+
break;
|
1488 |
+
|
1489 |
+
case 'color_drop':
|
1490 |
+
$control_class_name = 'Pix_Customize_Color_Drop_Control';
|
1491 |
+
break;
|
1492 |
+
|
1493 |
+
case 'ace_editor':
|
1494 |
+
if ( isset( $field_config['live'] ) ) {
|
1495 |
+
$control_args['live'] = $field_config['live'];
|
1496 |
+
}
|
1497 |
+
|
1498 |
+
if ( isset( $field_config['editor_type'] ) ) {
|
1499 |
+
$control_args['editor_type'] = $field_config['editor_type'];
|
1500 |
+
}
|
1501 |
+
|
1502 |
+
$control_class_name = 'Pix_Customize_Ace_Editor_Control';
|
1503 |
+
break;
|
1504 |
+
|
1505 |
+
case 'upload':
|
1506 |
+
$control_class_name = 'WP_Customize_Upload_Control';
|
1507 |
+
break;
|
1508 |
+
|
1509 |
+
case 'image':
|
1510 |
+
$control_class_name = 'WP_Customize_Image_Control';
|
1511 |
+
break;
|
1512 |
+
|
1513 |
+
case 'media':
|
1514 |
+
$control_class_name = 'WP_Customize_Media_Control';
|
1515 |
+
break;
|
1516 |
+
|
1517 |
+
case 'custom_background':
|
1518 |
+
if ( isset( $field_config['field'] ) ) {
|
1519 |
+
$control_args['field'] = $field_config['field'];
|
1520 |
+
}
|
1521 |
+
|
1522 |
+
$control_class_name = 'Pix_Customize_Background_Control';
|
1523 |
+
break;
|
1524 |
+
|
1525 |
+
case 'cropped_image':
|
1526 |
+
case 'cropped_media': // 'cropped_media' no longer works
|
1527 |
+
if ( isset( $field_config['width'] ) ) {
|
1528 |
+
$control_args['width'] = $field_config['width'];
|
1529 |
+
}
|
1530 |
+
|
1531 |
+
if ( isset( $field_config['height'] ) ) {
|
1532 |
+
$control_args['height'] = $field_config['height'];
|
1533 |
+
}
|
1534 |
+
|
1535 |
+
if ( isset( $field_config['flex_width'] ) ) {
|
1536 |
+
$control_args['flex_width'] = $field_config['flex_width'];
|
1537 |
+
}
|
1538 |
+
|
1539 |
+
if ( isset( $field_config['flex_height'] ) ) {
|
1540 |
+
$control_args['flex_height'] = $field_config['flex_height'];
|
1541 |
+
}
|
1542 |
+
|
1543 |
+
if ( isset( $field_config['button_labels'] ) ) {
|
1544 |
+
$control_args['button_labels'] = $field_config['button_labels'];
|
1545 |
+
}
|
1546 |
+
|
1547 |
+
$control_class_name = 'WP_Customize_Cropped_Image_Control';
|
1548 |
+
break;
|
1549 |
+
|
1550 |
+
// Custom types
|
1551 |
+
case 'typography' :
|
1552 |
+
$use_typography = PixCustomifyPlugin()->settings->get_plugin_setting( 'typography', '1' );
|
1553 |
+
|
1554 |
+
if ( $use_typography === false ) {
|
1555 |
+
$add_control = false;
|
1556 |
+
break;
|
1557 |
+
}
|
1558 |
+
|
1559 |
+
$control_class_name = 'Pix_Customize_Typography_Control';
|
1560 |
+
|
1561 |
+
if ( isset( $field_config['backup'] ) ) {
|
1562 |
+
$control_args['backup'] = $field_config['backup'];
|
1563 |
+
}
|
1564 |
+
|
1565 |
+
if ( isset( $field_config['font_weight'] ) ) {
|
1566 |
+
$control_args['font_weight'] = $field_config['font_weight'];
|
1567 |
+
}
|
1568 |
+
|
1569 |
+
if ( isset( $field_config['subsets'] ) ) {
|
1570 |
+
$control_args['subsets'] = $field_config['subsets'];
|
1571 |
+
}
|
1572 |
+
|
1573 |
+
if ( isset( $field_config['recommended'] ) ) {
|
1574 |
+
$control_args['recommended'] = array_flip( $field_config['recommended'] );
|
1575 |
+
}
|
1576 |
+
|
1577 |
+
if ( isset( $field_config['load_all_weights'] ) ) {
|
1578 |
+
$control_args['load_all_weights'] = $field_config['load_all_weights'];
|
1579 |
+
}
|
1580 |
+
|
1581 |
+
if ( isset( $field_config['default'] ) ) {
|
1582 |
+
$control_args['default'] = $field_config['default'];
|
1583 |
+
}
|
1584 |
+
|
1585 |
+
break;
|
1586 |
+
|
1587 |
+
case 'font' :
|
1588 |
+
$use_typography = PixCustomifyPlugin()->settings->get_plugin_setting( 'typography', '1' );
|
1589 |
+
|
1590 |
+
if ( $use_typography === false ) {
|
1591 |
+
$add_control = false;
|
1592 |
+
break;
|
1593 |
+
}
|
1594 |
+
|
1595 |
+
$control_class_name = 'Pix_Customize_Font_Control';
|
1596 |
+
|
1597 |
+
if ( isset( $field_config['backup'] ) ) {
|
1598 |
+
$control_args['backup'] = $field_config['backup'];
|
1599 |
+
}
|
1600 |
+
|
1601 |
+
if ( isset( $field_config['font_weight'] ) ) {
|
1602 |
+
$control_args['font_weight'] = $field_config['font_weight'];
|
1603 |
+
}
|
1604 |
+
|
1605 |
+
if ( isset( $field_config['subsets'] ) ) {
|
1606 |
+
$control_args['subsets'] = $field_config['subsets'];
|
1607 |
+
}
|
1608 |
+
|
1609 |
+
if ( isset( $field_config['recommended'] ) ) {
|
1610 |
+
$control_args['recommended'] = array_flip( $field_config['recommended'] );
|
1611 |
+
}
|
1612 |
+
|
1613 |
+
if ( isset( $field_config['load_all_weights'] ) ) {
|
1614 |
+
$control_args['load_all_weights'] = $field_config['load_all_weights'];
|
1615 |
+
}
|
1616 |
+
|
1617 |
+
if ( isset( $field_config['default'] ) ) {
|
1618 |
+
$control_args['default'] = $field_config['default'];
|
1619 |
+
}
|
1620 |
+
|
1621 |
+
if ( isset( $field_config['fields'] ) ) {
|
1622 |
+
$control_args['fields'] = $field_config['fields'];
|
1623 |
+
}
|
1624 |
+
$control_args['live'] = true;
|
1625 |
+
|
1626 |
+
break;
|
1627 |
+
|
1628 |
+
case 'select2' :
|
1629 |
+
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
|
1630 |
+
return;
|
1631 |
+
}
|
1632 |
+
|
1633 |
+
$control_args['choices'] = $field_config['choices'];
|
1634 |
+
|
1635 |
+
$control_class_name = 'Pix_Customize_Select2_Control';
|
1636 |
+
break;
|
1637 |
+
|
1638 |
+
case 'sm_radio' :
|
1639 |
+
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
|
1640 |
+
return;
|
1641 |
+
}
|
1642 |
+
|
1643 |
+
$control_args['choices'] = $field_config['choices'];
|
1644 |
+
|
1645 |
+
$control_class_name = 'Pix_Customize_SM_radio_Control';
|
1646 |
+
break;
|
1647 |
+
|
1648 |
+
case 'sm_palette_filter' :
|
1649 |
+
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
|
1650 |
+
return;
|
1651 |
+
}
|
1652 |
+
|
1653 |
+
$control_args['choices'] = $field_config['choices'];
|
1654 |
+
|
1655 |
+
$control_class_name = 'Pix_Customize_SM_palette_filter_Control';
|
1656 |
+
break;
|
1657 |
+
|
1658 |
+
case 'sm_switch' :
|
1659 |
+
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
|
1660 |
+
return;
|
1661 |
+
}
|
1662 |
+
|
1663 |
+
$control_args['choices'] = $field_config['choices'];
|
1664 |
+
|
1665 |
+
$control_class_name = 'Pix_Customize_SM_switch_Control';
|
1666 |
+
break;
|
1667 |
+
|
1668 |
+
case 'preset' :
|
1669 |
+
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
|
1670 |
+
return;
|
1671 |
+
}
|
1672 |
+
|
1673 |
+
$control_args['choices'] = $field_config['choices'];
|
1674 |
+
|
1675 |
+
if ( isset( $field_config['choices_type'] ) || ! empty( $field_config['choices_type'] ) ) {
|
1676 |
+
$control_args['choices_type'] = $field_config['choices_type'];
|
1677 |
+
}
|
1678 |
+
|
1679 |
+
if ( isset( $field_config['desc'] ) || ! empty( $field_config['desc'] ) ) {
|
1680 |
+
$control_args['description'] = $field_config['desc'];
|
1681 |
+
}
|
1682 |
+
|
1683 |
+
|
1684 |
+
$control_class_name = 'Pix_Customize_Preset_Control';
|
1685 |
+
break;
|
1686 |
+
|
1687 |
+
case 'radio_image' :
|
1688 |
+
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
|
1689 |
+
return;
|
1690 |
+
}
|
1691 |
+
|
1692 |
+
$control_args['choices'] = $field_config['choices'];
|
1693 |
+
|
1694 |
+
if ( isset( $field_config['choices_type'] ) || ! empty( $field_config['choices_type'] ) ) {
|
1695 |
+
$control_args['choices_type'] = $field_config['choices_type'];
|
1696 |
+
}
|
1697 |
+
|
1698 |
+
if ( isset( $field_config['desc'] ) || ! empty( $field_config['desc'] ) ) {
|
1699 |
+
$control_args['description'] = $field_config['desc'];
|
1700 |
+
}
|
1701 |
+
|
1702 |
+
|
1703 |
+
$control_class_name = 'Pix_Customize_Radio_Image_Control';
|
1704 |
+
break;
|
1705 |
+
|
1706 |
+
case 'button' :
|
1707 |
+
if ( ! isset( $field_config['action'] ) || empty( $field_config['action'] ) ) {
|
1708 |
+
return;
|
1709 |
+
}
|
1710 |
+
|
1711 |
+
$control_args['action'] = $field_config['action'];
|
1712 |
+
|
1713 |
+
$control_class_name = 'Pix_Customize_Button_Control';
|
1714 |
+
|
1715 |
+
break;
|
1716 |
+
|
1717 |
+
case 'html' :
|
1718 |
+
if ( isset( $field_config['html'] ) || ! empty( $field_config['html'] ) ) {
|
1719 |
+
$control_args['html'] = $field_config['html'];
|
1720 |
+
}
|
1721 |
+
|
1722 |
+
$control_class_name = 'Pix_Customize_HTML_Control';
|
1723 |
+
break;
|
1724 |
+
|
1725 |
+
case 'import_demo_data' :
|
1726 |
+
if ( isset( $field_config['html'] ) || ! empty( $field_config['html'] ) ) {
|
1727 |
+
$control_args['html'] = $field_config['html'];
|
1728 |
+
}
|
1729 |
+
|
1730 |
+
if ( ! isset( $field_config['label'] ) || empty( $field_config['label'] ) ) {
|
1731 |
+
$control_args['label'] = esc_html__( 'Import', 'customify' );
|
1732 |
+
} else {
|
1733 |
+
$control_args['label'] = $field_config['label'];
|
1734 |
+
}
|
1735 |
+
|
1736 |
+
if ( isset( $field_config['notices'] ) && ! empty( $field_config['notices'] ) ) {
|
1737 |
+
$control_args['notices'] = $field_config['notices'];
|
1738 |
+
}
|
1739 |
+
|
1740 |
+
$control_class_name = 'Pix_Customize_Import_Demo_Data_Control';
|
1741 |
+
break;
|
1742 |
+
|
1743 |
+
default:
|
1744 |
+
// if we don't have a real control just quit, it doesn't even matter
|
1745 |
+
return;
|
1746 |
+
break;
|
1747 |
+
}
|
1748 |
+
|
1749 |
+
$this_control = new $control_class_name(
|
1750 |
+
$wp_customize,
|
1751 |
+
$setting_id . '_control',
|
1752 |
+
$control_args
|
1753 |
+
);
|
1754 |
+
|
1755 |
+
if ( $add_control ) {
|
1756 |
+
$wp_customize->add_control( $this_control );
|
1757 |
+
}
|
1758 |
+
}
|
1759 |
+
|
1760 |
+
/**
|
1761 |
+
* Remove the sections selected by user
|
1762 |
+
*
|
1763 |
+
* @param WP_Customize_Manager $wp_customize
|
1764 |
+
*/
|
1765 |
+
function remove_default_sections( $wp_customize ) {
|
1766 |
+
global $wp_registered_sidebars;
|
1767 |
+
|
1768 |
+
$to_remove = PixCustomifyPlugin()->settings->get_plugin_setting( 'disable_default_sections' );
|
1769 |
+
|
1770 |
+
if ( ! empty( $to_remove ) ) {
|
1771 |
+
foreach ( $to_remove as $section => $nothing ) {
|
1772 |
+
|
1773 |
+
if ( $section === 'widgets' ) {
|
1774 |
+
foreach ( $wp_registered_sidebars as $widget => $settings ) {
|
1775 |
+
$wp_customize->remove_section( 'sidebar-widgets-' . $widget );
|
1776 |
+
}
|
1777 |
+
continue;
|
1778 |
+
}
|
1779 |
+
|
1780 |
+
$wp_customize->remove_section( $section );
|
1781 |
+
}
|
1782 |
+
}
|
1783 |
+
}
|
1784 |
+
|
1785 |
+
/**
|
1786 |
+
* Print JavaScript for adding additional data to _wpCustomizeSettings.settings object of the main window (not the preview window).
|
1787 |
+
*/
|
1788 |
+
public function customize_pane_settings_additional_data() {
|
1789 |
+
/**
|
1790 |
+
* @global WP_Customize_Manager $wp_customize
|
1791 |
+
*/
|
1792 |
+
global $wp_customize;
|
1793 |
+
|
1794 |
+
$options_name = PixCustomifyPlugin()->get_options_key();
|
1795 |
+
// Without an options name we can't do much.
|
1796 |
+
if ( empty( $options_name ) ) {
|
1797 |
+
return;
|
1798 |
+
}
|
1799 |
+
|
1800 |
+
$customizer_settings = $wp_customize->settings();
|
1801 |
+
?>
|
1802 |
+
<script type="text/javascript">
|
1803 |
+
if ( 'undefined' === typeof _wpCustomizeSettings.settings ) {
|
1804 |
+
_wpCustomizeSettings.settings = {};
|
1805 |
+
}
|
1806 |
+
|
1807 |
+
<?php
|
1808 |
+
echo "(function ( sAdditional ){\n";
|
1809 |
+
|
1810 |
+
$options = PixCustomifyPlugin()->get_options_details();
|
1811 |
+
foreach ( $options as $option_id => $option_config ) {
|
1812 |
+
// If we have been explicitly given a setting ID we will use that
|
1813 |
+
if ( ! empty( $option_config['setting_id'] ) ) {
|
1814 |
+
$setting_id = $option_config['setting_id'];
|
1815 |
+
} else {
|
1816 |
+
$setting_id = $options_name . '[' . $option_id . ']';
|
1817 |
+
}
|
1818 |
+
// @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()
|
1819 |
+
if ( ! empty( $customizer_settings[ $setting_id ] ) && ! empty( $option_config['connected_fields'] ) ) {
|
1820 |
+
// Pass through all the connected fields and make sure the id is in the final format
|
1821 |
+
$connected_fields = array();
|
1822 |
+
foreach ( $option_config['connected_fields'] as $key => $connected_field_config ) {
|
1823 |
+
$connected_field_data = array();
|
1824 |
+
|
1825 |
+
if ( is_string( $connected_field_config ) ) {
|
1826 |
+
$connected_field_id = $connected_field_config;
|
1827 |
+
} elseif ( is_array( $connected_field_config ) ) {
|
1828 |
+
// We have a full blown connected field config
|
1829 |
+
if ( is_string( $key ) ) {
|
1830 |
+
$connected_field_id = $key;
|
1831 |
+
} else {
|
1832 |
+
continue;
|
1833 |
+
}
|
1834 |
+
|
1835 |
+
// We will pass to JS all the configured connected field details.
|
1836 |
+
$connected_field_data = $connected_field_config;
|
1837 |
+
}
|
1838 |
+
|
1839 |
+
// Continue if we don't have a connected field ID to work with.
|
1840 |
+
if ( empty( $connected_field_id ) ) {
|
1841 |
+
continue;
|
1842 |
+
}
|
1843 |
+
|
1844 |
+
// If the connected setting is not one of our's, we will use it's ID as it is.
|
1845 |
+
if ( ! array_key_exists( $connected_field_id, $options ) ) {
|
1846 |
+
$connected_field_data['setting_id'] = $connected_field_id;
|
1847 |
+
}
|
1848 |
+
// If the connected setting specifies a setting ID, we will not prefix it and use it as it is.
|
1849 |
+
elseif ( ! empty( $options[ $connected_field_id ] ) && ! empty( $options[ $connected_field_id ]['setting_id'] ) ) {
|
1850 |
+
$connected_field_data['setting_id'] = $options[ $connected_field_id ]['setting_id'];
|
1851 |
+
} else {
|
1852 |
+
$connected_field_data['setting_id'] = $options_name . '[' . $connected_field_id . ']';
|
1853 |
+
}
|
1854 |
+
|
1855 |
+
$connected_fields[] = $connected_field_data;
|
1856 |
+
}
|
1857 |
+
|
1858 |
+
printf(
|
1859 |
+
"sAdditional[%s].%s = %s;\n",
|
1860 |
+
wp_json_encode( $setting_id ),
|
1861 |
+
'connected_fields',
|
1862 |
+
wp_json_encode( $connected_fields, JSON_FORCE_OBJECT )
|
1863 |
+
);
|
1864 |
+
}
|
1865 |
+
}
|
1866 |
+
echo "})( _wpCustomizeSettings.settings );\n";
|
1867 |
+
?>
|
1868 |
+
</script>
|
1869 |
+
<?php
|
1870 |
+
}
|
1871 |
+
|
1872 |
+
public function get_typography_fields( $fields_config, $key, $value, &$results, $input_key = 0 ) {
|
1873 |
+
if ( ! is_array( $fields_config ) ) {
|
1874 |
+
return;
|
1875 |
+
}
|
1876 |
+
|
1877 |
+
if ( isset( $fields_config[ $key ] ) && $fields_config[ $key ] == $value ) {
|
1878 |
+
$results[ $input_key ] = $fields_config;
|
1879 |
+
|
1880 |
+
$default = null;
|
1881 |
+
|
1882 |
+
if ( isset( $fields_config['default'] ) && is_array( $fields_config['default'] ) ) {
|
1883 |
+
$default = json_encode( $fields_config['default'] );
|
1884 |
+
}
|
1885 |
+
|
1886 |
+
$results[ $input_key ]['value'] = PixCustomifyPlugin()->get_option( $input_key, $default );
|
1887 |
+
}
|
1888 |
+
|
1889 |
+
foreach ( $fields_config as $i => $subarray ) {
|
1890 |
+
$this->get_typography_fields( $subarray, $key, $value, $results, $i );
|
1891 |
+
}
|
1892 |
+
}
|
1893 |
+
|
1894 |
+
/**
|
1895 |
+
* Sanitize functions
|
1896 |
+
*/
|
1897 |
+
|
1898 |
+
/**
|
1899 |
+
* Sanitize the checkbox.
|
1900 |
+
*
|
1901 |
+
* @param boolean $input .
|
1902 |
+
*
|
1903 |
+
* @return boolean true if is 1 or '1', false if anything else
|
1904 |
+
*/
|
1905 |
+
function setting_sanitize_checkbox( $input ) {
|
1906 |
+
if ( 1 == $input ) {
|
1907 |
+
return true;
|
1908 |
+
} else {
|
1909 |
+
return false;
|
1910 |
+
}
|
1911 |
+
}
|
1912 |
+
|
1913 |
+
/**
|
1914 |
+
* Main Customify_Customizer Instance
|
1915 |
+
*
|
1916 |
+
* Ensures only one instance of Customify_Customizer is loaded or can be loaded.
|
1917 |
+
*
|
1918 |
+
* @since 2.4.0
|
1919 |
+
* @static
|
1920 |
+
*
|
1921 |
+
* @return Customify_Customizer Main Customify_Customizer instance
|
1922 |
+
*/
|
1923 |
+
public static function instance() {
|
1924 |
+
|
1925 |
+
if ( is_null( self::$_instance ) ) {
|
1926 |
+
self::$_instance = new self();
|
1927 |
+
}
|
1928 |
+
|
1929 |
+
return self::$_instance;
|
1930 |
+
} // End instance ()
|
1931 |
+
|
1932 |
+
/**
|
1933 |
+
* Cloning is forbidden.
|
1934 |
+
*
|
1935 |
+
* @since 2.4.0
|
1936 |
+
*/
|
1937 |
+
public function __clone() {
|
1938 |
+
|
1939 |
+
_doing_it_wrong( __FUNCTION__,esc_html( __( 'Cheatin’ huh?' ) ), null );
|
1940 |
+
} // End __clone ()
|
1941 |
+
|
1942 |
+
/**
|
1943 |
+
* Unserializing instances of this class is forbidden.
|
1944 |
+
*
|
1945 |
+
* @since 2.4.0
|
1946 |
+
*/
|
1947 |
+
public function __wakeup() {
|
1948 |
+
|
1949 |
+
_doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin’ huh?' ) ), null );
|
1950 |
+
} // End __wakeup ()
|
1951 |
+
}
|
1952 |
+
|
1953 |
+
endif;
|
includes/class-customify-gutenberg.php
CHANGED
@@ -124,7 +124,7 @@ class Customify_Gutenberg {
|
|
124 |
// Styles on the front end.
|
125 |
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_styles' ), 999 );
|
126 |
|
127 |
-
add_action( '
|
128 |
}
|
129 |
|
130 |
/**
|
@@ -215,19 +215,20 @@ class Customify_Gutenberg {
|
|
215 |
public function dynamic_styles() {
|
216 |
$enqueue_parent_handle = $this->get_editor_style_handle();
|
217 |
|
218 |
-
if ( PixCustomifyPlugin()->get_plugin_setting( 'enable_editor_style', true ) ) {
|
219 |
add_filter( 'customify_typography_css_selector', array( $this, 'gutenbergify_font_css_selectors' ), 10, 2 );
|
220 |
-
wp_add_inline_script( 'wp-editor', PixCustomifyPlugin()->get_typography_dynamic_script() );
|
221 |
-
wp_add_inline_style( $enqueue_parent_handle, PixCustomifyPlugin()->get_typography_dynamic_style() );
|
222 |
remove_filter( 'customify_typography_css_selector', array( $this, 'gutenbergify_font_css_selectors' ), 10 );
|
223 |
|
224 |
add_filter( 'customify_font_css_selector', array( $this, 'gutenbergify_font_css_selectors' ), 10, 2 );
|
|
|
225 |
wp_add_inline_script( 'wp-editor', Customify_Font_Selector::instance()->get_fonts_dynamic_script() );
|
226 |
wp_add_inline_style( $enqueue_parent_handle, Customify_Font_Selector::instance()->get_fonts_dynamic_style() );
|
227 |
remove_filter( 'customify_font_css_selector', array( $this, 'gutenbergify_font_css_selectors' ), 10 );
|
228 |
|
229 |
add_filter( 'customify_css_selector', array( $this, 'gutenbergify_css_selectors' ), 10, 2 );
|
230 |
-
wp_add_inline_style( $enqueue_parent_handle, PixCustomifyPlugin()->get_dynamic_style() );
|
231 |
remove_filter( 'customify_css_selector', array( $this, 'gutenbergify_css_selectors' ), 10 );
|
232 |
|
233 |
// Add color palettes classes.
|
@@ -298,7 +299,7 @@ class Customify_Gutenberg {
|
|
298 |
return implode( ', ', $new_selectors );
|
299 |
}
|
300 |
|
301 |
-
public function gutenbergify_font_css_selectors( $selectors
|
302 |
|
303 |
// Treat the selector(s) as an array.
|
304 |
$selectors = $this->maybeExplodeSelectors( $selectors );
|
@@ -395,7 +396,7 @@ class Customify_Gutenberg {
|
|
395 |
return;
|
396 |
}
|
397 |
|
398 |
-
$
|
399 |
|
400 |
$master_color_control_ids = Customify_Color_Palettes::instance()->get_all_master_color_controls_ids();
|
401 |
if ( empty( $master_color_control_ids ) ) {
|
@@ -404,7 +405,7 @@ class Customify_Gutenberg {
|
|
404 |
|
405 |
$editor_color_palettes = array();
|
406 |
foreach ( $master_color_control_ids as $control_id ) {
|
407 |
-
if ( empty( $
|
408 |
continue;
|
409 |
}
|
410 |
|
@@ -414,7 +415,7 @@ class Customify_Gutenberg {
|
|
414 |
}
|
415 |
|
416 |
$editor_color_palettes[] = array(
|
417 |
-
'name' => $
|
418 |
'slug' => $control_id,
|
419 |
'color' => esc_html( $value ),
|
420 |
);
|
@@ -442,7 +443,7 @@ class Customify_Gutenberg {
|
|
442 |
return '';
|
443 |
}
|
444 |
|
445 |
-
$
|
446 |
|
447 |
$master_color_control_ids = Customify_Color_Palettes::instance()->get_all_master_color_controls_ids();
|
448 |
if ( empty( $master_color_control_ids ) ) {
|
@@ -452,7 +453,7 @@ class Customify_Gutenberg {
|
|
452 |
// Build styles.
|
453 |
$css = '';
|
454 |
foreach ( $master_color_control_ids as $control_id ) {
|
455 |
-
if ( empty( $
|
456 |
continue;
|
457 |
}
|
458 |
|
@@ -462,7 +463,7 @@ class Customify_Gutenberg {
|
|
462 |
}
|
463 |
|
464 |
$editor_color_palettes[] = array(
|
465 |
-
'name' => $
|
466 |
'slug' => $control_id,
|
467 |
'color' => esc_html( $value ),
|
468 |
);
|
124 |
// Styles on the front end.
|
125 |
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_styles' ), 999 );
|
126 |
|
127 |
+
add_action( 'admin_init', array( $this, 'editor_color_palettes' ), 20 );
|
128 |
}
|
129 |
|
130 |
/**
|
215 |
public function dynamic_styles() {
|
216 |
$enqueue_parent_handle = $this->get_editor_style_handle();
|
217 |
|
218 |
+
if ( PixCustomifyPlugin()->settings->get_plugin_setting( 'enable_editor_style', true ) ) {
|
219 |
add_filter( 'customify_typography_css_selector', array( $this, 'gutenbergify_font_css_selectors' ), 10, 2 );
|
220 |
+
wp_add_inline_script( 'wp-editor', PixCustomifyPlugin()->customizer->get_typography_dynamic_script() );
|
221 |
+
wp_add_inline_style( $enqueue_parent_handle, PixCustomifyPlugin()->customizer->get_typography_dynamic_style() );
|
222 |
remove_filter( 'customify_typography_css_selector', array( $this, 'gutenbergify_font_css_selectors' ), 10 );
|
223 |
|
224 |
add_filter( 'customify_font_css_selector', array( $this, 'gutenbergify_font_css_selectors' ), 10, 2 );
|
225 |
+
require_once( PixCustomifyPlugin()->get_base_path() . 'features/class-Font_Selector.php' );
|
226 |
wp_add_inline_script( 'wp-editor', Customify_Font_Selector::instance()->get_fonts_dynamic_script() );
|
227 |
wp_add_inline_style( $enqueue_parent_handle, Customify_Font_Selector::instance()->get_fonts_dynamic_style() );
|
228 |
remove_filter( 'customify_font_css_selector', array( $this, 'gutenbergify_font_css_selectors' ), 10 );
|
229 |
|
230 |
add_filter( 'customify_css_selector', array( $this, 'gutenbergify_css_selectors' ), 10, 2 );
|
231 |
+
wp_add_inline_style( $enqueue_parent_handle, PixCustomifyPlugin()->customizer->get_dynamic_style() );
|
232 |
remove_filter( 'customify_css_selector', array( $this, 'gutenbergify_css_selectors' ), 10 );
|
233 |
|
234 |
// Add color palettes classes.
|
299 |
return implode( ', ', $new_selectors );
|
300 |
}
|
301 |
|
302 |
+
public function gutenbergify_font_css_selectors( $selectors ) {
|
303 |
|
304 |
// Treat the selector(s) as an array.
|
305 |
$selectors = $this->maybeExplodeSelectors( $selectors );
|
396 |
return;
|
397 |
}
|
398 |
|
399 |
+
$options_details = PixCustomifyPlugin()->get_options_configs();
|
400 |
|
401 |
$master_color_control_ids = Customify_Color_Palettes::instance()->get_all_master_color_controls_ids();
|
402 |
if ( empty( $master_color_control_ids ) ) {
|
405 |
|
406 |
$editor_color_palettes = array();
|
407 |
foreach ( $master_color_control_ids as $control_id ) {
|
408 |
+
if ( empty( $options_details[ $control_id ] ) ) {
|
409 |
continue;
|
410 |
}
|
411 |
|
415 |
}
|
416 |
|
417 |
$editor_color_palettes[] = array(
|
418 |
+
'name' => $options_details[ $control_id ]['label'],
|
419 |
'slug' => $control_id,
|
420 |
'color' => esc_html( $value ),
|
421 |
);
|
443 |
return '';
|
444 |
}
|
445 |
|
446 |
+
$options_details = PixCustomifyPlugin()->get_options_configs();
|
447 |
|
448 |
$master_color_control_ids = Customify_Color_Palettes::instance()->get_all_master_color_controls_ids();
|
449 |
if ( empty( $master_color_control_ids ) ) {
|
453 |
// Build styles.
|
454 |
$css = '';
|
455 |
foreach ( $master_color_control_ids as $control_id ) {
|
456 |
+
if ( empty( $options_details[ $control_id ] ) ) {
|
457 |
continue;
|
458 |
}
|
459 |
|
463 |
}
|
464 |
|
465 |
$editor_color_palettes[] = array(
|
466 |
+
'name' => $options_details[ $control_id ]['label'],
|
467 |
'slug' => $control_id,
|
468 |
'color' => esc_html( $value ),
|
469 |
);
|
includes/class-customify-settings.php
ADDED
@@ -0,0 +1,430 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This is the class that handles the plugin settings page.
|
4 |
+
*
|
5 |
+
* @see https://pixelgrade.com
|
6 |
+
* @author Pixelgrade
|
7 |
+
* @since 2.4.0
|
8 |
+
*/
|
9 |
+
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit; // Exit if accessed directly
|
12 |
+
}
|
13 |
+
|
14 |
+
class Customify_Settings {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Instance of this class.
|
18 |
+
* @var object
|
19 |
+
*/
|
20 |
+
protected static $_instance = null;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Slug of the plugin screen.
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
protected $plugin_screen_hook_suffix = null;
|
27 |
+
|
28 |
+
public $display_admin_menu = false;
|
29 |
+
|
30 |
+
public $plugin_settings;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* The main plugin file.
|
34 |
+
* @var string
|
35 |
+
* @access public
|
36 |
+
*/
|
37 |
+
public $file;
|
38 |
+
|
39 |
+
public $slug;
|
40 |
+
public $version;
|
41 |
+
|
42 |
+
private $plugin_config = array();
|
43 |
+
|
44 |
+
protected function __construct( $file, $slug, $version = '1.0.0' ) {
|
45 |
+
$this->file = $file;
|
46 |
+
$this->slug = $slug;
|
47 |
+
$this->version = $version;
|
48 |
+
|
49 |
+
require plugin_dir_path( $this->file ) . 'includes/admin-settings/core/bootstrap.php';
|
50 |
+
|
51 |
+
// Load the config file
|
52 |
+
$this->plugin_config = self::get_plugin_config();
|
53 |
+
// Load the plugin's settings from the DB
|
54 |
+
$this->plugin_settings = get_option( $this->plugin_config['settings-key'] );
|
55 |
+
|
56 |
+
// Register all the needed hooks
|
57 |
+
$this->register_hooks();
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Register our actions and filters
|
62 |
+
*/
|
63 |
+
function register_hooks() {
|
64 |
+
|
65 |
+
// Starting with the menu item for this plugin
|
66 |
+
add_action( 'admin_menu', array( $this, 'add_plugin_admin_menu' ) );
|
67 |
+
|
68 |
+
// Add an action link pointing to the options page.
|
69 |
+
add_filter( 'plugin_action_links_' . plugin_basename( $this->file ), array( $this, 'add_action_links' ) );
|
70 |
+
|
71 |
+
// Load admin stylesheet and JavaScript.
|
72 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
|
73 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
74 |
+
|
75 |
+
|
76 |
+
add_action( 'rest_api_init', array( $this, 'add_rest_routes_api' ) );
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Register the administration menu for this plugin into the WordPress Dashboard menu.
|
81 |
+
*/
|
82 |
+
function add_plugin_admin_menu() {
|
83 |
+
$this->plugin_screen_hook_suffix = add_options_page( esc_html__( 'Customify', 'customify' ), esc_html__( 'Customify', 'customify' ), 'edit_plugins', $this->slug, array(
|
84 |
+
$this,
|
85 |
+
'display_plugin_admin_page'
|
86 |
+
) );
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Render the settings page for this plugin.
|
91 |
+
*/
|
92 |
+
function display_plugin_admin_page() {
|
93 |
+
include_once plugin_dir_path( $this->file ) . 'includes/admin-settings/views/admin.php';
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Settings page styles
|
98 |
+
*/
|
99 |
+
function enqueue_admin_styles() {
|
100 |
+
|
101 |
+
if ( ! isset( $this->plugin_screen_hook_suffix ) ) {
|
102 |
+
return;
|
103 |
+
}
|
104 |
+
|
105 |
+
$screen = get_current_screen();
|
106 |
+
if ( $screen->id === $this->plugin_screen_hook_suffix ) {
|
107 |
+
wp_enqueue_style( $this->slug . '-admin-styles', plugins_url( 'css/admin.css', $this->file ), array(), $this->version );
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Settings page scripts
|
113 |
+
*/
|
114 |
+
function enqueue_admin_scripts() {
|
115 |
+
|
116 |
+
if ( ! isset( $this->plugin_screen_hook_suffix ) ) {
|
117 |
+
return;
|
118 |
+
}
|
119 |
+
|
120 |
+
$screen = get_current_screen();
|
121 |
+
if ( $screen->id == $this->plugin_screen_hook_suffix ) {
|
122 |
+
wp_enqueue_script( $this->slug . '-admin-script', plugins_url( 'js/admin.js', $this->file ), array( 'jquery' ), $this->version );
|
123 |
+
wp_localize_script( $this->slug . '-admin-script', 'customify_settings', array(
|
124 |
+
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
125 |
+
'wp_rest' => array(
|
126 |
+
'root' => esc_url_raw( rest_url() ),
|
127 |
+
'nonce' => wp_create_nonce( 'wp_rest' ),
|
128 |
+
'customify_settings_nonce' => wp_create_nonce( 'customify_settings_nonce' )
|
129 |
+
),
|
130 |
+
) );
|
131 |
+
}
|
132 |
+
|
133 |
+
wp_localize_script( $this->slug . '-customizer-scripts', 'WP_API_Settings', array(
|
134 |
+
'root' => esc_url_raw( rest_url() ),
|
135 |
+
'nonce' => wp_create_nonce( 'wp_rest' )
|
136 |
+
) );
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Add settings action link to the plugins page.
|
141 |
+
*/
|
142 |
+
public function add_action_links( $links ) {
|
143 |
+
return array_merge( array( 'settings' => '<a href="' . esc_url( menu_page_url( $this->slug, false ) ) . '">' . esc_html__( 'Settings', 'customify' ) . '</a>' ), $links );
|
144 |
+
}
|
145 |
+
|
146 |
+
public function add_rest_routes_api() {
|
147 |
+
register_rest_route( 'customify/v1', '/delete_theme_mod', array(
|
148 |
+
'methods' => 'POST',
|
149 |
+
'callback' => array( $this, 'delete_theme_mod' ),
|
150 |
+
'permission_callback' => array( $this, 'permission_nonce_callback' ),
|
151 |
+
) );
|
152 |
+
}
|
153 |
+
|
154 |
+
public function delete_theme_mod() {
|
155 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
156 |
+
wp_send_json_error( esc_html__('You don\'t have admin privileges.', 'customify' ) );
|
157 |
+
}
|
158 |
+
|
159 |
+
$key = PixCustomifyPlugin()->get_options_key();
|
160 |
+
|
161 |
+
if ( empty( $key ) ) {
|
162 |
+
wp_send_json_error('no option key');
|
163 |
+
}
|
164 |
+
|
165 |
+
remove_theme_mod( $key );
|
166 |
+
|
167 |
+
wp_send_json_success('Deleted ' . $key . ' theme mod!');
|
168 |
+
}
|
169 |
+
|
170 |
+
public function permission_nonce_callback() {
|
171 |
+
return wp_verify_nonce( $this->get_nonce(), 'customify_settings_nonce' );
|
172 |
+
}
|
173 |
+
|
174 |
+
private function get_nonce() {
|
175 |
+
$nonce = null;
|
176 |
+
|
177 |
+
if ( isset( $_REQUEST['customify_settings_nonce'] ) ) {
|
178 |
+
$nonce = wp_unslash( $_REQUEST['customify_settings_nonce'] );
|
179 |
+
} elseif ( isset( $_POST['customify_settings_nonce'] ) ) {
|
180 |
+
$nonce = wp_unslash( $_POST['customify_settings_nonce'] );
|
181 |
+
}
|
182 |
+
|
183 |
+
return $nonce;
|
184 |
+
}
|
185 |
+
|
186 |
+
static public function get_plugin_config() {
|
187 |
+
|
188 |
+
$debug = false;
|
189 |
+
if ( isset( $_GET['debug'] ) && $_GET['debug'] === 'true' ) {
|
190 |
+
$debug = true;
|
191 |
+
}
|
192 |
+
|
193 |
+
return array(
|
194 |
+
'plugin-name' => 'pixcustomify',
|
195 |
+
'settings-key' => 'pixcustomify_settings',
|
196 |
+
'textdomain' => 'customify',
|
197 |
+
'template-paths' => array(
|
198 |
+
plugin_dir_path( __FILE__ ) . 'admin-settings/core/views/form-partials/',
|
199 |
+
plugin_dir_path( __FILE__ ) . 'admin-settings/views/form-partials/',
|
200 |
+
),
|
201 |
+
'fields' => array(
|
202 |
+
'hiddens' => array(
|
203 |
+
'type' => 'group',
|
204 |
+
'options' => array(
|
205 |
+
'settings_saved_once' => array(
|
206 |
+
'default' => '0',
|
207 |
+
'value' => '1',
|
208 |
+
'type' => 'hidden',
|
209 |
+
),
|
210 |
+
),
|
211 |
+
),
|
212 |
+
'general' => array(
|
213 |
+
'type' => 'postbox',
|
214 |
+
'label' => esc_html__( 'General Settings', 'customify' ),
|
215 |
+
'options' => array(
|
216 |
+
'values_store_mod' => array(
|
217 |
+
'name' => 'values_store_mod',
|
218 |
+
'label' => esc_html__( 'Store values as:', 'customify' ),
|
219 |
+
'desc' => esc_html__( 'You can store the values globally so you can use them with other themes or store them as a "theme_mod" which will make an individual set of options only for the current theme', 'customify' ),
|
220 |
+
'default' => 'option',
|
221 |
+
'type' => 'select',
|
222 |
+
'options' => array(
|
223 |
+
'option' => esc_html__( 'Option (global options)', 'customify' ),
|
224 |
+
'theme_mod' => esc_html__( 'Theme Mod (per theme options)', 'customify' ),
|
225 |
+
),
|
226 |
+
),
|
227 |
+
|
228 |
+
'disable_default_sections' => array(
|
229 |
+
'name' => 'disable_default_sections',
|
230 |
+
'label' => esc_html__( 'Disable default sections', 'customify' ),
|
231 |
+
'desc' => esc_html__( 'You can disable default sections', 'customify' ),
|
232 |
+
'type' => 'multicheckbox',
|
233 |
+
'options' => array(
|
234 |
+
'nav' => esc_html__( 'Navigation', 'customify' ),
|
235 |
+
'static_front_page' => esc_html__( 'Front Page', 'customify' ),
|
236 |
+
'title_tagline' => esc_html__( 'Title', 'customify' ),
|
237 |
+
'colors' => esc_html__( 'Colors', 'customify' ),
|
238 |
+
'background_image' => esc_html__( 'Background', 'customify' ),
|
239 |
+
'header_image' => esc_html__( 'Header', 'customify' ),
|
240 |
+
'widgets' => esc_html__( 'Widgets', 'customify' ),
|
241 |
+
),
|
242 |
+
),
|
243 |
+
|
244 |
+
'enable_reset_buttons' => array(
|
245 |
+
'name' => 'enable_reset_buttons',
|
246 |
+
'label' => esc_html__( 'Enable Reset Buttons', 'customify' ),
|
247 |
+
'desc' => esc_html__( 'You can enable "Reset to defaults" buttons for panels / sections or all settings. We have disabled this feature by default to avoid accidental resets. If you are sure that you need it please enable this.', 'customify' ),
|
248 |
+
'default' => false,
|
249 |
+
'type' => 'switch',
|
250 |
+
),
|
251 |
+
|
252 |
+
'enable_editor_style' => array(
|
253 |
+
'name' => 'enable_editor_style',
|
254 |
+
'label' => esc_html__( 'Enable Editor Style', 'customify' ),
|
255 |
+
'desc' => esc_html__( 'The styling added by Customify in front-end can be added in the WordPress editor too by enabling this option', 'customify' ),
|
256 |
+
'default' => true,
|
257 |
+
'type' => 'switch',
|
258 |
+
),
|
259 |
+
),
|
260 |
+
),
|
261 |
+
'output' => array(
|
262 |
+
'type' => 'postbox',
|
263 |
+
'label' => esc_html__( 'Output Settings', 'customify' ),
|
264 |
+
'options' => array(
|
265 |
+
'style_resources_location' => array(
|
266 |
+
'name' => 'style_resources_location',
|
267 |
+
'label' => esc_html__( 'Styles location:', 'customify' ),
|
268 |
+
'desc' => esc_html__( 'Here you can decide where to put your style output, in header or footer', 'customify' ),
|
269 |
+
'default' => 'wp_footer',
|
270 |
+
'type' => 'select',
|
271 |
+
'options' => array(
|
272 |
+
'wp_head' => esc_html__( 'In header (just before the head tag)', 'customify' ),
|
273 |
+
'wp_footer' => esc_html__( 'Footer (just before the end of the body tag)', 'customify' ),
|
274 |
+
),
|
275 |
+
),
|
276 |
+
),
|
277 |
+
),
|
278 |
+
'typography' => array(
|
279 |
+
'type' => 'postbox',
|
280 |
+
'label' => esc_html__( 'Typography Settings', 'customify' ),
|
281 |
+
'options' => array(
|
282 |
+
'typography' => array(
|
283 |
+
'label' => esc_html__( 'Enable Typography Options', 'customify' ),
|
284 |
+
'default' => true,
|
285 |
+
'type' => 'switch',
|
286 |
+
'show_group' => 'typography_group',
|
287 |
+
'display_option' => true,
|
288 |
+
),
|
289 |
+
|
290 |
+
'typography_group' => array(
|
291 |
+
'type' => 'group',
|
292 |
+
'options' => array(
|
293 |
+
'typography_standard_fonts' => array(
|
294 |
+
'name' => 'typography_standard_fonts',
|
295 |
+
'label' => esc_html__( 'Use Standard fonts:', 'customify' ),
|
296 |
+
'desc' => esc_html__( 'Would you like them?', 'customify' ),
|
297 |
+
'default' => true,
|
298 |
+
'type' => 'switch',
|
299 |
+
),
|
300 |
+
'typography_google_fonts' => array(
|
301 |
+
'name' => 'typography_google_fonts',
|
302 |
+
'label' => esc_html__( 'Use Google fonts:', 'customify' ),
|
303 |
+
'desc' => esc_html__( 'Would you like them?', 'customify' ),
|
304 |
+
'default' => true,
|
305 |
+
'type' => 'switch',
|
306 |
+
'show_group' => 'typography_google_fonts_group',
|
307 |
+
'display_option' => true,
|
308 |
+
),
|
309 |
+
'typography_google_fonts_group' => array(
|
310 |
+
'type' => 'group',
|
311 |
+
'options' => array(
|
312 |
+
'typography_group_google_fonts' => array(
|
313 |
+
'name' => 'typography_standard_fonts',
|
314 |
+
'label' => esc_html__( 'Group Google fonts:', 'customify' ),
|
315 |
+
'desc' => esc_html__( 'You can chose to see the google fonts in groups', 'customify' ),
|
316 |
+
'default' => true,
|
317 |
+
'type' => 'switch',
|
318 |
+
),
|
319 |
+
),
|
320 |
+
),
|
321 |
+
),
|
322 |
+
),
|
323 |
+
),
|
324 |
+
),
|
325 |
+
'tools' => array(
|
326 |
+
'type' => 'postbox',
|
327 |
+
'label' => esc_html__( 'Tools', 'customify' ),
|
328 |
+
'options' => array(
|
329 |
+
'reset_theme_mod' => array(
|
330 |
+
'name' => 'reset_theme_mod',
|
331 |
+
'label' => esc_html__( 'Reset', 'customify' ),
|
332 |
+
'type' => 'reset_theme_mod',
|
333 |
+
),
|
334 |
+
),
|
335 |
+
),
|
336 |
+
),
|
337 |
+
'processor' => array(
|
338 |
+
// callback signature: (array $input, customifyProcessor $processor)
|
339 |
+
'preupdate' => array(
|
340 |
+
// callbacks to run before update process
|
341 |
+
// cleanup and validation has been performed on data
|
342 |
+
),
|
343 |
+
),
|
344 |
+
'cleanup' => array(
|
345 |
+
'switch' => array( 'switch_not_available' ),
|
346 |
+
),
|
347 |
+
'checks' => array(
|
348 |
+
'counter' => array( 'is_numeric', 'not_empty' ),
|
349 |
+
),
|
350 |
+
'errors' => array(
|
351 |
+
'not_empty' => __( 'Invalid Value.', 'customify' ),
|
352 |
+
),
|
353 |
+
// shows exception traces on error
|
354 |
+
'debug' => $debug,
|
355 |
+
|
356 |
+
); # config
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Get an option's value from the config file
|
361 |
+
*
|
362 |
+
* @param $option
|
363 |
+
* @param null $default
|
364 |
+
*
|
365 |
+
* @return bool|null
|
366 |
+
*/
|
367 |
+
public function get_config_option( $option, $default = null ) {
|
368 |
+
|
369 |
+
if ( isset( $this->plugin_config[ $option ] ) ) {
|
370 |
+
return $this->plugin_config[ $option ];
|
371 |
+
} elseif ( $default !== null ) {
|
372 |
+
return $default;
|
373 |
+
}
|
374 |
+
|
375 |
+
return false;
|
376 |
+
}
|
377 |
+
|
378 |
+
public function get_plugin_setting( $option, $default = null ) {
|
379 |
+
|
380 |
+
if ( isset( $this->plugin_settings[ $option ] ) ) {
|
381 |
+
return $this->plugin_settings[ $option ];
|
382 |
+
} elseif ( $default !== null ) {
|
383 |
+
return $default;
|
384 |
+
}
|
385 |
+
|
386 |
+
return false;
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* Main Customify_Settings Instance
|
391 |
+
*
|
392 |
+
* Ensures only one instance of Customify_Settings is loaded or can be loaded.
|
393 |
+
*
|
394 |
+
* @static
|
395 |
+
*
|
396 |
+
* @param string $file File.
|
397 |
+
* @param string $slug Plugin slug.
|
398 |
+
* @param string $version Optional.
|
399 |
+
*
|
400 |
+
* @return Customify_Settings Main Customify_Settings instance
|
401 |
+
*/
|
402 |
+
public static function instance( $file, $slug, $version = '1.0.0' ) {
|
403 |
+
// If the single instance hasn't been set, set it now.
|
404 |
+
if ( is_null( self::$_instance ) ) {
|
405 |
+
self::$_instance = new self( $file, $slug, $version );
|
406 |
+
}
|
407 |
+
|
408 |
+
return self::$_instance;
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Cloning is forbidden.
|
413 |
+
*
|
414 |
+
* @since 1.5.0
|
415 |
+
*/
|
416 |
+
public function __clone() {
|
417 |
+
|
418 |
+
_doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin’ huh?' ) ), null );
|
419 |
+
} // End __clone ()
|
420 |
+
|
421 |
+
/**
|
422 |
+
* Unserializing instances of this class is forbidden.
|
423 |
+
*
|
424 |
+
* @since 1.5.0
|
425 |
+
*/
|
426 |
+
public function __wakeup() {
|
427 |
+
|
428 |
+
_doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin’ huh?' ) ), null );
|
429 |
+
} // End __wakeup ()
|
430 |
+
}
|
includes/class-pixcustomify.php
ADDED
@@ -0,0 +1,830 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* PixCustomify.
|
4 |
+
* @package PixCustomify
|
5 |
+
* @author Pixelgrade <contact@pixelgrade.com>
|
6 |
+
* @license GPL-2.0+
|
7 |
+
* @link https://pixelgrade.com
|
8 |
+
* @copyright 2014-2018 Pixelgrade
|
9 |
+
*/
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Plugin class.
|
13 |
+
* @package PixCustomify
|
14 |
+
* @author Pixelgrade <contact@pixelgrade.com>
|
15 |
+
*/
|
16 |
+
class PixCustomifyPlugin {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Plugin version, used for cache-busting of style and script file references.
|
20 |
+
* @since 1.5.0
|
21 |
+
* @const string
|
22 |
+
*/
|
23 |
+
protected $_version;
|
24 |
+
/**
|
25 |
+
* Unique identifier for your plugin.
|
26 |
+
* Use this value (not the variable name) as the text domain when internationalizing strings of text. It should
|
27 |
+
* match the Text Domain file header in the main plugin file.
|
28 |
+
* @since 1.0.0
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
protected $plugin_slug = 'customify';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Instance of this class.
|
35 |
+
* @since 1.5.0
|
36 |
+
* @var object
|
37 |
+
*/
|
38 |
+
protected static $_instance = null;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* The main plugin file.
|
42 |
+
* @var string
|
43 |
+
* @access public
|
44 |
+
* @since 1.5.0
|
45 |
+
*/
|
46 |
+
public $file;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Settings class object.
|
50 |
+
* @var Customify_Settings
|
51 |
+
* @access public
|
52 |
+
* @since 2.4.0
|
53 |
+
*/
|
54 |
+
public $settings = null;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Customizer class object.
|
58 |
+
* @var Customify_Customizer
|
59 |
+
* @access public
|
60 |
+
* @since 2.4.0
|
61 |
+
*/
|
62 |
+
public $customizer = null;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Style Manager class object.
|
66 |
+
* @var Customify_Style_Manager
|
67 |
+
* @access public
|
68 |
+
* @since 1.0.0
|
69 |
+
*/
|
70 |
+
public $style_manager = null;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Gutenberg class object.
|
74 |
+
* @var Customify_Gutenberg
|
75 |
+
* @access public
|
76 |
+
* @since 2.2.0
|
77 |
+
*/
|
78 |
+
public $gutenberg = null;
|
79 |
+
|
80 |
+
protected $options_minimal_details = array();
|
81 |
+
protected $options_details = array();
|
82 |
+
|
83 |
+
protected $opt_name;
|
84 |
+
|
85 |
+
protected $jetpack_default_modules = array();
|
86 |
+
protected $jetpack_blocked_modules = array();
|
87 |
+
protected $jetpack_sharing_default_options = array();
|
88 |
+
|
89 |
+
private $customizer_config = array();
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Minimal Required PHP Version
|
93 |
+
* @var string
|
94 |
+
* @access private
|
95 |
+
* @since 1.5.0
|
96 |
+
*/
|
97 |
+
private $minimalRequiredPhpVersion = '5.2';
|
98 |
+
|
99 |
+
protected function __construct( $file, $version = '1.0.0' ) {
|
100 |
+
//the main plugin file (the one that loads all this)
|
101 |
+
$this->file = $file;
|
102 |
+
//the current plugin version
|
103 |
+
$this->_version = $version;
|
104 |
+
|
105 |
+
if ( $this->php_version_check() ) {
|
106 |
+
// Only load and run the init function if we know PHP version can parse it.
|
107 |
+
$this->init();
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Initialize plugin
|
113 |
+
*/
|
114 |
+
private function init() {
|
115 |
+
// We don't want to put extra load on the heartbeat AJAX request.
|
116 |
+
if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && 'heartbeat' === $_REQUEST['action'] ) {
|
117 |
+
return;
|
118 |
+
}
|
119 |
+
|
120 |
+
// Handle the install and uninstall logic
|
121 |
+
register_activation_hook( $this->get_file(), array( 'PixCustomifyPlugin', 'install' ) );
|
122 |
+
|
123 |
+
/* Initialize the plugin settings logic. */
|
124 |
+
require_once( $this->get_base_path() . 'includes/class-customify-settings.php' );
|
125 |
+
if ( is_null( $this->settings ) ) {
|
126 |
+
$this->settings = Customify_Settings::instance( $this->get_file(), $this->get_slug(), $this->get_version() );
|
127 |
+
}
|
128 |
+
|
129 |
+
/* Initialize the Customizer logic. */
|
130 |
+
require_once( $this->get_base_path() . 'includes/class-customify-customizer.php' );
|
131 |
+
if ( is_null( $this->customizer ) ) {
|
132 |
+
$this->customizer = Customify_Customizer::instance();
|
133 |
+
}
|
134 |
+
|
135 |
+
/* Initialize the Style Manager logic. */
|
136 |
+
require_once( $this->get_base_path() . 'includes/class-customify-style-manager.php' );
|
137 |
+
if ( is_null( $this->style_manager ) ) {
|
138 |
+
$this->style_manager = Customify_Style_Manager::instance();
|
139 |
+
}
|
140 |
+
|
141 |
+
/* Initialize the Gutenberg logic. */
|
142 |
+
require_once( $this->get_base_path() . 'includes/class-customify-gutenberg.php' );
|
143 |
+
if ( is_null( $this->gutenberg ) ) {
|
144 |
+
$this->gutenberg = Customify_Gutenberg::instance();
|
145 |
+
}
|
146 |
+
|
147 |
+
// Register all the needed hooks
|
148 |
+
$this->register_hooks();
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Register our actions and filters
|
153 |
+
*/
|
154 |
+
function register_hooks() {
|
155 |
+
|
156 |
+
/*
|
157 |
+
* Load plugin text domain
|
158 |
+
*/
|
159 |
+
add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
|
160 |
+
|
161 |
+
/*
|
162 |
+
* Load the upgrade logic.
|
163 |
+
*/
|
164 |
+
add_action( 'admin_init', array( $this, 'upgrade' ) );
|
165 |
+
|
166 |
+
/*
|
167 |
+
* Handle the force clearing of the caches. We clear in a proactive manner.
|
168 |
+
*/
|
169 |
+
add_action( 'activated_plugin', array( $this, 'invalidate_customizer_config_cache' ), 1 );
|
170 |
+
add_action( 'activated_plugin', array( $this, 'invalidate_options_details_cache' ), 1 );
|
171 |
+
add_action( 'activated_plugin', array( $this, 'invalidate_customizer_opt_name_cache' ), 1 );
|
172 |
+
|
173 |
+
add_action( 'deactivated_plugin', array( $this, 'invalidate_customizer_config_cache' ), 1 );
|
174 |
+
add_action( 'deactivated_plugin', array( $this, 'invalidate_options_details_cache' ), 1 );
|
175 |
+
add_action( 'deactivated_plugin', array( $this, 'invalidate_customizer_opt_name_cache' ), 1 );
|
176 |
+
|
177 |
+
add_action( 'switch_theme', array( $this, 'invalidate_customizer_config_cache' ), 1 );
|
178 |
+
add_action( 'switch_theme', array( $this, 'invalidate_options_details_cache' ), 1 );
|
179 |
+
add_action( 'switch_theme', array( $this, 'invalidate_customizer_opt_name_cache' ), 1 );
|
180 |
+
|
181 |
+
add_action( 'upgrader_process_complete', array( $this, 'invalidate_customizer_config_cache' ), 1 );
|
182 |
+
add_action( 'upgrader_process_complete', array( $this, 'invalidate_options_details_cache' ), 1 );
|
183 |
+
add_action( 'upgrader_process_complete', array( $this, 'invalidate_customizer_opt_name_cache' ), 1 );
|
184 |
+
|
185 |
+
// Whenever we update data from the Customizer, we will invalidate the options details (that include the value).
|
186 |
+
add_filter( 'customize_changeset_save_data', array( $this, 'filter_invalidate_options_details_cache' ), 50, 1 );
|
187 |
+
|
188 |
+
// We also want to invalidate the cache whenever the Pixelgrade Care license is updated since it may unlock new features
|
189 |
+
// and so unlock new Customify options.
|
190 |
+
add_filter( 'pre_set_theme_mod_pixcare_license', array( $this, 'filter_invalidate_customizer_config_cache' ), 10, 1 );
|
191 |
+
add_filter( 'pre_set_theme_mod_pixcare_license', array( $this, 'filter_invalidate_options_details_cache' ), 10, 1 );
|
192 |
+
add_filter( 'pre_set_theme_mod_pixcare_license', array( $this, 'filter_invalidate_customizer_opt_name_cache' ), 10, 1 );
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Handle the logic to upgrade between versions. It will run only one per version change.
|
197 |
+
*/
|
198 |
+
public function upgrade() {
|
199 |
+
$customify_dbversion = get_option( 'customify_dbversion', '0.0.1' );
|
200 |
+
if ( $this->get_version() === $customify_dbversion ) {
|
201 |
+
return;
|
202 |
+
}
|
203 |
+
|
204 |
+
// For versions, previous of version 2.0.0 (the Color Palettes v2.0 release).
|
205 |
+
if ( version_compare( $customify_dbversion, '2.0.0', '<' ) ) {
|
206 |
+
// Delete the option holding the fact that the user offered feedback.
|
207 |
+
delete_option( 'style_manager_user_feedback_provided' );
|
208 |
+
}
|
209 |
+
|
210 |
+
// Put the current version in the database.
|
211 |
+
update_option( 'customify_dbversion', $this->get_version(), true );
|
212 |
+
}
|
213 |
+
|
214 |
+
public function get_options_key( $skip_cache = false ) {
|
215 |
+
if ( ! empty( $this->opt_name ) ) {
|
216 |
+
return $this->opt_name;
|
217 |
+
}
|
218 |
+
|
219 |
+
// First try and get the cached data
|
220 |
+
$data = get_option( $this->get_customizer_opt_name_cache_key() );
|
221 |
+
|
222 |
+
// Get the cache data expiration timestamp.
|
223 |
+
$expire_timestamp = get_option( $this->get_customizer_opt_name_cache_key() . '_timestamp' );
|
224 |
+
|
225 |
+
// The data isn't set, is expired or we were instructed to skip the cache; we need to regenerate the config.
|
226 |
+
if ( true === $skip_cache || false === $data || false === $expire_timestamp || $expire_timestamp < time() ) {
|
227 |
+
|
228 |
+
$data = $this->get_customizer_config( 'opt-name' );
|
229 |
+
|
230 |
+
// Cache the data in an option for 6 hours
|
231 |
+
update_option( $this->get_customizer_opt_name_cache_key() , $data, true );
|
232 |
+
update_option( $this->get_customizer_opt_name_cache_key() . '_timestamp' , time() + 6 * HOUR_IN_SECONDS, true );
|
233 |
+
}
|
234 |
+
|
235 |
+
$this->opt_name = $data;
|
236 |
+
return $data;
|
237 |
+
}
|
238 |
+
|
239 |
+
private function get_customizer_opt_name_cache_key() {
|
240 |
+
return 'customify_customizer_opt_name';
|
241 |
+
}
|
242 |
+
|
243 |
+
public function invalidate_customizer_opt_name_cache() {
|
244 |
+
update_option( $this->get_customizer_opt_name_cache_key() . '_timestamp' , time() - 24 * HOUR_IN_SECONDS, true );
|
245 |
+
}
|
246 |
+
|
247 |
+
public function filter_invalidate_customizer_opt_name_cache( $value ) {
|
248 |
+
$this->invalidate_customizer_opt_name_cache();
|
249 |
+
|
250 |
+
return $value;
|
251 |
+
}
|
252 |
+
|
253 |
+
|
254 |
+
public function get_options_details( $only_minimal_details = false, $skip_cache = false ) {
|
255 |
+
|
256 |
+
// If we already have the data, do as little as possible.
|
257 |
+
if ( true === $only_minimal_details && ! empty( $this->options_minimal_details ) ) {
|
258 |
+
return $this->options_minimal_details;
|
259 |
+
}
|
260 |
+
|
261 |
+
if ( ! empty( $this->options_details ) ) {
|
262 |
+
return $this->options_details;
|
263 |
+
}
|
264 |
+
|
265 |
+
// We will first look for cached data
|
266 |
+
|
267 |
+
// We don't force skip the cache for AJAX requests for performance reasons.
|
268 |
+
if ( defined('CUSTOMIFY_ALWAYS_GENERATE_CUSTOMIZER_CONFIG' )
|
269 |
+
&& true === CUSTOMIFY_ALWAYS_GENERATE_CUSTOMIZER_CONFIG ) {
|
270 |
+
$skip_cache = true;
|
271 |
+
}
|
272 |
+
|
273 |
+
$data = $this->options_minimal_details = get_option( $this->get_options_minimal_details_cache_key() );
|
274 |
+
if ( false !== $data && false === $only_minimal_details ) {
|
275 |
+
$extra_details_data = get_option( $this->get_options_extra_details_cache_key() );
|
276 |
+
if ( is_array( $extra_details_data ) ) {
|
277 |
+
$data = $this->options_details = Customify_Array::array_merge_recursive_distinct( $data, $extra_details_data );
|
278 |
+
} else {
|
279 |
+
// Something is wrong with the extra details and we need to regenerate.
|
280 |
+
$skip_cache = true;
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
+
// For performance reasons, we will use the cached data (even if stale)
|
285 |
+
// when a user is not logged in or a user without administrative capabilities is logged in.
|
286 |
+
if ( false !== $data && false === $skip_cache && ! current_user_can( 'manage_options' ) ) {
|
287 |
+
return $data;
|
288 |
+
}
|
289 |
+
|
290 |
+
// Get the cached data expiration timestamp.
|
291 |
+
$expire_timestamp = get_option( $this->get_options_details_cache_timestamp_key() );
|
292 |
+
|
293 |
+
// The data isn't set, is expired or we were instructed to skip the cache; we need to regenerate the config.
|
294 |
+
if ( true === $skip_cache || false === $data || false === $expire_timestamp || $expire_timestamp < time() ) {
|
295 |
+
$options_minimal_details = array();
|
296 |
+
$options_extra_details = array();
|
297 |
+
|
298 |
+
$minimal_detail_keys = array(
|
299 |
+
'type',
|
300 |
+
'setting_type',
|
301 |
+
'setting_id',
|
302 |
+
'default',
|
303 |
+
'css',
|
304 |
+
'output',
|
305 |
+
'value',
|
306 |
+
'load_all_weights',
|
307 |
+
'selector',
|
308 |
+
'callback',
|
309 |
+
'active_callback',
|
310 |
+
);
|
311 |
+
|
312 |
+
$customizer_config = $this->get_customizer_config();
|
313 |
+
|
314 |
+
if ( isset ( $customizer_config['panels'] ) ) {
|
315 |
+
foreach ( $customizer_config['panels'] as $pane_id => $panel_settings ) {
|
316 |
+
if ( isset( $panel_settings['sections'] ) ) {
|
317 |
+
foreach ( $panel_settings['sections'] as $section_id => $section_settings ) {
|
318 |
+
if ( isset( $section_settings['options'] ) ) {
|
319 |
+
foreach ( $section_settings['options'] as $option_id => $option_config ) {
|
320 |
+
if ( is_array( $option_config ) ) {
|
321 |
+
foreach ( $option_config as $key => $value ) {
|
322 |
+
if ( in_array( $key, $minimal_detail_keys ) ) {
|
323 |
+
$options_minimal_details[ $option_id ][ $key ] = $value;
|
324 |
+
} else {
|
325 |
+
$options_extra_details[ $option_id ][ $key ] = $value;
|
326 |
+
}
|
327 |
+
}
|
328 |
+
|
329 |
+
$options_minimal_details[ $option_id ]['value'] = $this->get_option( $option_id, null, $option_config );
|
330 |
+
}
|
331 |
+
}
|
332 |
+
}
|
333 |
+
}
|
334 |
+
}
|
335 |
+
}
|
336 |
+
}
|
337 |
+
|
338 |
+
if ( isset ( $customizer_config['sections'] ) ) {
|
339 |
+
foreach ( $customizer_config['sections'] as $section_id => $section_settings ) {
|
340 |
+
if ( isset( $section_settings['options'] ) ) {
|
341 |
+
foreach ( $section_settings['options'] as $option_id => $option_config ) {
|
342 |
+
if ( is_array( $option_config ) ) {
|
343 |
+
foreach ( $option_config as $key => $value ) {
|
344 |
+
if ( in_array( $key, $minimal_detail_keys ) ) {
|
345 |
+
$options_minimal_details[ $option_id ][ $key ] = $value;
|
346 |
+
} else {
|
347 |
+
$options_extra_details[ $option_id ][ $key ] = $value;
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
$options_minimal_details[ $option_id ]['value'] = $this->get_option( $option_id, null, $option_config );
|
352 |
+
}
|
353 |
+
}
|
354 |
+
}
|
355 |
+
}
|
356 |
+
}
|
357 |
+
|
358 |
+
// Cache the data for 6 hours
|
359 |
+
update_option( $this->get_options_minimal_details_cache_key() , $options_minimal_details, true );
|
360 |
+
update_option( $this->get_options_extra_details_cache_key() , $options_extra_details, false ); // we will not autoload extra details for performance reasons.
|
361 |
+
update_option( $this->get_options_details_cache_timestamp_key(), time() + 6 * HOUR_IN_SECONDS, true );
|
362 |
+
|
363 |
+
$data = $this->options_minimal_details = $options_minimal_details;
|
364 |
+
$this->options_details = Customify_Array::array_merge_recursive_distinct( $options_minimal_details, $options_extra_details );
|
365 |
+
if ( false === $only_minimal_details ) {
|
366 |
+
$data = $this->options_details;
|
367 |
+
}
|
368 |
+
}
|
369 |
+
|
370 |
+
return $data;
|
371 |
+
}
|
372 |
+
|
373 |
+
private function get_options_minimal_details_cache_key() {
|
374 |
+
return 'customify_options_minimal_details';
|
375 |
+
}
|
376 |
+
|
377 |
+
private function get_options_extra_details_cache_key() {
|
378 |
+
return 'customify_options_extra_details';
|
379 |
+
}
|
380 |
+
|
381 |
+
private function get_options_details_cache_timestamp_key() {
|
382 |
+
return 'customify_options_details_timestamp';
|
383 |
+
}
|
384 |
+
|
385 |
+
public function invalidate_options_details_cache() {
|
386 |
+
update_option( $this->get_options_details_cache_timestamp_key(), time() - 24 * HOUR_IN_SECONDS, true );
|
387 |
+
}
|
388 |
+
|
389 |
+
public function filter_invalidate_options_details_cache( $value ) {
|
390 |
+
$this->invalidate_options_details_cache();
|
391 |
+
|
392 |
+
return $value;
|
393 |
+
}
|
394 |
+
|
395 |
+
public function has_option( $option ) {
|
396 |
+
|
397 |
+
$options_details = $this->get_options_details(true);
|
398 |
+
if ( isset( $options_details[ $option ] ) ) {
|
399 |
+
return true;
|
400 |
+
}
|
401 |
+
|
402 |
+
return false;
|
403 |
+
}
|
404 |
+
|
405 |
+
public function get_customizer_config( $key = false ) {
|
406 |
+
$customizer_config = $this->load_customizer_config();
|
407 |
+
|
408 |
+
if ( false !== $key ) {
|
409 |
+
if ( is_array( $customizer_config ) && isset( $customizer_config[ $key ] ) ) {
|
410 |
+
return $customizer_config[ $key ];
|
411 |
+
}
|
412 |
+
|
413 |
+
return null;
|
414 |
+
}
|
415 |
+
|
416 |
+
return $customizer_config;
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Set the customizer configuration.
|
421 |
+
*
|
422 |
+
* @since 2.2.1
|
423 |
+
*
|
424 |
+
* @param bool $skip_cache Optional. Whether to use the cached config or generate a new one.
|
425 |
+
* @return array
|
426 |
+
*/
|
427 |
+
protected function load_customizer_config( $skip_cache = false ) {
|
428 |
+
if ( ! empty( $this->customizer_config ) && true !== $skip_cache ) {
|
429 |
+
return $this->customizer_config;
|
430 |
+
}
|
431 |
+
|
432 |
+
// First try and get the cached data
|
433 |
+
$data = get_option( $this->get_customizer_config_cache_key() );
|
434 |
+
|
435 |
+
// We don't force skip the cache for AJAX requests for performance reasons.
|
436 |
+
if ( ! wp_doing_ajax()
|
437 |
+
&& defined('CUSTOMIFY_ALWAYS_GENERATE_CUSTOMIZER_CONFIG' )
|
438 |
+
&& true === CUSTOMIFY_ALWAYS_GENERATE_CUSTOMIZER_CONFIG ) {
|
439 |
+
$skip_cache = true;
|
440 |
+
}
|
441 |
+
|
442 |
+
// For performance reasons, we will use the cached data (even if stale)
|
443 |
+
// when a user is not logged in or a user without administrative capabilities is logged in.
|
444 |
+
if ( false !== $data && false === $skip_cache && ! current_user_can( 'manage_options' ) ) {
|
445 |
+
$this->customizer_config = $data;
|
446 |
+
return $data;
|
447 |
+
}
|
448 |
+
|
449 |
+
// Get the cache data expiration timestamp.
|
450 |
+
$expire_timestamp = get_option( $this->get_customizer_config_cache_key() . '_timestamp' );
|
451 |
+
|
452 |
+
// The data isn't set, is expired or we were instructed to skip the cache; we need to regenerate the config.
|
453 |
+
if ( true === $skip_cache || false === $data || false === $expire_timestamp || $expire_timestamp < time() ) {
|
454 |
+
// Allow themes or other plugins to filter the config.
|
455 |
+
$data = apply_filters( 'customify_filter_fields', array() );
|
456 |
+
// We apply a second filter for those that wish to work with the final config and not rely on a a huge priority number.
|
457 |
+
$data = apply_filters( 'customify_final_config', $data );
|
458 |
+
|
459 |
+
// Cache the data in an option for 6 hours
|
460 |
+
update_option( $this->get_customizer_config_cache_key() , $data, false );
|
461 |
+
update_option( $this->get_customizer_config_cache_key() . '_timestamp' , time() + 6 * HOUR_IN_SECONDS, true );
|
462 |
+
}
|
463 |
+
|
464 |
+
$this->customizer_config = $data;
|
465 |
+
return $data;
|
466 |
+
}
|
467 |
+
|
468 |
+
private function get_customizer_config_cache_key() {
|
469 |
+
return 'customify_customizer_config';
|
470 |
+
}
|
471 |
+
|
472 |
+
public function invalidate_customizer_config_cache() {
|
473 |
+
update_option( $this->get_customizer_config_cache_key() . '_timestamp' , time() - 24 * HOUR_IN_SECONDS, true );
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Invalidate the customizer config cache, when hooked via a filter.
|
478 |
+
*
|
479 |
+
* @since 2.4.0
|
480 |
+
*
|
481 |
+
* @param mixed $value
|
482 |
+
* @return mixed
|
483 |
+
*/
|
484 |
+
public function filter_invalidate_customizer_config_cache( $value ) {
|
485 |
+
$this->invalidate_customizer_config_cache();
|
486 |
+
|
487 |
+
return $value;
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* Get the Customify configuration (and value, hence "details") of a certain option.
|
492 |
+
*
|
493 |
+
* @param string $option_id
|
494 |
+
* @param bool $minimal_details Optional. Whether to return only the minimum amount of details (mainly what is needed on the frontend).
|
495 |
+
* The advantage is that these details are cached, thus skipping the customizer_config!
|
496 |
+
* @param bool $skip_cache Optional.
|
497 |
+
*
|
498 |
+
* @return array|false The option config or false on failure.
|
499 |
+
*/
|
500 |
+
public function get_option_details( $option_id, $minimal_details = false, $skip_cache = false ) {
|
501 |
+
if ( empty( $option_id ) ) {
|
502 |
+
return false;
|
503 |
+
}
|
504 |
+
|
505 |
+
$options_details = $this->get_options_details( $minimal_details, $skip_cache );
|
506 |
+
if ( ! empty( $options_details ) && is_array( $options_details ) && isset( $options_details[ $option_id ] ) ) {
|
507 |
+
return $options_details[ $option_id ];
|
508 |
+
}
|
509 |
+
|
510 |
+
return false;
|
511 |
+
}
|
512 |
+
|
513 |
+
/**
|
514 |
+
* This is just a wrapper for get_options_details() for backwards compatibility.
|
515 |
+
*
|
516 |
+
* @param bool $only_minimal_details
|
517 |
+
* @param bool $skip_cache
|
518 |
+
*
|
519 |
+
* @return array|mixed|void
|
520 |
+
*/
|
521 |
+
public function get_options_configs( $only_minimal_details = false, $skip_cache = false ) {
|
522 |
+
return $this->get_options_details( $only_minimal_details, $skip_cache );
|
523 |
+
}
|
524 |
+
|
525 |
+
protected function get_theme_mod_value( $setting_id ) {
|
526 |
+
global $wp_customize;
|
527 |
+
|
528 |
+
if ( empty( $setting_id ) ) {
|
529 |
+
return null;
|
530 |
+
}
|
531 |
+
|
532 |
+
if ( ! empty( $wp_customize ) && method_exists( $wp_customize, 'get_setting' ) ) {
|
533 |
+
$setting = $wp_customize->get_setting( $setting_id );
|
534 |
+
if ( ! empty( $setting ) ) {
|
535 |
+
return $setting->value();
|
536 |
+
}
|
537 |
+
}
|
538 |
+
|
539 |
+
$values = get_theme_mod( $this->get_options_key() );
|
540 |
+
|
541 |
+
if ( ! empty( $values ) && is_array( $values ) && isset( $values[ $setting_id ] ) ) {
|
542 |
+
return $values[ $setting_id ];
|
543 |
+
}
|
544 |
+
|
545 |
+
return null;
|
546 |
+
}
|
547 |
+
|
548 |
+
/**
|
549 |
+
* A public function to get an option's value.
|
550 |
+
* If there is a value and return it.
|
551 |
+
* Otherwise try to get the default parameter or the default from config.
|
552 |
+
*
|
553 |
+
* @param $option_id
|
554 |
+
* @param mixed $default Optional.
|
555 |
+
* @param array $option_details Optional.
|
556 |
+
*
|
557 |
+
* @return bool|null|string
|
558 |
+
*/
|
559 |
+
public function get_option( $option_id, $default = null, $option_details = null ) {
|
560 |
+
|
561 |
+
if ( null === $option_details ) {
|
562 |
+
// Get the field config.
|
563 |
+
$option_details = $this->get_option_details( $option_id, true );
|
564 |
+
}
|
565 |
+
|
566 |
+
// If the development constant CUSTOMIFY_DEV_FORCE_DEFAULTS has been defined we will not retrieve anything from the database
|
567 |
+
// Always go with the default
|
568 |
+
if ( defined( 'CUSTOMIFY_DEV_FORCE_DEFAULTS' )
|
569 |
+
&& true === CUSTOMIFY_DEV_FORCE_DEFAULTS
|
570 |
+
&& ! $this->skip_dev_mode_force_defaults( $option_id, $option_details ) ) {
|
571 |
+
|
572 |
+
$value = null;
|
573 |
+
} else {
|
574 |
+
|
575 |
+
if ( empty( $option_id ) || empty( $option_details ) || ! is_array( $option_details ) ) {
|
576 |
+
$value = null;
|
577 |
+
} elseif ( isset( $option_details['value'] ) ) {
|
578 |
+
// If we already have the value cached in the option details, we will use that.
|
579 |
+
$value = $option_details['value'];
|
580 |
+
} else {
|
581 |
+
$setting_id = $this->get_options_key() . '[' . $option_id . ']';
|
582 |
+
// If we have been explicitly given a setting ID we will use that
|
583 |
+
if ( ! empty( $option_details['setting_id'] ) ) {
|
584 |
+
$setting_id = $option_details['setting_id'];
|
585 |
+
}
|
586 |
+
|
587 |
+
if ( isset( $option_details['setting_type'] ) && $option_details['setting_type'] === 'option' ) {
|
588 |
+
// We have a setting that is saved in the wp_options table, not in theme_mods.
|
589 |
+
// We will fetch it directly.
|
590 |
+
$value = get_option( $setting_id, null );
|
591 |
+
} else {
|
592 |
+
// Get the value stores in theme_mods.
|
593 |
+
$value = $this->get_theme_mod_value( $option_id );
|
594 |
+
}
|
595 |
+
}
|
596 |
+
}
|
597 |
+
|
598 |
+
// If we have a non-null value, return it.
|
599 |
+
if ( $value !== null ) {
|
600 |
+
return $value;
|
601 |
+
}
|
602 |
+
|
603 |
+
// If we have a non-null default, return it.
|
604 |
+
if ( $default !== null ) {
|
605 |
+
return $default;
|
606 |
+
}
|
607 |
+
|
608 |
+
// Finally, attempt to use the default value set in the config, if available.
|
609 |
+
if ( ! empty( $option_details ) && is_array( $option_details ) && isset( $option_details['default'] ) ) {
|
610 |
+
return $option_details['default'];
|
611 |
+
}
|
612 |
+
|
613 |
+
return null;
|
614 |
+
}
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Determine if we should NOT enforce the CUSTOMIFY_DEV_FORCE_DEFAULTS behavior on a certain option.
|
618 |
+
*
|
619 |
+
* @param string $option_id
|
620 |
+
* @param array $option_config Optional.
|
621 |
+
*
|
622 |
+
* @return bool
|
623 |
+
*/
|
624 |
+
public function skip_dev_mode_force_defaults( $option_id, $option_config = null ) {
|
625 |
+
// Preprocess the $option_id.
|
626 |
+
if ( false !== strpos( $option_id, '::' ) ) {
|
627 |
+
$option_id = substr( $option_id, strpos( $option_id, '::' ) + 2 );
|
628 |
+
}
|
629 |
+
if ( false !== strpos( $option_id, '[' ) ) {
|
630 |
+
$option_id = explode( '[', $option_id );
|
631 |
+
$option_id = rtrim( $option_id[1], ']' );
|
632 |
+
}
|
633 |
+
|
634 |
+
if ( null === $option_config ) {
|
635 |
+
$option_config = $this->get_option_details( $option_id, true );
|
636 |
+
}
|
637 |
+
if ( empty( $option_config ) || ! is_array( $option_config ) ) {
|
638 |
+
return false;
|
639 |
+
}
|
640 |
+
|
641 |
+
// We will skip certain field types that generally don't have a default value.
|
642 |
+
if ( ! empty( $option_config['type'] ) ) {
|
643 |
+
switch ( $option_config['type'] ) {
|
644 |
+
case 'cropped_image':
|
645 |
+
case 'cropped_media':
|
646 |
+
case 'image':
|
647 |
+
case 'media':
|
648 |
+
case 'custom_background':
|
649 |
+
case 'upload':
|
650 |
+
return true;
|
651 |
+
break;
|
652 |
+
default:
|
653 |
+
break;
|
654 |
+
}
|
655 |
+
}
|
656 |
+
|
657 |
+
return false;
|
658 |
+
}
|
659 |
+
|
660 |
+
public function get_version() {
|
661 |
+
return $this->_version;
|
662 |
+
}
|
663 |
+
|
664 |
+
public function get_slug() {
|
665 |
+
return $this->plugin_slug;
|
666 |
+
}
|
667 |
+
|
668 |
+
public function get_file() {
|
669 |
+
return $this->file;
|
670 |
+
}
|
671 |
+
|
672 |
+
public function get_base_path() {
|
673 |
+
return plugin_dir_path( $this->file );
|
674 |
+
}
|
675 |
+
|
676 |
+
/**
|
677 |
+
* Load the plugin text domain for translation.
|
678 |
+
* @since 1.0.0
|
679 |
+
*/
|
680 |
+
function load_plugin_textdomain() {
|
681 |
+
$domain = $this->plugin_slug;
|
682 |
+
load_plugin_textdomain( $domain, false, basename( dirname( $this->file ) ) . '/languages/' );
|
683 |
+
}
|
684 |
+
|
685 |
+
/**
|
686 |
+
* Checks whether an array is associative or not
|
687 |
+
*
|
688 |
+
* @param array $array
|
689 |
+
*
|
690 |
+
* @return bool
|
691 |
+
*/
|
692 |
+
public function is_assoc( $array ) {
|
693 |
+
|
694 |
+
if ( ! is_array( $array ) ) {
|
695 |
+
return false;
|
696 |
+
}
|
697 |
+
|
698 |
+
// Keys of the array
|
699 |
+
$keys = array_keys( $array );
|
700 |
+
|
701 |
+
// If the array keys of the keys match the keys, then the array must
|
702 |
+
// not be associative (e.g. the keys array looked like {0:0, 1:1...}).
|
703 |
+
return array_keys( $keys ) !== $keys;
|
704 |
+
}
|
705 |
+
|
706 |
+
/**
|
707 |
+
* Does the same thing the JS encodeURIComponent() does
|
708 |
+
*
|
709 |
+
* @param string $str
|
710 |
+
*
|
711 |
+
* @return string
|
712 |
+
*/
|
713 |
+
public static function encodeURIComponent( $str ) {
|
714 |
+
//if we get an array we just let it be
|
715 |
+
if ( is_string( $str ) ) {
|
716 |
+
$revert = array( '%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')' );
|
717 |
+
$str = strtr( rawurlencode( $str ), $revert );
|
718 |
+
}
|
719 |
+
|
720 |
+
return $str;
|
721 |
+
}
|
722 |
+
|
723 |
+
/**
|
724 |
+
* Does the same thing the JS decodeURIComponent() does
|
725 |
+
*
|
726 |
+
* @param string $str
|
727 |
+
*
|
728 |
+
* @return string
|
729 |
+
*/
|
730 |
+
public static function decodeURIComponent( $str ) {
|
731 |
+
// If we get an array we just let it be
|
732 |
+
if ( is_string( $str ) ) {
|
733 |
+
$revert = array( '!' => '%21', '*' => '%2A', "'" => '%27', '(' => '%28', ')' => '%29' );
|
734 |
+
$str = rawurldecode( strtr( $str, $revert ) );
|
735 |
+
}
|
736 |
+
|
737 |
+
return $str;
|
738 |
+
}
|
739 |
+
|
740 |
+
/**
|
741 |
+
* PHP version check
|
742 |
+
*/
|
743 |
+
protected function php_version_check() {
|
744 |
+
|
745 |
+
if ( version_compare( phpversion(), $this->minimalRequiredPhpVersion ) < 0 ) {
|
746 |
+
add_action( 'admin_notices', array( $this, 'notice_php_version_wrong' ) );
|
747 |
+
|
748 |
+
return false;
|
749 |
+
}
|
750 |
+
|
751 |
+
return true;
|
752 |
+
}
|
753 |
+
|
754 |
+
/*
|
755 |
+
* Install everything needed
|
756 |
+
*/
|
757 |
+
static public function install() {
|
758 |
+
$config = Customify_Settings::get_plugin_config();
|
759 |
+
|
760 |
+
$defaults = array(
|
761 |
+
|
762 |
+
# Hidden fields
|
763 |
+
'settings_saved_once' => '0',
|
764 |
+
# General
|
765 |
+
'values_store_mod' => 'theme_mod',
|
766 |
+
|
767 |
+
'typography' => true,
|
768 |
+
'typography_standard_fonts' => true,
|
769 |
+
'typography_google_fonts' => true,
|
770 |
+
'typography_group_google_fonts' => true,
|
771 |
+
'disable_default_sections' => array(),
|
772 |
+
'disable_customify_sections' => array(),
|
773 |
+
'enable_reset_buttons' => false,
|
774 |
+
'enable_editor_style' => true,
|
775 |
+
'style_resources_location' => 'wp_head'
|
776 |
+
);
|
777 |
+
|
778 |
+
$current_data = get_option( $config['settings-key'] );
|
779 |
+
|
780 |
+
if ( $current_data === false ) {
|
781 |
+
add_option( $config['settings-key'], $defaults );
|
782 |
+
} elseif ( count( array_diff_key( $defaults, $current_data ) ) != 0) {
|
783 |
+
$plugin_data = array_merge( $defaults, $current_data );
|
784 |
+
update_option( $config['settings-key'], $plugin_data );
|
785 |
+
}
|
786 |
+
}
|
787 |
+
|
788 |
+
/**
|
789 |
+
* Main PixCustomifyPlugin Instance
|
790 |
+
*
|
791 |
+
* Ensures only one instance of PixCustomifyPlugin is loaded or can be loaded.
|
792 |
+
*
|
793 |
+
* @since 1.0.0
|
794 |
+
* @static
|
795 |
+
*
|
796 |
+
* @param string $file File.
|
797 |
+
* @param string $version Version.
|
798 |
+
*
|
799 |
+
* @see PixCustomifyPlugin()
|
800 |
+
* @return PixCustomifyPlugin Main PixCustomifyPlugin instance
|
801 |
+
*/
|
802 |
+
public static function instance( $file = '', $version = '1.0.0' ) {
|
803 |
+
// If the single instance hasn't been set, set it now.
|
804 |
+
if ( is_null( self::$_instance ) ) {
|
805 |
+
self::$_instance = new self( $file, $version );
|
806 |
+
}
|
807 |
+
|
808 |
+
return self::$_instance;
|
809 |
+
}
|
810 |
+
|
811 |
+
/**
|
812 |
+
* Cloning is forbidden.
|
813 |
+
*
|
814 |
+
* @since 1.5.0
|
815 |
+
*/
|
816 |
+
public function __clone() {
|
817 |
+
|
818 |
+
_doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin’ huh?' ) ), null );
|
819 |
+
} // End __clone ()
|
820 |
+
|
821 |
+
/**
|
822 |
+
* Unserializing instances of this class is forbidden.
|
823 |
+
*
|
824 |
+
* @since 1.5.0
|
825 |
+
*/
|
826 |
+
public function __wakeup() {
|
827 |
+
|
828 |
+
_doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin’ huh?' ) ), null );
|
829 |
+
} // End __wakeup ()
|
830 |
+
}
|
includes/extras.php
ADDED
@@ -0,0 +1,354 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Extra functionality.
|
4 |
+
*/
|
5 |
+
|
6 |
+
if ( ! function_exists('add_customify_base_options') ) {
|
7 |
+
/**
|
8 |
+
* This filter is used to change the Customizer Options
|
9 |
+
* You can also copy this function inside your functions.php
|
10 |
+
* file but DO NOT FORGET TO CHANGE ITS NAME
|
11 |
+
*
|
12 |
+
* @param $config array This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
|
13 |
+
* @return $config
|
14 |
+
*/
|
15 |
+
function add_customify_base_options( $config ) {
|
16 |
+
|
17 |
+
$config['opt-name'] = 'customify_defaults';
|
18 |
+
|
19 |
+
$config['sections'] = array(
|
20 |
+
/**
|
21 |
+
* Presets - This section will handle other options
|
22 |
+
*/
|
23 |
+
'presets_section' => array(
|
24 |
+
'title' => esc_html__( 'Style Presets', 'customify' ),
|
25 |
+
'options' => array(
|
26 |
+
'theme_style' => array(
|
27 |
+
'type' => 'preset',
|
28 |
+
'label' => esc_html__( 'Select a style:', 'customify' ),
|
29 |
+
'desc' => esc_html__( 'Conveniently change the design of your site with built-in style presets. Easy as pie.', 'customify' ),
|
30 |
+
'default' => 'royal',
|
31 |
+
'choices_type' => 'awesome',
|
32 |
+
'choices' => array(
|
33 |
+
'royal' => array(
|
34 |
+
'label' => esc_html__( 'Royal', 'customify' ),
|
35 |
+
'preview' => array(
|
36 |
+
'color-text' => '#ffffff',
|
37 |
+
'background-card' => '#615375',
|
38 |
+
'background-label' => '#46414c',
|
39 |
+
'font-main' => 'Abril Fatface',
|
40 |
+
'font-alt' => 'PT Serif',
|
41 |
+
),
|
42 |
+
'options' => array(
|
43 |
+
'links_color' => '#8eb2c5',
|
44 |
+
'headings_color' => '#725c92',
|
45 |
+
'body_color' => '#6f8089',
|
46 |
+
'page_background' => '#615375',
|
47 |
+
'headings_font' => 'Abril Fatface',
|
48 |
+
'body_font' => 'PT Serif',
|
49 |
+
)
|
50 |
+
),
|
51 |
+
'lovely' => array(
|
52 |
+
'label' => esc_html__( 'Lovely', 'customify' ),
|
53 |
+
'preview' => array(
|
54 |
+
'color-text' => '#ffffff',
|
55 |
+
'background-card' => '#d15c57',
|
56 |
+
'background-label' => '#5c374b',
|
57 |
+
'font-main' => 'Playfair Display',
|
58 |
+
'font-alt' => 'Playfair Display',
|
59 |
+
),
|
60 |
+
'options' => array(
|
61 |
+
'links_color' => '#cc3747',
|
62 |
+
'headings_color' => '#d15c57',
|
63 |
+
'body_color' => '#5c374b',
|
64 |
+
'page_background' => '#d15c57',
|
65 |
+
'headings_font' => 'Playfair Display',
|
66 |
+
'body_font' => 'Playfair Display',
|
67 |
+
)
|
68 |
+
),
|
69 |
+
'queen' => array(
|
70 |
+
'label' => esc_html__( 'Queen', 'customify' ),
|
71 |
+
'preview' => array(
|
72 |
+
'color-text' => '#fbedec',
|
73 |
+
'background-card' => '#773347',
|
74 |
+
'background-label' => '#41212a',
|
75 |
+
'font-main' => 'Cinzel Decorative',
|
76 |
+
'font-alt' => 'Gentium Basic',
|
77 |
+
),
|
78 |
+
'options' => array(
|
79 |
+
'links_color' => '#cd8085',
|
80 |
+
'headings_color' => '#54323c',
|
81 |
+
'body_color' => '#cd8085',
|
82 |
+
'page_background' => '#fff',
|
83 |
+
'headings_font' => 'Cinzel Decorative',
|
84 |
+
'body_font' => 'Gentium Basic',
|
85 |
+
)
|
86 |
+
),
|
87 |
+
'carrot' => array(
|
88 |
+
'label' => esc_html__( 'Carrot', 'customify' ),
|
89 |
+
'preview' => array(
|
90 |
+
'color-text' => '#ffffff',
|
91 |
+
'background-card' => '#df421d',
|
92 |
+
'background-label' => '#85210a',
|
93 |
+
'font-main' => 'Oswald',
|
94 |
+
'font-alt' => 'PT Sans Narrow',
|
95 |
+
),
|
96 |
+
'options' => array(
|
97 |
+
'links_color' => '#df421d',
|
98 |
+
'headings_color' => '#df421d',
|
99 |
+
'body_color' => '#7e7e7e',
|
100 |
+
'page_background' => '#fff',
|
101 |
+
'headings_font' => 'Oswald',
|
102 |
+
'body_font' => 'PT Sans Narrow',
|
103 |
+
)
|
104 |
+
),
|
105 |
+
|
106 |
+
|
107 |
+
|
108 |
+
'adler' => array(
|
109 |
+
'label' => esc_html__( 'Adler', 'customify' ),
|
110 |
+
'preview' => array(
|
111 |
+
'color-text' => '#fff',
|
112 |
+
'background-card' => '#0e364f',
|
113 |
+
'background-label' => '#000000',
|
114 |
+
'font-main' => 'Permanent Marker',
|
115 |
+
'font-alt' => 'Droid Sans Mono',
|
116 |
+
),
|
117 |
+
'options' => array(
|
118 |
+
'links_color' => '#68f3c8',
|
119 |
+
'headings_color' => '#0e364f',
|
120 |
+
'body_color' => '#45525a',
|
121 |
+
'page_background' => '#ffffff',
|
122 |
+
'headings_font' => 'Permanent Marker',
|
123 |
+
'body_font' => 'Droid Sans Mono'
|
124 |
+
)
|
125 |
+
),
|
126 |
+
'velvet' => array(
|
127 |
+
'label' => esc_html__( 'Velvet', 'customify' ),
|
128 |
+
'preview' => array(
|
129 |
+
'color-text' => '#ffffff',
|
130 |
+
'background-card' => '#282828',
|
131 |
+
'background-label' => '#000000',
|
132 |
+
'font-main' => 'Pinyon Script',
|
133 |
+
'font-alt' => 'Josefin Sans',
|
134 |
+
),
|
135 |
+
'options' => array(
|
136 |
+
'links_color' => '#000000',
|
137 |
+
'headings_color' => '#000000',
|
138 |
+
'body_color' => '#000000',
|
139 |
+
'page_background' => '#000000',
|
140 |
+
'headings_font' => 'Pinyon Script',
|
141 |
+
'body_font' => 'Josefin Sans',
|
142 |
+
)
|
143 |
+
),
|
144 |
+
|
145 |
+
)
|
146 |
+
),
|
147 |
+
)
|
148 |
+
),
|
149 |
+
|
150 |
+
/**
|
151 |
+
* COLORS - This section will handle different elements colors (eg. links, headings)
|
152 |
+
*/
|
153 |
+
'colors_section' => array(
|
154 |
+
'title' => esc_html__( 'Colors', 'customify' ),
|
155 |
+
'options' => array(
|
156 |
+
'links_color' => array(
|
157 |
+
'type' => 'color',
|
158 |
+
'label' => esc_html__( 'Links Color', 'customify' ),
|
159 |
+
'live' => true,
|
160 |
+
'default' => '#6c6e70',
|
161 |
+
'css' => array(
|
162 |
+
array(
|
163 |
+
'property' => 'color',
|
164 |
+
'selector' => 'a, .entry-meta a',
|
165 |
+
),
|
166 |
+
)
|
167 |
+
),
|
168 |
+
'headings_color' => array(
|
169 |
+
'type' => 'color',
|
170 |
+
'label' => esc_html__( 'Headings Color', 'customify' ),
|
171 |
+
'live' => true,
|
172 |
+
'default' => '#0aa0d9',
|
173 |
+
'css' => array(
|
174 |
+
array(
|
175 |
+
'property' => 'color',
|
176 |
+
'selector' => '.site-title a, h1, h2, h3, h4, h5, h6,
|
177 |
+
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
|
178 |
+
.widget-title,
|
179 |
+
a:hover, .entry-meta a:hover'
|
180 |
+
)
|
181 |
+
)
|
182 |
+
),
|
183 |
+
'body_color' => array(
|
184 |
+
'type' => 'color',
|
185 |
+
'label' => esc_html__( 'Body Color', 'customify' ),
|
186 |
+
'live' => true,
|
187 |
+
'default' => '#2d3033',
|
188 |
+
'css' => array(
|
189 |
+
array(
|
190 |
+
'selector' => 'body',
|
191 |
+
'property' => 'color'
|
192 |
+
)
|
193 |
+
)
|
194 |
+
)
|
195 |
+
)
|
196 |
+
),
|
197 |
+
|
198 |
+
/**
|
199 |
+
* FONTS - This section will handle different elements fonts (eg. headings, body)
|
200 |
+
*/
|
201 |
+
'typography_section' => array(
|
202 |
+
'title' => esc_html__( 'Fonts', 'customify' ),
|
203 |
+
'options' => array(
|
204 |
+
'headings_font' => array(
|
205 |
+
'type' => 'typography',
|
206 |
+
'label' => esc_html__( 'Headings', 'customify' ),
|
207 |
+
'default' => 'Playfair Display',
|
208 |
+
'selector' => '.site-title a, h1, h2, h3, h4, h5, h6,
|
209 |
+
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
|
210 |
+
.widget-title',
|
211 |
+
'font_weight' => true,
|
212 |
+
'subsets' => true,
|
213 |
+
'recommended' => array(
|
214 |
+
'Playfair Display',
|
215 |
+
'Oswald',
|
216 |
+
'Lato',
|
217 |
+
'Open Sans',
|
218 |
+
'Exo',
|
219 |
+
'PT Sans',
|
220 |
+
'Ubuntu',
|
221 |
+
'Vollkorn',
|
222 |
+
'Lora',
|
223 |
+
'Arvo',
|
224 |
+
'Josefin Slab',
|
225 |
+
'Crete Round',
|
226 |
+
'Kreon',
|
227 |
+
'Bubblegum Sans',
|
228 |
+
'The Girl Next Door',
|
229 |
+
'Pacifico',
|
230 |
+
'Handlee',
|
231 |
+
'Satify',
|
232 |
+
'Pompiere'
|
233 |
+
)
|
234 |
+
),
|
235 |
+
'body_font' => array(
|
236 |
+
'type' => 'typography',
|
237 |
+
'label' => esc_html__( 'Body Text', 'customify' ),
|
238 |
+
'default' => 'Lato',
|
239 |
+
'selector' => 'html body',
|
240 |
+
'load_all_weights' => true,
|
241 |
+
'recommended' => array(
|
242 |
+
'Lato',
|
243 |
+
'Open Sans',
|
244 |
+
'PT Sans',
|
245 |
+
'Cabin',
|
246 |
+
'Gentium Book Basic',
|
247 |
+
'PT Serif',
|
248 |
+
'Droid Serif'
|
249 |
+
)
|
250 |
+
)
|
251 |
+
)
|
252 |
+
),
|
253 |
+
|
254 |
+
/**
|
255 |
+
* BACKGROUNDS - This section will handle different elements colors (eg. links, headings)
|
256 |
+
*/
|
257 |
+
'backgrounds_section' => array(
|
258 |
+
'title' => esc_html__( 'Backgrounds', 'customify' ),
|
259 |
+
'options' => array(
|
260 |
+
'page_background' => array(
|
261 |
+
'type' => 'color',
|
262 |
+
'label' => esc_html__( 'Page Background', 'customify' ),
|
263 |
+
'live' => true,
|
264 |
+
'default' => '#ffffff',
|
265 |
+
'css' => array(
|
266 |
+
array(
|
267 |
+
'property' => 'background',
|
268 |
+
'selector' => 'body, .site',
|
269 |
+
)
|
270 |
+
)
|
271 |
+
),
|
272 |
+
)
|
273 |
+
),
|
274 |
+
/**
|
275 |
+
* LAYOUTS - This section will handle different elements colors (eg. links, headings)
|
276 |
+
*/
|
277 |
+
'layout_options' => array(
|
278 |
+
'title' => esc_html__( 'Layout', 'customify' ),
|
279 |
+
'options' => array(
|
280 |
+
'site_title_size' => array(
|
281 |
+
'type' => 'range',
|
282 |
+
'label' => 'Site Title Size',
|
283 |
+
'live' => true,
|
284 |
+
'input_attrs' => array(
|
285 |
+
'min' => 24,
|
286 |
+
'max' => 100,
|
287 |
+
'step' => 1,
|
288 |
+
'data-preview' => true
|
289 |
+
),
|
290 |
+
'default' => 24,
|
291 |
+
'css' => array(
|
292 |
+
array(
|
293 |
+
'property' => 'font-size',
|
294 |
+
'selector' => '.site-title',
|
295 |
+
'media' => 'screen and (min-width: 1000px)',
|
296 |
+
'unit' => 'px',
|
297 |
+
)
|
298 |
+
)
|
299 |
+
),
|
300 |
+
'page_content_spacing' => array(
|
301 |
+
'type' => 'range',
|
302 |
+
'label' => 'Page Content Spacing',
|
303 |
+
'live' => true,
|
304 |
+
'input_attrs' => array(
|
305 |
+
'min' => 0,
|
306 |
+
'max' => 100,
|
307 |
+
'step' => 1,
|
308 |
+
),
|
309 |
+
'default' => 18,
|
310 |
+
'css' => array(
|
311 |
+
array(
|
312 |
+
'property' => 'padding',
|
313 |
+
'selector' => '.site-content',
|
314 |
+
'media' => 'screen and (min-width: 1000px)',
|
315 |
+
'unit' => 'px',
|
316 |
+
)
|
317 |
+
)
|
318 |
+
)
|
319 |
+
)
|
320 |
+
)
|
321 |
+
);
|
322 |
+
|
323 |
+
/**
|
324 |
+
* A self explanatory example of panels **
|
325 |
+
**/
|
326 |
+
// $config['panels'] = array(
|
327 |
+
// 'panel_id' => array(
|
328 |
+
// 'title' => esc_html__( 'Panel Title', 'customify' ),
|
329 |
+
// 'sections' => array(
|
330 |
+
// 'panel_section' => array(
|
331 |
+
// 'title' => esc_html__( 'Section Title', 'customify' ),
|
332 |
+
// 'options' => array(
|
333 |
+
// 'setting_id' => array(
|
334 |
+
// 'type' => 'color',
|
335 |
+
// 'label' => esc_html__( 'Label', 'customify' ),
|
336 |
+
// 'live' => true, // or false
|
337 |
+
// 'default' => '#6c6e70',
|
338 |
+
// 'css' => array(
|
339 |
+
// array(
|
340 |
+
// 'property' => 'color',
|
341 |
+
// 'selector' => 'a, .entry-meta a',
|
342 |
+
// ),
|
343 |
+
// )
|
344 |
+
// ),
|
345 |
+
// )
|
346 |
+
// )
|
347 |
+
// )
|
348 |
+
// )
|
349 |
+
// );
|
350 |
+
|
351 |
+
return $config;
|
352 |
+
}
|
353 |
+
}
|
354 |
+
add_filter( 'customify_filter_fields', 'add_customify_base_options', 5, 1 );
|
includes/index.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden
|
3 |
+
// Golden is deprecated
|
includes/lib/index.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden
|
3 |
+
// Golden is deprecated
|
js/admin.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
(function ($) {
|
2 |
-
|
3 |
$(function () {
|
4 |
|
5 |
/**
|
@@ -18,68 +18,68 @@
|
|
18 |
/** End Checkbox value switcher **/
|
19 |
|
20 |
/* Ensure groups visibility */
|
21 |
-
$('.switch input[type=checkbox], .select select').each(function(){
|
22 |
|
23 |
-
if (
|
24 |
|
25 |
-
var show = false
|
26 |
-
if (
|
|
|
|
|
27 |
show = true
|
28 |
-
} else if ( typeof $(this).data('display_option') !== "undefined" && $(this).data('display_option') === $(this).val() ) {
|
29 |
-
show = true;
|
30 |
}
|
31 |
|
32 |
-
toggleGroup(
|
33 |
}
|
34 |
-
})
|
35 |
|
36 |
-
$('.switch, .select ').on('change', 'input[type=checkbox], select', function(){
|
37 |
-
if (
|
38 |
-
var show = false
|
39 |
-
if (
|
40 |
-
show = true
|
41 |
-
} else if (
|
42 |
-
show = true
|
43 |
}
|
44 |
-
toggleGroup(
|
45 |
}
|
46 |
-
})
|
47 |
-
})
|
48 |
|
49 |
-
var toggleGroup = function(
|
50 |
-
var $group = $(
|
51 |
|
52 |
-
if (
|
53 |
-
$group.show()
|
54 |
} else {
|
55 |
-
$group.hide()
|
56 |
}
|
57 |
-
}
|
58 |
|
59 |
/*
|
60 |
* Useful functions
|
61 |
*/
|
62 |
-
function check_checkbox_checked(
|
63 |
-
if (
|
64 |
-
$(input).siblings('input:hidden').val('on')
|
65 |
} else {
|
66 |
-
$(input).siblings('input:hidden').val('off')
|
67 |
}
|
68 |
} /* End check_checkbox_checked() */
|
69 |
|
70 |
-
$.fn.check_for_extended_options = function() {
|
71 |
-
var extended_options = $(this).siblings('fieldset.group')
|
72 |
-
if (
|
73 |
-
if (
|
74 |
extended_options
|
75 |
.data('extended', false)
|
76 |
-
.css('height', '0')
|
77 |
-
} else if (
|
78 |
extended_options
|
79 |
.data('extended', true)
|
80 |
-
.css('height', 'auto')
|
81 |
}
|
82 |
}
|
83 |
-
}
|
84 |
|
85 |
-
}(jQuery))
|
1 |
(function ($) {
|
2 |
+
'use strict'
|
3 |
$(function () {
|
4 |
|
5 |
/**
|
18 |
/** End Checkbox value switcher **/
|
19 |
|
20 |
/* Ensure groups visibility */
|
21 |
+
$('.switch input[type=checkbox], .select select').each(function () {
|
22 |
|
23 |
+
if ($(this).data('show_group')) {
|
24 |
|
25 |
+
var show = false
|
26 |
+
if ($(this).attr('checked')) {
|
27 |
+
show = true
|
28 |
+
} else if (typeof $(this).data('display_option') !== 'undefined' && $(this).data('display_option') === $(this).val()) {
|
29 |
show = true
|
|
|
|
|
30 |
}
|
31 |
|
32 |
+
toggleGroup($(this).data('show_group'), show)
|
33 |
}
|
34 |
+
})
|
35 |
|
36 |
+
$('.switch, .select ').on('change', 'input[type=checkbox], select', function () {
|
37 |
+
if ($(this).data('show_group')) {
|
38 |
+
var show = false
|
39 |
+
if ($(this).attr('checked')) {
|
40 |
+
show = true
|
41 |
+
} else if (typeof $(this).data('display_option') !== 'undefined' && $(this).data('display_option') === $(this).val()) {
|
42 |
+
show = true
|
43 |
}
|
44 |
+
toggleGroup($(this).data('show_group'), show)
|
45 |
}
|
46 |
+
})
|
47 |
+
})
|
48 |
|
49 |
+
var toggleGroup = function (name, show) {
|
50 |
+
var $group = $('#' + name)
|
51 |
|
52 |
+
if (show) {
|
53 |
+
$group.show()
|
54 |
} else {
|
55 |
+
$group.hide()
|
56 |
}
|
57 |
+
}
|
58 |
|
59 |
/*
|
60 |
* Useful functions
|
61 |
*/
|
62 |
+
function check_checkbox_checked (input) { // yes the name is an ironic
|
63 |
+
if ($(input).attr('checked') === 'checked') {
|
64 |
+
$(input).siblings('input:hidden').val('on')
|
65 |
} else {
|
66 |
+
$(input).siblings('input:hidden').val('off')
|
67 |
}
|
68 |
} /* End check_checkbox_checked() */
|
69 |
|
70 |
+
$.fn.check_for_extended_options = function () {
|
71 |
+
var extended_options = $(this).siblings('fieldset.group')
|
72 |
+
if ($(this).data('show-next')) {
|
73 |
+
if (extended_options.data('extended') === true) {
|
74 |
extended_options
|
75 |
.data('extended', false)
|
76 |
+
.css('height', '0')
|
77 |
+
} else if ((typeof extended_options.data('extended') === 'undefined' && $(this).attr('checked') === 'checked') || extended_options.data('extended') === false) {
|
78 |
extended_options
|
79 |
.data('extended', true)
|
80 |
+
.css('height', 'auto')
|
81 |
}
|
82 |
}
|
83 |
+
}
|
84 |
|
85 |
+
}(jQuery))
|
js/customizer.js
CHANGED
@@ -1,1263 +1,1263 @@
|
|
1 |
(
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
)(jQuery, window, wp)
|
1 |
(
|
2 |
+
function ($, exports, wp) {
|
3 |
+
var api = wp.customize
|
4 |
+
var $window = $(window)
|
5 |
+
|
6 |
+
// when the customizer is ready prepare our fields events
|
7 |
+
wp.customize.bind('ready', function () {
|
8 |
+
var timeout = null
|
9 |
+
|
10 |
+
// Create a stack of callbacks bound to parent settings to be able to unbind them
|
11 |
+
// when altering the connected_fields attribute.
|
12 |
+
if (typeof window.connectedFieldsCallbacks === 'undefined') {
|
13 |
+
window.connectedFieldsCallbacks = {}
|
14 |
+
}
|
15 |
+
|
16 |
+
// add ace editors
|
17 |
+
$('.customify_ace_editor').each(function (key, el) {
|
18 |
+
var id = $(this).attr('id'),
|
19 |
+
css_editor = ace.edit(id)
|
20 |
+
|
21 |
+
var editor_type = $(this).data('editor_type')
|
22 |
+
// init the ace editor
|
23 |
+
css_editor.setTheme('ace/theme/github')
|
24 |
+
css_editor.getSession().setMode('ace/mode/' + editor_type)
|
25 |
+
|
26 |
+
// hide the textarea and enable the ace editor
|
27 |
+
var textarea = $('#' + id + '_textarea').hide()
|
28 |
+
css_editor.getSession().setValue(textarea.val())
|
29 |
+
|
30 |
+
// each time a change is triggered start a timeout of 1,5s and when is finished refresh the previewer
|
31 |
+
// if the user types faster than this delay then reset it
|
32 |
+
css_editor.getSession().on('change', function (e) {
|
33 |
+
if (timeout !== null) {
|
34 |
+
clearTimeout(timeout)
|
35 |
+
timeout = null
|
36 |
+
} else {
|
37 |
+
timeout = setTimeout(function () {
|
38 |
+
//var state = css_editor.session.getState();
|
39 |
+
textarea.val(css_editor.getSession().getValue())
|
40 |
+
textarea.trigger('change')
|
41 |
+
}, 1500)
|
42 |
+
}
|
43 |
+
})
|
44 |
+
})
|
45 |
+
|
46 |
+
// simple select2 field
|
47 |
+
$('.customify_select2').select2()
|
48 |
+
|
49 |
+
setTimeout(function () {
|
50 |
+
CustomifyFontSelectFields.init()
|
51 |
+
}, 333)
|
52 |
+
|
53 |
+
prepare_typography_field()
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Make the customizer save on CMD/CTRL+S action
|
57 |
+
* This is awesome!!!
|
58 |
+
*/
|
59 |
+
$(window).bind('keydown', function (event) {
|
60 |
+
if (event.ctrlKey || event.metaKey) {
|
61 |
+
switch (String.fromCharCode(event.which).toLowerCase()) {
|
62 |
+
case 's':
|
63 |
+
event.preventDefault()
|
64 |
+
api.previewer.save()
|
65 |
+
break
|
66 |
+
}
|
67 |
+
}
|
68 |
+
})
|
69 |
+
|
70 |
+
// for each range input add a value preview output
|
71 |
+
$('.accordion-section-content[id*="' + customify_settings.options_name + '"], #sub-accordion-section-style_manager_section').each(function () {
|
72 |
+
|
73 |
+
// Initialize range fields logic
|
74 |
+
customifyHandleRangeFields(this)
|
75 |
+
})
|
76 |
+
|
77 |
+
if ($('button[data-action="reset_customify"]').length > 0) {
|
78 |
+
// reset_button
|
79 |
+
$(document).on('click', '#customize-control-reset_customify button', function (ev) {
|
80 |
+
ev.preventDefault()
|
81 |
+
|
82 |
+
var iAgree = confirm('Do you really want to reset to defaults all the fields? Watch out, this will reset all your Customify options and will save them!')
|
83 |
+
|
84 |
+
if (!iAgree) {
|
85 |
+
return
|
86 |
+
}
|
87 |
+
|
88 |
+
$.each(api.settings.controls, function (key, ctrl) {
|
89 |
+
var setting_id = key.replace('_control', '')
|
90 |
+
var setting = customify_settings.settings[setting_id]
|
91 |
+
|
92 |
+
if (!_.isUndefined(setting) && !_.isUndefined(setting.default)) {
|
93 |
+
api_set_setting_value(setting_id, setting.default)
|
94 |
+
}
|
95 |
+
})
|
96 |
+
|
97 |
+
api.previewer.save()
|
98 |
+
})
|
99 |
+
|
100 |
+
// add a reset button for each panel
|
101 |
+
$('.panel-meta').each(function (el, key) {
|
102 |
+
var container = $(this).parents('.control-panel'),
|
103 |
+
id = container.attr('id')
|
104 |
+
|
105 |
+
if (typeof id !== 'undefined') {
|
106 |
+
var panel_id = id.replace('accordion-panel-', '')
|
107 |
+
$(this).parent().append('<button class="reset_panel button" data-panel="' + panel_id + '">Panel\'s defaults</button>')
|
108 |
+
}
|
109 |
+
})
|
110 |
+
|
111 |
+
// reset panel
|
112 |
+
$(document).on('click', '.reset_panel', function (e) {
|
113 |
+
e.preventDefault()
|
114 |
+
|
115 |
+
var panel_id = $(this).data('panel'),
|
116 |
+
panel = api.panel(panel_id),
|
117 |
+
sections = panel.sections(),
|
118 |
+
iAgree = confirm('Do you really want to reset ' + panel.params.title + '?')
|
119 |
+
|
120 |
+
if (!iAgree) {
|
121 |
+
return
|
122 |
+
}
|
123 |
+
if (sections.length > 0) {
|
124 |
+
$.each(sections, function () {
|
125 |
+
//var settings = this.settings();
|
126 |
+
var controls = this.controls()
|
127 |
+
|
128 |
+
if (controls.length > 0) {
|
129 |
+
$.each(controls, function (key, ctrl) {
|
130 |
+
var setting_id = ctrl.id.replace('_control', ''),
|
131 |
+
setting = customify_settings.settings[setting_id]
|
132 |
+
|
133 |
+
if (!_.isUndefined(setting) && !_.isUndefined(setting.default)) {
|
134 |
+
api_set_setting_value(setting_id, setting.default)
|
135 |
+
}
|
136 |
+
})
|
137 |
+
}
|
138 |
+
})
|
139 |
+
}
|
140 |
+
})
|
141 |
+
|
142 |
+
//add reset section
|
143 |
+
$('.accordion-section-content').each(function (el, key) {
|
144 |
+
var section_id = $(this).attr('id')
|
145 |
+
|
146 |
+
if ((
|
147 |
+
(
|
148 |
+
!_.isUndefined(section_id)
|
149 |
+
) ? section_id.indexOf(customify_settings.options_name) : -1
|
150 |
+
) === -1) {
|
151 |
+
return
|
152 |
+
}
|
153 |
+
|
154 |
+
if (!_.isUndefined(section_id) && section_id.indexOf('sub-accordion-section-') > -1) {
|
155 |
+
var id = section_id.replace('sub-accordion-section-', '')
|
156 |
+
$(this).append('<button class="reset_section button" data-section="' + id + '">Reset All Options for This Section</button>')
|
157 |
+
}
|
158 |
+
})
|
159 |
+
|
160 |
+
// reset section event
|
161 |
+
$(document).on('click', '.reset_section', function (e) {
|
162 |
+
e.preventDefault()
|
163 |
+
|
164 |
+
var section_id = $(this).data('section'),
|
165 |
+
section = api.section(section_id),
|
166 |
+
controls = section.controls()
|
167 |
+
|
168 |
+
var iAgree = confirm('Do you really want to reset ' + section.params.title + '?')
|
169 |
+
|
170 |
+
if (!iAgree) {
|
171 |
+
return
|
172 |
+
}
|
173 |
+
|
174 |
+
if (controls.length > 0) {
|
175 |
+
$.each(controls, function (key, ctrl) {
|
176 |
+
var setting_id = ctrl.id.replace('_control', ''),
|
177 |
+
setting = customify_settings.settings[setting_id]
|
178 |
+
|
179 |
+
if (!_.isUndefined(setting) && !_.isUndefined(setting.default)) {
|
180 |
+
api_set_setting_value(setting_id, setting.default)
|
181 |
+
}
|
182 |
+
})
|
183 |
+
}
|
184 |
+
})
|
185 |
+
}
|
186 |
+
|
187 |
+
$(document).on('change keyup', '.customize-control-range input.range-value', function () {
|
188 |
+
var range = $(this).siblings('input[type="range"]')
|
189 |
+
range.val($(this).val())
|
190 |
+
range.trigger('change')
|
191 |
+
})
|
192 |
+
|
193 |
+
$(document).on('change', '.customify_typography_font_subsets', function (ev) {
|
194 |
+
|
195 |
+
var $input = $(this).parents('.options').siblings('.customify_typography').children('.customify_typography_values'),
|
196 |
+
current_val = $input.val()
|
197 |
+
|
198 |
+
current_val = JSON.parse(decodeURIComponent(current_val))
|
199 |
+
|
200 |
+
//maybe the selected option holds a JSON in its value
|
201 |
+
current_val.selected_subsets = maybeJsonParse($(this).val())
|
202 |
+
|
203 |
+
$input.val(encodeURIComponent(JSON.stringify(current_val)))
|
204 |
+
|
205 |
+
$input.trigger('change')
|
206 |
+
})
|
207 |
+
|
208 |
+
$(document).on('change', '.customify_typography_font_weight', function (ev) {
|
209 |
+
|
210 |
+
var $input = $(this).parents('.options').siblings('.customify_typography').children('.customify_typography_values'),
|
211 |
+
current_val = $input.val()
|
212 |
+
|
213 |
+
current_val = maybeJsonParse(current_val)
|
214 |
+
// @todo currently the font weight selector works for one value only
|
215 |
+
// maybe make this a multiselect
|
216 |
+
|
217 |
+
//maybe the selected option holds a JSON in its value
|
218 |
+
current_val.selected_variants = {0: maybeJsonParse($(this).val())}
|
219 |
+
|
220 |
+
$input.val(encodeURIComponent(JSON.stringify(current_val)))
|
221 |
+
$input.trigger('change')
|
222 |
+
})
|
223 |
+
|
224 |
+
$('body').on('customify:preset-change', function (e) {
|
225 |
+
const data = $(e.target).data('options')
|
226 |
+
|
227 |
+
if (!_.isUndefined(data)) {
|
228 |
+
$.each(data, function (setting_id, value) {
|
229 |
+
api_set_setting_value(setting_id, value)
|
230 |
+
})
|
231 |
+
}
|
232 |
+
})
|
233 |
+
|
234 |
+
$(document).on('change', '.customify_preset.select', function () {
|
235 |
+
const $source = $(this)
|
236 |
+
const $target = $source.children('[value="' + $source.val() + '"]')
|
237 |
+
$target.trigger('customify:preset-change')
|
238 |
+
})
|
239 |
+
|
240 |
+
$(document).on('click', '.customify_preset.radio input, .customify_preset.radio_buttons input, .awesome_presets input', function () {
|
241 |
+
$(this).trigger('customify:preset-change')
|
242 |
+
})
|
243 |
+
|
244 |
+
// bind our event on click
|
245 |
+
$(document).on('click', '.customify_import_demo_data_button', function (event) {
|
246 |
+
let key = $(this).data('key')
|
247 |
+
let import_queue = new Queue(api)
|
248 |
+
let steps = []
|
249 |
+
|
250 |
+
if (!_.isUndefined(customify_settings.settings[key].imports)) {
|
251 |
+
|
252 |
+
$.each(customify_settings.settings[key].imports, function (i, import_setts, k) {
|
253 |
+
if (_.isUndefined(import_setts.steps)) {
|
254 |
+
steps.push({id: i, type: import_setts.type})
|
255 |
+
} else {
|
256 |
+
var count = import_setts.steps
|
257 |
+
|
258 |
+
while (count >= 1) {
|
259 |
+
steps.push({id: i, type: import_setts.type, count: count})
|
260 |
+
count = count - 1
|
261 |
+
}
|
262 |
+
}
|
263 |
+
})
|
264 |
+
}
|
265 |
+
|
266 |
+
import_queue.add_steps('import_demo_data_action_id', steps)
|
267 |
+
return false
|
268 |
+
})
|
269 |
+
|
270 |
+
customifyBackgroundJsControl.init()
|
271 |
+
|
272 |
+
// sometimes a php save may be needed
|
273 |
+
if (getUrlVars('save_customizer_once')) {
|
274 |
+
api.previewer.save()
|
275 |
+
}
|
276 |
+
|
277 |
+
setTimeout(function () {
|
278 |
+
customifyFoldingFields()
|
279 |
+
}, 1000);
|
280 |
+
|
281 |
+
// Handle the section tabs (ex: Layout | Fonts | Colors)
|
282 |
+
(
|
283 |
+
function () {
|
284 |
+
var $navs = $('.js-section-navigation')
|
285 |
+
|
286 |
+
$navs.each(function () {
|
287 |
+
var $nav = $(this)
|
288 |
+
var $title = $nav.parents('.accordion-section-content').find('.customize-section-title')
|
289 |
+
|
290 |
+
$nav.closest('.customize-control').addClass('screen-reader-text')
|
291 |
+
$title.append($nav).parent().addClass('has-nav')
|
292 |
+
})
|
293 |
+
|
294 |
+
$('.js-section-navigation a').on('click', function (e) {
|
295 |
+
e.preventDefault()
|
296 |
+
|
297 |
+
var $sidebar = $(this).parents('.customize-pane-child')
|
298 |
+
var $parent = $(this).parents('.accordion-section-content')
|
299 |
+
var href = $.attr(this, 'href')
|
300 |
+
|
301 |
+
if (href != '#') {
|
302 |
+
$sidebar.animate({
|
303 |
+
scrollTop: $($.attr(this, 'href')).position().top - $parent.find('.customize-section-title').outerHeight()
|
304 |
+
}, 500)
|
305 |
+
}
|
306 |
+
})
|
307 |
+
}
|
308 |
+
)();
|
309 |
+
|
310 |
+
(
|
311 |
+
function () {
|
312 |
+
// Close a font field when clicking on another field
|
313 |
+
$('.customify_font_tooltip').on('click', function () {
|
314 |
+
if ($(this).prop('checked') === true) {
|
315 |
+
$('.customify_font_tooltip').prop('checked', false)
|
316 |
+
$(this).prop('checked', true)
|
317 |
+
}
|
318 |
+
})
|
319 |
+
}
|
320 |
+
)()
|
321 |
+
|
322 |
+
// Bind any connected fields, except those in the Style Manager.
|
323 |
+
// Those are handled by the appropriate Style Manager component (Color Palettes, Font Palettes, etc ).
|
324 |
+
bindConnectedFields()
|
325 |
+
|
326 |
+
})
|
327 |
+
|
328 |
+
const getConnectedFieldsCallback = function (parent_setting_data, parent_setting_id) {
|
329 |
+
return function (new_value, old_value) {
|
330 |
+
_.each(parent_setting_data.connected_fields, function (connected_field_data) {
|
331 |
+
if (_.isUndefined(connected_field_data) || _.isUndefined(connected_field_data.setting_id) || !_.isString(connected_field_data.setting_id)) {
|
332 |
+
return
|
333 |
+
}
|
334 |
+
const setting = wp.customize(connected_field_data.setting_id)
|
335 |
+
if (_.isUndefined(setting)) {
|
336 |
+
return
|
337 |
+
}
|
338 |
+
setting.set(new_value)
|
339 |
+
})
|
340 |
+
}
|
341 |
+
}
|
342 |
+
|
343 |
+
const bindConnectedFields = function () {
|
344 |
+
_.each(wp.customize.settings.settings, function (parent_setting_data, parent_setting_id) {
|
345 |
+
// We don't want to handle the binding of the Style Manager settings
|
346 |
+
if (typeof ColorPalettes !== 'undefined'
|
347 |
+
&& typeof ColorPalettes.masterSettingIds !== 'undefined'
|
348 |
+
&& _.contains(ColorPalettes.masterSettingIds, parent_setting_id)) {
|
349 |
+
return
|
350 |
+
}
|
351 |
+
if (typeof FontPalettes !== 'undefined'
|
352 |
+
&& typeof FontPalettes.masterSettingIds !== 'undefined'
|
353 |
+
&& _.contains(FontPalettes.masterSettingIds, parent_setting_id)) {
|
354 |
+
return
|
355 |
+
}
|
356 |
+
|
357 |
+
let parent_setting = wp.customize(parent_setting_id)
|
358 |
+
if (typeof parent_setting_data.connected_fields !== 'undefined') {
|
359 |
+
connectedFieldsCallbacks[parent_setting_id] = getConnectedFieldsCallback(parent_setting_data, parent_setting_id)
|
360 |
+
parent_setting.bind(connectedFieldsCallbacks[parent_setting_id])
|
361 |
+
}
|
362 |
+
})
|
363 |
+
}
|
364 |
+
|
365 |
+
const unbindConnectedFields = function () {
|
366 |
+
_.each(wp.customize.settings.settings, function (parent_setting_data, parent_setting_id) {
|
367 |
+
// We don't want to handle the binding of the Style Manager settings
|
368 |
+
if (typeof ColorPalettes !== 'undefined'
|
369 |
+
&& typeof ColorPalettes.masterSettingIds !== 'undefined'
|
370 |
+
&& _.contains(ColorPalettes.masterSettingIds, parent_setting_id)) {
|
371 |
+
return
|
372 |
+
}
|
373 |
+
if (typeof FontPalettes !== 'undefined'
|
374 |
+
&& typeof FontPalettes.masterSettingIds !== 'undefined'
|
375 |
+
&& _.contains(FontPalettes.masterSettingIds, parent_setting_id)) {
|
376 |
+
return
|
377 |
+
}
|
378 |
+
|
379 |
+
let parent_setting = wp.customize(parent_setting_id)
|
380 |
+
if (typeof parent_setting_data.connected_fields !== 'undefined' && typeof connectedFieldsCallbacks[parent_setting_id] !== 'undefined') {
|
381 |
+
parent_setting.unbind(connectedFieldsCallbacks[parent_setting_id])
|
382 |
+
}
|
383 |
+
delete connectedFieldsCallbacks[parent_setting_id]
|
384 |
+
})
|
385 |
+
}
|
386 |
+
|
387 |
+
const customifyHandleRangeFields = function (el) {
|
388 |
+
|
389 |
+
// For each range input add a number field (for preview mainly - but it can also be used for input)
|
390 |
+
$(el).find('input[type="range"]').each(function () {
|
391 |
+
if (!$(this).siblings('.range-value').length) {
|
392 |
+
var $clone = $(this).clone()
|
393 |
+
|
394 |
+
$clone
|
395 |
+
.attr('type', 'number')
|
396 |
+
.attr('class', 'range-value')
|
397 |
+
.removeAttr('data-field')
|
398 |
+
|
399 |
+
$(this).after($clone)
|
400 |
+
}
|
401 |
+
|
402 |
+
// Update the number field when changing the range
|
403 |
+
$(this).on('change', function () {
|
404 |
+
$(this).siblings('.range-value').val($(this).val())
|
405 |
+
})
|
406 |
+
|
407 |
+
// And the other way around, update the range field when changing the number
|
408 |
+
$($clone).on('change', function () {
|
409 |
+
$(this).siblings('input[type="range"]').val($(this).val())
|
410 |
+
})
|
411 |
+
})
|
412 |
+
}
|
413 |
+
|
414 |
+
/**
|
415 |
+
* This function will search for all the interdependend fields and make a bound between them.
|
416 |
+
* So whenever a target is changed, it will take actions to the dependent fields.
|
417 |
+
* @TODO this is still written in a barbaric way, refactor when needed
|
418 |
+
*/
|
419 |
+
var customifyFoldingFields = function () {
|
420 |
+
|
421 |
+
if (_.isUndefined(customify_settings) || _.isUndefined(customify_settings.settings)) {
|
422 |
+
return // bail
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* Let's iterate through all the customify settings and gather all the fields that have a "show_if"
|
427 |
+
* property set.
|
428 |
+
*
|
429 |
+
* At the end `targets` will hold a list of [ target : [field, field,...], ... ]
|
430 |
+
* so when a target is changed we will change all the fields.
|
431 |
+
*/
|
432 |
+
var targets = {}
|
433 |
+
|
434 |
+
$.fn.reactor.defaults.compliant = function () {
|
435 |
+
$(this).slideDown()
|
436 |
+
// $(this).animate({opacity: 1});
|
437 |
+
$(this).find(':disabled').attr({disabled: false})
|
438 |
+
}
|
439 |
+
|
440 |
+
$.fn.reactor.defaults.uncompliant = function () {
|
441 |
+
$(this).slideUp()
|
442 |
+
// $(this).animate({opacity: 0.25});
|
443 |
+
$(this).find(':enabled').attr({disabled: true})
|
444 |
+
}
|
445 |
+
|
446 |
+
var IS = $.extend({}, $.fn.reactor.helpers)
|
447 |
+
|
448 |
+
var bind_folding_events = function (parent_id, field, relation) {
|
449 |
+
|
450 |
+
var key = null
|
451 |
+
|
452 |
+
if (_.isString(field)) {
|
453 |
+
key = field
|
454 |
+
} else if (!_.isUndefined(field.id)) {
|
455 |
+
key = field.id
|
456 |
+
} else if (isString(field[0])) {
|
457 |
+
key = field[0]
|
458 |
+
} else {
|
459 |
+
return // no key, no fun
|
460 |
+
}
|
461 |
+
|
462 |
+
var value = 1, // by default we use 1 the most used value for checkboxes or inputs
|
463 |
+
compare = '==', // ... ye
|
464 |
+
action = 'show',
|
465 |
+
between = [0, 1] // can only be `show` or `hide`
|
466 |
+
|
467 |
+
var target_key = customify_settings.options_name + '[' + key + ']'
|
468 |
+
|
469 |
+
var target_type = customify_settings.settings[target_key].type
|
470 |
+
|
471 |
+
// we support the usual syntax like a config array like `array( 'id' => $id, 'value' => $value, 'compare' => $compare )`
|
472 |
+
// but we also support a non-associative array like `array( $id, $value, $compare )`
|
473 |
+
if (!_.isUndefined(field.value)) {
|
474 |
+
value = field.value
|
475 |
+
} else if (!_.isUndefined(field[1]) && !_.isString(field[1])) {
|
476 |
+
value = field[1]
|
477 |
+
}
|
478 |
+
|
479 |
+
if (!_.isUndefined(field.compare)) {
|
480 |
+
compare = field.compare
|
481 |
+
} else if (!_.isUndefined(field[2])) {
|
482 |
+
compare = field[2]
|
483 |
+
}
|
484 |
+
|
485 |
+
if (!_.isUndefined(field.action)) {
|
486 |
+
action = field.action
|
487 |
+
} else if (!_.isUndefined(field[3])) {
|
488 |
+
action = field[3]
|
489 |
+
}
|
490 |
+
|
491 |
+
// a field can also overwrite the parent relation
|
492 |
+
if (!_.isUndefined(field.relation)) {
|
493 |
+
action = field.relation
|
494 |
+
} else if (!_.isUndefined(field[4])) {
|
495 |
+
action = field[4]
|
496 |
+
}
|
497 |
+
|
498 |
+
if (!_.isUndefined(field.between)) {
|
499 |
+
between = field.between
|
500 |
+
}
|
501 |
+
|
502 |
+
/**
|
503 |
+
* Now for each target we have, we will bind a change event to hide or show the dependent fields
|
504 |
+
*/
|
505 |
+
var target_selector = '[data-customize-setting-link="' + customify_settings.options_name + '[' + key + ']"]'
|
506 |
+
|
507 |
+
switch (target_type) {
|
508 |
+
case 'checkbox':
|
509 |
+
$(parent_id).reactIf(target_selector, function () {
|
510 |
+
return $(this).is(':checked') == value
|
511 |
+
})
|
512 |
+
break
|
513 |
+
|
514 |
+
case 'radio':
|
515 |
+
case 'sm_radio':
|
516 |
+
case 'sm_switch':
|
517 |
+
case 'radio_image':
|
518 |
+
|
519 |
+
// in case of an array of values we use the ( val in array) condition
|
520 |
+
if (_.isObject(value)) {
|
521 |
+
$(parent_id).reactIf(target_selector, function () {
|
522 |
+
return (
|
523 |
+
value.indexOf($(target_selector + ':checked').val()) !== -1
|
524 |
+
)
|
525 |
+
})
|
526 |
+
} else { // in any other case we use a simple == comparison
|
527 |
+
$(parent_id).reactIf(target_selector, function () {
|
528 |
+
return $(target_selector + ':checked').val() == value
|
529 |
+
})
|
530 |
+
}
|
531 |
+
break
|
532 |
+
|
533 |
+
case 'range':
|
534 |
+
var x = IS.Between(between[0], between[1])
|
535 |
+
|
536 |
+
$(parent_id).reactIf(target_selector, x)
|
537 |
+
break
|
538 |
+
|
539 |
+
default:
|
540 |
+
// in case of an array of values we use the ( val in array) condition
|
541 |
+
if (_.isObject(value)) {
|
542 |
+
$(parent_id).reactIf(target_selector, function () {
|
543 |
+
return (
|
544 |
+
value.indexOf($(target_selector).val()) !== -1
|
545 |
+
)
|
546 |
+
})
|
547 |
+
} else { // in any other case we use a simple == comparison
|
548 |
+
$(parent_id).reactIf(target_selector, function () {
|
549 |
+
return $(target_selector).val() == value
|
550 |
+
})
|
551 |
+
}
|
552 |
+
break
|
553 |
+
}
|
554 |
+
|
555 |
+
$(target_selector).trigger('change')
|
556 |
+
$('.reactor').trigger('change.reactor') // triggers all events on load
|
557 |
+
}
|
558 |
+
|
559 |
+
$.each(customify_settings.settings, function (id, field) {
|
560 |
+
/**
|
561 |
+
* Here we have the id of the fields. but we know for sure that we just need his parent selector
|
562 |
+
* So we just create it
|
563 |
+
*/
|
564 |
+
var parent_id = id.replace('[', '-')
|
565 |
+
parent_id = parent_id.replace(']', '')
|
566 |
+
parent_id = '#customize-control-' + parent_id + '_control'
|
567 |
+
|
568 |
+
// get only the fields that have a 'show_if' property
|
569 |
+
if (field.hasOwnProperty('show_if')) {
|
570 |
+
var relation = 'AND'
|
571 |
+
|
572 |
+
if (!_.isUndefined(field.show_if.relation)) {
|
573 |
+
relation = field.show_if.relation
|
574 |
+
// remove the relation property, we need the config to be array based only
|
575 |
+
delete field.show_if.relation
|
576 |
+
}
|
577 |
+
|
578 |
+
/**
|
579 |
+
* The 'show_if' can be a simple array with one target like: [ id, value, comparison, action ]
|
580 |
+
* Or it could be an array of multiple targets and we need to process both cases
|
581 |
+
*/
|
582 |
+
|
583 |
+
if (!_.isUndefined(field.show_if.id)) {
|
584 |
+
bind_folding_events(parent_id, field.show_if, relation)
|
585 |
+
} else if (_.isObject(field.show_if)) {
|
586 |
+
$.each(field.show_if, function (i, j) {
|
587 |
+
bind_folding_events(parent_id, j, relation)
|
588 |
+
})
|
589 |
+
}
|
590 |
+
}
|
591 |
+
})
|
592 |
+
}
|
593 |
+
|
594 |
+
var get_typography_font_family = function ($el) {
|
595 |
+
|
596 |
+
var font_family_value = $el.val()
|
597 |
+
// first time this will not be a json so catch that error
|
598 |
+
try {
|
599 |
+
font_family_value = JSON.parse(font_family_value)
|
600 |
+
} catch (e) {
|
601 |
+
return {font_family: font_family_value}
|
602 |
+
}
|
603 |
+
|
604 |
+
if (!_.isUndefined(font_family_value.font_family)) {
|
605 |
+
return font_family_value.font_family
|
606 |
+
}
|
607 |
+
|
608 |
+
return false
|
609 |
+
}
|
610 |
+
|
611 |
+
// get each typography field and bind events
|
612 |
+
// @todo Are we still using the typography field since we have the font field?
|
613 |
+
var prepare_typography_field = function () {
|
614 |
+
|
615 |
+
var $typos = $('.customify_typography_font_family')
|
616 |
+
|
617 |
+
$typos.each(function () {
|
618 |
+
var font_family_select = this,
|
619 |
+
$input = $(font_family_select).siblings('.customify_typography_values')
|
620 |
+
// on change
|
621 |
+
$(font_family_select).on('change', function () {
|
622 |
+
update_siblings_selects(font_family_select)
|
623 |
+
$input.trigger('change')
|
624 |
+
})
|
625 |
+
update_siblings_selects(font_family_select)
|
626 |
+
})
|
627 |
+
}
|
628 |
+
|
629 |
+
var api_set_setting_value = function (setting_id, value) {
|
630 |
+
let setting = api(setting_id),
|
631 |
+
field = $('[data-customize-setting-link="' + setting_id + '"]'),
|
632 |
+
field_class = $(field).parent().attr('class')
|
633 |
+
|
634 |
+
// Legacy field type
|
635 |
+
if (!_.isUndefined(field_class) && field_class === 'customify_typography') {
|
636 |
+
|
637 |
+
let family_select = field.siblings('select')
|
638 |
+
|
639 |
+
if (_.isString(value)) {
|
640 |
+
let this_option = family_select.find('option[value="' + value + '"]')
|
641 |
+
$(this_option[0]).attr('selected', 'selected')
|
642 |
+
update_siblings_selects(family_select)
|
643 |
+
} else if (_.isObject(value)) {
|
644 |
+
let this_family_option = family_select.find('option[value="' + value['font_family'] + '"]')
|
645 |
+
|
646 |
+
$(this_family_option[0]).attr('selected', 'selected')
|
647 |
+
|
648 |
+
update_siblings_selects(this_family_option)
|
649 |
+
|
650 |
+
setTimeout(function () {
|
651 |
+
let weight_select = field.parent().siblings('.options').find('.customify_typography_font_weight'),
|
652 |
+
this_weight_option = weight_select.find('option[value="' + value['selected_variants'] + '"]')
|
653 |
+
|
654 |
+
$(this_weight_option[0]).attr('selected', 'selected')
|
655 |
+
|
656 |
+
update_siblings_selects(this_family_option)
|
657 |
+
|
658 |
+
weight_select.trigger('change')
|
659 |
+
}, 300)
|
660 |
+
}
|
661 |
+
|
662 |
+
family_select.trigger('change')
|
663 |
+
|
664 |
+
} else if (!_.isUndefined(field_class) && field_class === 'font-options__wrapper') {
|
665 |
+
|
666 |
+
// if the value is a simple string it must be the font family
|
667 |
+
if (_.isString(value)) {
|
668 |
+
let option = field.parent().find('option[value="' + value + '"]')
|
669 |
+
|
670 |
+
option.attr('selected', 'selected')
|
671 |
+
// option.parents('select').trigger('change');
|
672 |
+
} else if (_.isObject(value)) {
|
673 |
+
// Find the options list wrapper
|
674 |
+
let optionsList = field.parent().children('.font-options__options-list')
|
675 |
+
|
676 |
+
if (optionsList.length) {
|
677 |
+
// We will process each font property and update it
|
678 |
+
_.each(value, function (val, key) {
|
679 |
+
// We need to map the keys to the data attributes we are using - I know :(
|
680 |
+
let mappedKey = key
|
681 |
+
switch (key) {
|
682 |
+
case 'font-family':
|
683 |
+
mappedKey = 'font_family'
|
684 |
+
break
|
685 |
+
case 'font-size':
|
686 |
+
mappedKey = 'font_size'
|
687 |
+
break
|
688 |
+
case 'font-weight':
|
689 |
+
mappedKey = 'selected_variants'
|
690 |
+
break
|
691 |
+
case 'letter-spacing':
|
692 |
+
mappedKey = 'letter_spacing'
|
693 |
+
break
|
694 |
+
case 'text-transform':
|
695 |
+
mappedKey = 'text_transform'
|
696 |
+
break
|
697 |
+
default:
|
698 |
+
break
|
699 |
+
}
|
700 |
+
let subField = optionsList.find('[data-field="' + mappedKey + '"]')
|
701 |
+
if (subField.length) {
|
702 |
+
subField.val(val)
|
703 |
+
subField.trigger('change')
|
704 |
+
}
|
705 |
+
})
|
706 |
+
}
|
707 |
+
}
|
708 |
+
|
709 |
+
} else {
|
710 |
+
setting.set(value)
|
711 |
+
}
|
712 |
+
}
|
713 |
+
|
714 |
+
var update_siblings_selects = function (font_select) {
|
715 |
+
var selected_font = $(font_select).val(),
|
716 |
+
$input = $(font_select).siblings('.customify_typography_values'),
|
717 |
+
current_val = $input.attr('value')
|
718 |
+
|
719 |
+
if (current_val === '[object Object]') {
|
720 |
+
current_val = $input.data('default')
|
721 |
+
} else if (_.isString(current_val) && !isJsonString(current_val) && current_val.substr(0, 1) == '[') {
|
722 |
+
// a rare case when the value isn't a json but is a representative string like [family,weight]
|
723 |
+
current_val = current_val.split(',')
|
724 |
+
var new_current_value = {}
|
725 |
+
if (!_.isUndefined(current_val[0])) {
|
726 |
+
new_current_value['font_family'] = current_val[0]
|
727 |
+
}
|
728 |
+
|
729 |
+
if (!_.isUndefined(current_val[1])) {
|
730 |
+
new_current_value['selected_variants'] = current_val[1]
|
731 |
+
}
|
732 |
+
|
733 |
+
current_val = JSON.stringify(new_current_value)
|
734 |
+
}
|
735 |
+
|
736 |
+
var $font_weight = $(font_select).parent().siblings('ul.options').find('.customify_typography_font_weight'),
|
737 |
+
$font_subsets = $(font_select).parent().siblings('ul.options').find('.customify_typography_font_subsets')
|
738 |
+
|
739 |
+
try {
|
740 |
+
current_val = JSON.parse(decodeURIComponent(current_val))
|
741 |
+
} catch (e) {
|
742 |
+
|
743 |
+
// in case of an error, force the rebuild of the json
|
744 |
+
if (_.isUndefined($(font_select).data('bound_once'))) {
|
745 |
+
|
746 |
+
$(font_select).data('bound_once', true)
|
747 |
+
|
748 |
+
$(font_select).change()
|
749 |
+
$font_weight.change()
|
750 |
+
$font_subsets.change()
|
751 |
+
}
|
752 |
+
}
|
753 |
+
|
754 |
+
// first try to get the font from sure sources, not from the recommended list.
|
755 |
+
var option_data = $(font_select).find(':not(optgroup[label=Recommended]) option[value="' + selected_font + '"]')
|
756 |
+
// however, if there isn't an option found, get what you can
|
757 |
+
if (option_data.length < 1) {
|
758 |
+
option_data = $(font_select).find('option[value="' + selected_font + '"]')
|
759 |
+
}
|
760 |
+
|
761 |
+
if (option_data.length > 0) {
|
762 |
+
|
763 |
+
var font_type = option_data.data('type'),
|
764 |
+
value_to_add = {'type': font_type, 'font_family': selected_font},
|
765 |
+
variants = null,
|
766 |
+
subsets = null
|
767 |
+
|
768 |
+
if (font_type == 'std') {
|
769 |
+
variants = {
|
770 |
+
0: '100',
|
771 |
+
1: '200',
|
772 |
+
3: '300',
|
773 |
+
4: '400',
|
774 |
+
5: '500',
|
775 |
+
6: '600',
|
776 |
+
7: '700',
|
777 |
+
8: '800',
|
778 |
+
9: '900'
|
779 |
+
}
|
780 |
+
if (!_.isUndefined($(option_data[0]).data('variants'))) {
|
781 |
+
//maybe the variants are a JSON
|
782 |
+
variants = maybeJsonParse($(option_data[0]).data('variants'))
|
783 |
+
}
|
784 |
+
} else {
|
785 |
+
//maybe the variants are a JSON
|
786 |
+
variants = maybeJsonParse($(option_data[0]).data('variants'))
|
787 |
+
|
788 |
+
//maybe the subsets are a JSON
|
789 |
+
subsets = maybeJsonParse($(option_data[0]).data('subsets'))
|
790 |
+
}
|
791 |
+
|
792 |
+
// make the variants selector
|
793 |
+
if (!_.isUndefined(variants) && !_.isNull(variants) && !_.isEmpty(variants)) {
|
794 |
+
|
795 |
+
value_to_add['variants'] = variants
|
796 |
+
// when a font is selected force the first weight to load
|
797 |
+
value_to_add['selected_variants'] = {0: variants[0]}
|
798 |
+
|
799 |
+
var variants_options = '',
|
800 |
+
count_weights = 0
|
801 |
+
|
802 |
+
if (_.isArray(variants) || _.isObject(variants)) {
|
803 |
+
// Take each variant and produce the option markup
|
804 |
+
$.each(variants, function (key, el) {
|
805 |
+
var is_selected = ''
|
806 |
+
if (_.isObject(current_val.selected_variants) && inObject(el, current_val.selected_variants)) {
|
807 |
+
is_selected = ' selected="selected"'
|
808 |
+
} else if (_.isString(current_val.selected_variants) && el === current_val.selected_variants) {
|
809 |
+
is_selected = ' selected="selected"'
|
810 |
+
}
|
811 |
+
|
812 |
+
// initialize
|
813 |
+
var variant_option_value = el,
|
814 |
+
variant_option_display = el
|
815 |
+
|
816 |
+
// If we are dealing with a object variant then it means things get tricky (probably it's our fault but bear with us)
|
817 |
+
// This probably comes from our Fonto plugin - a font with individually named variants - hence each has its own font-family
|
818 |
+
if (_.isObject(el)) {
|
819 |
+
//put the entire object in the variation value - we will need it when outputting the custom CSS
|
820 |
+
variant_option_value = encodeURIComponent(JSON.stringify(el))
|
821 |
+
variant_option_display = ''
|
822 |
+
|
823 |
+
//if we have weight and style then "compose" them into something standard
|
824 |
+
if (!_.isUndefined(el['font-weight'])) {
|
825 |
+
variant_option_display += el['font-weight']
|
826 |
+
}
|
827 |
+
|
828 |
+
if (_.isString(el['font-style']) && $.inArray(el['font-style'].toLowerCase(), [
|
829 |
+
'normal',
|
830 |
+
'regular'
|
831 |
+
]) < 0) { //this comparison means it hasn't been found
|
832 |
+
variant_option_display += el['font-style']
|
833 |
+
}
|
834 |
+
}
|
835 |
+
|
836 |
+
variants_options += '<option value="' + variant_option_value + '"' + is_selected + '>' + variant_option_display + '</option>'
|
837 |
+
count_weights++
|
838 |
+
})
|
839 |
+
}
|
840 |
+
|
841 |
+
if (!_.isUndefined($font_weight)) {
|
842 |
+
$font_weight.html(variants_options)
|
843 |
+
// if there is no weight or just 1 we hide the weight select ... cuz is useless
|
844 |
+
if ($(font_select).data('load_all_weights') === true || count_weights <= 1) {
|
845 |
+
$font_weight.parent().css('display', 'none')
|
846 |
+
} else {
|
847 |
+
$font_weight.parent().css('display', 'inline-block')
|
848 |
+
}
|
849 |
+
}
|
850 |
+
} else if (!_.isUndefined($font_weight)) {
|
851 |
+
$font_weight.parent().css('display', 'none')
|
852 |
+
}
|
853 |
+
|
854 |
+
// make the subsets selector
|
855 |
+
if (!_.isUndefined(subsets) && !_.isNull(subsets) && !_.isEmpty(subsets)) {
|
856 |
+
|
857 |
+
value_to_add['subsets'] = subsets
|
858 |
+
// when a font is selected force the first subset to load
|
859 |
+
value_to_add['selected_subsets'] = {0: subsets[0]}
|
860 |
+
var subsets_options = '',
|
861 |
+
count_subsets = 0
|
862 |
+
$.each(subsets, function (key, el) {
|
863 |
+
var is_selected = ''
|
864 |
+
if (_.isObject(current_val.selected_subsets) && inObject(el, current_val.selected_subsets)) {
|
865 |
+
is_selected = ' selected="selected"'
|
866 |
+
}
|
867 |
+
|
868 |
+
subsets_options += '<option value="' + el + '"' + is_selected + '>' + el + '</option>'
|
869 |
+
count_subsets++
|
870 |
+
})
|
871 |
+
|
872 |
+
if (!_.isUndefined($font_subsets)) {
|
873 |
+
$font_subsets.html(subsets_options)
|
874 |
+
|
875 |
+
// if there is no subset or just 1 we hide the subsets select ... cuz is useless
|
876 |
+
if (count_subsets <= 1) {
|
877 |
+
$font_subsets.parent().css('display', 'none')
|
878 |
+
} else {
|
879 |
+
$font_subsets.parent().css('display', 'inline-block')
|
880 |
+
}
|
881 |
+
}
|
882 |
+
} else if (!_.isUndefined($font_subsets)) {
|
883 |
+
$font_subsets.parent().css('display', 'none')
|
884 |
+
}
|
885 |
+
|
886 |
+
$input.val(encodeURIComponent(JSON.stringify(value_to_add)))
|
887 |
+
}
|
888 |
+
}
|
889 |
+
|
890 |
+
/** Modules **/
|
891 |
+
|
892 |
+
var customifyBackgroundJsControl = (
|
893 |
+
function () {
|
894 |
+
'use strict'
|
895 |
+
|
896 |
+
function init () {
|
897 |
+
// Remove the image button
|
898 |
+
$('.customize-control-custom_background .remove-image, .customize-control-custom_background .remove-file').unbind('click').on('click', function (e) {
|
899 |
+
removeImage($(this).parents('.customize-control-custom_background:first'))
|
900 |
+
preview($(this))
|
901 |
+
return false
|
902 |
+
})
|
903 |
+
|
904 |
+
// Upload media button
|
905 |
+
$('.customize-control-custom_background .background_upload_button').unbind().on('click', function (event) {
|
906 |
+
addImage(event, $(this).parents('.customize-control-custom_background:first'))
|
907 |
+
})
|
908 |
+
|
909 |
+
$('.customify_background_select').on('change', function () {
|
910 |
+
preview($(this))
|
911 |
+
})
|
912 |
+
}
|
913 |
+
|
914 |
+
// Add a file via the wp.media function
|
915 |
+
function addImage (event, selector) {
|
916 |
+
|
917 |
+
event.preventDefault()
|
918 |
+
|
919 |
+
var frame
|
920 |
+
var jQueryel = jQuery(this)
|
921 |
+
|
922 |
+
// If the media frame already exists, reopen it.
|
923 |
+
if (frame) {
|
924 |
+
frame.open()
|
925 |
+
return
|
926 |
+
}
|
927 |
+
|
928 |
+
// Create the media frame.
|
929 |
+
frame = wp.media({
|
930 |
+
multiple: false,
|
931 |
+
library: {
|
932 |
+
//type: 'image' //Only allow images
|
933 |
+
},
|
934 |
+
// Set the title of the modal.
|
935 |
+
title: jQueryel.data('choose'),
|
936 |
+
|
937 |
+
// Customize the submit button.
|
938 |
+
button: {
|
939 |
+
// Set the text of the button.
|
940 |
+
text: jQueryel.data('update')
|
941 |
+
// Tell the button not to close the modal, since we're
|
942 |
+
// going to refresh the page when the image is selected.
|
943 |
+
}
|
944 |
+
})
|
945 |
+
|
946 |
+
// When an image is selected, run a callback.
|
947 |
+
frame.on('select', function () {
|
948 |
+
// Grab the selected attachment.
|
949 |
+
var attachment = frame.state().get('selection').first()
|
950 |
+
frame.close()
|
951 |
+
|
952 |
+
if (attachment.attributes.type !== 'image') {
|
953 |
+
return
|
954 |
+
}
|
955 |
+
|
956 |
+
selector.find('.upload').attr('value', attachment.attributes.url)
|
957 |
+
selector.find('.upload-id').attr('value', attachment.attributes.id)
|
958 |
+
selector.find('.upload-height').attr('value', attachment.attributes.height)
|
959 |
+
selector.find('.upload-width').attr('value', attachment.attributes.width)
|
960 |
+
|
961 |
+
var thumbSrc = attachment.attributes.url
|
962 |
+
if (!_.isUndefined(attachment.attributes.sizes) && !_.isUndefined(attachment.attributes.sizes.thumbnail)) {
|
963 |
+
thumbSrc = attachment.attributes.sizes.thumbnail.url
|
964 |
+
} else if (!_.isUndefined(attachment.attributes.sizes)) {
|
965 |
+
var height = attachment.attributes.height
|
966 |
+
for (var key in attachment.attributes.sizes) {
|
967 |
+
var object = attachment.attributes.sizes[key]
|
968 |
+
if (object.height < height) {
|
969 |
+
height = object.height
|
970 |
+
thumbSrc = object.url
|
971 |
+
}
|
972 |
+
}
|
973 |
+
} else {
|
974 |
+
thumbSrc = attachment.attributes.icon
|
975 |
+
}
|
976 |
+
|
977 |
+
selector.find('.customify_background_input.background-image').val(attachment.attributes.url)
|
978 |
+
|
979 |
+
if (!selector.find('.upload').hasClass('noPreview')) {
|
980 |
+
selector.find('.preview_screenshot').empty().hide().append('<img class="preview_image" src="' + thumbSrc + '">').slideDown('fast')
|
981 |
+
}
|
982 |
+
//selector.find('.media_upload_button').unbind();
|
983 |
+
selector.find('.remove-image').removeClass('hide')//show "Remove" button
|
984 |
+
selector.find('.customify_background_select').removeClass('hide')//show "Remove" button
|
985 |
+
|
986 |
+
preview(selector)
|
987 |
+
})
|
988 |
+
|
989 |
+
// Finally, open the modal.
|
990 |
+
frame.open()
|
991 |
+
}
|
992 |
+
|
993 |
+
// Update the background preview
|
994 |
+
function preview (selector) {
|
995 |
+
|
996 |
+
var $parent = selector.parents('.customize-control-custom_background:first')
|
997 |
+
|
998 |
+
if (selector.hasClass('customize-control-custom_background')) {
|
999 |
+
$parent = selector
|
1000 |
+
}
|
1001 |
+
|
1002 |
+
if ($parent.length > 0) {
|
1003 |
+
$parent = $($parent[0])
|
1004 |
+
} else {
|
1005 |
+
return
|
1006 |
+
}
|
1007 |
+
|
1008 |
+
var image_holder = $parent.find('.background-preview')
|
1009 |
+
|
1010 |
+
if (!image_holder) { // No preview present
|
1011 |
+
return
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
var the_id = $parent.find('.button.background_upload_button').data('setting_id'),
|
1015 |
+
this_setting = api.instance(the_id)
|
1016 |
+
|
1017 |
+
var background_data = {}
|
1018 |
+
|
1019 |
+
$parent.find('.customify_background_select, .customify_background_input').each(function () {
|
1020 |
+
var data = $(this).serializeArray()
|
1021 |
+
|
1022 |
+
data = data[0]
|
1023 |
+
if (data && data.name.indexOf('[background-') != -1) {
|
1024 |
+
|
1025 |
+
background_data[$(this).data('select_name')] = data.value
|
1026 |
+
|
1027 |
+
//default_default[data.name] = data.value;
|
1028 |
+
//if (data.name == "background-image") {
|
1029 |
+
// css += data.name + ':url("' + data.value + '");';
|
1030 |
+
//} else {
|
1031 |
+
// css += data.name + ':' + data.value + ';';
|
1032 |
+
//}
|
1033 |
+
}
|
1034 |
+
})
|
1035 |
+
|
1036 |
+
api.instance(the_id).set(background_data)
|
1037 |
+
//// Notify the customizer api about this change
|
1038 |
+
api.trigger('change')
|
1039 |
+
api.previewer.refresh()
|
1040 |
+
|
1041 |
+
//image_holder.attr('style', css).fadeIn();
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
// Update the background preview
|
1045 |
+
function removeImage (parent) {
|
1046 |
+
var selector = parent.find('.upload_button_div')
|
1047 |
+
// This shouldn't have been run...
|
1048 |
+
if (!selector.find('.remove-image').addClass('hide')) {
|
1049 |
+
return
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
selector.find('.remove-image').addClass('hide')//hide "Remove" button
|
1053 |
+
parent.find('.customify_background_select').addClass('hide')
|
1054 |
+
|
1055 |
+
selector.find('.upload').val('')
|
1056 |
+
selector.find('.upload-id').val('')
|
1057 |
+
selector.find('.upload-height').val('')
|
1058 |
+
selector.find('.upload-width').val('')
|
1059 |
+
parent.find('.customify_background_input.background-image').val('')
|
1060 |
+
|
1061 |
+
var customizer_id = selector.find('.background_upload_button').data('setting_id'),
|
1062 |
+
this_setting = api.control(customizer_id + '_control'),
|
1063 |
+
current_vals = this_setting.setting(),
|
1064 |
+
screenshot = parent.find('.preview_screenshot'),
|
1065 |
+
to_array = $.map(current_vals, function (value, index) {
|
1066 |
+
return [value]
|
1067 |
+
})
|
1068 |
+
|
1069 |
+
// Hide the screenshot
|
1070 |
+
screenshot.slideUp()
|
1071 |
+
selector.find('.remove-file').unbind()
|
1072 |
+
to_array['background-image'] = ''
|
1073 |
+
this_setting.setting(to_array)
|
1074 |
+
}
|
1075 |
+
|
1076 |
+
return {
|
1077 |
+
init: init
|
1078 |
+
}
|
1079 |
+
}
|
1080 |
+
)(jQuery)
|
1081 |
+
|
1082 |
+
var Queue = function () {
|
1083 |
+
var lastPromise = null
|
1084 |
+
var queueDeferred = null
|
1085 |
+
var methodDeferred = null
|
1086 |
+
|
1087 |
+
this.add_steps = function (key, steps, args) {
|
1088 |
+
var self = this
|
1089 |
+
this.methodDeferred = $.Deferred()
|
1090 |
+
this.queueDeferred = this.setup()
|
1091 |
+
|
1092 |
+
$.each(steps, function (i, step) {
|
1093 |
+
self.queue(key, step)
|
1094 |
+
})
|
1095 |
+
}
|
1096 |
+
|
1097 |
+
this.process_remote_step = function (key, data, step) {
|
1098 |
+
var self = this
|
1099 |
+
|
1100 |
+
if (_.isUndefined(data) || _.isNull(data)) {
|
1101 |
+
return false
|
1102 |
+
}
|
1103 |
+
|
1104 |
+
var new_step = step
|
1105 |
+
$.each(data, function (i, k) {
|
1106 |
+
debugger
|
1107 |
+
// prepare data for new requests
|
1108 |
+
new_step.recall_data = k.data
|
1109 |
+
new_step.recall_type = k.type
|
1110 |
+
new_step.type = 'recall'
|
1111 |
+
|
1112 |
+
self.queue(key, new_step, k.id)
|
1113 |
+
})
|
1114 |
+
}
|
1115 |
+
|
1116 |
+
this.log_action = function (action, key, msg) {
|
1117 |
+
if (action === 'start') {
|
1118 |
+
$('.wpGrade-import-results').show()
|
1119 |
+
$('.wpGrade-import-results').append('<span class="import_step_note imports_step_' + key + '" ><span class="step_info" data-balloon="Working on it" data-balloon-pos="up"></span>Importing ' + key + '</span>')
|
1120 |
+
} else if (action === 'end') {
|
1121 |
+
var $notice = $('.imports_step_' + key + ' .step_info')
|
1122 |
+
|
1123 |
+
if ($notice.length > 0 || msg !== 'undefined') {
|
1124 |
+
$notice.attr('data-balloon', msg)
|
1125 |
+
$notice.addClass('success')
|
1126 |
+
} else {
|
1127 |
+
$notice.attr('data-balloon', 'Done')
|
1128 |
+
$notice.addClass('failed')
|
1129 |
+
}
|
1130 |
+
}
|
1131 |
+
}
|
1132 |
+
|
1133 |
+
this.queue = function (key, data, step_key) {
|
1134 |
+
var self = this
|
1135 |
+
if (!_.isUndefined(step_key)) {
|
1136 |
+
this.log_action('start', step_key)
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
// execute next queue method
|
1140 |
+
this.queueDeferred.done(this.request(key, data, step_key))
|
1141 |
+
lastPromise = self.methodDeferred.promise()
|
1142 |
+
}
|
1143 |
+
|
1144 |
+
this.request = function (key, step, step_key) {
|
1145 |
+
var self = this
|
1146 |
+
// call actual method and wrap output in deferred
|
1147 |
+
//setTimeout( function() {
|
1148 |
+
var data_args = {
|
1149 |
+
action: 'customify_import_step',
|
1150 |
+
step_id: step.id,
|
1151 |
+
step_type: step.type,
|
1152 |
+
option_key: key
|
1153 |
+
}
|
1154 |
+
|
1155 |
+
if (!_.isUndefined(step.recall_data)) {
|
1156 |
+
data_args.recall_data = step.recall_data
|
1157 |
+
}
|
1158 |
+
|
1159 |
+
if (!_.isUndefined(step.recall_type)) {
|
1160 |
+
data_args.recall_type = step.recall_type
|
1161 |
+
}
|
1162 |
+
|
1163 |
+
$.ajax({
|
1164 |
+
url: customify_settings.import_rest_url + 'customify/1.0/import',
|
1165 |
+
method: 'POST',
|
1166 |
+
beforeSend: function (xhr) {
|
1167 |
+
xhr.setRequestHeader('X-WP-Nonce', WP_API_Settings.nonce)
|
1168 |
+
},
|
1169 |
+
dataType: 'json',
|
1170 |
+
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
1171 |
+
data: data_args
|
1172 |
+
}).done(function (response) {
|
1173 |
+
if (!_.isUndefined(response.success) && response.success) {
|
1174 |
+
var results = response.data
|
1175 |
+
if (step.type === 'remote') {
|
1176 |
+
self.process_remote_step(key, results, step)
|
1177 |
+
}
|
1178 |
+
}
|
1179 |
+
|
1180 |
+
if (!_.isUndefined(step_key) && !_.isUndefined(response.message)) {
|
1181 |
+
self.log_action('end', step_key, response.message)
|
1182 |
+
}
|
1183 |
+
})
|
1184 |
+
|
1185 |
+
self.methodDeferred.resolve()
|
1186 |
+
//}, 3450 );
|
1187 |
+
}
|
1188 |
+
|
1189 |
+
this.setup = function () {
|
1190 |
+
var self = this
|
1191 |
+
|
1192 |
+
self.queueDeferred = $.Deferred()
|
1193 |
+
|
1194 |
+
// when the previous method returns, resolve this one
|
1195 |
+
$.when(lastPromise).always(function () {
|
1196 |
+
self.queueDeferred.resolve()
|
1197 |
+
})
|
1198 |
+
|
1199 |
+
return self.queueDeferred.promise()
|
1200 |
+
}
|
1201 |
+
}
|
1202 |
+
|
1203 |
+
/** HELPERS **/
|
1204 |
+
|
1205 |
+
/**
|
1206 |
+
* Function to check if a value exists in an object
|
1207 |
+
* @param value
|
1208 |
+
* @param obj
|
1209 |
+
* @returns {boolean}
|
1210 |
+
*/
|
1211 |
+
var inObject = function (value, obj) {
|
1212 |
+
for (var k in obj) {
|
1213 |
+
if (!obj.hasOwnProperty(k)) {
|
1214 |
+
continue
|
1215 |
+
}
|
1216 |
+
if (_.isEqual(obj[k], value)) {
|
1217 |
+
return true
|
1218 |
+
}
|
1219 |
+
}
|
1220 |
+
return false
|
1221 |
+
}
|
1222 |
+
|
1223 |
+
var maybeJsonParse = function (value) {
|
1224 |
+
var parsed
|
1225 |
+
|
1226 |
+
//try and parse it, with decodeURIComponent
|
1227 |
+
try {
|
1228 |
+
parsed = JSON.parse(decodeURIComponent(value))
|
1229 |
+
} catch (e) {
|
1230 |
+
|
1231 |
+
// in case of an error, treat is as a string
|
1232 |
+
parsed = value
|
1233 |
+
}
|
1234 |
+
|
1235 |
+
return parsed
|
1236 |
+
}
|
1237 |
+
|
1238 |
+
var getUrlVars = function (name) {
|
1239 |
+
var vars = [], hash
|
1240 |
+
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&')
|
1241 |
+
for (var i = 0; i < hashes.length; i++) {
|
1242 |
+
hash = hashes[i].split('=')
|
1243 |
+
|
1244 |
+
vars.push(hash[0])
|
1245 |
+
vars[hash[0]] = hash[1]
|
1246 |
+
}
|
1247 |
+
|
1248 |
+
if (!_.isUndefined(vars[name])) {
|
1249 |
+
return vars[name]
|
1250 |
+
}
|
1251 |
+
return false
|
1252 |
+
}
|
1253 |
+
|
1254 |
+
var isJsonString = function (str) {
|
1255 |
+
try {
|
1256 |
+
JSON.parse(str)
|
1257 |
+
} catch (e) {
|
1258 |
+
return false
|
1259 |
+
}
|
1260 |
+
return true
|
1261 |
+
}
|
1262 |
+
}
|
1263 |
)(jQuery, window, wp)
|
js/customizer/style-manager.js
CHANGED
@@ -1,158 +1,157 @@
|
|
1 |
(
|
2 |
-
function(
|
3 |
-
var api = wp.customize
|
4 |
-
var $window = $(
|
5 |
|
6 |
-
wp.customize.bind(
|
7 |
|
8 |
// Handle the Style Manager user feedback logic.
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
}
|
106 |
}
|
107 |
-
)(
|
108 |
-
|
109 |
|
110 |
// Reverses a hex color to either black or white
|
111 |
-
function customifyInverseHexColorToBlackOrWhite(
|
112 |
-
return customifyInverseHexColor(
|
113 |
}
|
114 |
|
115 |
// Taken from here: https://stackoverflow.com/a/35970186/6260836
|
116 |
-
function customifyInverseHexColor(
|
117 |
-
if (
|
118 |
-
hex = hex.slice(
|
119 |
}
|
120 |
// convert 3-digit hex to 6-digits.
|
121 |
-
if (
|
122 |
-
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
|
123 |
}
|
124 |
-
if (
|
125 |
-
throw new Error(
|
126 |
}
|
127 |
-
var r = parseInt(
|
128 |
-
g = parseInt(
|
129 |
-
b = parseInt(
|
130 |
-
if (
|
131 |
// http://stackoverflow.com/a/3943023/112731
|
132 |
return (
|
133 |
-
|
134 |
-
|
135 |
? '#000000'
|
136 |
-
: '#FFFFFF'
|
137 |
}
|
138 |
// invert color components
|
139 |
r = (
|
140 |
255 - r
|
141 |
-
).toString(
|
142 |
g = (
|
143 |
255 - g
|
144 |
-
).toString(
|
145 |
b = (
|
146 |
255 - b
|
147 |
-
).toString(
|
148 |
// pad each with zeros and return
|
149 |
-
return
|
150 |
}
|
151 |
|
152 |
-
function customifyPadZero(
|
153 |
-
len = len || 2
|
154 |
-
var zeros = new Array(
|
155 |
return (
|
156 |
zeros + str
|
157 |
-
).slice(
|
158 |
}
|
1 |
(
|
2 |
+
function ($, exports, wp) {
|
3 |
+
var api = wp.customize
|
4 |
+
var $window = $(window)
|
5 |
|
6 |
+
wp.customize.bind('ready', function () {
|
7 |
|
8 |
// Handle the Style Manager user feedback logic.
|
9 |
+
var $styleManagerUserFeedbackModal = $('#style-manager-user-feedback-modal')
|
10 |
+
if ($styleManagerUserFeedbackModal.length) {
|
11 |
+
var $styleManagerUserFeedbackForm = $styleManagerUserFeedbackModal.find('form'),
|
12 |
+
$styleManagerUserFeedbackCloseBtn = $styleManagerUserFeedbackModal.find('.close'),
|
13 |
+
$styleManagerUserFeedbackFirstStep = $styleManagerUserFeedbackModal.find('.first-step'),
|
14 |
+
$styleManagerUserFeedbackSecondStep = $styleManagerUserFeedbackModal.find('.second-step'),
|
15 |
+
$styleManagerUserFeedbackThanksStep = $styleManagerUserFeedbackModal.find('.thanks-step'),
|
16 |
+
$styleManagerUserFeedbackErrorStep = $styleManagerUserFeedbackModal.find('.error-step'),
|
17 |
+
styleManagerUserFeedbackModalShown = false,
|
18 |
+
styleManagerColorPaletteChanged = false
|
19 |
+
|
20 |
+
// Handle when to open the modal.
|
21 |
+
api.bind('saved', function () {
|
22 |
+
// We will only show the modal once per Customizer session.
|
23 |
+
if (!styleManagerUserFeedbackModalShown && styleManagerColorPaletteChanged) {
|
24 |
+
$('body').addClass('modal-open')
|
25 |
+
styleManagerUserFeedbackModalShown = true
|
26 |
+
}
|
27 |
+
})
|
28 |
+
|
29 |
+
// Handle the color palette changed info update.
|
30 |
+
const colorPaletteSetting = api('sm_color_palette')
|
31 |
+
if (!_.isUndefined(colorPaletteSetting)) {
|
32 |
+
colorPaletteSetting.bind(function (new_value, old_value) {
|
33 |
+
if (new_value != old_value) {
|
34 |
+
styleManagerColorPaletteChanged = true
|
35 |
+
}
|
36 |
+
})
|
37 |
+
}
|
38 |
+
const colorPaletteVariationSetting = api('sm_color_palette_variation')
|
39 |
+
if (!_.isUndefined(colorPaletteVariationSetting)) {
|
40 |
+
colorPaletteVariationSetting.bind(function (new_value, old_value) {
|
41 |
+
if (new_value != old_value) {
|
42 |
+
styleManagerColorPaletteChanged = true
|
43 |
+
}
|
44 |
+
})
|
45 |
+
}
|
46 |
+
|
47 |
+
// Handle the modal submit.
|
48 |
+
$styleManagerUserFeedbackForm.on('submit', function (event) {
|
49 |
+
event.preventDefault()
|
50 |
+
|
51 |
+
let $form = $(event.target)
|
52 |
+
|
53 |
+
let data = {
|
54 |
+
action: 'customify_style_manager_user_feedback',
|
55 |
+
nonce: customify_settings.style_manager_user_feedback_nonce,
|
56 |
+
type: $form.find('input[name=type]').val(),
|
57 |
+
rating: $form.find('input[name=rating]:checked').val(),
|
58 |
+
message: $form.find('textarea[name=message]').val()
|
59 |
+
}
|
60 |
+
|
61 |
+
$.post(
|
62 |
+
customify_settings.ajax_url,
|
63 |
+
data,
|
64 |
+
function (response) {
|
65 |
+
if (true === response.success) {
|
66 |
+
$styleManagerUserFeedbackFirstStep.hide()
|
67 |
+
$styleManagerUserFeedbackSecondStep.hide()
|
68 |
+
$styleManagerUserFeedbackThanksStep.show()
|
69 |
+
$styleManagerUserFeedbackErrorStep.hide()
|
70 |
+
} else {
|
71 |
+
$styleManagerUserFeedbackFirstStep.hide()
|
72 |
+
$styleManagerUserFeedbackSecondStep.hide()
|
73 |
+
$styleManagerUserFeedbackThanksStep.hide()
|
74 |
+
$styleManagerUserFeedbackErrorStep.show()
|
75 |
+
}
|
76 |
+
}
|
77 |
+
)
|
78 |
+
})
|
79 |
+
|
80 |
+
$styleManagerUserFeedbackForm.find('input[name=rating]').on('change', function (event) {
|
81 |
+
// Leave everything in working order
|
82 |
+
setTimeout(function () {
|
83 |
+
$styleManagerUserFeedbackSecondStep.show()
|
84 |
+
}, 300)
|
85 |
+
|
86 |
+
let rating = $styleManagerUserFeedbackForm.find('input[name=rating]:checked').val()
|
87 |
+
|
88 |
+
$styleManagerUserFeedbackForm.find('.rating-placeholder').text(rating)
|
89 |
+
})
|
90 |
+
|
91 |
+
$styleManagerUserFeedbackCloseBtn.on('click', function (event) {
|
92 |
+
event.preventDefault()
|
93 |
+
|
94 |
+
$('body').removeClass('modal-open')
|
95 |
+
|
96 |
+
// Leave everything in working order
|
97 |
+
setTimeout(function () {
|
98 |
+
$styleManagerUserFeedbackFirstStep.show()
|
99 |
+
$styleManagerUserFeedbackSecondStep.hide()
|
100 |
+
$styleManagerUserFeedbackThanksStep.hide()
|
101 |
+
$styleManagerUserFeedbackErrorStep.hide()
|
102 |
+
}, 300)
|
103 |
+
})
|
104 |
+
}
|
105 |
+
})
|
106 |
}
|
107 |
+
)(jQuery, window, wp)
|
|
|
108 |
|
109 |
// Reverses a hex color to either black or white
|
110 |
+
function customifyInverseHexColorToBlackOrWhite (hex) {
|
111 |
+
return customifyInverseHexColor(hex, true)
|
112 |
}
|
113 |
|
114 |
// Taken from here: https://stackoverflow.com/a/35970186/6260836
|
115 |
+
function customifyInverseHexColor (hex, bw) {
|
116 |
+
if (hex.indexOf('#') === 0) {
|
117 |
+
hex = hex.slice(1)
|
118 |
}
|
119 |
// convert 3-digit hex to 6-digits.
|
120 |
+
if (hex.length === 3) {
|
121 |
+
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
|
122 |
}
|
123 |
+
if (hex.length !== 6) {
|
124 |
+
throw new Error('Invalid HEX color.')
|
125 |
}
|
126 |
+
var r = parseInt(hex.slice(0, 2), 16),
|
127 |
+
g = parseInt(hex.slice(2, 4), 16),
|
128 |
+
b = parseInt(hex.slice(4, 6), 16)
|
129 |
+
if (bw) {
|
130 |
// http://stackoverflow.com/a/3943023/112731
|
131 |
return (
|
132 |
+
r * 0.299 + g * 0.587 + b * 0.114
|
133 |
+
) > 186
|
134 |
? '#000000'
|
135 |
+
: '#FFFFFF'
|
136 |
}
|
137 |
// invert color components
|
138 |
r = (
|
139 |
255 - r
|
140 |
+
).toString(16)
|
141 |
g = (
|
142 |
255 - g
|
143 |
+
).toString(16)
|
144 |
b = (
|
145 |
255 - b
|
146 |
+
).toString(16)
|
147 |
// pad each with zeros and return
|
148 |
+
return '#' + customifyPadZero(r) + customifyPadZero(g) + customifyPadZero(b)
|
149 |
}
|
150 |
|
151 |
+
function customifyPadZero (str, len) {
|
152 |
+
len = len || 2
|
153 |
+
var zeros = new Array(len).join('0')
|
154 |
return (
|
155 |
zeros + str
|
156 |
+
).slice(-len)
|
157 |
}
|
js/customizer_preview.js
CHANGED
@@ -1,338 +1,338 @@
|
|
1 |
;(function ($, window, document, undefined) {
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
})(jQuery, window, document)
|
1 |
;(function ($, window, document, undefined) {
|
2 |
|
3 |
+
const fonts_cache = []
|
4 |
|
5 |
+
$(document).ready(function () {
|
6 |
+
var api = parent.wp.customize,
|
7 |
+
wp_settings = api.settings.settings
|
8 |
|
9 |
+
load_webfont_once()
|
10 |
+
|
11 |
+
$.each(customify_settings.settings, function (key, el) {
|
12 |
|
13 |
+
if (el.type === 'font') {
|
14 |
+
api(key, function (setting) {
|
15 |
+
setting.bind(function (to) {
|
16 |
+
let $values = maybeJsonParse(to)
|
17 |
+
|
18 |
+
if (typeof $values !== 'undefined') {
|
19 |
+
if (typeof $values.font_family !== 'undefined') {
|
20 |
+
maybeLoadFontFamily($values)
|
21 |
+
}
|
22 |
+
|
23 |
+
let vls = get_CSS_values(this.id, $values),
|
24 |
+
CSS = get_CSS_code(this.id, vls),
|
25 |
+
field_style = $('#customify_font_output_for_' + el.html_safe_option_id)
|
26 |
+
|
27 |
+
field_style.html(CSS)
|
28 |
+
}
|
29 |
+
})
|
30 |
+
})
|
31 |
+
|
32 |
+
} else if (typeof wp_settings !== 'undefined' && typeof wp_settings[key] !== 'undefined' && typeof el.css !== 'undefined' && typeof el.live !== 'undefined' && el.live === true) {
|
33 |
+
api(key, function (setting) {
|
34 |
+
|
35 |
+
setting.bind(function (to) {
|
36 |
+
|
37 |
+
$.each(el.css, function (counter, property_config) {
|
38 |
+
let properties = []
|
39 |
+
|
40 |
+
properties[property_config.property] = property_config.selector
|
41 |
+
if (typeof property_config.callback_filter !== 'undefined') {
|
42 |
+
properties['callback'] = property_config.callback_filter
|
43 |
+
}
|
44 |
+
|
45 |
+
let css_update_args = {
|
46 |
+
properties: properties,
|
47 |
+
propertyValue: to,
|
48 |
+
negative_value: property_config.hasOwnProperty('negative_value') ? property_config['negative_value'] : false
|
49 |
+
}
|
50 |
+
|
51 |
+
if (typeof this.unit !== 'undefined') {
|
52 |
+
css_update_args.unit = this.unit
|
53 |
+
}
|
54 |
+
|
55 |
+
// Replace all dashes with underscores thus making the CSS property safe to us in a HTML ID.
|
56 |
+
let regex_for_multiple_replace = new RegExp('-', 'g'),
|
57 |
+
cssStyleSelector = '.dynamic_setting_' + el.html_safe_option_id + '_property_' + property_config.property.replace(regex_for_multiple_replace, '_') + '_' + counter
|
58 |
+
|
59 |
+
$(cssStyleSelector).cssUpdate(css_update_args)
|
60 |
+
})
|
61 |
+
|
62 |
+
})
|
63 |
+
})
|
64 |
+
} else if (typeof el.live === 'object' && el.live.length > 0) {
|
65 |
+
// if the live parameter is an object it means that is a list of css classes
|
66 |
+
// these classes should be affected by the change of the text fields
|
67 |
+
var field_class = el.live.join()
|
68 |
+
|
69 |
+
// if this field is allowed to modify text then we'll edit this live
|
70 |
+
if ($.inArray(el.type, ['text', 'textarea', 'ace_editor']) > -1) {
|
71 |
+
wp.customize(key, function (value) {
|
72 |
+
value.bind(function (text) {
|
73 |
+
let sanitizer = document.createElement('div')
|
74 |
+
|
75 |
+
sanitizer.innerHTML = text
|
76 |
+
$(field_class).html(text)
|
77 |
+
})
|
78 |
+
})
|
79 |
+
}
|
80 |
+
}
|
81 |
+
})
|
82 |
+
|
83 |
+
/*** HELPERS **/
|
84 |
+
|
85 |
+
function load_webfont_once () {
|
86 |
+
if (typeof WebFont === 'undefined') {
|
87 |
+
let tk = document.createElement('script')
|
88 |
+
tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js'
|
89 |
+
tk.type = 'text/javascript'
|
90 |
+
let s = document.getElementsByTagName('script')[0]
|
91 |
+
s.parentNode.insertBefore(tk, s)
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
const get_CSS_values = function (ID, values) {
|
96 |
+
|
97 |
+
let store = {}
|
98 |
+
|
99 |
+
if (typeof values.font_family !== 'undefined') {
|
100 |
+
store['font-family'] = values.font_family
|
101 |
+
}
|
102 |
+
|
103 |
+
if (typeof values.selected_variants !== 'undefined') {
|
104 |
+
|
105 |
+
let variants = null
|
106 |
+
|
107 |
+
if (typeof values.selected_variants !== 'undefined' && values.selected_variants !== null) {
|
108 |
+
variants = values.selected_variants
|
109 |
+
} else if (typeof values.variants !== 'undefined' && typeof values.variants[0] !== 'undefined') {
|
110 |
+
variants = values.variants[0]
|
111 |
+
}
|
112 |
+
|
113 |
+
// google fonts also have the italic string inside, split that
|
114 |
+
if (variants !== null && _.isString(variants) && variants.indexOf('italic') !== -1) {
|
115 |
+
store['font-style'] = 'italic'
|
116 |
+
variants = variants.replace('italic', '')
|
117 |
+
}
|
118 |
+
|
119 |
+
if (variants !== '') {
|
120 |
+
if (variants === 'regular') {
|
121 |
+
variants = 'normal'
|
122 |
+
}
|
123 |
+
|
124 |
+
store['font-weight'] = variants
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
if (typeof values.font_size !== 'undefined') {
|
129 |
+
store['font-size'] = values.font_size
|
130 |
+
// If the value already contains a unit (is not numeric), go with that.
|
131 |
+
if (isNaN(values.font_size)) {
|
132 |
+
// If we have a standardized value field (as array), use that.
|
133 |
+
if (typeof values.font_size.value !== 'undefined') {
|
134 |
+
store['font-size'] = values.font_size.value
|
135 |
+
if (typeof values.font_size.unit !== 'undefined') {
|
136 |
+
store['font-size'] += values.font_size.unit
|
137 |
+
}
|
138 |
+
} else {
|
139 |
+
store['font-size'] += get_field_unit(ID, 'font-size')
|
140 |
+
}
|
141 |
+
} else {
|
142 |
+
store['font-size'] += get_field_unit(ID, 'font-size')
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
if (typeof values.letter_spacing !== 'undefined') {
|
147 |
+
store['letter-spacing'] = values.letter_spacing
|
148 |
+
// If the value already contains a unit (is not numeric), go with that.
|
149 |
+
if (isNaN(values.letter_spacing)) {
|
150 |
+
// If we have a standardized value field (as array), use that.
|
151 |
+
if (typeof values.letter_spacing.value !== 'undefined') {
|
152 |
+
store['letter-spacing'] = values.letter_spacing.value
|
153 |
+
if (typeof values.letter_spacing.unit !== 'undefined') {
|
154 |
+
store['letter-spacing'] += values.letter_spacing.unit
|
155 |
+
}
|
156 |
+
} else {
|
157 |
+
store['letter-spacing'] += get_field_unit(ID, 'letter-spacing')
|
158 |
+
}
|
159 |
+
} else {
|
160 |
+
store['letter-spacing'] += get_field_unit(ID, 'letter-spacing')
|
161 |
+
}
|
162 |
+
}
|
163 |
+
|
164 |
+
if (typeof values.line_height !== 'undefined') {
|
165 |
+
store['line-height'] = values.line_height
|
166 |
+
// If the value already contains a unit (is not numeric), go with that.
|
167 |
+
if (isNaN(values.line_height)) {
|
168 |
+
// If we have a standardized value field (as array), use that.
|
169 |
+
if (typeof values.line_height.value !== 'undefined') {
|
170 |
+
store['line-height'] = values.line_height.value
|
171 |
+
if (typeof values.line_height.unit !== 'undefined') {
|
172 |
+
store['line-height'] += values.line_height.unit
|
173 |
+
}
|
174 |
+
} else {
|
175 |
+
store['line-height'] += get_field_unit(ID, 'line-height')
|
176 |
+
}
|
177 |
+
} else {
|
178 |
+
store['line-height'] += get_field_unit(ID, 'line-height')
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
if (typeof values.text_align !== 'undefined') {
|
183 |
+
store['text-align'] = values.text_align
|
184 |
+
}
|
185 |
+
|
186 |
+
if (typeof values.text_transform !== 'undefined') {
|
187 |
+
store['text-transform'] = values.text_transform
|
188 |
+
}
|
189 |
+
if (typeof values.text_decoration !== 'undefined') {
|
190 |
+
store['text-decoration'] = values.text_decoration
|
191 |
+
}
|
192 |
+
|
193 |
+
return store
|
194 |
+
}
|
195 |
+
|
196 |
+
const get_CSS_code = function (ID, values) {
|
197 |
+
|
198 |
+
let field = customify_settings.settings[ID]
|
199 |
+
let output = ''
|
200 |
+
|
201 |
+
if (typeof window !== 'undefined' && typeof field.callback !== 'undefined' && typeof window[field.callback] === 'function') {
|
202 |
+
output = window[field.callback](values, field)
|
203 |
+
} else {
|
204 |
+
output = field.selector + '{\n'
|
205 |
+
$.each(values, function (k, v) {
|
206 |
+
output += k + ': ' + v + ';\n'
|
207 |
+
})
|
208 |
+
output += '}\n'
|
209 |
+
}
|
210 |
+
|
211 |
+
return output
|
212 |
+
}
|
213 |
+
|
214 |
+
const get_field_unit = function (ID, field) {
|
215 |
+
let unit = ''
|
216 |
+
if (typeof customify_settings.settings[ID] === 'undefined' || typeof customify_settings.settings[ID].fields[field] === 'undefined') {
|
217 |
+
return unit
|
218 |
+
}
|
219 |
+
|
220 |
+
if (typeof customify_settings.settings[ID].fields[field].unit !== 'undefined') {
|
221 |
+
return customify_settings.settings[ID].fields[field].unit
|
222 |
+
} else if (typeof customify_settings.settings[ID].fields[field][3] !== 'undefined') {
|
223 |
+
// in case of an associative array
|
224 |
+
return customify_settings.settings[ID].fields[field][3]
|
225 |
+
}
|
226 |
+
}
|
227 |
+
|
228 |
+
const maybeLoadFontFamily = function (font) {
|
229 |
+
|
230 |
+
if (typeof WebFont === 'undefined') {
|
231 |
+
let tk = document.createElement('script')
|
232 |
+
tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js'
|
233 |
+
tk.type = 'text/javascript'
|
234 |
+
let s = document.getElementsByTagName('script')[0]
|
235 |
+
s.parentNode.insertBefore(tk, s)
|
236 |
+
}
|
237 |
+
|
238 |
+
// If the font type is not defined, we assume is a Google font.
|
239 |
+
if (typeof font.type === 'undefined') {
|
240 |
+
font.type = 'google'
|
241 |
+
}
|
242 |
+
|
243 |
+
if (font.type === 'theme_font') {
|
244 |
+
WebFont.load({
|
245 |
+
custom: {
|
246 |
+
families: [font.font_family],
|
247 |
+
urls: [font.src]
|
248 |
+
}
|
249 |
+
})
|
250 |
+
} else if (font.type === 'google') {
|
251 |
+
let family = font.font_family,
|
252 |
+
variants = null,
|
253 |
+
subsets = null
|
254 |
+
|
255 |
+
if (typeof font.variants !== 'undefined') {
|
256 |
+
variants = maybeJsonParse(font.variants)
|
257 |
+
|
258 |
+
if (typeof variants === 'string' || typeof variants === 'number') {
|
259 |
+
variants = [variants]
|
260 |
+
}
|
261 |
+
|
262 |
+
$.each(variants, function (k, v) {
|
263 |
+
|
264 |
+
if (k == 0) {
|
265 |
+
family = family + ':'
|
266 |
+
}
|
267 |
+
|
268 |
+
family = family + v
|
269 |
+
|
270 |
+
if (Object.keys(variants).length > (parseInt(k) + 1)) {
|
271 |
+
family = family + ','
|
272 |
+
} else if (typeof font.selected_subsets !== 'undefined') {
|
273 |
+
// in case there is a subset selected, we need to separate it from the font weight
|
274 |
+
family = family + ':'
|
275 |
+
}
|
276 |
+
})
|
277 |
+
}
|
278 |
+
|
279 |
+
if (typeof font.selected_subsets !== 'undefined') {
|
280 |
+
subsets = maybeJsonParse(font.selected_subsets)
|
281 |
+
|
282 |
+
$.each(subsets, function (k, v) {
|
283 |
+
|
284 |
+
if (k === '0') {
|
285 |
+
family = family + ':'
|
286 |
+
}
|
287 |
+
|
288 |
+
family = family + v
|
289 |
+
|
290 |
+
if (Object.keys(subsets).length > (parseInt(k) + 1)) {
|
291 |
+
family = family + ','
|
292 |
+
}
|
293 |
+
})
|
294 |
+
}
|
295 |
+
|
296 |
+
if (fonts_cache.indexOf(family) === -1) {
|
297 |
+
setTimeout(function () {
|
298 |
+
WebFont.load({
|
299 |
+
google: {families: [family]},
|
300 |
+
classes: false,
|
301 |
+
events: false,
|
302 |
+
error: function (e) {
|
303 |
+
console.log(e)
|
304 |
+
},
|
305 |
+
active: function () {
|
306 |
+
sessionStorage.fonts = true
|
307 |
+
}
|
308 |
+
})
|
309 |
+
}, 10)
|
310 |
+
|
311 |
+
fonts_cache.push(family)
|
312 |
+
}
|
313 |
+
|
314 |
+
} else {
|
315 |
+
// else what?
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
const maybeJsonParse = function (value) {
|
320 |
+
let parsed
|
321 |
+
|
322 |
+
if (typeof value !== 'string') {
|
323 |
+
return value
|
324 |
+
}
|
325 |
+
|
326 |
+
//try and parse it, with decodeURIComponent
|
327 |
+
try {
|
328 |
+
parsed = JSON.parse(decodeURIComponent(value))
|
329 |
+
} catch (e) {
|
330 |
+
|
331 |
+
// in case of an error, treat is as a string
|
332 |
+
parsed = value
|
333 |
+
}
|
334 |
+
|
335 |
+
return parsed
|
336 |
+
}
|
337 |
+
})
|
338 |
})(jQuery, window, document)
|
readme.txt
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
=== Customify - A Theme Customizer Booster ===
|
2 |
Contributors: pixelgrade, euthelup, babbardel, vlad.olaru, raduconstantin, razvanonofrei
|
3 |
-
Tags: customizer, css, editor, live, preview, customizer
|
4 |
-
Requires at least: 4.
|
5 |
-
Tested up to: 5.
|
6 |
-
Stable tag: 2.3.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
10 |
-
Customify is a Theme Customizer Booster
|
11 |
|
12 |
== Description ==
|
13 |
|
@@ -45,6 +45,12 @@ With [Customify](https://github.com/pixelgrade/customify), developers can easily
|
|
45 |
|
46 |
== Changelog ==
|
47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
= 2.3.2 =
|
49 |
* Fixed the fact that Customizer style changes were not reflected in the live preview. A problem introduced in the previous update.
|
50 |
|
1 |
=== Customify - A Theme Customizer Booster ===
|
2 |
Contributors: pixelgrade, euthelup, babbardel, vlad.olaru, raduconstantin, razvanonofrei
|
3 |
+
Tags: customizer, css, editor, gutenberg, live, preview, customizer
|
4 |
+
Requires at least: 4.9.9
|
5 |
+
Tested up to: 5.2.0
|
6 |
+
Stable tag: 2.3.4
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
10 |
+
Customify is a Theme Customizer Booster to easily customize Fonts, Colors, and other options for your site.
|
11 |
|
12 |
== Description ==
|
13 |
|
45 |
|
46 |
== Changelog ==
|
47 |
|
48 |
+
= 2.3.4 =
|
49 |
+
* Fixed warnings that were appearing when PHP has version 7.2.0+.
|
50 |
+
|
51 |
+
= 2.3.3 =
|
52 |
+
* Fixed Google Fonts not working in the new block editor (Gutenberg).
|
53 |
+
|
54 |
= 2.3.2 =
|
55 |
* Fixed the fact that Customizer style changes were not reflected in the live preview. A problem introduced in the previous update.
|
56 |
|