is_advanced_mode() ) {
if ( is_file( THEME_DIR . '/customizer-config.php' ) ) {
require_once THEME_DIR . '/customizer-config.php';
}
} else {
if ( is_file( THEME_DIR . '/customizer-basic-config.php' ) ) {
require_once THEME_DIR . '/customizer-basic-config.php';
} elseif ( is_file( THEME_DIR . '/customizer-config.php' ) ) {
// This is for backwards compatibility in case user upgrades framework but not theme
// in which case the customizer-basic-config.php won't be there yet.
require_once THEME_DIR . '/customizer-config.php';
}
}
// Build list of settings for live preview and CSS generation
add_action( 'customize_register', array( $this, 'build_settings_and_styles' ), 12 );
add_action( 'after_setup_theme', array( $this, 'build_settings_and_styles' ) );
// Initialize Theme Customizer
add_action( 'customize_register' , array( $this, 'customize_register' ), 14 );
// Enqueue Javascript for Theme Customizer control
add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_control_scripts' ) );
// Enqueue Javascript for Theme Customizer live preview
add_action( 'customize_preview_init' , array( $this, 'live_preview_scripts' ) );
add_action( 'wp_ajax_themify_customizer_save_option', array( $this, 'save_option' ) );
add_action( 'wp_ajax_themify_customizer_get_option', array( $this, 'get_option' ) );
// Build CSS and save stylesheet
add_action( 'customize_save_after', array( $this, 'write_stylesheet' ) );
// Output custom styling
add_action( 'wp_enqueue_scripts' , array( $this, 'enqueue_stylesheet' ), 14 );
// Remove stylesheet on theme switch
add_action( 'switch_theme' , array( $this, 'delete_stylesheet' ) );
}
/**
* Build list of styling settings with:
* - controls for live preview
* - selectors/properties for CSS rules generation
*
* @since 1.0.0
*/
function build_settings_and_styles() {
////////////////////////
// Build Controls
////////////////////////
$this->settings = apply_filters( 'themify_base_customizer_settings', array() );
////////////////////////
// Build CSS Styling
////////////////////////
foreach ( $this->settings as $key => $setting ) {
if ( isset( $setting['selector'] ) ) {
$this->styles[$setting['selector']][] = array(
'prop' => isset( $setting['prop'] ) ? $setting['prop'] : '',
'key' => isset( $key ) ? $key : '',
'prefix' => isset( $setting['prefix'] ) ? $setting['prefix'] : '',
);
}
}
}
/**
* Parameters for accordion start.
*
* @param string $label
* @param string $section
* @return array
*/
function accordion_start( $label = '', $section = 'themify_options' ) {
return array(
'control' => array(
'type' => 'Themify_Sub_Accordion_Start',
'label' => $label,
'section' => $section,
),
);
}
/**
* Parameters for accordion end.
*
* @param string $label
* @param string $section
* @return array
*/
function accordion_end( $label = '', $section = 'themify_options' ) {
return array();
}
/**
* Enqueue script for custom control.
*/
function customize_control_scripts() {
// If Customizer is active and user cleared all styling.
if ( isset( $_GET['cleared'] ) && 'true' == $_GET['cleared'] ) {
$this->delete_stylesheet();
}
// Font Icon CSS
wp_enqueue_style( 'themify-icons', THEMIFY_CUSTOMIZER_URI . '/css/themify-icons.css', array(), THEMIFY_BASE_VERSION );
// Minicolors CSS
wp_enqueue_style( 'themify-colorpicker', THEMIFY_BASE_URI . '/css/jquery.minicolors.css', array(), THEMIFY_BASE_VERSION );
// Enqueue media scripts
wp_enqueue_media();
// Controls CSS
wp_enqueue_style( 'themify-customize-control', THEMIFY_CUSTOMIZER_URI . '/css/themify.customize-control.css', array(), THEMIFY_BASE_VERSION );
// Minicolors JS
wp_enqueue_script( 'themify-colorpicker-js', THEMIFY_BASE_URI . '/js/jquery.minicolors.js', array('jquery'), THEMIFY_BASE_VERSION );
// Controls JS
wp_enqueue_script( 'themify-customize-control', THEMIFY_CUSTOMIZER_URI . '/js/themify.customize-control.js', array( 'jquery', 'customize-controls', 'underscore', 'backbone' ), THEMIFY_BASE_VERSION, true );
$controls = array(
'nonce' => wp_create_nonce( 'ajax-nonce' ),
'clearMessage' => __( 'This will reset all styling and customization. Do you want to proceed?', 'themify' ),
'confirm_on_unload' => __('You have unsaved data.', 'themify'),
);
// Pass JS variables to controls
wp_localize_script( 'themify-customize-control', 'themifyCustomizerControls', $controls );
}
/**
* Enqueue script for live preview.
*/
function live_preview_scripts() {
// Live preview JS
wp_enqueue_script( 'themify-customize-preview', THEMIFY_CUSTOMIZER_URI . '/js/themify.customize-preview.js', array( 'jquery', 'customize-preview', 'underscore', 'backbone' ), THEMIFY_BASE_VERSION, true );
$controls = array(
'nonce' => wp_create_nonce( 'ajax-nonce' ),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'isRTL' => is_rtl(),
);
foreach ( $this->settings as $key => $params ) {
if ( ! isset( $params['selector'] ) ) {
continue;
}
if ( false !== stripos( $key, '_font' ) ) {
$controls['fontControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_background' ) ) {
$controls['backgroundControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '-logo_' ) ) {
$controls['logoControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '-tagline' ) ) {
$controls['taglineControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_border' ) ) {
$controls['borderControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_margin' ) ) {
$controls['marginControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_padding' ) ) {
$controls['paddingControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_width' ) ) {
$controls['widthControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_height' ) ) {
$controls['heightControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_position' ) ) {
$controls['positionControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_color' ) ) {
$controls['colorControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, 'customcss' ) ) {
$controls['customcssControls'][$key] = $params['selector'];
}
if ( false !== stripos( $key, '_imageselect' ) ) {
$controls['imageselectControls'][$key] = $params['selector'];
}
}
// Pass JS variables to live preview scripts
wp_localize_script( 'themify-customize-preview', 'themifyCustomizer', $controls );
}
/**
* Save a blog option.
*
* @since 1.0.0
*/
function save_option(){
check_ajax_referer( 'ajax-nonce', 'nonce' );
if ( isset( $_POST['option'] ) && isset( $_POST['value'] ) ) {
update_option( $_POST['option'], stripslashes( $_POST['value'] ) );
echo 'saved';
} else {
echo 'notsaved';
}
die();
}
/**
* Get a blog option.
*
* @since 1.0.0
*/
function get_option(){
check_ajax_referer( 'ajax-nonce', 'nonce' );
if ( isset( $_POST['option'] ) && '' != $_POST['option'] ) {
switch( $_POST['option'] ) {
case 'blogname':
echo preg_replace_callback("/([0-9]+;)/", array( $this, 'decode_entities' ), html_entity_decode( get_bloginfo( 'name' ) ) );
break;
case 'blogdescription':
echo preg_replace_callback("/([0-9]+;)/", array( $this, 'decode_entities' ), html_entity_decode( get_bloginfo( 'description' ) ) );
break;
default:
echo get_option( $_POST['option'] );
break;
}
} else {
echo 'notfound';
}
die();
}
/**
* Checks if the user enabled advanced or basic mode.
* Saves option to database to fetch when customizer mode is not indicated by $_GET var.
*
* @since 2.0.6
*
* @return bool
*/
function is_advanced_mode() {
if ( !isset( $this->mode ) ) {
$key = 'themify_customizer';
// Check that var set is only 'advanced' or 'basic' since it will be saved to db
if ( isset( $_GET[$key] ) && ( 'advanced' == $_GET[$key] || 'basic' == $_GET[$key] ) ) {
update_option( $key, $_GET[$key] );
$this->mode = ( 'advanced' == $_GET[$key] ) ? 'advanced' : 'basic';
} else {
$this->mode = ( 'advanced' == get_option( $key, 'basic' ) ) ? 'advanced' : 'basic';
}
}
return 'advanced' == $this->mode;
}
/**
* Converts encoding for HTML entities not catched by html_entity_decode.
* @param array $matches
* @return string
*/
function decode_entities( $matches ) {
return mb_convert_encoding( $matches[1], 'UTF-8', 'HTML-ENTITIES' );
}
/**
* Add customizer controls.
* @param \WP_Customize_Manager $wp_customize
*/
function customize_register ( $wp_customize ) {
foreach ( array(
'themify-control',
'fonts-control',
'image-select-control',
'text-decoration-control',
'background-control',
'border-control',
'margin-control',
'padding-control',
'color-control',
'color-transparent-control',
'width-control',
'height-control',
'position-control',
'customcss-control',
'image-control',
'logo-control',
'tagline-control',
'clear-control',
'sub-accordion', ) as $control ) {
require_once THEMIFY_CUSTOMIZER_DIR . "/class-$control.php";
}
$wp_customize->add_section( 'themify_options', array(
'title' => __( 'Themify Options', 'themify' ),
'description' => sprintf( '
%s%s%s%s
',
$this->is_advanced_mode() ? 'href="' . admin_url( 'customize.php?themify_customizer=basic' ) . '"' : '',
$this->is_advanced_mode() ? 'switchto' : 'selected',
__( 'Basic', 'themify' ),
__( 'Less Options', 'themify' ),
$this->is_advanced_mode() ? '' : 'href="' . admin_url( 'customize.php?themify_customizer=advanced' ) . '"',
$this->is_advanced_mode() ? 'selected' : 'switchto',
__( 'Advanced', 'themify' ),
__( 'More Options', 'themify' )
),
)
);
$priority = 10;
foreach ( $this->settings as $setting_id => $field ) {
$setting = isset( $field['setting'] ) ? $field['setting'] : array( 'default' => '' );
$wp_customize->add_setting(
$setting_id, // serialized solo cuando type es 'option'
array(
'default' => isset( $setting['default'] ) ? $setting['default'] : '',
'type' => isset( $setting['type'] ) ? $setting['type'] : 'theme_mod',
'capability' => isset( $setting['capability'] ) ? $setting['capability'] : 'edit_theme_options',
'transport' => isset( $setting['transport'] ) ? $setting['transport'] : 'postMessage',
'sanitize_callback' => isset( $setting['sanitize'] ) ? $setting['sanitize'] : false,
)
);
if ( isset( $field['control'] ) ) {
if ( 'Themify_Sub_Accordion_Start' == $field['control']['type'] ) {
$this->set_accordion_id();
}
$control = $field['control'];
$class = $control['type'];
if ( class_exists( $class ) ) {
$wp_customize->add_control( new $class
(
$wp_customize,
$setting_id . '_ctrl',
array(
'label' => isset( $control['label'] ) ? $control['label'] : '',
'show_label' => isset( $control['show_label'] ) ? $control['show_label'] : true,
'color_label' => isset( $control['color_label'] ) ? $control['color_label'] : __( 'Color', 'themify' ),
'image_options' => isset( $control['image_options'] ) ? $control['image_options'] : array(),
'section' => isset( $control['section'] ) ? $control['section'] : 'themify_options',
'settings' => isset( $control['settings'] ) ? $control['settings'] : $setting_id,
'priority' => $priority,
'accordion_id' => $this->get_accordion_id(),
)
));
} elseif ( 'nav_menu' == $class ) {
$this->add_nav_menu_control( $wp_customize, $control['location'], array(
'priority' => $priority,
'accordion_id' => $this->get_accordion_id(),
) );
} else {
$options = array(
'label' => isset( $control['label'] ) ? $control['label'] : '',
'show_label' => isset( $control['show_label'] ) ? $control['show_label'] : true,
'color_label' => isset( $control['color_label'] ) ? $control['color_label'] : __( 'Color', 'themify' ),
'image_options' => isset( $control['image_options'] ) ? $control['image_options'] : array(),
'section' => isset( $control['section'] ) ? $control['section'] : 'themify_options',
'settings' => isset( $control['settings'] ) ? $control['settings'] : $setting_id,
'priority' => $priority,
'type' => $class,
'accordion_id' => $this->get_accordion_id(),
);
if ( 'select' == $class ) {
$options['choices'] = $control['choices'];
}
$wp_customize->add_control( $setting_id . '_ctrl', $options );
}
} elseif ( isset( $field['builtin'] ) ) {
}
$priority++;
}
// Remove Nav Menus Section
$wp_customize->remove_section( 'nav' );
// Remove title and tagline section
$wp_customize->remove_setting( 'blogname' );
$wp_customize->remove_setting( 'blogdescription' );
$wp_customize->remove_control( 'blogname' );
$wp_customize->remove_control( 'blogdescription' );
// Remove control for Posts Page in Static Front Page section
$wp_customize->remove_control( 'page_for_posts' );
}
/**
* Sets the current accordion being rendered. Used to identify controls that are nested inside it.
*
* @return number
*/
function set_accordion_id() {
$this->current_accordion_slug++;
}
/**
* Returns the current accordion being rendered. Set initially when accordion_start() is called.
*
* @return number
*/
function get_accordion_id() {
return $this->current_accordion_slug;
}
/**
* Add the control to render a navigation menu selector
*
* @param object $wp_customize Customizer instance.
* @param string $menu_location Location to add menu to.
* @param array $args Extra arguments to setup the control.
*/
function add_nav_menu_control( $wp_customize, $menu_location = '', $args = array() ) {
$locations = get_registered_nav_menus();
$menus = wp_get_nav_menus();
if ( $menus ) {
$choices = array( 0 => __( '— Select —', 'themify' ) );
foreach ( $menus as $menu ) {
$choices[ $menu->term_id ] = wp_html_excerpt( $menu->name, 40, '…' );
}
foreach ( $locations as $location => $description ) {
if ( $location == $menu_location ) {
$menu_setting_id = "nav_menu_locations[{$location}]";
$wp_customize->add_setting( $menu_setting_id, array(
'sanitize_callback' => 'absint',
'theme_supports' => 'menus',
) );
$wp_customize->add_control( $menu_setting_id, array(
'label' => $description,
'section' => 'themify_options',
'type' => 'select',
'choices' => $choices,
'priority' => $args['priority'],
) );
break;
}
}
}
}
/**
* Return the URL or the directory path for the global styling stylesheet.
*
* @since 1.1.7
*
* @param string $mode Whether to return the directory or the URL. Can be 'bydir' or 'byurl' correspondingly.
*
* @return string
*/
function get_stylesheet( $mode = 'bydir' ) {
static $before;
if ( ! isset( $before ) ) {
$upload_dir = wp_upload_dir();
$before = array(
'bydir' => $upload_dir['basedir'],
'byurl' => $upload_dir['baseurl'],
);
}
$stylesheet = "$before[$mode]/themify-customizer.css";
/**
* Filters the return URL or directory path including the file name.
*
* @since 1.1.7
*
* @param string $stylesheet Path or URL for the global styling stylesheet.
* @param string $mode What was being retrieved, 'bydir' or 'byurl'.
*/
return apply_filters( 'themify_customizer_stylesheet', $stylesheet, $mode );
}
/**
* Write stylesheet file.
*
* @since 1.1.7
*
* @return bool
*/
function write_stylesheet( $delete_empty = true ) {
$this->saving_stylesheet = true;
$css_file = $this->get_stylesheet();
$css_to_save = $this->generate_css();
// Load WP Filesystem
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
WP_Filesystem();
global $wp_filesystem;
if ( ! empty( $css_to_save ) ) {
$wp_filesystem->delete( $css_file );
if ( $wp_filesystem->put_contents( $css_file, $css_to_save, FS_CHMOD_FILE ) ) {
update_option( 'themify_customizer_stylesheet_timestamp', current_time( 'y.m.d.H.i.s' ) );
}
} elseif ( $delete_empty ) {
$wp_filesystem->delete( $css_file );
}
$this->saving_stylesheet = false;
}
/**
* Checks if the customize stylesheet exists and enqueues it. Otherwise hooks an action to wp_head to build the CSS and output it.
*
* @since 1.1.7
*/
function delete_stylesheet() {
$css_file = $this->get_stylesheet();
// Load WP Filesystem
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
WP_Filesystem();
global $wp_filesystem;
if ( $wp_filesystem->is_file( $css_file ) ) {
$wp_filesystem->delete( $css_file );
}
}
/**
* Checks whether a file exists, can be loaded and is not empty.
*
* @since 1.1.7
*
* @param string $file_path Path in server to the file to check.
*
* @return bool
*/
function is_readable_and_not_empty( $file_path = '' ) {
if ( empty( $file_path ) ) {
return false;
}
return is_readable( $file_path ) && 0 !== filesize( $file_path );
}
/**
* Tries to enqueue stylesheet. If it's not possible, it hooks an action to wp_head to build the CSS and output it.
*
* @since 1.1.7
*/
function enqueue_stylesheet() {
if ( apply_filters( 'themify_customizer_enqueue_stylesheet', true ) ) {
global $wp_customize;
if ( ( $wp_customize instanceof WP_Customize_Manager ) && $wp_customize->is_preview() ) {
add_action( 'wp_head', array( $this, 'output_css' ) );
} else {
// If enqueue fails, maybe the file doesn't exist...
if ( ! $this->test_and_enqueue() ) {
// so try to generate stylesheet...
$this->write_stylesheet( false );
// and check again
if ( ! $this->test_and_enqueue() ) {
// No luck. Let's do it inline.
add_action( 'wp_head', array( $this, 'output_css' ) );
}
}
}
}
}
/**
* Checks if the customize stylesheet exists and enqueues it.
*
* @since 1.1.7
*
* @return bool True if enqueue was successful, false otherwise.
*/
function test_and_enqueue() {
if ( $this->is_readable_and_not_empty( $this->get_stylesheet() ) ) {
wp_enqueue_style( 'themify-customize', themify_base_https_esc( $this->get_stylesheet( 'byurl' ) ), array(), $this->get_stylesheet_version() );
$this->enqueue_fonts();
return true;
}
return false;
}
/**
* Return timestamp to use as stylesheet version.
*
* @since 1.1.7
*/
function get_stylesheet_version() {
return get_option( 'themify_customizer_stylesheet_timestamp' );
}
/**
* Builds the CSS and outputs it.
*
* @since 1.1.7
*/
function output_css() {
$css = $this->generate_css();
if ( ! empty( $css ) ) {
echo "\n\n";
}
}
/**
* Enqueues Google Fonts
*
* @since 2.2.6
* @since 2.2.7 Fonts are enqueued in a single call.
*/
function enqueue_fonts() {
$this->generate_css( true ); // Call only to enqueue fonts.
if ( ! empty( $this->customizer_fonts ) ) {
$subsets = 'latin';
$user_subsets = implode( ',', themify_base_get( 'setting-subsets', array() ) );
if ( ! empty( $user_subsets ) ) {
$subsets .= ",$user_subsets";
}
$this->customizer_fonts = str_replace( ' ', '+', implode( '|', $this->customizer_fonts ) );
wp_enqueue_style( 'customizer-google-fonts' . md5( $this->customizer_fonts . $subsets ), themify_base_https_esc( 'http://fonts.googleapis.com/css' ) . '?family=' . $this->customizer_fonts . '&subset=' . $subsets );
}
}
/**
* Generate CSS rules and output them.
* @uses filter 'themify_theme_styling' over output.
*
* @param bool $fonts_only Whether to extracts fonts or not.
*
* @return string
*/
function generate_css( $fonts_only = false ) {
global $wp_customize;
$is_customize = isset( $wp_customize );
// Styles are saved by selector to later output them all at once
$css = array();
$custom_css = '';
foreach ( $this->styles as $selector => $style ) {
if ( ! isset( $css[$selector] ) ) {
$css[$selector] = '';
}
if ( ! $fonts_only ) {
if ( 'customcss' == $selector && ( ! $is_customize || $this->saving_stylesheet ) ) {
$custom_css = $this->custom_css();
continue;
}
}
if ( isset( $style[0] ) ) {
if ( is_array( $style[0] ) ) {
foreach( array_map( 'unserialize', array_unique( array_map( 'serialize', $style ) ) ) as $mstyle ) {
if ( 'logo' == $mstyle['prop'] || 'tagline' == $mstyle['prop'] ) {
if ( $logo_props = $this->build_image_size_rule( $mstyle['key'] ) ) {
$css[$selector . ' img'] = $logo_props;
}
if ( 'logo' == $mstyle['prop'] ) {
$css[$selector . ' a'] = $this->build_color_rule( $mstyle['key'] );
}
}
$css[$selector] .= $this->build_css_rule( $selector, $mstyle['prop'], $mstyle['key'],
isset( $mstyle['prefix'] ) ? $mstyle['prefix'] : '',
isset( $mstyle['suffix'] ) ? $mstyle['suffix'] : '',
$fonts_only
);
}
} else {
if ( 'logo' == $style['prop'] || 'tagline' == $style['prop'] ) {
if ( $logo_props = $this->build_image_size_rule( $style['key'] ) ) {
$css[$selector . ' img'] = $logo_props;
}
if ( 'logo' == $style['prop'] ) {
$css[$selector . ' a'] = $this->build_color_rule( $style['key'] );
}
}
$css[$selector] .= $this->build_css_rule( $selector, $style['prop'], $style['key'],
isset( $style['prefix'] ) ? $style['prefix'] : '',
isset( $style['suffix'] ) ? $style['suffix'] : '',
$fonts_only
);
}
}
}
$out = '';
if ( ! $fonts_only ) {
if ( ! empty( $css ) ) {
foreach ( $css as $selector => $properties ) {
$out .= '' != $properties ? "$selector {\t$properties \n}\n" : '';
}
if ( ! empty( $out ) ) {
$out = "/* Themify Customize Styling */\n" . apply_filters( 'themify_customizer_styling', $out );
}
}
if ( ! empty( $custom_css ) ) {
$out .= "\n/* Themify Custom CSS */\n" . apply_filters( 'themify_customizer_custom_css', $custom_css );
}
}
return $out;
}
/**
* Outputs image width and height for the logo/description image if they are available.
*
* @param string $mod_name
* @return string
*/
function build_image_size_rule( $mod_name ) {
$element = json_decode( $this->get_cached_mod( $mod_name ) );
$element_props = '';
if ( ! empty( $element->imgwidth ) ) {
$element_props .= "\twidth: {$element->imgwidth}px;";
}
if ( ! empty( $element->imgheight ) ) {
$element_props .= "\n\theight: {$element->imgheight}px;";
}
return $element_props;
}
/**
* Outputs color for the logo in text mode since it's needed for the .
*
* @param string $mod_name
* @return string
*/
function build_color_rule( $mod_name ) {
$element = json_decode( $this->get_cached_mod( $mod_name ) );
$element_props = '';
if ( ! empty( $element->imgwidth ) ) {
$element_props .= "\twidth: {$element->imgwidth}px;";
}
if ( isset( $element->color ) && '' != $element->color ) {
$element_props .= "\n\tcolor: #$element->color;";
$opacity = ( isset( $element->opacity ) && '' != $element->opacity ) ? $element->opacity : '1';
$element_props .= "\n\tcolor: rgba(" . $this->hex2rgb( $element->color ) . ',' . $opacity . ');';
}
return $element_props;
}
/**
* Checks if there's a Custom CSS text stored, formats it and returns it to be output.
*
* @return string
*/
function custom_css() {
$mod = $this->get_cached_mod( 'customcss' );
// Remove JSON stuff
$mod = str_replace( '{"css":"', '', $mod );
$mod = str_replace( '"}', '', $mod );
// Escape backslashes, single and double quotes
$mod = addslashes( $mod );
// Rebuild JSON
$mod = '{"css":"' . $mod . '"}';
$customcss = json_decode( $mod );
$out = '';
if ( isset( $customcss->css ) && '' != $customcss->css ) {
$out .= str_replace( array( '{', '}' ), array( "{\n\t", "\n}\n" ), trim( $customcss->css ) );
}
return $out;
}
/**
* Return theme mod using cached static var if possible.
*
* @param $name
* @param bool $default
*
* @return mixed|void
*/
function get_cached_mod( $name, $default = false ) {
static $mods;
if ( ! isset( $mods ) ) {
$mods = get_theme_mods();
}
if ( isset( $mods[$name] ) ) {
/**
* Filter the theme modification, or 'theme_mod', value.
*
* The dynamic portion of the hook name, $name, refers to
* the key name of the modification array. For example,
* 'header_textcolor', 'header_image', and so on depending
* on the theme options.
*
* @since 2.2.0
*
* @param string $current_mod The value of the current theme modification.
*/
return apply_filters( "theme_mod_{$name}", $mods[$name] );
}
if ( is_string( $default ) )
$default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() );
/** This filter is documented in wp-includes/theme.php */
return apply_filters( "theme_mod_{$name}", $default );
}
/**
* Build a CSS rule.
*
* @param string $selector CSS selector.
* @param string $style CSS property to write.
* @param string $mod_name The 'theme_mod' option to fetch.
* @param string $prefix Prefix for CSS property value.
* @param string $suffix Suffix for CSS property value.
* @param bool $fonts_only Whether to extracts fonts or not.
* @return string CSS rule: selector, property and property value. Empty if 'theme_mod' option specified is empty.
*/
function build_css_rule( $selector, $style, $mod_name, $prefix = '', $suffix = '', $fonts_only = false ) {
$mod = $this->get_cached_mod( $mod_name );
$out = '';
if ( ! empty( $mod ) ) {
if ( 'font' == $style || 'logo' == $style || 'tagline' == $style || 'decoration' == $style ) {
// Font Rule
$font = json_decode( $mod );
if ( isset( $font->family->name ) && '' != $font->family->name ) {
if ( isset( $font->family->fonttype ) && 'google' == $font->family->fonttype ) {
$this->customizer_fonts[] = $font->family->name;
}
$out .= sprintf("\n\tfont-family:%s;", $prefix . $font->family->name . $suffix );
}
if ( ! isset( $font->nostyle ) || '' == $font->nostyle ) {
if ( isset( $font->italic ) && '' != $font->italic ) {
$out .= sprintf("\tfont-style:%s;\n", $prefix . $font->italic . $suffix );
}
if ( isset( $font->bold ) && '' != $font->bold ) {
$out .= sprintf("\tfont-weight:%s;\n", $prefix . $font->bold . $suffix );
}
if ( isset( $font->underline ) && '' != $font->underline ) {
$out .= sprintf("\ttext-decoration:%s;\n", $prefix . $font->underline . $suffix );
} elseif ( isset( $font->linethrough ) && '' != $font->linethrough ) {
$font->linethrough = 'linethrough' == $font->linethrough ? 'line-through' : $font->linethrough;
$out .= sprintf("\ttext-decoration:%s;\n", $prefix . $font->linethrough . $suffix );
}
} else {
$out .= sprintf("\tfont-style:%s;\n", $prefix . 'normal' . $suffix );
$out .= sprintf("\tfont-weight:%s;\n", $prefix . 'normal' . $suffix );
$out .= sprintf("\ttext-decoration:%s;\n", $prefix . 'none' . $suffix );
}
if ( isset( $font->sizenum ) && '' != $font->sizenum ) {
$unit = isset( $font->sizeunit ) && '' != $font->sizeunit ? $font->sizeunit : 'px';
$out .= sprintf("\tfont-size:%s;\n", $prefix . $font->sizenum . $unit . $suffix );
}
if ( isset( $font->linenum ) && '' != $font->linenum ) {
$unit = isset( $font->lineunit ) && '' != $font->lineunit ? $font->lineunit : 'px';
$out .= sprintf("\tline-height:%s;\n", $prefix . $font->linenum . $unit . $suffix );
}
if ( isset( $font->texttransform ) && '' != $font->texttransform ) {
if ( 'notexttransform' == $font->texttransform ) {
$out .= sprintf("\ttext-transform:%s;", $prefix . 'none' . $suffix );
} else {
$out .= sprintf("\ttext-transform:%s;", $prefix . $font->texttransform . $suffix );
}
}
if ( isset( $font->align ) && '' != $font->align ) {
if ( 'noalign' != $font->align ) {
$out .= sprintf("\ttext-align:%s;", $prefix . $font->align . $suffix );
} else {
if ( '' == is_rtl() ) {
$out .= sprintf("\ttext-align:%s;", $prefix . 'left' . $suffix );
} else {
$out .= sprintf("\ttext-align:%s;", $prefix . 'right' . $suffix );
}
}
}
if ( isset( $font->color ) && '' != $font->color ) {
$out .= "\n\tcolor: #$font->color;";
$opacity = ( isset( $font->opacity ) && '' != $font->opacity ) ? $font->opacity : '1';
$out .= "\n\tcolor: rgba(" . $this->hex2rgb( $font->color ) . ',' . $opacity . ');';
}
}
if ( $fonts_only ) {
return '';
}
if ( 'logo' == $style || 'tagline' == $style ) {
// Logo/description Rule
$element = json_decode( $mod );
if ( isset( $element->mode ) ) {
if ( 'none' == $element->mode ) {
$out .= 'display: none;';
}
}
} elseif ( 'color' == $style ) {
// Color Rule
$color = json_decode( $mod );
if ( isset( $color->color ) && '' != $color->color ) {
$out .= "\n\tcolor: #$color->color;";
$opacity = ( isset( $color->opacity ) && '' != $color->opacity ) ? $color->opacity : '1';
$out .= "\n\tcolor: rgba(" . $this->hex2rgb( $color->color ) . ',' . $opacity . ');';
}
} elseif ( 'background' == $style ) {
// Background Rule
$bg = json_decode( $mod );
if ( isset( $bg->noimage ) && 'noimage' == $bg->noimage ) {
$out .= 'background-image: none;';
} elseif ( isset( $bg->src ) && '' != $bg->src ) {
$out .= sprintf("background-image: url(%s);", $prefix . $bg->src . $suffix );
}
if ( isset( $bg->style ) && '' != $bg->style ) {
if ( 'fullcover' == $bg->style ) {
$out .= "\n\tbackground-size: cover;";
} else {
$out .= "\n\tbackground-repeat: {$bg->style};";
}
}
if ( isset( $bg->position ) && '' != $bg->position ) {
$out .= "\n\tbackground-position: {$bg->position};";
}
if ( isset( $bg->transparent ) && '' != $bg->transparent ) {
$out .= "\n\tbackground-color: $bg->transparent;";
} elseif ( isset( $bg->color ) && '' != $bg->color ) {
$out .= "\n\tbackground-color: #$bg->color;";
$opacity = ( isset( $bg->opacity ) && '' != $bg->opacity ) ? $bg->opacity : '1';
$out .= "\n\tbackground-color: rgba(" . $this->hex2rgb( $bg->color ) . ',' . $opacity . ');';
}
} elseif ( 'border' == $style ) {
// Border Rule
$border = json_decode( $mod );
if ( isset( $border->disabled ) && 'disabled' == $border->disabled ) {
$out .= 'border: none;';
} else {
$same = ( isset( $border->same ) && '' != $border->same ) ? 'same' : '';
if ( '' == $same ) {
foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) {
if ( isset( $border->{$side} ) ) {
$border_side = $border->{$side};
$out .= $this->setBorder( $border_side, 'border-' . $side );
}
}
} else {
$out .= $this->setBorder( $border );
}
}
} elseif ( 'margin' == $style || 'padding' == $style ) {
// Margin/Padding Rule
$marginpadding = json_decode( $mod );
$same = ( isset( $marginpadding->same ) && '' != $marginpadding->same ) ? 'same' : '';
if ( '' == $same ) {
foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) {
if ( isset( $marginpadding->{$side} ) ) {
if ( 'margin' == $style && isset( $marginpadding->{$side}->auto ) && 'auto' == $marginpadding->{$side}->auto ) {
$out .= $style . '-' . $side . ': auto;';
} else {
$this_side = $marginpadding->{$side};
$out .= $this->setDimension( $this_side, $style . '-' . $side );
}
}
}
} else {
if ( 'margin' == $style && isset( $marginpadding->auto ) && 'auto' == $marginpadding->auto ) {
$out .= $style . ': auto;';
} else {
$out .= $this->setDimension( $marginpadding, $style );
}
}
} elseif ( 'width' == $style || 'height' == $style ) {
// Width/Height Rule
$widthheight = json_decode( $mod );
if ( isset( $widthheight->auto ) && 'auto' == $widthheight->auto ) {
$out .= $style . ': auto;';
} else {
$out .= $this->setDimension( $widthheight, $style );
}
} elseif ( 'position' == $style ) {
// Position Rule
$position = json_decode( $mod );
if ( isset( $position->position ) && '' != $position->position ) {
$out .= sprintf("\tposition:%s;\n", $prefix . $position->position . $suffix );
}
foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) {
if ( isset( $position->{$side} ) ) {
if ( isset( $position->{$side}->auto ) && 'auto' == $position->{$side}->auto ) {
$out .= $side . ': auto;';
} else {
$this_side = $position->{$side};
$out .= $this->setDimension( $this_side, $side );
}
}
}
} elseif ( 'image' == $style ) {
// Image Rule does nothing because it's not styling by markup injected in a php function.
}
}
// Build rule to return
if ( '' != $out ) {
$out = "\t$out";
}
return $out;
}
/**
* Generate border properties.
*
* @uses hex2rgb()
*
* @param object $border Object with all the necessary values.
* @param string $property Property to set, can be border or border-left for example
* @return string
*/
function setBorder( $border, $property = 'border' ) {
$out = '';
if ( isset( $border->style ) && 'none' != $border->style ) {
if ( '' != $border->style ) {
$out .= "\n\t$property-style: $border->style;";
}
if ( isset( $border->width ) && '' != $border->width ) {
$out .= "\n\t$property-width: {$border->width}px;";
}
if ( isset( $border->color ) && '' != $border->color ) {
$out .= "\n\t$property-color: #$border->color;";
$opacity = ( isset( $border->opacity ) && '' != $border->opacity ) ? $border->opacity : '1';
$out .= "\n\t$property-color: rgba(" . $this->hex2rgb( $border->color ) . ',' . $opacity . ');';
}
} else {
$out .= "\n\t$property: none;";
}
return $out;
}
/**
* Generate dimension properties for cases like padding or margin.
*
* @param object $object Object with all the necessary values.
* @param string $property Property to set, can be margin or padding-left for example
* @return string
*/
function setDimension( $object, $property = 'margin' ) {
$out = '';
if ( isset( $object->unit ) && 'px' != $object->unit ) {
$unit = $object->unit;
} else {
$unit = 'px';
}
if ( isset( $object->width ) && '' != $object->width ) {
$out .= "\n\t$property: {$object->width}$unit;";
}
return $out;
}
/**
* Converts color in hexadecimal format to RGB format.
*
* @param string $hex Color in hexadecimal format.
* @return string Color in RGB components separated by comma.
*/
function hex2rgb( $hex ) {
$hex = str_replace( "#", "", $hex );
if ( strlen( $hex ) == 3 ) {
$r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
$g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
$b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
} else {
$r = hexdec( substr( $hex, 0, 2 ) );
$g = hexdec( substr( $hex, 2, 2 ) );
$b = hexdec( substr( $hex, 4, 2 ) );
}
return implode( ',', array( $r, $g, $b ) );
}
/**
* Inserts logo image in site title or hides it.
*
* @param string $location
* @return string
*/
function site_logo( $location = '' ) {
$site_name = get_bloginfo( 'name' );
$logo = json_decode( $this->get_cached_mod( $location . '_image' ) );
$has_image_src = isset( $logo->src ) && '' != $logo->src;
$is_image_mode = isset( $logo->mode ) && 'image' == $logo->mode;
if ( $is_image_mode ) {
$url = apply_filters( 'themify_customizer_logo_home_url', isset( $logo->link ) && ! empty( $logo->link ) ? $logo->link : home_url() );
} else {
$url = apply_filters( 'themify_customizer_logo_home_url', isset( $logo->link ) && ! empty( $logo->link ) ? $logo->link : home_url() );
}
$html = '';
if ( isset( $this->settings[$location . '_image'] ) && $has_image_src && $is_image_mode ) {
$html .= '
';
$html .= '' . $site_name . '';
} else {
$html .= '' . $site_name . '';
}
$html .= '';
return $html;
}
/**
* Inserts image in site description or hides it.
*
* @param string $location
* @return string
*/
function site_description( $location = 'site-tagline' ) {
$site_desc = get_bloginfo( 'description' );
$desc = json_decode( $this->get_cached_mod( $location ) );
$has_image_src = isset( $desc->src ) && '' != $desc->src;
$is_image_mode = isset( $desc->mode ) && 'image' == $desc->mode;
$html = '';
if ( isset( $this->settings[$location] ) && $has_image_src && $is_image_mode ) {
$html .= '
';
$html .= '' . $site_desc . '';
} else {
$html .= '' . $site_desc . '';
}
return $html;
}
}
$GLOBALS['themify_customizer'] = new Themify_Customizer;