Server : Apache System : Linux server.lienzindia.com 4.18.0-348.7.1.el8_5.x86_64 #1 SMP Wed Dec 22 13:25:12 UTC 2021 x86_64 User : plutus ( 1007) PHP Version : 7.4.33 Disable Function : NONE Directory : /home/plutus/public_html/wp-content/themes/vrm/inc/ |
Upload File : |
<?php namespace TotalTheme; use TotalTheme\Helpers\Add_Template; \defined( 'ABSPATH' ) || exit; /** * WP Customizer Support. */ class Customizer { /** * Customizer sections. * * @var array */ public $sections = []; /** * Is postMessage enabled? * * @var bool */ protected $enable_postMessage = true; /** * Check if currently in customizer preview mode. * * @var array */ protected $is_customize_preview = null; /** * Instance. */ private static $instance; /** * Create or retrieve the instance of our class. */ public static function instance() { if ( \is_null( self::$instance ) ) { self::$instance = new self(); self::$instance->initialize(); } return self::$instance; } /** * Constructor. */ public function __construct() {} /** * Initialize */ public function initialize() { \define( 'WPEX_CUSTOMIZER_DIR', WPEX_INC_DIR . 'customizer/' ); $this->init_hooks(); $this->load_customizer_manager(); } /** * Hook into actions and filters. */ public function init_hooks() { $is_customize_preview = $this->is_customize_preview(); if ( wpex_is_request( 'frontend' ) || $is_customize_preview ) { \add_action( 'wp_loaded', [ $this, 'add_to_customizer' ], 1 ); \add_action( 'init', [ $this, 'inline_css' ] ); } if ( $is_customize_preview || ( is_admin() && wp_doing_ajax() ) ) { \add_action( 'wp_ajax_totaltheme_customize_create_template', [ $this, 'ajax_create_template' ] ); } } /** * Include Customizer Manager. */ public function load_customizer_manager() { if ( \get_theme_mod( 'customizer_panel_enable', true ) && \is_admin() ) { new Customizer\Manager; } } /** * Check if currently in customize mode. */ protected function is_customize_preview() { if ( null === $this->is_customize_preview ) { $this->is_customize_preview = \is_customize_preview(); } return $this->is_customize_preview; } /** * Define panels. */ public function panels(): array { $panels = [ 'global_styles' => array( 'title' => \esc_html__( 'Global Styles', 'total' ), ), 'general' => array( 'title' => \esc_html__( 'General Theme Options', 'total' ), ), 'layout' => array( 'title' => \esc_html__( 'Layout', 'total' ), ), 'typography' => array( 'title' => \esc_html__( 'Typography', 'total' ), ), 'togglebar' => array( 'title' => \esc_html__( 'Toggle Bar', 'total' ), 'is_section' => true, ), 'topbar' => array( 'title' => \esc_html__( 'Top Bar', 'total' ), ), 'header' => array( 'title' => \esc_html__( 'Header', 'total' ), ), 'sidebar' => array( 'title' => \esc_html__( 'Sidebar', 'total' ), 'is_section' => true, ), 'blog' => array( 'title' => \esc_html__( 'Blog', 'total' ), ), 'portfolio' => array( 'title' => wpex_get_portfolio_name(), 'condition' => 'wpex_is_total_portfolio_enabled', ), 'staff' => array( 'title' => wpex_get_staff_name(), 'condition' => 'wpex_is_total_staff_enabled', ), 'testimonials' => array( 'title' => wpex_get_testimonials_name(), 'condition' => 'wpex_is_total_testimonials_enabled', ), // @todo rename to footer_callout 'callout' => array( 'title' => \esc_html__( 'Callout', 'total' ), ), 'footer_widgets' => array( 'title' => \esc_html__( 'Footer Widgets', 'total' ), 'is_section' => true, ), 'footer_bottom' => array( 'title' => \esc_html__( 'Footer Bottom', 'total' ), 'is_section' => true, ), ]; /** * Filters the customizer panels. * * @param array $panels */ $panels = (array) \apply_filters( 'wpex_customizer_panels', $panels ); return $panels; } /** * Returns array of enabled panels. */ public function enabled_panels() { $panels = $this->panels(); $disabled_panels = (array) \get_option( 'wpex_disabled_customizer_panels' ); if ( $disabled_panels ) { foreach ( $panels as $key => $val ) { if ( \in_array( $key, $disabled_panels ) ) { unset( $panels[ $key ] ); } } } return $panels; } /** * Check if customizer section is enabled. */ public function is_section_enabled( array $section, string $section_id ): bool { $section_panel = ! empty( $section[ 'panel' ] ) ? $section[ 'panel' ] : $section_id; if ( $section_panel ) { $enabled_panels = $this->enabled_panels(); $section_panel = \str_replace( 'wpex_', '', $section_panel ); if ( empty( $enabled_panels[ $section_panel ] ) ) { return false; } } return true; // all enabled by default } /** * Initialize customizer settings. */ public function add_to_customizer() { if ( ! $this->sections ) { $this->add_sections(); } \add_action( 'customize_controls_enqueue_scripts', [ $this, 'customize_controls_enqueue_scripts' ] ); \add_action( 'customize_controls_print_styles', [ $this, 'customize_controls_print_styles' ] ); \add_action( 'customize_register', [ $this, 'register_control_types' ] ); \add_action( 'customize_register', [ $this, 'active_callback_functions' ] ); \add_action( 'customize_register', [ $this, 'remove_core_sections' ], 11 ); \add_action( 'customize_register', [ $this, 'add_customizer_panels_sections' ], 40 ); \add_action( 'customize_preview_init', [ $this, 'customize_preview_init' ] ); } /** * Inline css. */ public function inline_css() { if ( $this->is_customize_preview() && $this->enable_postMessage ) { \add_action( 'wp_head', [ $this, 'live_preview_styles' ], 99999 ); } else { \add_filter( 'wpex_head_css', [ $this, 'head_css' ], 999 ); } } /** * Adds custom controls. */ public function customize_controls_enqueue_scripts() { // Chosen \wp_enqueue_style( 'wpex-chosen' ); \wp_enqueue_script( 'wpex-chosen' ); \wp_enqueue_script( 'wpex-chosen-icon' ); // Controls JS \wp_enqueue_script( 'totaltheme-customize-controls', wpex_asset_url( 'js/customize/controls.min.js' ), [ 'customize-controls', 'wpex-chosen', 'jquery' ], WPEX_THEME_VERSION ); \wp_localize_script( 'totaltheme-customize-controls', 'totaltheme_customize_controls_vars', [ 'deleteConfirm' => \esc_html__( 'Are you sure you want to delete this?', 'total' ), 'duplicate' => \esc_html__( 'This item has already been added', 'total' ), 'nonce' => \wp_create_nonce( 'totaltheme_customize_nonce' ) ] ); \wp_enqueue_script( 'totaltheme-customize-control-display', \wpex_asset_url( 'js/customize/control-display.min.js' ), [ 'customize-controls' ], WPEX_THEME_VERSION ); \wp_localize_script( 'totaltheme-customize-control-display', 'totaltheme_customize_control_display_vars', $this->get_control_visibility_settings() ); // Customizer CSS \wp_enqueue_style( 'totaltheme-customize-controls', \wpex_asset_url( 'css/customize/controls.css' ), [], WPEX_THEME_VERSION ); } /** * Registered custom controls that are eligible to be rendered via JS and created dynamically. * * @link https://developer.wordpress.org/reference/classes/wp_customize_manager/register_control_type/ */ public function register_control_types( $wp_customize ) { $wp_customize->register_control_type( 'TotalTheme\\Customizer\\Controls\\Hr' ); $wp_customize->register_control_type( 'TotalTheme\\Customizer\\Controls\\Heading' ); $wp_customize->register_control_type( 'TotalTheme\\Customizer\\Controls\\Notice' ); $wp_customize->register_control_type( 'TotalTheme\\Customizer\\Controls\\Icon_Select' ); } /** * Adds custom controls. */ public function active_callback_functions() { require_once WPEX_CUSTOMIZER_DIR . 'active-callback-functions.php'; } /** * Adds CSS for customizer custom controls. * * MUST Be added inline to get post type Icons. */ public function customize_controls_print_styles() { $portfolio_icon = \wpex_dashicon_css_content( \wpex_get_portfolio_menu_icon() ); $staff_icon = \wpex_dashicon_css_content( \wpex_get_staff_menu_icon() ); $testimonials_icon = \wpex_dashicon_css_content( \wpex_get_testimonials_menu_icon() ); // Get admin color. // @todo remove once this becomes available as a CSS variable. $admin_color = \get_user_option( 'admin_color' ); switch ( $admin_color ) { case 'light': $icon_color = '#04a4cc'; break; case 'blue': $icon_color = '#0073aa'; break; case 'coffee': $icon_color = '#c7a589'; break; case 'ectoplasm': $icon_color = '#a3b745'; break; case 'midnight': $icon_color = '#e14d43'; break; case 'ocean': $icon_color = '#9ebaa0'; break; case 'sunrise': $icon_color = '#dd823b'; break; case 'modern': $icon_color = '#3858e9'; break; default: $icon_color = '#2271b1'; break; } ?> <style id="wpex-customizer-controls-css"> /* Icons */ li.control-panel:not(.customize-pane-child)[id^="accordion-panel-wpex_"] > .accordion-section-title:before, li.control-section:not(.control-subsection)[id^="accordion-section-wpex_"] > .accordion-section-title:before { display: inline-block; width: 20px; height: 20px; font-size: 20px; line-height: 1; text-decoration: inherit; font-weight: 400; font-style: normal; vertical-align: top; text-align: center; transition: inherit; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color:<?php echo esc_attr( $icon_color ) ?>; margin-right: 10px; font-family: "dashicons"; content: "\f108"; } <?php if ( is_rtl() ) { ?> li.control-panel:not(.customize-pane-child)[id^="accordion-panel-wpex_"] > .accordion-section-title:before, li.control-section:not(.control-subsection)[id^="accordion-section-wpex_"] > .accordion-section-title:before { margin-right: 0; margin-left: 10px; } <?php } ?> #accordion-panel-wpex_global_styles > .accordion-section-title:before { content: "\f100" } #accordion-panel-wpex_typography > .accordion-section-title:before { content: "\f216" } #accordion-panel-wpex_layout > .accordion-section-title:before { content: "\f535" } #accordion-section-wpex_togglebar > .accordion-section-title:before { content: "\f132" } #accordion-panel-wpex_topbar > .accordion-section-title:before { content: "\f157" } #accordion-panel-wpex_header > .accordion-section-title:before { content: "\f175" } #accordion-section-wpex_sidebar > .accordion-section-title:before { content: "\f135" } #accordion-panel-wpex_blog > .accordion-section-title:before { content: "\f109" } #accordion-panel-wpex_portfolio > .accordion-section-title:before { content: "\<?php echo esc_attr( $portfolio_icon ); ?>" } #accordion-panel-wpex_staff > .accordion-section-title:before { content: "\<?php echo esc_attr( $staff_icon ); ?>" } #accordion-panel-wpex_testimonials > .accordion-section-title:before { content: "\<?php echo esc_attr( $testimonials_icon ); ?>" } #accordion-panel-wpex_callout > .accordion-section-title:before { content: "\f488" } #accordion-section-wpex_footer_widgets > .accordion-section-title:before { content: "\f209" } #accordion-section-wpex_footer_bottom > .accordion-section-title:before { content: "\f209"; } #accordion-section-wpex_visual_composer > .accordion-section-title:before { content: ""; background-image: url("data:image/svg+xml,%3Csvg fill='%230473aa' height='20' width='20' viewBox='0.0004968540742993355 -0.00035214610397815704 65.50897979736328 49.80835723876953' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M51.345 9.041c-4.484-.359-6.371.747-8.509 1.039 2.169 1.135 5.125 2.099 8.708 1.89-3.3 1.296-8.657.853-12.355-1.406-.963-.589-1.975-1.519-2.733-2.262C33.459 5.583 31.247.401 21.683.018 9.687-.457.465 8.347.016 19.645s8.91 20.843 20.907 21.318c.158.008.316.006.472.006 3.137-.184 7.27-1.436 10.383-3.355-1.635 2.32-7.746 4.775-10.927 5.553.319 2.527 1.671 3.702 2.78 4.497 2.459 1.76 5.378-.73 12.11-.606 3.746.069 7.61 1.001 10.734 2.75l3.306-11.54c8.402.13 15.4-6.063 15.716-14.018.321-8.088-5.586-14.527-14.152-15.209h0z'%3E%3C/path%3E%3C/svg%3E"); } #accordion-panel-wpex_woocommerce > .accordion-section-title:before { content: ""; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath fill='%237F54B3' d='M612.192 426.336c0-6.896-3.136-51.6-28-51.6-37.36 0-46.704 72.256-46.704 82.624 0 3.408 3.152 58.496 28.032 58.496 34.192-.032 46.672-72.288 46.672-89.52zm202.192 0c0-6.896-3.152-51.6-28.032-51.6-37.28 0-46.608 72.256-46.608 82.624 0 3.408 3.072 58.496 27.952 58.496 34.192-.032 46.688-72.288 46.688-89.52zM141.296.768c-68.224 0-123.504 55.488-123.504 123.92v650.72c0 68.432 55.296 123.92 123.504 123.92h339.808l123.504 123.936V899.328h278.048c68.224 0 123.52-55.472 123.52-123.92v-650.72c0-68.432-55.296-123.92-123.52-123.92h-741.36zm526.864 422.16c0 55.088-31.088 154.88-102.64 154.88-6.208 0-18.496-3.616-25.424-6.016-32.512-11.168-50.192-49.696-52.352-66.256 0 0-3.072-17.792-3.072-40.752 0-22.992 3.072-45.328 3.072-45.328 15.552-75.728 43.552-106.736 96.448-106.736 59.072-.032 83.968 58.528 83.968 110.208zM486.496 302.4c0 3.392-43.552 141.168-43.552 213.424v75.712c-2.592 12.08-4.16 24.144-21.824 24.144-46.608 0-88.88-151.472-92.016-161.84-6.208 6.896-62.24 161.84-96.448 161.84-24.864 0-43.552-113.648-46.608-123.936C176.704 436.672 160 334.224 160 327.328c0-20.672 1.152-38.736 26.048-38.736 6.208 0 21.6 6.064 23.712 17.168 11.648 62.032 16.688 120.512 29.168 185.968 1.856 2.928 1.504 7.008 4.56 10.432 3.152-10.288 66.928-168.784 94.96-168.784 22.544 0 30.4 44.592 33.536 61.824 6.208 20.656 13.088 55.216 22.416 82.752 0-13.776 12.48-203.12 65.392-203.12 18.592.032 26.704 6.928 26.704 27.568zM870.32 422.928c0 55.088-31.088 154.88-102.64 154.88-6.192 0-18.448-3.616-25.424-6.016-32.432-11.168-50.176-49.696-52.288-66.256 0 0-3.888-17.92-3.888-40.896s3.888-45.184 3.888-45.184c15.552-75.728 43.488-106.736 96.384-106.736 59.104-.032 83.968 58.528 83.968 110.208z'/%3E%3C/svg%3E"); } #accordion-section-wpex_tribe_events > .accordion-section-title:before { content: "\f145" } #accordion-section-wpex_bbpress > .accordion-section-title:before { content: "\f449" } #accordion-panel-wpex_learndash > .accordion-section-title:before { content: "\f118" } #accordion-panel-wpex_buddypress > .accordion-section-title:before { content: "\f448" } #accordion-panel-wpex_sensei > .accordion-section-title:before { font-family: sensei; content: ""; } </style> <?php } /** * Removes core modules. */ public function remove_core_sections( $wp_customize ) { // Remove core sections. $wp_customize->remove_section( 'colors' ); $wp_customize->remove_section( 'background_image' ); // Remove core controls. $wp_customize->remove_control( 'blogdescription' ); $wp_customize->remove_control( 'header_textcolor' ); $wp_customize->remove_control( 'background_color' ); $wp_customize->remove_control( 'background_image' ); // Remove default settings. $wp_customize->remove_setting( 'background_color' ); $wp_customize->remove_setting( 'background_image' ); } /** * Get all sections. */ public function add_sections() { $panels = $this->panels(); if ( ! $panels ) { return; } foreach ( $panels as $id => $val ) { // These have their own sections outside the main class scope. if ( 'typography' === $id ) { continue; } // Continue if condition isn't me. if ( isset( $val['condition'] ) && ! call_user_func( $val['condition'] ) ) { continue; } // Section file location. if ( ! empty( $val['settings'] ) ) { $file = $val['settings']; } else { $file = WPEX_CUSTOMIZER_DIR . "settings/{$id}.php"; } // Include file and update sections var. if ( ! is_array( $file ) && file_exists( $file ) ) { require_once $file; } } // Loop through sections and set keys equal to ID for easier child theming. // Also remove anything that is only needed in the customizer to free up memory. $parsed_sections = []; if ( $this->sections && is_array( $this->sections ) ) { foreach ( $this->sections as $key => $val ) { $new_settings = []; if ( ! $this->is_customize_preview() ) { unset( $val['title'], $val['panel'], $val['description'] ); } foreach ( $val['settings'] as $skey => $sval ) { if ( $this->is_customize_preview() ) { $new_settings[$sval['id']] = $sval; } else { if ( empty( $sval['inline_css'] ) ) { continue; // only inline_css needed for frontend. } if ( isset( $sval['control']['type'] ) ) { $sval['type'] = $sval['control']['type']; } unset( $sval['transport'], $sval['control'], $sval['control_display'], $sval['description'] ); $new_settings[$sval['id']] = $sval; } } if ( $new_settings ) { $val['settings'] = $new_settings; $parsed_sections[$key] = $val; } } } /** * Filters the customizer sections. * * @param array $sections */ $this->sections = (array) \apply_filters( 'wpex_customizer_sections', $parsed_sections ); } /** * Registers new controls. * * Removes default customizer sections and settings * Adds new customizer sections, settings & controls */ public function add_customizer_panels_sections( $wp_customize ) { $all_panels = $this->panels(); $enabled_panels = $this->enabled_panels(); if ( ! $enabled_panels ) { return; } $priority = 140; foreach ( $all_panels as $id => $val ) { $priority++; // Continue if panel is disabled or it's the typography panel. if ( ! isset( $enabled_panels[$id] ) || 'typography' === $id ) { continue; } // Continue if condition isn't met. if ( isset( $val['condition'] ) && ! $val['condition'] ) { continue; } // Get panel title. $title = $val['title'] ?? $val; // Check if panel is a section. $is_section = isset( $val['is_section'] ); // Add section. if ( $is_section ) { $wp_customize->add_section( "wpex_{$id}", [ 'priority' => $priority, 'title' => $title, ] ); } // Add Panel. else { $wp_customize->add_panel( "wpex_{$id}", [ 'priority' => $priority, 'title' => $title, ] ); } } // Create the new customizer sections. if ( ! empty( $this->sections ) ) { $this->create_sections( $wp_customize, $this->sections ); } } /** * Creates the Sections and controls for the customizer. */ public function create_sections( $wp_customize ) { $enabled_panels = $this->enabled_panels(); // Loop through sections and add create the customizer sections, settings & controls. foreach ( $this->sections as $section_id => $section ) { // Check if section panel is enabled. if ( ! $this->is_section_enabled( $section, $section_id ) ) { continue; } // Get section settings. $settings = ! empty( $section['settings'] ) ? $section['settings'] : null; // Return if no settings are found. if ( ! $settings ) { return; } // Add customizer section. if ( isset( $section['panel'] ) ) { $wp_customize->add_section( $section_id, array( 'title' => $section['title'], 'panel' => $section['panel'], 'description' => $section['description'] ?? '', ) ); } // Add settings+controls. foreach ( $settings as $setting ) { if ( empty( $setting['id'] ) ) { continue; } // Get vals. $id = $setting['id']; $transport = $setting['transport'] ?? 'refresh'; $default = $setting['default'] ?? ''; $control_type = $setting['control']['type'] ?? 'text'; // Check partial refresh. if ( 'partialRefresh' === $transport ) { $transport = isset( $wp_customize->selective_refresh ) ? 'postMessage' : 'refresh'; } // Set transport to refresh if postMessage is disabled. if ( ! $this->enable_postMessage || 'wpex_heading' === $control_type ) { $transport = 'refresh'; } // Add values to control. $setting['control']['settings'] = $setting['id']; $setting['control']['section'] = $section_id; // Get global setting description. if ( empty( $setting['control']['description'] ) ) { $control_description = $this->get_control_description( $setting ); if ( $control_description ) { $setting['control']['description'] = $control_description; } } // Control object. if ( ! empty( $setting['control']['object'] ) ) { $control_obj = $setting['control']['object']; } else { $control_obj = $this->get_control_object( $control_type ); } // Add sanitize callbacks. // All customizer settings should have a sanitize callback - IMPORTANT !!!! if ( ! empty( $setting['sanitize_callback'] ) ) { $sanitize_callback = $setting['sanitize_callback']; } else { $sanitize_callback = $this->get_sanitize_callback( $control_type ); } // Add setting. $wp_customize->add_setting( $id, array( 'type' => 'theme_mod', 'transport' => $transport, 'default' => $default, 'sanitize_callback' => $sanitize_callback, ) ); if ( isset( $setting['control'] ) ) { // Add choices here so we don't have to store them in memory on the frontend. if ( isset( $setting['control']['choices'] ) ) { $setting['control']['choices'] = $this->parse_control_choices( $setting['control']['choices'] ); } $wp_customize->add_control( new $control_obj( $wp_customize, $id, $setting['control'] ) ); } } } // Load partial refresh functions. if ( isset( $wp_customize->selective_refresh ) ) { require_once WPEX_CUSTOMIZER_DIR . 'partial-refresh.php'; } } /** * Returns object name for for given control type. */ public function get_control_object( $control_type ) { switch ( $control_type ) { case 'image': return 'WP_Customize_Image_Control'; break; case 'media': return 'WP_Customize_Media_Control'; break; case 'color': return 'WP_Customize_Color_Control'; break; case 'hr': return 'TotalTheme\\Customizer\\Controls\\Hr'; break; case 'wpex_blocks': return 'TotalTheme\\Customizer\\Controls\\Blocks'; break; case 'wpex_social_profiles': return 'TotalTheme\\Customizer\\Controls\\Social_Profiles'; break; case 'wpex-heading': return 'TotalTheme\\Customizer\\Controls\\Heading'; break; case 'wpex_notice': return 'TotalTheme\\Customizer\\Controls\\Notice'; break; case 'wpex_length_unit': return 'TotalTheme\\Customizer\\Controls\\Length_Unit'; break; case 'wpex_trbl': return 'TotalTheme\\Customizer\\Controls\\Top_Right_Bottom_Left'; break; case 'wpex_svg_select': return 'TotalTheme\\Customizer\\Controls\\SVG_Select'; break; case 'wpex_pixel': return 'TotalTheme\\Customizer\\Controls\\Pixel'; break; case 'wpex_toggle': return 'TotalTheme\\Customizer\\Controls\\Toggle'; break; case 'wpex-sortable': case 'wpex_sortable': return 'TotalTheme\\Customizer\\Controls\\Sortable'; break; case 'wpex_ticon_select': // @todo rename to "wpex_icon_select". case 'wpex-fa-icon-select': case 'ticon-select': return 'TotalTheme\\Customizer\\Controls\\Icon_Select'; break; case 'wpex-dropdown-pages': return 'TotalTheme\\Customizer\\Controls\\Dropdown_Pages'; break; case 'wpex-font-family': return 'TotalTheme\\Customizer\\Controls\\Font_Family'; break; case 'wpex-card-select': return 'TotalTheme\\Customizer\\Controls\\Card_Select'; break; case 'wpex-dropdown-templates': return 'TotalTheme\\Customizer\\Controls\\Dropdown_Templates'; break; case 'wpex_textarea': return 'TotalTheme\\Customizer\\Controls\\Textarea'; break; case 'wpex_bg_patterns': return 'TotalTheme\\Customizer\\Controls\\Bg_Patterns'; break; case 'wpex_responsive_field': return 'TotalTheme\\Customizer\\Controls\\Responsive_Field'; break; case 'wpex-columns': case 'wpex-grid-columns': return 'TotalTheme\\Customizer\\Controls\\Grid_Columns'; break; case 'multi-select': case 'wpex_multi_select': return 'TotalTheme\\Customizer\\Controls\\Multiple_Select'; break; case 'wpex-visibility-select': return 'TotalTheme\\Customizer\\Controls\\Visibility_Select'; break; default : return 'WP_Customize_Control'; break; } } /** * Returns control description when not defined. */ protected function get_control_description( $control ) { $control_type = $control['type'] ?? 'text'; switch ( $control_type ) { case 'wpex-dropdown-templates': return \esc_html__( 'Create a dynamic template to override the default content layout.', 'total' ); break; } } /** * Returns sanitize_callback for given control type. */ public function get_sanitize_callback( $control_type ) { switch ( $control_type ) { case 'checkbox': case 'wpex_toggle': return 'wpex_sanitize_checkbox'; break; case 'wpex_length_unit': return self::class . '::sanitize_length_unit'; break; case 'wpex_pixel': return self::class . '::sanitize_px_field'; break; case 'select': return 'wpex_sanitize_customizer_select'; break; case 'image': return 'esc_url'; break; case 'wpex-dropdown-templates': return self::class . '::sanitize_template_select'; break; case 'wpex-dropdown-pages': case 'media': return 'absint'; break; case 'color': return 'sanitize_hex_color'; break; case 'wpex_bg_patterns': return 'wp_strip_all_tags'; break; case 'wpex-columns': return 'wpex_sanitize_customizer_columns'; break; case 'wpex-card-select': case 'multiple-select': return 'sanitize_text_field'; break; case 'wpex-visibility-select': return 'wpex_sanitize_visibility'; break; case 'wpex_textarea': default: return 'wp_kses_post'; break; } } /** * Loads js file for customizer preview. */ public function customize_preview_init() { if ( ! $this->enable_postMessage ) { return; } \wp_enqueue_script( 'totaltheme-customize-preview', wpex_asset_url( 'js/customize/preview.min.js' ), [ 'customize-preview' ], WPEX_THEME_VERSION, true ); wp_localize_script( 'totaltheme-customize-preview', 'totaltheme_customize_preview_vars', [ 'inline_css' => $this->get_inline_css_settings(), ] ); } /** * Loops through all settings and returns visibility settings. */ protected function get_control_visibility_settings() { if ( ! $this->sections ) { return; } $control_visibility = []; $settings = array_column( $this->sections, 'settings' ); if ( ! $settings ) { return []; } $settings = array_merge( ...$settings ); // combine the array of arrays into a single array. foreach ( $settings as $setting ) { if ( isset( $setting['control_display'] ) ) { $control_visibility[$setting['id']] = $this->parse_control_display( $setting['control_display'] ); } } return $control_visibility; } /** * Loops through all settings and returns array of online inline_css settings. */ public function get_inline_css_settings() { if ( ! $this->sections ) { return; } $css_settings = []; $settings = array_column( $this->sections, 'settings' ); if ( ! $settings ) { return; } $color_scheme_switcher_enabled = false; // @todo $settings = array_merge( ...$settings ); // combine the array of arrays into a single array. foreach ( $settings as $setting ) { if ( isset( $setting['inline_css'] ) ) { if ( $color_scheme_switcher_enabled && isset( $setting['type'] ) && 'color' === $setting['type'] && isset( $setting['inline_css']['target'] ) ) { $setting['inline_css']['target'] = $this->parse_inline_css_target( $setting['inline_css']['target'] ); } $css_settings[$setting['id']] = $setting['inline_css']; if ( isset( $setting['default'] ) ) { $css_settings[$setting['id']]['default'] = $setting['default']; } } } return $css_settings; } /** * Parses the inline_css target element to see if it * needs the ".wpex-color-scheme-default" class or not. */ protected function parse_inline_css_target( $target ) { if ( is_string( $target ) ) { $target = $this->inline_css_target_default_color_scheme( $target ); } else { foreach ( $target as $k => $val ) { $target[$k] = $this->inline_css_target_default_color_scheme( $val ); } } return $target; } /** * Remove color scheme--default target. */ protected function inline_css_target_default_color_scheme( $target ) { if ( is_string( $target ) ) { if ( ':root' === $target ) { $target = \str_replace( ':root', '.wpex-color-scheme-default', $target ); } else { if ( str_starts_with( $target, 'body' ) ) { $target = \str_replace( 'body', '.wpex-color-scheme-default', $target ); } else { $target = ".wpex-color-scheme-default {$target}"; } } } return $target; } /** * Generates inline CSS for styling options. */ public function loop_through_inline_css( $return = 'css' ) { $settings = $this->get_inline_css_settings(); if ( ! $settings ) { return; } $elements_to_alter = []; $preview_styles = []; $add_css = ''; // Combine and add media queries last for front-end CSS (not needed for live preview). $media_queries = [ '(min-width: 960px)' => null, '(min-width: 960px) and (max-width:1280px)' => null, '(min-width: 768px) and (max-width:959px)' => null, '(max-width: 767px)' => null, '(min-width: 480px) and (max-width:767px)' => null, ]; foreach ( $settings as $key => $inline_css ) { // Store setting ID. $setting_id = $key; // Conditional CSS check to add CSS or not. if ( isset( $inline_css['condition'] ) && ! call_user_func( $inline_css['condition'] ) ) { continue; } // Get theme mod value. $default = $inline_css['default'] ?? null; $theme_mod = get_theme_mod( $setting_id, $default ); // Checkboxes. if ( isset( $inline_css['value'] ) && wp_validate_boolean( $theme_mod ) ) { $theme_mod = $inline_css['value']; } // Get css params. $sanitize = $inline_css['sanitize'] ?? false; $alter = $inline_css['alter'] ?? ''; $media_query = $inline_css['media_query'] ?? false; $target = $inline_css['target'] ?? ''; $important = isset( $inline_css['important'] ) ? '!important' : false; $multi_prop_val = []; // @todo move loop into it's own function so we can use recursive instead. // If alter is set to "display" and type equals 'checkbox' then set correct value. if ( 'display' === $alter && 'checkbox' === $sanitize ) { $theme_mod = $theme_mod ? '' : 'none'; } // Theme mod can't be empty (prevent 0 inputs). if ( ! $theme_mod ) { continue; } // Add to preview_styles array. if ( 'preview_styles' === $return ) { $preview_styles[$setting_id] = ''; } // Target and alter vars are required, if they are empty continue onto the next setting. if ( ! $target || ! $alter ) { continue; } // Multi target element (trbl) - currently only supported for padding. if ( 'padding' === $alter && false !== strpos( $theme_mod, ':' ) ) { $multi_prop_val = $this->parse_css_multi_property( $theme_mod, $alter ); if ( $multi_prop_val && is_array( $multi_prop_val ) ) { $og_alter = $alter; $alter = []; foreach ( $multi_prop_val as $prop => $val ) { $alter[] = $prop; } } } // Sanitize output. if ( $sanitize ) { $theme_mod = wpex_sanitize_data( $theme_mod, $sanitize ); if ( '' === $theme_mod || null === $theme_mod ) { continue; // value is empty after sanitization. } } // Set to array if not. $target = is_array( $target ) ? $target : array( $target ); $target = array_filter( $target ); // remove empty targets (some targets maybe conditionally added). // Loop through items. foreach ( $target as $element ) { // Add each element to the elements to alter to prevent undefined indexes. if ( 'css' === $return && ! $media_query && ! isset( $elements_to_alter[$element] ) ) { $elements_to_alter[$element] = ''; } // Return CSS or js. if ( is_array( $alter ) ) { // Loop through elements to alter. foreach ( $alter as $alter_val ) { // Modify theme_mod for multi properties. if ( $multi_prop_val && is_array( $multi_prop_val ) ) { $theme_mod = $multi_prop_val[$alter_val] ?? null; if ( ! $theme_mod ) { continue; } } // Define el css output. $el_css = "{$alter_val}:{$theme_mod}{$important};"; // Inline CSS. if ( 'css' === $return ) { if ( $media_query ) { $media_queries[$media_query][$element][] = $el_css; } else { $elements_to_alter[$element] .= $el_css; } } // Live preview styles. elseif ( 'preview_styles' === $return ) { if ( $media_query ) { $preview_styles[$setting_id] .= "@media only screen and {$media_query}{{$element}{{$el_css};}}"; } else { $preview_styles[$setting_id] .= "{$element}{{$el_css};}"; } } } } // Single element to alter. else { // Add url to background-image params. if ( 'background-image' === $alter ) { $safe_bg = esc_url( $theme_mod ); $theme_mod = "url({$safe_bg})"; } // Define el css output. $el_css = "{$alter}:{$theme_mod}{$important};"; // Inline CSS. if ( 'css' === $return ) { if ( $media_query ) { $media_queries[$media_query][$element][] = $el_css; } else { $elements_to_alter[$element] .= $el_css; } } // Live preview styles. elseif ( 'preview_styles' === $return ) { if ( $media_query ) { $preview_styles[$setting_id] .= "@media only screen and {$media_query}{{$element}{{$el_css}}}"; } else { $preview_styles[$setting_id] .= "{$element}{{$el_css};}"; } } } } } // End settings loop. // Loop through elements and return CSS. if ( 'css' === $return ) { if ( $elements_to_alter && is_array( $elements_to_alter ) ) { foreach ( $elements_to_alter as $element => $attributes ) { if ( is_string( $attributes ) && $attributes = trim( $attributes ) ) { $add_css .= "{$element}{{$attributes}}"; } } } if ( $media_queries && is_array( $media_queries ) ) { foreach ( $media_queries as $media_query => $elements ) { if ( is_array( $elements ) && $elements ) { $add_css .= "@media only screen and {$media_query}{"; foreach ( $elements as $element => $attributes ) { if ( $attributes && is_array( $attributes ) ) { $attributes_string = implode( '', $attributes ); if ( $attributes_string ) { $add_css .= "{$element}{{$attributes_string}}"; } } } $add_css .= '}'; } } } return $add_css; } // Return preview styles. if ( 'preview_styles' === $return ) { return $preview_styles; } } /** * Returns CSS to output to wp_head. */ public function head_css( $output ) { $inline_css = $this->loop_through_inline_css( 'css' ); if ( $inline_css ) { $output .= "/*CUSTOMIZER STYLING*/{$inline_css}"; } unset( $this->sections ); return $output; } /** * Returns CSS to output to wp_head. */ public function live_preview_styles() { $live_preview_styles = $this->loop_through_inline_css( 'preview_styles' ); if ( $live_preview_styles ) { foreach ( $live_preview_styles as $key => $val ) { if ( ! empty( $val ) ) { echo '<style id="wpex-customizer-' . sanitize_html_class( $key ) . '">' . $val . '</style>'; } } } } /** * Parses the control_display so we dynamically add values rather then storing me memory. */ protected function parse_control_display( $display ) { if ( isset( $display['value'] ) ) { $display['value'] = $this->parse_control_display_value( $display['value'] ); } return $display; } /** * Parses the control_display value key. */ protected function parse_control_display_value( $value ) { switch ( $value ) { case 'header_has_aside': $value = wpex_get_header_styles_with_aside_support(); break; } return $value; } /** * Parses control choices to return values when needed rather then storing them in memory. */ protected function parse_control_choices( $choices ) { if ( is_array( $choices ) ) { return $choices; } switch ( $choices ) { case 'header_style': $choices = wpex_get_header_styles(); break; case 'post_types': $choices = wpex_get_post_types( 'customizer_settings', array( 'attachment' ) ); break; case 'opacity': $choices = wpex_utl_opacities(); break; case 'margin': $choices = wpex_utl_margins(); break; case 'padding': $choices = wpex_utl_paddings(); break; case 'shadow': $choices = wpex_utl_shadows(); break; case 'border_radius': $choices = wpex_utl_border_radius(); break; case 'column_gap': $choices = wpex_column_gaps(); break; case 'breakpoint': $choices = wpex_utl_breakpoints(); break; case 'font_size': $choices = wpex_utl_font_sizes(); break; case 'bg_style': $choices = wpex_get_bg_img_styles(); break; case 'page_header_style': $choices = wpex_get_page_header_styles(); break; case 'post_layout': $choices = wpex_get_post_layouts(); break; case 'social_styles': $choices = $this->choices_social_styles(); break; case 'blog_taxonomies': $choices = $this->choices_taxonomies( 'post' ); break; case 'portfolio_taxonomies': $choices = $this->choices_taxonomies( 'portfolio' ); break; case 'staff_taxonomies': $choices = $this->choices_taxonomies( 'staff' ); break; case 'overlay': $choices = wpex_overlay_styles_array(); break; case 'font_weight': $choices = array( '' => \esc_html__( 'Default', 'total' ), '100' => '100', '200' => '200', '300' => '300', '400' => '400', '500' => '500', '600' => '600', '700' => '700', '900' => '900', ); break; case 'html_tag': $choices = array( 'div' => 'div', 'h2' => 'h2', 'h3' => 'h3', 'h4' => 'h4', 'h5' => 'h5', 'h6' => 'h6', ); break; default: if ( is_string( $choices ) && is_callable( $choices ) ) { $choices = call_user_func( $choices ); } break; } return $choices; } /** * Returns array of taxonomies associated with the blog. */ protected function choices_taxonomies( $postype ) { $taxonomies = [ 'null' => \esc_html__( 'Anything', 'total' ), ]; $get_taxonomies = get_object_taxonomies( $postype ); if ( $get_taxonomies ) { foreach ( $get_taxonomies as $tax ) { $taxonomies[$tax] = get_taxonomy($tax)->labels->name; } } return $taxonomies; } /** * Returns array of social styles. */ protected function choices_social_styles() { $social_styles = [ 'colored-icons' => \esc_html__( 'Colored Image Icons (Legacy)', 'total' ), ]; return array_merge( wpex_social_button_styles(), $social_styles ); } /** * Sanitize template select. */ public static function sanitize_template_select( $input, $setting ) { return absint( $input ) ?: ''; } /** * Sanitize length unit field. */ public static function sanitize_length_unit( $input, $setting ) { if ( is_numeric( $input ) ) { $allow_numeric = $setting->manager->get_control( $setting->id )->allow_numeric ?? true; if ( ! $allow_numeric ) { return '0px'; } $input = floatval( $input ) . 'px'; } return sanitize_text_field( $input ); } /** * Sanitize pixel input (needs to match Sanitize_Data class). */ public static function sanitize_px_field( $input ) { if ( $input && '0px' !== $input ) { if ( 'none' === $input ) { $input = '0px'; } else { $input = floatval( $input ) . 'px'; } } return sanitize_text_field( $input ); } /** * Parses a multi property theme mod. */ protected function parse_css_multi_property( $value = '', $property = '' ) { $result = []; $params_pairs = explode( '|', $value ); if ( ! empty( $params_pairs ) ) { foreach ( $params_pairs as $pair ) { $param = preg_split( '/\:/', $pair ); if ( ! empty( $param[0] ) && isset( $param[1] ) ) { $key = $property ? "{$property}-{$param[0]}" : $param[0]; $result[$key] = $param[1]; } } } if ( $result ) { return $result; } } /** * Create template ajax. */ public function ajax_create_template() { if ( ! \current_user_can( 'publish_pages' ) || ! \current_user_can( 'edit_theme_options' ) || empty( $_POST['post_title'] ) || ! \post_type_exists( 'wpex_templates' ) ) { \wp_die(); } \check_ajax_referer( 'totaltheme_customize_nonce', 'nonce' ); $result = [ 'success' => 0 ]; $title = $_POST['post_title']; $type = $_POST['type'] ?? ''; $template_id = (new Add_Template($title, $type))->template_id; if ( $template_id ) { $result['success'] = 1; $result['template_id'] = \absint( $template_id ); } echo \wp_json_encode( $result ); \wp_die(); } }