localized = array(
'config' => array(
'options_name' => PixCustomifyPlugin()->get_options_key(),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'webfontloader_url' => plugins_url( 'js/vendor/webfontloader-1-6-28.min.js', PixCustomifyPlugin()->get_file() ),
'px_dependent_css_props' => self::$pixel_dependent_css_properties,
),
// For localizing strings.
'l10n' => array(
'panelResetButton' => esc_html__( 'Panel\'s defaults', 'customify' ),
'sectionResetButton' => esc_html__( 'Reset All Options for This Section', 'customify' ),
'resetGlobalConfirmMessage' => wp_kses_post( __( 'Do you really want to reset to defaults all the fields? Watch out, this will reset all your Customify options and will save them!', 'customify' ) ),
'resetPanelConfirmMessage' => wp_kses_post( __( 'Do you really want to reset the settings in this panel?', 'customify' ) ),
'resetSectionConfirmMessage' => wp_kses_post( __( 'Do you really want to reset the settings in this section?', 'customify' ) ),
)
);
// Hook up.
$this->add_hooks();
}
/**
* Initiate our hooks
*
* @since 2.4.0
*/
public function add_hooks() {
// Styles for the Customizer
add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_styles' ), 10 );
add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_styles' ), 10 );
// Scripts enqueued in the Customizer
add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_scripts' ), 15 );
add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 15 );
// Scripts enqueued only in the theme preview
add_action( 'customize_preview_init', array( $this, 'customizer_live_preview_register_scripts' ), 10 );
add_action( 'customize_preview_init', array( $this, 'customizer_live_preview_enqueue_scripts' ), 99999 );
// Add extra settings data to _wpCustomizeSettings.settings of the parent window.
add_action( 'customize_controls_print_footer_scripts', array( $this, 'customize_pane_settings_additional_data' ), 10000 );
// The frontend effects of the Customizer controls
$load_location = PixCustomifyPlugin()->settings->get_plugin_setting( 'style_resources_location', 'wp_head' );
add_action( $load_location, array( $this, 'output_dynamic_style' ), 99 );
add_action( 'customize_register', array( $this, 'remove_default_sections' ), 11 );
add_action( 'customize_register', array( $this, 'process_customizer_config' ), 12 );
// Maybe the theme has instructed us to do things like removing sections or controls.
add_action( 'customize_register', array( $this, 'maybe_process_config_extras' ), 13 );
/*
* Development related
*/
if ( defined( 'CUSTOMIFY_DEV_FORCE_DEFAULTS' ) && true === CUSTOMIFY_DEV_FORCE_DEFAULTS ) {
// If the development constant CUSTOMIFY_DEV_FORCE_DEFAULTS has been defined we will not save anything in the database
// Always go with the default
add_filter( 'customize_changeset_save_data', array( $this, 'prevent_changeset_save_in_devmode' ), 50, 1 );
// Add a JS to display a notification
add_action( 'customize_controls_print_footer_scripts', array( $this, 'prevent_changeset_save_in_devmode_notification' ), 100 );
}
}
/**
* Register Customizer admin styles
*/
function register_admin_customizer_styles() {
$rtl_suffix = is_rtl() ? '-rtl' : '';
wp_register_style( 'customify_style', plugins_url( 'css/customizer' . $rtl_suffix . '.css', PixCustomifyPlugin()->get_file() ), array( 'dashicons' ), PixCustomifyPlugin()->get_version() );
}
/**
* Enqueue Customizer admin styles
*/
function enqueue_admin_customizer_styles() {
wp_enqueue_style( 'customify_style' );
}
/**
* Register Customizer admin scripts
*/
function register_admin_customizer_scripts() {
$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
wp_register_script( PixCustomifyPlugin()->get_slug() . '-select2',
plugins_url( 'js/vendor/select2-4.0.13/dist/js/select2.full' . $suffix . '.js', PixCustomifyPlugin()->get_file() ),
array( 'jquery' ), PixCustomifyPlugin()->get_version() );
wp_register_script( 'jquery-react',
plugins_url( 'js/vendor/jquery-react' . $suffix . '.js', PixCustomifyPlugin()->get_file() ),
array( 'jquery' ), PixCustomifyPlugin()->get_version() );
wp_register_script( PixCustomifyPlugin()->get_slug() . '-fontfields',
plugins_url( 'js/customizer/font-fields' . $suffix . '.js', PixCustomifyPlugin()->get_file() ),
array( 'jquery', 'underscore' ), PixCustomifyPlugin()->get_version() );
wp_register_script( PixCustomifyPlugin()->get_slug() . '-customizer-scripts',
plugins_url( 'js/customizer' . $suffix . '.js', PixCustomifyPlugin()->get_file() ),
array(
'jquery',
PixCustomifyPlugin()->get_slug() . '-select2',
'underscore',
'customize-controls',
PixCustomifyPlugin()->get_slug() . '-fontfields',
),
PixCustomifyPlugin()->get_version() );
}
/**
* Enqueue Customizer admin scripts
*/
function enqueue_admin_customizer_scripts() {
wp_enqueue_script( 'jquery-react' );
wp_enqueue_script( PixCustomifyPlugin()->get_slug() . '-customizer-scripts' );
wp_add_inline_script( PixCustomifyPlugin()->get_slug() . '-customizer-scripts',
self::getlocalizeToWindowScript( 'customify',
apply_filters( 'customify_localized_js_settings', $this->localized )
), 'before' );
}
/** Register Customizer scripts loaded only on previewer page */
function customizer_live_preview_register_scripts() {
$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
wp_register_script( PixCustomifyPlugin()->get_slug() . '-CSSOM',
plugins_url( 'js/vendor/CSSOM' . $suffix . '.js', PixCustomifyPlugin()->get_file() ),
array(),
PixCustomifyPlugin()->get_version(), true );
wp_register_script( PixCustomifyPlugin()->get_slug() . '-cssUpdate',
plugins_url( 'js/jquery.cssUpdate' . $suffix . '.js', PixCustomifyPlugin()->get_file() ),
array( 'jquery' ),
PixCustomifyPlugin()->get_version(), true );
wp_register_script( PixCustomifyPlugin()->get_slug() . '-previewer-scripts',
plugins_url( 'js/customizer_preview' . $suffix . '.js', PixCustomifyPlugin()->get_file() ),
array(
'jquery',
'customize-preview',
'underscore',
PixCustomifyPlugin()->get_slug() . '-CSSOM',
PixCustomifyPlugin()->get_slug() . '-cssUpdate'
),
PixCustomifyPlugin()->get_version(), true );
}
/** Enqueue Customizer scripts loaded only on previewer page */
function customizer_live_preview_enqueue_scripts() {
wp_enqueue_script( PixCustomifyPlugin()->get_slug() . '-previewer-scripts' );
}
/**
* Prevent saving of plugin options in the Customizer
*
* @param array $data The data to save
*
* @return array
*/
public function prevent_changeset_save_in_devmode( $data ) {
// Get the options key
$options_key = PixCustomifyPlugin()->get_options_key();
if ( ! empty( $options_key ) ) {
// Remove any Customify data thus preventing it from saving
foreach ( $data as $option_id => $value ) {
if ( false !== strpos( $option_id, $options_key ) && ! PixCustomifyPlugin()->skip_dev_mode_force_defaults( $option_id ) ) {
unset( $data[ $option_id ] );
}
}
}
return $data;
}
public function prevent_changeset_save_in_devmode_notification() { ?>
get_options_details( false, true ) as $option_id => $option_details ) {
if ( isset( $option_details['type'] ) && $option_details['type'] === 'custom_background' ) {
$custom_background_output = $this->process_custom_background_field_output( $option_details ); ?>
$properties_set ) {
// We need to use a class because we may have multiple ';
echo $inline_style;
}
}
}
}
function get_dynamic_style() {
$custom_css = '';
foreach ( PixCustomifyPlugin()->get_options_details( true ) as $option_id => $option_details ) {
if ( isset( $option_details['css'] ) && ! empty( $option_details['css'] ) ) {
// now process each
$custom_css .= $this->convert_setting_to_css( $option_id, $option_details );
}
if ( isset( $option_details['type'] ) && $option_details['type'] === 'custom_background' ) {
$custom_css .= $this->process_custom_background_field_output( $option_details ) . "\n";
}
}
if ( ! empty( $this->media_queries ) ) {
foreach ( $this->media_queries as $media_query => $properties ) {
if ( empty( $properties ) ) {
continue;
}
$media_query_custom_css = '';
foreach ( $properties as $key => $property ) {
$property_settings = $property['property'];
$property_value = $property['value'];
$css_output = $this->process_css_property( $property_settings, $property_value );
if ( ! empty( $css_output ) ) {
$media_query_custom_css .= "\t" . $css_output . "\n";
}
}
if ( ! empty( $media_query_custom_css ) ) {
$media_query_custom_css = "\n" . '@media ' . $media_query . " { " . "\n" . "\n" . $media_query_custom_css . "}" . "\n";
}
if ( ! empty( $media_query_custom_css ) ) {
$custom_css .= $media_query_custom_css;
}
}
}
return apply_filters( 'customify_dynamic_style', $custom_css );
}
/**
* Turn css options into a valid CSS output
*
* @param $option_id
* @param array $option_details
*
* @return string
*/
protected function convert_setting_to_css( $option_id, $option_details ) {
$output = '';
if ( empty( $option_details['css'] ) ) {
return $output;
}
foreach ( $option_details['css'] as $css_property ) {
if ( isset( $css_property['media'] ) && ! empty( $css_property['media'] ) ) {
$this->media_queries[ $css_property['media'] ][ $option_id ] = array(
'property' => $css_property,
'value' => $option_details['value']
);
continue;
}
if ( isset( $css_property['selector'] ) && isset( $css_property['property'] ) ) {
$output .= $this->process_css_property( $css_property, $option_details['value'] );
}
}
return $output;
}
protected function process_css_property( $css_property, $value ) {
$unit = isset( $css_property['unit'] ) ? $css_property['unit'] : '';
// If the unit is empty (string, not boolean false) but the property should have a unit force 'px' as it
if ( '' === $unit && in_array( $css_property['property'], self::$pixel_dependent_css_properties ) ) {
$unit = 'px';
}
$css_property['selector'] = apply_filters( 'customify_css_selector', $this->cleanup_whitespace_css( $css_property['selector'] ), $css_property );
if ( empty( $css_property['selector'] ) ) {
return '';
}
$property_output = $css_property['selector'] . ' { ' . $css_property['property'] . ': ' . $value . $unit . "; }" . "\n";
// Handle the value filter callback.
if ( isset( $css_property['filter_value_cb'] ) ) {
$value = $this->maybe_apply_filter( $css_property['filter_value_cb'], $value );
}
// Handle output callback.
if ( isset( $css_property['callback_filter'] ) && is_callable( $css_property['callback_filter'] ) ) {
$property_output = call_user_func( $css_property['callback_filter'], $value, $css_property['selector'], $css_property['property'], $unit );
}
return $property_output;
}
/**
* Apply a filter (config) to a value.
*
* We currently handle filters like these:
* // Elaborate filter config
* array(
* 'callback' => 'is_post_type_archive',
* // The arguments we should pass to the check function.
* // Think post types, taxonomies, or nothing if that is the case.
* // It can be an array of values or a single value.
* 'args' => array(
* 'jetpack-portfolio',
* ),
* ),
* // Simple filter - just the function name
* 'is_404',
*
* @param array|string $filter
* @param mixed $value The value to apply the filter to.
*
* @return mixed The filtered value.
*/
public function maybe_apply_filter( $filter, $value ) {
// Let's get some obvious things off the table.
// On invalid data, we just return what we've received.
if ( empty( $filter ) ) {
return $value;
}
// First, we handle the shorthand version: just a function name
if ( is_string( $filter ) && is_callable( $filter ) ) {
$value = call_user_func( $filter );
} elseif ( is_array( $filter ) && ! empty( $filter['callback'] ) && is_callable( $filter['callback'] ) ) {
if ( empty( $filter['args'] ) ) {
$filter['args'] = array();
}
// The value is always the first argument.
$filter['args'] = array( $value ) + $filter['args'];
$value = call_user_func_array( $filter['callback'], $filter['args'] );
}
return $value;
}
protected function process_custom_background_field_output( $option_details ) {
$selector = $output = '';
if ( ! isset( $option_details['value'] ) ) {
return false;
}
$value = $option_details['value'];
if ( ! isset( $option_details['output'] ) ) {
return $selector;
} elseif ( is_string( $option_details['output'] ) ) {
$selector = $option_details['output'];
} elseif ( is_array( $option_details['output'] ) ) {
$selector = implode( ' ', $option_details['output'] );
}
// Loose the ton of tabs.
$selector = trim( preg_replace( '/\t+/', '', $selector ) );
$output .= $selector . " {";
if ( isset( $value['background-image'] ) && ! empty( $value['background-image'] ) ) {
$output .= "background-image: url( " . $value['background-image'] . ");";
} else {
$output .= "background-image: none;";
}
if ( isset( $value['background-repeat'] ) && ! empty( $value['background-repeat'] ) ) {
$output .= "background-repeat:" . $value['background-repeat'] . ";";
}
if ( isset( $value['background-position'] ) && ! empty( $value['background-position'] ) ) {
$output .= "background-position:" . $value['background-position'] . ";";
}
if ( isset( $value['background-size'] ) && ! empty( $value['background-size'] ) ) {
$output .= "background-size:" . $value['background-size'] . ";";
}
if ( isset( $value['background-attachment'] ) && ! empty( $value['background-attachment'] ) ) {
$output .= "background-attachment:" . $value['background-attachment'] . ";";
}
$output .= "}\n";
return $output;
}
protected function load_customizer_controls() {
// First require the base customizer extend class.
require_once( trailingslashit( PixCustomifyPlugin()->get_base_path() ) . 'includes/customizer-controls/class-Pix_Customize_Control.php' );
// Now load all the controls' files.
$path = apply_filters( 'customify_customizer_controls_path', trailingslashit( PixCustomifyPlugin()->get_base_path() ) . 'includes/customizer-controls/' );
pixcustomify::require_all( $path );
do_action( 'customify_loaded_customizer_controls' );
}
/**
* Register all the panels, sections and controls we receive through the plugin's config.
*
* @param WP_Customize_Manager $wp_customize
*/
function process_customizer_config( $wp_customize ) {
do_action( 'customify_before_process_customizer_config', $wp_customize );
// Require all the control classes available.
$this->load_customizer_controls();
// Load the customizer config.
$customizer_config = apply_filters( 'customify_customizer_config_pre_processing', PixCustomifyPlugin()->get_customizer_config(), $wp_customize );
// Bail if we don't have a config, or we are missing the 'opt-name' entry.
if ( empty( $customizer_config ) || empty( $customizer_config['opt-name'] ) ) {
do_action( 'customify_skip_process_customizer_config', $customizer_config, $wp_customize );
return;
}
$options_name = $customizer_config['opt-name'];
$wp_customize->options_key = $options_name;
// Handle panels.
if ( isset( $customizer_config['panels'] ) && ! empty( $customizer_config['panels'] ) ) {
foreach ( $customizer_config['panels'] as $panel_id => $panel_config ) {
if ( ! empty( $panel_id ) && isset( $panel_config['sections'] ) && ! empty( $panel_config['sections'] ) ) {
// If we have been explicitly given a panel ID we will use that
if ( ! empty( $panel_config['panel_id'] ) ) {
$panel_id = $panel_config['panel_id'];
} else {
$panel_id = $options_name . '[' . $panel_id . ']';
}
$panel_args = array(
'priority' => 10,
'capability' => 'edit_theme_options',
'title' => esc_html__( 'Panel title is required', 'customify' ),
'description' => esc_html__( 'Description of what this panel does.', 'customify' ),
'auto_expand_sole_section' => false,
);
if ( isset( $panel_config['priority'] ) && ! empty( $panel_config['priority'] ) ) {
$panel_args['priority'] = $panel_config['priority'];
}
if ( isset( $panel_config['title'] ) && ! empty( $panel_config['title'] ) ) {
$panel_args['title'] = $panel_config['title'];
}
if ( isset( $panel_config['description'] ) && ! empty( $panel_config['description'] ) ) {
$panel_args['description'] = $panel_config['description'];
}
if ( isset( $panel_config['auto_expand_sole_section'] ) ) {
$panel_args['auto_expand_sole_section'] = $panel_config['auto_expand_sole_section'];
}
$panel = $wp_customize->add_panel( $panel_id, $panel_args );
// Fire a general added panel hook
do_action( 'customify_process_customizer_config_added_panel', $panel, $panel_args, $wp_customize );
foreach ( $panel_config['sections'] as $section_id => $section_config ) {
if ( ! empty( $section_id ) && isset( $section_config['options'] ) && ! empty( $section_config['options'] ) ) {
$this->register_section( $panel_id, $section_id, $options_name, $section_config, $wp_customize );
}
}
// Fire a general finished panel hook
do_action( 'customify_process_customizer_config_finished_panel', $panel, $panel_args, $wp_customize );
}
}
}
// Handle sections.
if ( isset( $customizer_config['sections'] ) && ! empty( $customizer_config['sections'] ) ) {
foreach ( $customizer_config['sections'] as $section_id => $section_config ) {
if ( ! empty( $section_id ) && isset( $section_config['options'] ) && ! empty( $section_config['options'] ) ) {
$this->register_section( $panel_id = false, $section_id, $options_name, $section_config, $wp_customize );
}
}
}
// Handle development helper buttons.
if ( PixCustomifyPlugin()->settings->get_plugin_setting('enable_reset_buttons') ) {
// create a toolbar section which will be present all the time
$reset_section_settings = array(
'title' => esc_html__( 'Customify Toolbox', 'customify' ),
'capability' => 'manage_options',
'priority' => 999999999,
'options' => array(
'reset_all_button' => array(
'type' => 'button',
'label' => esc_html__( 'Reset Customify', 'customify' ),
'action' => 'reset_customify',
'value' => 'Reset',
),
)
);
$wp_customize->add_section(
'customify_toolbar',
$reset_section_settings
);
$wp_customize->add_setting(
'reset_customify',
array()
);
$wp_customize->add_control( new Pix_Customize_Button_Control(
$wp_customize,
'reset_customify',
array(
'label' => esc_html__( 'Reset All Customify Options to Default', 'customify' ),
'section' => 'customify_toolbar',
'settings' => 'reset_customify',
'action' => 'reset_customify',
)
) );
}
do_action( 'customify_after_process_customizer_config', $wp_customize );
}
/**
* @param string $panel_id
* @param string $section_key
* @param string $options_name
* @param array $section_config
* @param WP_Customize_Manager $wp_customize
*/
protected function register_section( $panel_id, $section_key, $options_name, $section_config, $wp_customize ) {
// If we have been explicitly given a section ID we will use that
if ( ! empty( $section_config['section_id'] ) ) {
$section_id = $section_config['section_id'];
} else {
$section_id = $options_name . '[' . $section_key . ']';
}
// Add the new section to the Customizer, but only if it is not already added.
if ( ! $wp_customize->get_section( $section_id ) ) {
// Merge the section settings with the defaults
$section_args = wp_parse_args( $section_config, array(
'priority' => 10,
'panel' => $panel_id,
'capability' => 'edit_theme_options',
'theme_supports' => '',
'title' => esc_html__( 'Title Section is required', 'customify' ),
'description' => '',
'type' => 'default',
'description_hidden' => false,
) );
// Only add the section if it is not of type `hidden`
if ( 'hidden' !== $section_args['type'] ) {
$section = $wp_customize->add_section( $section_id, $section_args );
// Fire a general added section hook
do_action( 'customify_process_customizer_config_added_section', $section, $section_args, $wp_customize );
}
}
// Now go through each section option and add the fields
foreach ( $section_config['options'] as $option_id => $option_config ) {
if ( empty( $option_id ) || ! isset( $option_config['type'] ) ) {
continue;
}
// If we have been explicitly given a setting ID we will use that
if ( ! empty( $option_config['setting_id'] ) ) {
$setting_id = $option_config['setting_id'];
} else {
$setting_id = $options_name . '[' . $option_id . ']';
}
// Add the option config to the localized array so we can pass the info to JS.
// @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.
// Filter some settings that have purely visual purpose.
if ( ! empty( $option_config['type'] ) && ! in_array( $option_config['type'], array( 'html', 'button' ) ) ) {
$this->localized['config']['settings'][ $setting_id ] = $option_config;
}
// Generate a safe option ID (not the final setting ID) to us in HTML attributes like ID or class
$this->localized['config']['settings'][ $setting_id ]['html_safe_option_id'] = sanitize_html_class( $option_id );
$this->register_field( $section_id, $setting_id, $option_config, $wp_customize );
}
// Fire a general finished section hook
do_action( 'customify_process_customizer_config_finished_section', $section_id, $wp_customize );
}
/**
* Register a Customizer field (setting and control).
*
* @see WP_Customize_Setting
* @see WP_Customize_Control
*
* @param string $section_id
* @param string $setting_id
* @param array $field_config
* @param WP_Customize_Manager $wp_customize
*/
protected function register_field( $section_id, $setting_id, $field_config, $wp_customize ) {
$add_control = true;
// defaults
$setting_args = array(
'type' => 'theme_mod',
'default' => '',
'capability' => 'edit_theme_options',
'transport' => 'refresh',
);
$control_args = array(
'priority' => 10,
'label' => '',
'section' => $section_id,
'settings' => $setting_id,
);
// sanitize settings
if ( ! empty( $field_config['live'] ) || $field_config['type'] === 'font' ) {
$setting_args['transport'] = 'postMessage';
}
if ( isset( $field_config['default'] ) ) {
$setting_args['default'] = $field_config['default'];
if ( is_array( $setting_args['default'] ) ) {
$setting_args['default'] = (object) $setting_args['default'];
}
}
if ( ! empty( $field_config['capability'] ) ) {
$setting_args['capability'] = $field_config['capability'];
}
// If the setting defines it's own type we will respect that, otherwise we will follow the global plugin setting.
if ( ! empty( $field_config['setting_type'] ) && 'option' === $field_config['setting_type'] ) {
$setting_args['type'] = 'option';
} elseif ( PixCustomifyPlugin()->settings->get_plugin_setting('values_store_mod') === 'option' ) {
$setting_args['type'] = 'option';
}
if ( ! empty( $field_config['sanitize_callback'] ) && is_callable( $field_config['sanitize_callback'] ) ) {
$setting_args['sanitize_callback'] = $field_config['sanitize_callback'];
} elseif ( 'checkbox' === $field_config['type'] ) {
$setting_args['sanitize_callback'] = array( $this, 'setting_sanitize_checkbox' );
}
// Add the setting
$wp_customize->add_setting( $setting_id, $setting_args );
// Stop the control registration, if we are presented with the right type.
if ( 'hidden_control' === $field_config['type'] ) {
return;
}
$control_args['type'] = $field_config['type'];
// now sanitize the control
if ( ! empty( $field_config['label'] ) ) {
$control_args['label'] = $field_config['label'];
}
if ( ! empty( $field_config['priority'] ) ) {
$control_args['priority'] = $field_config['priority'];
}
if ( ! empty( $field_config['desc'] ) ) {
$control_args['description'] = $field_config['desc'];
}
if ( ! empty( $field_config['active_callback'] ) ) {
$control_args['active_callback'] = $field_config['active_callback'];
}
// select the control type
// but first init a default
$control_class_name = 'Pix_Customize_Text_Control';
// If is a standard wp field type call it here and skip the rest.
if ( in_array( $field_config['type'], array(
'checkbox',
'dropdown-pages',
'url',
'date',
'time',
'datetime',
'week',
'search'
) ) ) {
$wp_customize->add_control( $setting_id . '_control', $control_args );
return;
} elseif ( in_array( $field_config['type'], array(
'radio',
'select'
) ) && ! empty( $field_config['choices'] )
) {
$control_args['choices'] = $field_config['choices'];
$wp_customize->add_control( $setting_id . '_control', $control_args );
return;
} elseif ( in_array( $field_config['type'], array( 'range' ) ) && ! empty( $field_config['input_attrs'] ) ) {
$control_args['input_attrs'] = $field_config['input_attrs'];
$wp_customize->add_control( $setting_id . '_control', $control_args );
}
// If we arrive here this means we have a custom field control (with a corresponding class in includes/customizer-controls).
switch ( $field_config['type'] ) {
case 'text':
if ( isset( $field_config['live'] ) ) {
$control_args['live'] = $field_config['live'];
}
$control_class_name = 'Pix_Customize_Text_Control';
break;
case 'textarea':
if ( isset( $field_config['live'] ) ) {
$control_args['live'] = $field_config['live'];
}
$control_class_name = 'Pix_Customize_Textarea_Control';
break;
case 'color':
$control_class_name = 'WP_Customize_Color_Control';
break;
case 'color_drop':
$control_class_name = 'Pix_Customize_Color_Drop_Control';
break;
case 'ace_editor':
if ( isset( $field_config['live'] ) ) {
$control_args['live'] = $field_config['live'];
}
if ( isset( $field_config['editor_type'] ) ) {
$control_args['editor_type'] = $field_config['editor_type'];
}
$control_class_name = 'Pix_Customize_Ace_Editor_Control';
break;
case 'upload':
$control_class_name = 'WP_Customize_Upload_Control';
break;
case 'image':
$control_class_name = 'WP_Customize_Image_Control';
break;
case 'media':
$control_class_name = 'WP_Customize_Media_Control';
break;
case 'custom_background':
if ( isset( $field_config['field'] ) ) {
$control_args['field'] = $field_config['field'];
}
$control_class_name = 'Pix_Customize_Background_Control';
break;
case 'cropped_image':
case 'cropped_media': // 'cropped_media' no longer works
if ( isset( $field_config['width'] ) ) {
$control_args['width'] = $field_config['width'];
}
if ( isset( $field_config['height'] ) ) {
$control_args['height'] = $field_config['height'];
}
if ( isset( $field_config['flex_width'] ) ) {
$control_args['flex_width'] = $field_config['flex_width'];
}
if ( isset( $field_config['flex_height'] ) ) {
$control_args['flex_height'] = $field_config['flex_height'];
}
if ( isset( $field_config['button_labels'] ) ) {
$control_args['button_labels'] = $field_config['button_labels'];
}
$control_class_name = 'WP_Customize_Cropped_Image_Control';
break;
case 'font' :
// Only add the control if typography is turned on in the plugin settings.
if ( ! PixCustomifyPlugin()->settings->get_plugin_setting( 'typography', '1' ) ) {
$add_control = false;
break;
}
$control_class_name = 'Pix_Customize_Font_Control';
if ( isset( $field_config['recommended'] ) ) {
$control_args['recommended'] = $field_config['recommended'];
}
if ( isset( $field_config['live'] ) ) {
$control_args['live'] = $field_config['live'];
}
// This is used only as an extreme failsafe.
// Normally, when there is no value, the WP Settings system will fallback on the default given for the setting.
// See above when registering the setting corresponding to this control.
if ( isset( $field_config['default'] ) ) {
$control_args['default'] = $field_config['default'];
}
// We should always receive a subfields configuration.
if ( isset( $field_config['fields'] ) ) {
$control_args['fields'] = $field_config['fields'];
} else {
$control_args['fields'] = array();
}
break;
case 'select2' :
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
return;
}
$control_args['choices'] = $field_config['choices'];
$control_class_name = 'Pix_Customize_Select2_Control';
break;
case 'sm_radio' :
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
return;
}
$control_args['choices'] = $field_config['choices'];
$control_class_name = 'Pix_Customize_SM_radio_Control';
break;
case 'sm_palette_filter' :
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
return;
}
$control_args['choices'] = $field_config['choices'];
$control_class_name = 'Pix_Customize_SM_palette_filter_Control';
break;
case 'sm_switch' :
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
return;
}
$control_args['choices'] = $field_config['choices'];
$control_class_name = 'Pix_Customize_SM_switch_Control';
break;
case 'preset' :
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
return;
}
$control_args['choices'] = $field_config['choices'];
if ( isset( $field_config['choices_type'] ) || ! empty( $field_config['choices_type'] ) ) {
$control_args['choices_type'] = $field_config['choices_type'];
}
if ( isset( $field_config['desc'] ) || ! empty( $field_config['desc'] ) ) {
$control_args['description'] = $field_config['desc'];
}
$control_class_name = 'Pix_Customize_Preset_Control';
break;
case 'radio_image' :
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
return;
}
$control_args['choices'] = $field_config['choices'];
if ( isset( $field_config['choices_type'] ) || ! empty( $field_config['choices_type'] ) ) {
$control_args['choices_type'] = $field_config['choices_type'];
}
if ( isset( $field_config['desc'] ) || ! empty( $field_config['desc'] ) ) {
$control_args['description'] = $field_config['desc'];
}
$control_class_name = 'Pix_Customize_Radio_Image_Control';
break;
case 'radio_html' :
if ( ! isset( $field_config['choices'] ) || empty( $field_config['choices'] ) ) {
return;
}
$control_args['choices'] = $field_config['choices'];
if ( isset( $field_config['desc'] ) || ! empty( $field_config['desc'] ) ) {
$control_args['description'] = $field_config['desc'];
}
$control_class_name = 'Pix_Customize_Radio_HTML_Control';
break;
case 'button' :
if ( ! isset( $field_config['action'] ) || empty( $field_config['action'] ) ) {
return;
}
$control_args['action'] = $field_config['action'];
$control_class_name = 'Pix_Customize_Button_Control';
break;
case 'html' :
if ( isset( $field_config['html'] ) || ! empty( $field_config['html'] ) ) {
$control_args['html'] = $field_config['html'];
}
$control_class_name = 'Pix_Customize_HTML_Control';
break;
default:
// if we don't have a real control just quit, it doesn't even matter
return;
break;
}
$this_control = new $control_class_name(
$wp_customize,
$setting_id . '_control',
$control_args
);
if ( $add_control ) {
$wp_customize->add_control( $this_control );
}
}
/**
* Remove the sections selected by user
*
* @param WP_Customize_Manager $wp_customize
*/
function remove_default_sections( $wp_customize ) {
global $wp_registered_sidebars;
$to_remove = PixCustomifyPlugin()->settings->get_plugin_setting( 'disable_default_sections' );
if ( ! empty( $to_remove ) ) {
foreach ( $to_remove as $section => $nothing ) {
if ( $section === 'widgets' ) {
foreach ( $wp_registered_sidebars as $widget => $settings ) {
$wp_customize->remove_section( 'sidebar-widgets-' . $widget );
}
continue;
}
$wp_customize->remove_section( $section );
}
}
}
/**
* Print JavaScript for adding additional data to _wpCustomizeSettings.settings object of the main window (not the preview window).
*/
public function customize_pane_settings_additional_data() {
/**
* @global WP_Customize_Manager $wp_customize
*/
global $wp_customize;
$options_name = PixCustomifyPlugin()->get_options_key();
// Without an options name we can't do much.
if ( empty( $options_name ) ) {
return;
}
$customizer_settings = $wp_customize->settings();
?>
get_customizer_config();
// Bail if we have no external theme config data.
if ( empty( $customizer_config ) || ! is_array( $customizer_config ) ) {
return;
}
// Maybe remove panels
if ( ! empty( $customizer_config['remove_panels'] ) ) {
// Standardize it.
if ( is_string( $customizer_config['remove_panels'] ) ) {
$customizer_config['remove_panels'] = array( $customizer_config['remove_panels'] );
}
foreach ( $customizer_config['remove_panels'] as $panel_id ) {
$wp_customize->remove_panel( $panel_id );
}
}
// Maybe change panel props.
if ( ! empty( $customizer_config['change_panel_props'] ) ) {
foreach ( $customizer_config['change_panel_props'] as $panel_id => $panel_props ) {
if ( ! is_array( $panel_props ) ) {
continue;
}
$panel = $wp_customize->get_panel( $panel_id );
if ( empty( $panel ) || ! $panel instanceof WP_Customize_Panel ) {
continue;
}
$public_props = get_class_vars( get_class( $panel ) );
foreach ( $panel_props as $prop_name => $prop_value ) {
if ( ! in_array( $prop_name, array_keys( $public_props ) ) ) {
continue;
}
$panel->$prop_name = $prop_value;
}
}
}
// Maybe remove sections
if ( ! empty( $customizer_config['remove_sections'] ) ) {
// Standardize it.
if ( is_string( $customizer_config['remove_sections'] ) ) {
$customizer_config['remove_sections'] = array( $customizer_config['remove_sections'] );
}
foreach ( $customizer_config['remove_sections'] as $section_id ) {
if ( 'widgets' === $section_id ) {
global $wp_registered_sidebars;
foreach ( $wp_registered_sidebars as $widget => $settings ) {
$wp_customize->remove_section( 'sidebar-widgets-' . $widget );
}
continue;
}
$wp_customize->remove_section( $section_id );
}
}
// Maybe change section props.
if ( ! empty( $customizer_config['change_section_props'] ) ) {
foreach ( $customizer_config['change_section_props'] as $section_id => $section_props ) {
if ( ! is_array( $section_props ) ) {
continue;
}
$section = $wp_customize->get_section( $section_id );
if ( empty( $section ) || ! $section instanceof WP_Customize_Section ) {
continue;
}
$public_props = get_class_vars( get_class( $section ) );
foreach ( $section_props as $prop_name => $prop_value ) {
if ( ! in_array( $prop_name, array_keys( $public_props ) ) ) {
continue;
}
$section->$prop_name = $prop_value;
}
}
}
// Maybe remove settings
if ( ! empty( $customizer_config['remove_settings'] ) ) {
// Standardize it.
if ( is_string( $customizer_config['remove_settings'] ) ) {
$customizer_config['remove_settings'] = array( $customizer_config['remove_settings'] );
}
foreach ( $customizer_config['remove_settings'] as $setting_id ) {
$wp_customize->remove_setting( $setting_id );
}
}
// Maybe change setting props.
if ( ! empty( $customizer_config['change_setting_props'] ) ) {
foreach ( $customizer_config['change_setting_props'] as $setting_id => $setting_props ) {
if ( ! is_array( $setting_props ) ) {
continue;
}
$setting = $wp_customize->get_setting( $setting_id );
if ( empty( $setting ) || ! $setting instanceof WP_Customize_Setting ) {
continue;
}
$public_props = get_class_vars( get_class( $setting ) );
foreach ( $setting_props as $prop_name => $prop_value ) {
if ( ! in_array( $prop_name, array_keys( $public_props ) ) ) {
continue;
}
$setting->$prop_name = $prop_value;
}
}
}
// Maybe remove controls
if ( ! empty( $customizer_config['remove_controls'] ) ) {
// Standardize it.
if ( is_string( $customizer_config['remove_controls'] ) ) {
$customizer_config['remove_controls'] = array( $customizer_config['remove_controls'] );
}
foreach ( $customizer_config['remove_controls'] as $control_id ) {
$wp_customize->remove_control( $control_id );
}
}
// Maybe change control props.
if ( ! empty( $customizer_config['change_control_props'] ) ) {
foreach ( $customizer_config['change_control_props'] as $control_id => $control_props ) {
if ( ! is_array( $control_props ) ) {
continue;
}
$control = $wp_customize->get_control( $control_id );
if ( empty( $control ) || ! $control instanceof WP_Customize_Control ) {
continue;
}
$public_props = get_class_vars( get_class( $control ) );
foreach ( $control_props as $prop_name => $prop_value ) {
if ( ! in_array( $prop_name, array_keys( $public_props ) ) ) {
continue;
}
$control->$prop_name = $prop_value;
}
}
}
}
/* HELPERS */
/**
* Cleanup stuff like tab characters.
*
* @param string $string
*
* @return string
*/
function cleanup_whitespace_css( $string ) {
$string = normalize_whitespace( $string );
return $string;
}
public function get_fields_by_key( $fields_config, $key, $value, &$results, $input_key = 0 ) {
if ( ! is_array( $fields_config ) ) {
return;
}
if ( isset( $fields_config[ $key ] ) && $fields_config[ $key ] == $value ) {
$results[ $input_key ] = $fields_config;
$default = null;
if ( isset( $fields_config['default'] ) ) {
$default = $fields_config['default'];
}
$results[ $input_key ]['value'] = PixCustomifyPlugin()->get_option( $input_key, $default );
}
foreach ( $fields_config as $i => $subarray ) {
$this->get_fields_by_key( $subarray, $key, $value, $results, $i );
}
}
/**
* Return a script for flexibly localizing data to a window property.
*
* Unlike wp_localize_script() that simply creates a variable and assigns it the value,
* thus overwriting anything that may have been in that variable, we will output a script that
* will test if the variable exists and only overwrite the first level nodes, not everything.
*
* @since 2.7.0
*
* @param string $object_name Name of the variable that will contain the data.
* @param array $l10n Array of data to localize.
*
* @return bool True on success, false on failure.
*/
public static function getlocalizeToWindowScript( $object_name, $l10n ) {
$script = "window.$object_name = window.$object_name || parent.$object_name || {};\n";
foreach ( (array) $l10n as $key => $value ) {
if ( is_scalar( $value ) ) {
$value = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
}
$script .= "$object_name.$key = " . wp_json_encode( $value ) . ";\n";
}
return $script;
}
/* SANITIZATION HELPERS */
/**
* Sanitize the checkbox.
*
* @param boolean $input .
*
* @return boolean true if is 1 or '1', false if anything else
*/
function setting_sanitize_checkbox( $input ) {
if ( 1 == $input ) {
return true;
} else {
return false;
}
}
/**
* Main PixCustomify_Customizer Instance
*
* Ensures only one instance of PixCustomify_Customizer is loaded or can be loaded.
*
* @since 2.4.0
* @static
*
* @return PixCustomify_Customizer Main PixCustomify_Customizer instance
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
} // End instance ()
/**
* Cloning is forbidden.
*
* @since 2.4.0
*/
public function __clone() {
_doing_it_wrong( __FUNCTION__,esc_html__( 'You should not do that!', 'customify' ), null );
}
/**
* Unserializing instances of this class is forbidden.
*
* @since 2.4.0
*/
public function __wakeup() {
_doing_it_wrong( __FUNCTION__, esc_html__( 'You should not do that!', 'customify' ), null );
}
}
endif;