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 WP_Customize_Control; use WP_Customize_Color_Control; use TotalTheme\Customizer\Controls\Top_Right_Bottom_Left as Control_Top_Right_Bottom_Left; use TotalTheme\Customizer\Controls\Length_Unit as Control_Length_Unit; \defined( 'ABSPATH' ) || exit; /** * Adds all Typography options to the Customizer and outputs the custom CSS for them. */ class Typography { /** * Holds an array of supported fonts. */ private $supported_fonts = null; /** * Instance. */ private static $instance; /** * Create or retrieve the instance of our class. */ public static function instance() { if ( \is_null( static::$instance ) ) { static::$instance = new self(); } return static::$instance; } /** * Main constructor. */ public function __construct() { // Register customizer settings. if ( \wpex_has_customizer_panel( 'typography' ) ) { \add_action( 'customize_register', array( $this, 'register' ), 40 ); } // Front-end actions. if ( \wpex_is_request( 'frontend' ) ) { // Enqueue Google Fonts. if ( \wpex_has_google_services_support() ) { if ( get_theme_mod( 'google_fonts_in_footer' ) ) { \add_action( 'wp_footer', array( $this, 'frontend_enqueue_google_fonts' ) ); } else { \add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_google_fonts' ) ); } } } // CSS output for typography settings. if ( is_customize_preview() && \wpex_has_customizer_panel( 'typography' ) ) { \add_action( 'wp_enqueue_scripts', array( $this, 'customize_enqueue_registered_fonts' ) ); \add_action( 'customize_preview_init', array( $this, 'customize_preview_js' ) ); \add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_js' ) ); \add_action( 'wp_head', array( $this, 'customize_css' ), 999 ); } else { \add_filter( 'wpex_head_css', array( $this, 'frontend_css' ), 99 ); } } /** * Array of Typography settings to add to the customizer. */ public function get_settings(): array { $settings = array( 'body' => array( 'label' => \esc_html__( 'Body', 'total' ), 'target' => 'body', ), 'logo' => array( 'label' => \esc_html__( 'Logo', 'total' ), 'target' => '#site-logo .site-logo-text', 'exclude' => array( 'color' ), 'active_callback' => 'wpex_cac_hasnt_custom_logo', 'condition' => 'wpex_header_has_text_logo', ), 'button' => array( 'label' => \esc_html__( 'Buttons', 'total' ), 'target' => ':root', 'exclude' => [ 'color', 'margin', 'font-size' ], 'css_vars' => [ 'text-transform' => '--wpex-btn-text-transform', 'letter-spacing' => '--wpex-btn-letter-spacing', 'font-family' => '--wpex-btn-font-family', 'font-style' => '--wpex-btn-font-style', 'font-weight' => '--wpex-btn-font-weight', 'line-height' => '--wpex-btn-line-height', ], ), 'toggle_bar' => array( 'label' => \esc_html__( 'Toggle Bar', 'total' ), 'target' => '#toggle-bar-wrap', 'exclude' => array( 'color' ), 'active_callback' => 'wpex_cac_has_togglebar', 'condition' => 'wpex_has_togglebar', ), // @todo should this be renamed to topbar? 'top_menu' => array( 'label' => \esc_html__( 'Top Bar', 'total' ), 'target' => '#top-bar-content', 'exclude' => array( 'color' ), 'active_callback' => 'wpex_cac_has_topbar', 'condition' => 'wpex_has_topbar', ), 'header_aside' => array( 'label' => \esc_html__( 'Header Aside', 'total' ), 'target' => '.header-aside-content', ), 'menu' => array( 'label' => \esc_html__( 'Main Menu', 'total' ), 'target' => '.main-navigation-ul .link-inner', // @todo Should we add : #current-shop-items-dropdown, #searchform-dropdown input[type="search"] ?? 'exclude' => array( 'color', 'line-height' ), // Can't include color causes issues with menu styling settings 'active_callback' => 'wpex_cac_supports_menu_typo', 'condition' => 'wpex_hasnt_dev_style_header', ), 'menu_dropdown' => array( 'label' => \esc_html__( 'Main Menu: Dropdowns', 'total' ), 'target' => '.main-navigation-ul .sub-menu .link-inner', 'exclude' => array( 'color' ), 'active_callback' => 'wpex_cac_supports_menu_typo', 'condition' => 'wpex_hasnt_dev_style_header', ), 'mobile_menu' => array( 'label' => \esc_html__( 'Mobile Menu', 'total' ), 'target' => '.wpex-mobile-menu, #sidr-main', 'exclude' => array( 'color' ), ), 'page_title' => array( 'label' => \esc_html__( 'Page Header Title', 'total' ), 'target' => '.page-header .page-header-title', 'exclude' => array( 'color' ), 'active_callback' => 'wpex_cac_has_page_header', 'condition' => 'TotalTheme\\Page\\Header::is_enabled', 'description' => \esc_html__( 'Important: These settings will only affect the Globally set page header style in order to prevent conflicts when using a custom style on a per-page basis.', 'total' ), ), 'page_subheading' => array( 'label' => \esc_html__( 'Page Title Subheading', 'total' ), 'target' => '.page-header .page-subheading', 'active_callback' => 'wpex_cac_has_page_header', 'condition' => 'TotalTheme\\Page\\Header::is_enabled', ), 'blog_entry_title' => array( 'label' => \esc_html__( 'Blog Entry Title', 'total' ), 'target' => '.blog-entry-title.entry-title, .blog-entry-title.entry-title a, .blog-entry-title.entry-title a:hover', ), 'blog_entry_meta' => array( 'label' => \esc_html__( 'Blog Entry Meta', 'total' ), 'target' => '.blog-entry .meta', ), 'blog_entry_content' => array( 'label' => \esc_html__( 'Blog Entry Excerpt', 'total' ), 'target' => '.blog-entry-excerpt', ), 'blog_post_title' => array( 'label' => \esc_html__( 'Blog Post Title', 'total' ), 'target' => 'body.single-post .single-post-title', ), 'blog_post_meta' => array( 'label' => \esc_html__( 'Blog Post Meta', 'total' ), 'target' => '.single-post .meta', ), 'breadcrumbs' => array( 'label' => \esc_html__( 'Breadcrumbs', 'total' ), 'target' => '.site-breadcrumbs', 'exclude' => array( 'color', 'line-height' ), 'active_callback' => 'wpex_cac_has_breadcrumbs', 'condition' => 'wpex_has_breadcrumbs', ), 'blockquote' => array( 'label' => \esc_html__( 'Blockquote', 'total' ), 'target' => 'blockquote', 'exclude' => array( 'color' ), ), 'sidebar' => array( 'label' => \esc_html__( 'Sidebar', 'total' ), 'target' => '#sidebar', 'exclude' => array( 'color' ), 'condition' => 'wpex_has_sidebar', ), 'sidebar_widget_title' => array( 'label' => \esc_html__( 'Sidebar Widget Heading', 'total' ), 'target' => '.sidebar-box .widget-title', 'margin' => true, 'exclude' => array( 'color' ), ), 'headings' => array( 'label' => \esc_html__( 'Headings', 'total' ), 'target' => ':root', // important so it doesn't break the wpex-dark-surface class. 'exclude' => array( 'font-size' ), 'css_vars' => [ 'color' => '--wpex-heading-color', 'text-transform' => '--wpex-heading-text-transform', 'letter-spacing' => '--wpex-heading-letter-spacing', 'font-family' => '--wpex-heading-font-family', 'font-style' => '--wpex-heading-font-style', 'font-weight' => '--wpex-heading-font-weight', 'line-height' => '--wpex-heading-line-height', ], ), 'theme_heading' => array( 'label' => \esc_html__( 'Theme Heading', 'total' ), 'target' => '.theme-heading', 'margin' => true, ), 'entry_h1' => array( 'label' => \esc_html__( 'H1', 'total' ), 'target' => 'h1,.wpex-h1', 'margin' => true, 'description' => \esc_html__( 'Will target headings in your post content.', 'total' ), ), 'entry_h2' => array( 'label' => 'H2', 'target' => 'h2,.wpex-h2', 'margin' => true, 'description' => \esc_html__( 'Will target headings in your post content.', 'total' ), ), 'entry_h3' => array( 'label' => 'H3', 'target' => 'h3,.wpex-h3', 'margin' => true, 'description' => \esc_html__( 'Will target headings in your post content.', 'total' ), ), 'entry_h4' => array( 'label' => 'H4', 'target' => 'h4,.wpex-h4', 'margin' => true, 'description' => \esc_html__( 'Will target headings in your post content.', 'total' ), ), 'post_content' => array( 'label' => \esc_html__( 'Post Content', 'total' ), 'target' => '.single-blog-content, .vcex-post-content-c, .wpb_text_column, body.no-composer .single-content, .woocommerce-Tabs-panel--description', ), 'footer_widgets' => array( 'label' => \esc_html__( 'Footer Widgets', 'total' ), 'target' => '#footer-widgets', 'exclude' => array( 'color' ), 'active_callback' => 'wpex_cac_has_footer_widgets', 'condition' => 'TotalTheme\\Footer\\Widgets::is_enabled', ), 'footer_widget_title' => array( 'label' => \esc_html__( 'Footer Widget Heading', 'total' ), 'target' => '.footer-widget .widget-title', 'exclude' => array( 'color' ), 'margin' => true, 'active_callback' => 'wpex_cac_has_footer_widgets', 'condition' => 'TotalTheme\\Footer\\Widgets::is_enabled', ), 'callout' => array( 'label' => \esc_html__( 'Footer Callout', 'total' ), 'target' => '.footer-callout-content', 'exclude' => array( 'color' ), 'condition' => 'TotalTheme\\Footer\\Callout::is_enabled', ), 'copyright' => array( 'label' => \esc_html__( 'Footer Bottom Text', 'total' ), 'target' => '#copyright', 'exclude' => array( 'color' ), 'condition' => 'wpex_has_footer_bottom', ), 'footer_menu' => array( 'label' => \esc_html__( 'Footer Bottom Menu', 'total' ), 'target' => '#footer-bottom-menu', 'exclude' => array( 'color' ), 'condition' => 'wpex_has_footer_bottom', ), ); /** * Filters the typography settings. * * @param array $settings */ $settings = (array) \apply_filters( 'wpex_typography_settings', $settings ); return $settings; } /** * Loads scripts for live previews. */ public function customize_preview_js() { \wp_enqueue_script( 'totaltheme-customize-typography', \wpex_asset_url( 'js/customize/typography.min.js' ), [ 'customize-preview' ], \WPEX_THEME_VERSION, true ); \wp_localize_script( 'totaltheme-customize-typography', 'totaltheme_customize_typography_vars', [ 'stdFonts' => \wpex_standard_fonts(), 'userFonts' => \array_keys( \wpex_get_registered_fonts() ), 'customFonts' => \wpex_add_custom_fonts(), 'googleFontsUrl' => \wpex_get_google_fonts_url(), 'googleFontsSuffix' => '100i,200i,300i,400i,500i,600i,700i,800i,100,200,300,400,500,600,700,800', 'sytemUIFontStack' => \wpex_get_system_ui_font_stack(), 'settings' => $this->get_settings(), 'properties' => [ 'font-family', 'font-weight', 'font-style', 'font-size', 'color', 'line-height', 'letter-spacing', 'text-transform', 'margin', ], ] ); } /** * Loads scripts for custom controls. */ public function customize_controls_js() { \wp_enqueue_script( 'totaltheme-customize-typography-quicklinks', \wpex_asset_url( 'js/customize/typography-quick-links.min.js' ), [ 'customize-controls' ], \WPEX_THEME_VERSION ); \wp_localize_script( 'totaltheme-customize-typography-quicklinks', 'totaltheme_customize_typography_quicklinks_vars', [ 'linkText' => \esc_html__( 'edit font', 'total' ), 'backLinkText' => \esc_html__( 'back to setting', 'total' ), ] ); } /** * Register typography options to the Customizer. */ public function register( $wp_customize ) { if ( ! \class_exists( '\TotalTheme\Customizer', false ) ) { return; } // Get Settings. $settings = $this->get_settings(); // Return if settings are empty. This check is needed due to the filter added above. if ( empty( $settings ) ) { return; } // Add General Panel. $wp_customize->add_panel( 'wpex_typography', array( 'priority' => 144, 'capability' => 'edit_theme_options', 'title' => \esc_html__( 'Typography', 'total' ), ) ); // Add General Tab with font smoothing. $wp_customize->add_section( 'wpex_typography_general' , array( 'title' => \esc_html__( 'General', 'total' ), 'priority' => 1, 'panel' => 'wpex_typography', ) ); // Font Smoothing. $wp_customize->add_setting( 'enable_font_smoothing', array( 'type' => 'theme_mod', 'transport' => 'postMessage', 'sanitize_callback' => 'wpex_sanitize_checkbox', ) ); $wp_customize->add_control( new Customizer\Controls\Toggle( $wp_customize, 'enable_font_smoothing', array( 'label' => \esc_html__( 'Font Smoothing', 'total' ), 'section' => 'wpex_typography_general', 'settings' => 'enable_font_smoothing', 'type' => 'wpex_toggle', 'description' => \esc_html__( 'Enable font-smoothing site wide. This makes fonts look a little "skinner". ', 'total' ), ) ) ); // Load fonts in footer. $wp_customize->add_setting( 'google_fonts_in_footer', array( 'type' => 'theme_mod', 'transport' => 'postMessage', 'sanitize_callback' => 'wpex_sanitize_checkbox', ) ); $wp_customize->add_control( new Customizer\Controls\Toggle( $wp_customize, 'google_fonts_in_footer', array( 'label' => \esc_html__( 'Load Fonts Last', 'total' ), 'section' => 'wpex_typography_general', 'settings' => 'google_fonts_in_footer', 'type' => 'wpex_toggle', 'description' => \esc_html__( 'Enable to load fonts after your body tag. This can help with render blocking scripts but also means your text will swap fonts so it may not render nicely.', 'total' ), ) ) ); // Bold Font Weight. $wp_customize->add_setting( 'bold_font_weight', array( 'type' => 'theme_mod', 'sanitize_callback' => 'sanitize_text_field', ) ); $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'bold_font_weight', array( 'label' => \esc_html__( 'Bold Font Weight', 'total' ), 'section' => 'wpex_typography_general', 'settings' => 'bold_font_weight', 'type' => 'select', 'choices' => $this->choices_font_weights(), 'description' => \esc_html__( 'Controls the defaul font weight for bold elements in the theme.', 'total' ), ) ) ); // Google Font settings. if ( wpex_has_google_services_support() ) { // Load custom font 1. $wp_customize->add_setting( 'load_custom_google_font_1', array( 'type' => 'theme_mod', 'sanitize_callback' => 'sanitize_text_field', ) ); $wp_customize->add_control( new Customizer\Controls\Font_Family( $wp_customize, 'load_custom_google_font_1', array( 'label' => \esc_html__( 'Load Custom Font', 'total' ), 'section' => 'wpex_typography_general', 'settings' => 'load_custom_google_font_1', 'type' => 'wpex-font-family', 'description' => \esc_html__( 'Allows you to load a custom font site wide for use with custom CSS. ', 'total' ), ) ) ); // Google font display option. $wp_customize->add_setting( 'google_font_display', array( 'type' => 'theme_mod', 'transport' => 'postMessage', 'default' => 'swap', 'sanitize_callback' => 'wpex_sanitize_customizer_select', ) ); $wp_customize->add_control( new WP_Customize_Control( $wp_customize, 'google_font_display', array( 'label' => \esc_html__( 'Google Font Display Type', 'total' ), 'section' => 'wpex_typography_general', 'settings' => 'google_font_display', 'type' => 'select', 'choices' => array( '' => \esc_html__( 'None', 'total' ), 'auto' => 'auto', 'block' => 'block', 'swap' => 'swap', 'fallback' => 'fallback', 'optional' => 'optional', ), 'description' => '<a href="https://developer.chrome.com/blog/font-display/#which-font-display-is-right-for-you" target="_blank" rel="noopener noreferrer">' . \esc_html__( 'Learn More', 'total' ) . ' ↗</a>' ) ) ); // Select subsets. $wp_customize->add_setting( 'google_font_subsets', array( 'type' => 'theme_mod', 'default' => 'latin', 'sanitize_callback' => 'sanitize_text_field', ) ); $wp_customize->add_control( new Customizer\Controls\Multiple_Select( $wp_customize, 'google_font_subsets', array( 'label' => \esc_html__( 'Font Subsets', 'total' ), 'section' => 'wpex_typography_general', 'settings' => 'google_font_subsets', 'choices' => array( 'latin' => 'latin', 'latin-ext' => 'latin-ext', 'cyrillic' => 'cyrillic', 'cyrillic-ext' => 'cyrillic-ext', 'greek' => 'greek', 'greek-ext' => 'greek-ext', 'vietnamese' => 'vietnamese', ), ) ) ); } // Loop through settings. foreach ( $settings as $element => $array ) { $label = $array['label'] ?? null; if ( ! $label ) { continue; // label is required. } $active_callback = $array['active_callback'] ?? null; $description = $array['description'] ?? ''; $transport = $array['transport'] ?? 'postMessage'; /* Create description based on targets. if ( empty( $description ) ) { $description = '<strong>Target(s)</strong>: ' . wp_strip_all_tags( $array['target'] ); }*/ // Get attributes. if ( ! empty ( $array['attributes'] ) ) { $attributes = $array['attributes']; } else { $attributes = [ 'font-family', 'font-weight', 'font-style', 'text-transform', 'font-size', 'line-height', 'letter-spacing', 'color', ]; } // Margin must be enabled seperately. if ( isset( $array['margin'] ) && true === $array['margin'] ) { $attributes[] = 'margin'; } // Set keys equal to vals. $attributes = \array_combine( $attributes, $attributes ); // Exclude attributes for specific options. if ( ! empty( $array['exclude'] ) && is_array( $array['exclude'] ) ) { foreach ( $array['exclude'] as $key => $val ) { unset( $attributes[ $val ] ); } } // Define Section. $wp_customize->add_section( "wpex_typography_{$element}" , array( 'title' => $label, 'panel' => 'wpex_typography', 'description' => $description, ) ); // Font Family. if ( \in_array( 'font-family', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[font-family]", array( 'type' => 'theme_mod', 'transport' => $transport, 'sanitize_callback' => 'sanitize_text_field', ) ); $control_args = [ 'type' => 'wpex-font-family', 'label' => \esc_html__( 'Font Family', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[font-family]", 'active_callback' => $active_callback, ]; if ( \class_exists( 'WPEX_Font_Manager', false ) ) { $control_args['description'] = sprintf( \esc_html__( 'You can use the %sFont Manager%s to register additional Google, Adobe or custom fonts.', 'total' ), '<a href="' . esc_url( admin_url( 'edit.php?post_type=wpex_font' ) ) . '" target="_blank" rel="noopener noreferrer">', ' ↗</a>' ); } $wp_customize->add_control( new Customizer\Controls\Font_Family( $wp_customize, "{$element}_typography[font-family]", $control_args ) ); } // Font Weight. if ( \in_array( 'font-weight', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[font-weight]", array( 'type' => 'theme_mod', 'sanitize_callback' => 'wpex_sanitize_customizer_select', 'transport' => $transport, ) ); $wp_customize->add_control( "{$element}_typography[font-weight]", array( 'label' => \esc_html__( 'Font Weight', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[font-weight]", 'type' => 'select', 'active_callback' => $active_callback, 'choices' => $this->choices_font_weights(), 'description' => \esc_html__( 'Note: Not all Fonts support every font weight style. ', 'total' ), ) ); } // Font Style. if ( \in_array( 'font-style', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[font-style]", array( 'type' => 'theme_mod', 'sanitize_callback' => 'wpex_sanitize_customizer_select', 'transport' => $transport, ) ); $wp_customize->add_control( "{$element}_typography[font-style]", array( 'label' => \esc_html__( 'Font Style', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[font-style]", 'type' => 'select', 'active_callback' => $active_callback, 'choices' => $this->choices_font_style(), ) ); } // Text-Transform. if ( \in_array( 'text-transform', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[text-transform]", array( 'type' => 'theme_mod', 'sanitize_callback' => 'wpex_sanitize_customizer_select', 'transport' => $transport, ) ); $wp_customize->add_control( "{$element}_typography[text-transform]", array( 'label' => \esc_html__( 'Text Transform', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[text-transform]", 'type' => 'select', 'active_callback' => $active_callback, 'choices' => $this->choices_text_transform(), ) ); } // Font Size. if ( \in_array( 'font-size', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[font-size]", array( 'type' => 'theme_mod', 'sanitize_callback' => 'wpex_sanitize_font_size_mod', 'transport' => $transport, ) ); $wp_customize->add_control( new Customizer\Controls\Responsive_Field( $wp_customize, "{$element}_typography[font-size]", array( 'label' => \esc_html__( 'Font Size', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[font-size]", 'type' => 'wpex_responsive_field', 'description' => \esc_html__( 'Please specify a unit (px, em, vm, vmax, vmin). If no unit is specified px will be used by default.', 'total' ), 'active_callback' => $active_callback, ) ) ); } // Font Color. if ( \in_array( 'color', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[color]", array( 'type' => 'theme_mod', 'sanitize_callback' => 'sanitize_hex_color', 'transport' => $transport, ) ); $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, "{$element}_typography_color", array( 'label' => \esc_html__( 'Color', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[color]", 'active_callback' => $active_callback, ) ) ); } // Line Height. if ( \in_array( 'line-height', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[line-height]", array( 'type' => 'theme_mod', 'sanitize_callback' => 'sanitize_text_field', 'transport' => $transport, ) ); $wp_customize->add_control( new Control_Length_Unit( $wp_customize, "{$element}_typography[line-height]", array( 'label' => \esc_html__( 'Line Height', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[line-height]", 'type' => 'wpex_length_unit', 'default_unit' => 'num', 'units' => array( 'num', 'px', 'em', 'rem', '%', 'vmin', 'vmax', 'var', 'func' ), 'active_callback' => $active_callback, ) ) ); } // Letter Spacing. if ( \in_array( 'letter-spacing', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[letter-spacing]", array( 'type' => 'theme_mod', 'sanitize_callback' => 'wpex_sanitize_letter_spacing', 'transport' => $transport, ) ); $wp_customize->add_control( new Control_Length_Unit( $wp_customize, "{$element}_typography_letter_spacing", array( 'label' => \esc_html__( 'Letter Spacing', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[letter-spacing]", 'type' => 'wpex_length_unit', 'units' => array( 'px', 'em', 'rem', 'vmin', 'vmax', 'var', 'func' ), 'active_callback' => $active_callback, ) ) ); } // Margin. if ( \in_array( 'margin', $attributes ) ) { $wp_customize->add_setting( "{$element}_typography[margin]", array( 'type' => 'theme_mod', 'sanitize_callback' => 'sanitize_text_field', 'transport' => $transport, ) ); $wp_customize->add_control( new Control_Top_Right_Bottom_Left( $wp_customize, "{$element}_typography[margin]", array( 'label' => \esc_html__( 'Margin', 'total' ), 'section' => "wpex_typography_{$element}", 'settings' => "{$element}_typography[margin]", 'type' => 'wpex_trbl', 'active_callback' => $active_callback, ) ) ); } } } /** * Loop through settings. * * @todo combine CSS targeting the same selector (such as :root). */ public function loop( $return = 'css' ) { $end_css = ''; $css = ''; $tablet_landscape_css = ''; $tablet_portrait_css = ''; $phone_landscape_css = ''; $phone_portrait_css = ''; $preview_styles = []; $settings = $this->get_settings(); if ( ! $settings ) { return; } // Loop through settings that need typography styling applied to them. foreach ( $settings as $element => $array ) { if ( empty( $array['target'] ) ) { continue; } $target = $array['target']; $get_mod = $this->get_setting_val( $element ); if ( ! $get_mod ) { continue; } // Check conditional when running CSS loop. // Prevents CSS from being added to the page if not needed. if ( 'css' === $return // important to prevent customizer issues. && isset( $array['condition'] ) && \is_callable( $array['condition'] ) && ! \call_user_func( $array['condition'] ) ) { continue; } // Attributes to loop through. if ( ! empty( $array['attributes'] ) ) { $attributes = $array['attributes']; } else { $attributes = [ 'font-family', 'font-weight', 'font-style', 'font-size', 'color', 'line-height', 'letter-spacing', 'text-transform', ]; // Allow for margin on this setting if enabled. if ( isset( $array['margin'] ) && true === $array['margin'] ) { $attributes[] = 'margin'; } } // Set attributes keys equal to vals. $attributes = \array_combine( $attributes, $attributes ); $css_vars = $array['css_vars'] ?? []; // Exclude attributes. if ( ! empty( $array['exclude'] ) ) { foreach ( $array['exclude'] as $k => $v ) { unset( $attributes[ $v ] ); } } // Define responsive css vars. $desktop_props = ''; $tablet_landscape_props = ''; $tablet_portrait_props = ''; $phone_landscape_props = ''; $phone_portrait_props = ''; // Loop through attributes. foreach ( $attributes as $attribute ) { // Define attribute value. $val = $get_mod[$attribute] ?? null; if ( 'font-family' === $attribute && ! $this->is_font_supported( $val ) ) { $val = null; } // Val needed. if ( ! $val ) { continue; } // Font Sizes have responsive settings so we need to treat them differently. if ( 'font-size' === $attribute && is_array( $val ) ) { $fontsize_pstyle = ''; $responsive_bkpoints = [ 'd' => '', 'tl' => '', 'tp' => '', 'pl' => '', 'pp' => '', ]; $val = \array_map( 'wpex_sanitize_font_size', $val ); // sanitize. foreach ( $responsive_bkpoints as $bk_id => $bk_val ) { if ( ! empty( $val[$bk_id] ) ) { $bk_val = $attribute . ':' . $val[$bk_id] . ';'; switch ( $bk_id ) { case 'd': if ( 'css' === $return ) { $desktop_props .= $bk_val; } $fontsize_pstyle .= $target . '{' . $bk_val . ';}'; break; case 'tl': if ( 'css' === $return ) { $tablet_landscape_props .= $bk_val; } $fontsize_pstyle .= '@media(max-width:1024px){' . $target . '{' . $bk_val . ';}}'; break; case 'tp': if ( 'css' === $return ) { $tablet_portrait_props .= $bk_val; } $fontsize_pstyle .= '@media(max-width:959px){' . $target . '{' . $bk_val . ';}}'; break; case 'pl': if ( 'css' === $return ) { $phone_landscape_props .= $bk_val; } $fontsize_pstyle .= '@media(max-width:767px){' . $target . '{' . $bk_val . ';}}'; break; case 'pp': if ( 'css' === $return ) { $phone_portrait_props .= $bk_val; } $fontsize_pstyle .= '@media(max-width:479px){' . $target . '{' . $bk_val . ';}}'; break; } // end switch if ( 'preview_styles' === $return ) { $preview_styles["wpex-customizer-{$element}-font-size"] = $fontsize_pstyle; } } } } // All other settings that aren't font sizes. else { // Parse the attribute value. $val = $this->parse_attribute_val( $val, $attribute ); // No value for this setting. if ( ! $val ) { continue; } // Add to inline CSS. if ( 'margin' === $attribute && false !== \strpos( $val, ':' ) ) { $multi_prop_val = $this->parse_css_multi_property( $val, $attribute ); if ( $multi_prop_val && is_array( $multi_prop_val ) ) { $preview_css = ''; foreach ( $multi_prop_val as $prop => $val ) { if ( 'css' === $return ) { $desktop_props .= "{$prop}:{$val};"; } elseif ( 'preview_styles' === $return ) { $preview_css .= "{$prop}:{$val};"; } } } } else { $property = $css_vars[$attribute] ?? $attribute; if ( 'css' === $return ) { $desktop_props .= "{$property}:{$val};"; } elseif ( 'preview_styles' === $return ) { $preview_css = "{$property}:{$val};"; } } // Customizer styles need to be added for each attribute. if ( 'preview_styles' === $return && ! empty( $preview_css ) ) { $preview_styles["wpex-customizer-{$element}-{$attribute}"] = "{$target}{{$preview_css}}"; } } } // End foreach attributes. // Front-end inline CSS. if ( $desktop_props ) { $css .= "{$target}{{$desktop_props}}"; } if ( $tablet_landscape_props ) { $tablet_landscape_css .= "{$target}{{$tablet_landscape_props}}"; } if ( $tablet_portrait_props ) { $tablet_portrait_css .= "{$target}{{$tablet_portrait_props}}"; } if ( $phone_landscape_props ) { $phone_landscape_css .= "{$target}{{$phone_landscape_props}}"; } if ( $phone_portrait_props ) { $phone_portrait_css .= "{$target}{{$phone_portrait_props}}"; } } // End foreach settings. // Combine all settings CSS. if ( $css ) { $end_css .= $css; } // Combine all media query CSS for output. if ( $tablet_landscape_css ) { $end_css .= '@media(max-width:1024px){' . \esc_attr( $tablet_landscape_css ) . '}'; } if ( $tablet_portrait_css ) { $end_css .= '@media(max-width:959px){' . \esc_attr( $tablet_portrait_css ) . '}'; } if ( $phone_landscape_css ) { $end_css .= '@media(max-width:767px){' . \esc_attr( $phone_landscape_css ) . '}'; } if ( $phone_portrait_css ) { $end_css .= '@media(max-width:479px){' . \esc_attr( $phone_portrait_css ) . '}'; } // Add comment for typography css. if ( $css ) { $end_css = "/*TYPOGRAPHY*/{$end_css}"; } switch ( $return ) { case 'css': return $end_css; break; case 'preview_styles': return $preview_styles; break; } } /** * Outputs the typography custom CSS. */ public function frontend_css( $output ) { $typography_css = $this->loop( 'css' ); if ( $typography_css ) { $output .= $typography_css; } return $output; } /** * Returns correct CSS to output to wp_head. */ public function customize_css() { $styles = $this->loop( 'preview_styles' ); if ( ! $styles || ! is_array( $styles ) ) { return; } foreach ( $styles as $style_key => $style_css ) { if ( empty( $style_css ) ) { continue; } echo '<style id="' . \esc_attr( $style_key ) . '"> ' . $style_css . '</style>'; } } /** * Loads Google fonts via wp_enqueue_style. */ public function frontend_enqueue_google_fonts() { $gfonts = []; if ( $custom_font = \get_theme_mod( 'load_custom_google_font_1' ) ) { $gfonts[] = $custom_font; } foreach ( $this->get_settings() as $setting_k => $setting_args ) { $mod_val = $this->get_setting_val( $setting_k, $setting_args ); if ( empty( $mod_val['font-family'] ) || ! $this->setting_supports_css_property( 'font-family', $setting_args ) ) { continue; } $gfonts[] = $mod_val['font-family']; } if ( $gfonts ) { $gfonts = \array_unique( $gfonts ); foreach ( $gfonts as $gfont ) { \wpex_enqueue_google_font( $gfont ); } } } /** * Return text transform choices. */ public function choices_text_transform() { return [ '' => \esc_html__( 'Default', 'total' ), 'capitalize' => \esc_html__( 'Capitalize', 'total' ), 'lowercase' => \esc_html__( 'Lowercase', 'total' ), 'uppercase' => \esc_html__( 'Uppercase', 'total' ), 'none' => \esc_html__( 'None', 'total' ), ]; } /** * Return font style choices. */ public function choices_font_style() { return [ '' => \esc_html__( 'Default', 'total' ), 'normal' => \esc_html__( 'Normal', 'total' ), 'italic' => \esc_html__( 'Italic', 'total' ), ]; } /** * Return font weight choices. */ public function choices_font_weights() { return [ '' => \esc_html__( 'Default', 'total' ), '100' => \esc_html__( 'Extra Light: 100', 'total' ), '200' => \esc_html__( 'Light: 200', 'total' ), '300' => \esc_html__( 'Book: 300', 'total' ), '400' => \esc_html__( 'Normal: 400', 'total' ), '500' => \esc_html__( 'Medium: 500', 'total' ), '600' => \esc_html__( 'Semibold: 600', 'total' ), '700' => \esc_html__( 'Bold: 700', 'total' ), '800' => \esc_html__( 'Extra Bold: 800', 'total' ), '900' => \esc_html__( 'Black: 900', 'total' ), ]; } /** * Loads all registered fonts in the Customizer for use with Typography options. */ public function customize_enqueue_registered_fonts() { $user_fonts = (array) \wpex_get_registered_fonts(); if ( empty( $user_fonts ) ) { return; } foreach ( $user_fonts as $user_font => $user_font_args ) { if ( 'other' === $user_font_args['type'] ) { continue; } \wpex_enqueue_font( $user_font, 'registered', $user_font_args ); } } /** * Return setting value. */ protected function get_setting_val( $setting = '' ) { return \get_theme_mod( "{$setting}_typography" ); } /** * Checks if a setting supports a specific CSS property. */ protected function setting_supports_css_property( $property = '', $setting_args = [] ): bool { return ( isset( $setting_args['attributes'][ $property ] ) || empty( $setting_args['exclude'] ) || ! \in_array( $property, $setting_args['exclude'] ) ); } /** * Parses an attribute value. */ protected function parse_attribute_val( $val = '', $attribute = '' ) { if ( ! $val || ! \is_string( $val ) ) { return; } $val = \str_replace( '"', '', $val ); // remove extra quotes. switch ( $attribute ) { case 'letter-spacing': $val = \wpex_sanitize_letter_spacing( $val ); break; case 'font-size': $val = \wpex_sanitize_font_size( $val ); break; case 'font-family': $val = \wpex_sanitize_font_family( $val ); // convert html characters. if ( \str_contains( $val, '"' ) || \str_contains( $val, ',' ) ) { $val = $val; } else { // perhaps this should only be added if there is a space inside the font name. $val = '"' . \esc_html( $val ) . '"'; } break; } return \wp_strip_all_tags( $val ); // @todo use sanitize_text_field instead? } /** * Returns a list of supported fonts. */ protected function get_supported_fonts() { if ( null !== $this->supported_fonts ) { return $this->supported_fonts; } /** * Support the disable Google font services function. * * If Google services is disabled and the user hasn't * registered any fonts set the supported fonts to standard fonts * plus any custom fonts added via legacy methods. */ if ( ! \wpex_has_google_services_support() && ! \wpex_has_registered_fonts() ) { $this->supported_fonts = \array_merge( \wpex_standard_fonts(), \wpex_add_custom_fonts() ); } else { $this->supported_fonts = []; } return $this->supported_fonts; } /** * Checks if a given font is supported. * * Returns true if the get_supported_fonts function doesn't return any fonts or if it's in the array * of supported fonts. */ protected function is_font_supported( $font ): bool { $supported_fonts = $this->get_supported_fonts(); return ( ! $supported_fonts || \in_array( $font, $supported_fonts ) ); } /** * 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; } } }