'var(--global-kb-spacing-auto, auto)', 'xxs' => 'var(--global-kb-spacing-xxs, 0.5rem)', 'xs' => 'var(--global-kb-spacing-xs, 1rem)', 'sm' => 'var(--global-kb-spacing-sm, 1.5rem)', 'md' => 'var(--global-kb-spacing-md, 2rem)', 'lg' => 'var(--global-kb-spacing-lg, 3rem)', 'xl' => 'var(--global-kb-spacing-xl, 4rem)', 'xxl' => 'var(--global-kb-spacing-xxl, 5rem)', '3xl' => 'var(--global-kb-spacing-3xl, 6.5rem)', '4xl' => 'var(--global-kb-spacing-4xl, 8rem)', '5xl' => 'var(--global-kb-spacing-5xl, 10rem)' ); /** * Font size variables used in string based font sizes. */ protected $font_sizes = array( 'sm' => 'var(--global-kb-font-size-sm, 0.9rem)', 'md' => 'var(--global-kb-font-size-md, 1.25rem)', 'lg' => 'var(--global-kb-font-size-lg, 2rem)', 'xl' => 'var(--global-kb-font-size-xl, 3rem)', 'xxl' => 'var(--global-kb-font-size-xxl, 4rem)', '3xl' => 'var(--global-kb-font-size-xxxl, 5rem)', ); /** * Gaps variables used in string based gutters. */ protected $gap_sizes = array( 'none' => 'var(--global-kb-gap-none, 0rem )', 'skinny' => 'var(--global-kb-gap-sm, 1rem)', 'narrow' => '20px', 'wide' => '40px', 'widest' => '80px', 'default' => 'var(--global-kb-gap-md, 2rem)', 'wider' => 'var(--global-kb-gap-lg, 4rem)', 'xs' => 'var(--global-kb-gap-xs, 0.5rem )', 'sm' => 'var(--global-kb-gap-sm, 1rem)', 'md' => 'var(--global-kb-gap-md, 2rem)', 'lg' => 'var(--global-kb-gap-lg, 4rem)', ); /** * Instance Control */ public static function get_instance() { if ( is_null( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Class Constructor. */ public function __construct() { add_action( 'wp_enqueue_scripts', array( $this, 'frontend_block_css' ), 180 ); } /** * Render block CSS helper function */ public function frontend_block_css() { if ( ! empty( self::$styles ) ) { self::$head_styles = self::$styles; $output = ''; foreach ( self::$styles as $key => $value ) { $output .= $value; } $custom_output = ''; if ( ! empty( self::$custom_styles ) && is_array( self::$custom_styles ) ) { foreach ( self::$custom_styles as $c_key => $c_value ) { $custom_output .= $c_value; } } if ( ! empty( $output ) ) { wp_register_style( 'kadence_blocks_css', false ); wp_enqueue_style( 'kadence_blocks_css' ); wp_add_inline_style( 'kadence_blocks_css', $output ); } if ( ! empty( $custom_output ) ) { wp_register_style( 'kadence_blocks_custom_css', false ); wp_enqueue_style( 'kadence_blocks_custom_css' ); wp_add_inline_style( 'kadence_blocks_custom_css', $custom_output ); } } } /** * Sets a style id to keep a record of rendering. * * @access public * @since 1.0 * * @param string $style_id - the css group id. * @return $this */ public function set_style_id( $style_id = '' ) { if ( empty( $style_id ) ) { return; } // Render the css in the output string everytime the style_id changes. if ( ! isset( self::$styles[ $style_id ] ) ) { self::$styles[ $style_id ] = ''; } $this->_style_id = $style_id; return $this; } /** * Sets a style id to keep a record of rendering. * * @access public * @since 1.0 * * @param string $style_id - the css group id. * @return $this */ public function has_styles( $style_id = '' ) { if ( empty( $style_id ) ) { return false; } if ( isset( self::$styles[ $style_id ] ) ) { return true; } return false; } /** * Sets a style id to keep a record of rendering. * * @access public * @since 1.0 * * @param string $style_id - the css group id. * @return $this */ public function has_header_styles( $style_id = '' ) { if ( empty( $style_id ) ) { return false; } if ( isset( self::$head_styles[ $style_id ] ) ) { return true; } return false; } /** * Sets a selector to the object and changes the current selector to a new one * * @access public * @since 1.0 * * @param string $selector - the css identifier of the html that you wish to target. * @return $this */ public function set_selector( $selector = '' ) { // Render the css in the output string everytime the selector changes. if ( '' !== $this->_selector ) { $this->add_selector_rules_to_output(); } $this->_selector = $selector; return $this; } /** * Sets css string for final output. * * @param string $string - the css string. * @return $this */ public function add_css_string( $string ) { $string = str_replace( PHP_EOL, '', trim( $string ) ); $this->_css_string .= $string; return $this; } /** * Get media queries. * * @param string $device - the device size. * @return $this */ public function get_media_queries( $device ) { if ( ! isset( $this->media_queries[ $device ] ) ) { $media_query = array(); $media_query['mobile'] = apply_filters( 'kadence_mobile_media_query', '(max-width: 767px)' ); $media_query['tablet'] = apply_filters( 'kadence_tablet_media_query', '(max-width: 1024px)' ); $media_query['tabletPro'] = apply_filters( 'kadence_tablet_pro_media_query', '(max-width: 1024px), only screen and (min-device-width: 1024px) and (max-device-width: 1366px) and (-webkit-min-device-pixel-ratio: 2) and (hover: none)' ); $media_query['desktop'] = apply_filters( 'kadence_desktop_media_query', '(min-width: 1025px)' ); $media_query['mobileReverse'] = apply_filters( 'kadence_mobile_reverse_media_query', '(min-width: 768px)' ); $media_query['tabletOnlyPro'] = apply_filters( 'kadence_tablet_only_pro_media_query', '(min-width: 768px) and (max-width: 1024px), only screen and (min-device-width: 1024px) and (max-device-width: 1366px) and (-webkit-min-device-pixel-ratio: 2) and (hover: none)' ); $media_query['tabletOnly'] = apply_filters( 'kadence_tablet_only_media_query', '(min-width: 768px) and (max-width: 1024px)' ); $this->media_queries = $media_query; } return isset( $this->media_queries[ $device ] ) ? $this->media_queries[ $device ] : ''; } /** * Wrapper for the set_selector method, changes the selector to add new rules * * @access public * @since 1.0 * * @see set_selector() * @param string $selector the css selector. * @return $this */ public function change_selector( $selector = '' ) { return $this->set_selector( $selector ); } /** * Adds a pseudo class to the selector ex. :hover, :active, :focus * * @access public * @since 1.0 * * @param $state - the selector state * @param reset - if true the $_selector_states variable will be reset * @return $this */ public function add_selector_state( $state, $reset = true ) { if ( $reset ) { $this->reset_selector_states(); } $this->_selector_states[] = $state; return $this; } /** * Adds multiple pseudo classes to the selector * * @access public * @since 1.0 * * @param array $states - the states you would like to add * @return $this */ public function add_selector_states( $states = array() ) { $this->reset_selector_states(); foreach ( $states as $state ) { $this->add_selector_state( $state, false ); } return $this; } /** * Removes the selector's pseudo classes * * @access public * @since 1.0 * * @return $this */ public function reset_selector_states() { $this->add_selector_rules_to_output(); if ( ! empty( $this->_selector_states ) ) { $this->_selector_states = array(); } return $this; } /** * Check to see if variable contains a number including 0. * * @access public * * @param string $value - the css property. * @return boolean */ public function is_number( &$value ) { return isset( $value ) && is_numeric( $value ); } /** * Adds a new rule to the css output * * @access public * @since 1.0 * * @param string $property - the css property. * @param string $value - the value to be placed with the property. * @param string $prefix - not required, but allows for the creation of a browser prefixed property. * @return $this */ public function add_rule( $property, $value, $prefix = null ) { $format = is_null( $prefix ) ? '%1$s:%2$s;' : '%3$s%1$s:%2$s;'; if ( $value && ! empty( $value ) ) { if ( 'mobile' === $this->_media_state ) { if ( ! isset( $this->_mobile_media_query[ $this->_selector ] ) ) { $this->_mobile_media_query[ $this->_selector ] = ''; } $this->_mobile_media_query[ $this->_selector ] .= sprintf( $format, $property, $value, $prefix ); } elseif ( 'tablet' === $this->_media_state ) { if ( ! isset( $this->_tablet_media_query[ $this->_selector ] ) ) { $this->_tablet_media_query[ $this->_selector ] = ''; } $this->_tablet_media_query[ $this->_selector ] .= sprintf( $format, $property, $value, $prefix ); } elseif ( 'tabletPro' === $this->_media_state ) { if ( ! isset( $this->_tablet_pro_media_query[ $this->_selector ] ) ) { $this->_tablet_pro_media_query[ $this->_selector ] = ''; } $this->_tablet_pro_media_query[ $this->_selector ] .= sprintf( $format, $property, $value, $prefix ); } elseif ( 'tabletOnly' === $this->_media_state ) { if ( ! isset( $this->_tablet_only_media_query[ $this->_selector ] ) ) { $this->_tablet_only_media_query[ $this->_selector ] = ''; } $this->_tablet_only_media_query[ $this->_selector ] .= sprintf( $format, $property, $value, $prefix ); } elseif ( 'tabletOnlyPro' === $this->_media_state ) { if ( ! isset( $this->_tablet_only_pro_media_query[ $this->_selector ] ) ) { $this->_tablet_only_pro_media_query[ $this->_selector ] = ''; } $this->_tablet_only_pro_media_query[ $this->_selector ] .= sprintf( $format, $property, $value, $prefix ); } elseif ( 'desktopOnly' === $this->_media_state ) { if ( ! isset( $this->_desktop_only_media_query[ $this->_selector ] ) ) { $this->_desktop_only_media_query[ $this->_selector ] = ''; } $this->_desktop_only_media_query[ $this->_selector ] .= sprintf( $format, $property, $value, $prefix ); } else { $this->_css .= sprintf( $format, $property, $value, $prefix ); } } return $this; } /** * Adds browser prefixed rules, and other special rules to the css output * * @access public * @since 1.0 * * @param string $property - the css property * @param string $value - the value to be placed with the property * @return $this */ public function add_special_rules( $property, $value ) { // Switch through the property types and add prefixed rules. switch ( $property ) { case 'border-top-left-radius': $this->add_rule( $property, $value, '-webkit-' ); $this->add_rule( $property, $value ); break; case 'border-top-right-radius': $this->add_rule( $property, $value, '-webkit-' ); $this->add_rule( $property, $value ); break; case 'border-bottom-left-radius': $this->add_rule( $property, $value, '-webkit-' ); $this->add_rule( $property, $value ); break; case 'border-bottom-right-radius': $this->add_rule( $property, $value, '-webkit-' ); $this->add_rule( $property, $value ); break; case 'background-image': $this->add_rule( $property, sprintf( "url('%s')", $value ) ); break; case 'content': $this->add_rule( $property, sprintf( '%s', $value ) ); break; case 'flex': $this->add_rule( $property, $value, '-webkit-' ); $this->add_rule( $property, $value ); break; default: $this->add_rule( $property, $value, '-webkit-' ); $this->add_rule( $property, $value, '-moz-' ); $this->add_rule( $property, $value ); break; } return $this; } /** * Adds a css property with value to the css output * * @access public * @since 1.0 * * @param string $property - the css property * @param mixed $value - the value to be placed with the property * @param mixed $check_empty - the value to be checkd if empty * @return $this */ public function add_property( $property, $value = null, $check_empty = null ) { if ( null === $value ) { return $this; } if ( null !== $check_empty && empty( $check_empty ) ) { return $this; } $value = wp_strip_all_tags( $value ); if ( in_array( $property, $this->_special_properties_list ) ) { $this->add_special_rules( $property, $value ); } else { $this->add_rule( $property, $value ); } return $this; } /** * Adds multiple properties with their values to the css output * * @access public * @since 1.0 * * @param array $properties - a list of properties and values * @return $this */ public function add_properties( $properties ) { foreach ( (array) $properties as $property => $value ) { $this->add_property( $property, $value ); } return $this; } /** * Sets a media query in the class * * @since 1.1 * @param string $value * @return $this */ public function start_media_query( $value ) { // Add the current rules to the output $this->add_selector_rules_to_output(); // Add any previous media queries to the output if ( $this->has_media_query() ) { $this->add_media_query_rules_to_output(); } // Set the new media query $this->_media_query = $value; return $this; } /** * Sets a media query in the class * * @since 1.1 * @param string $value * @return $this */ public function set_media_state( $value ) { // Set the new media query $this->_media_state = $value; return $this; } /** * Get media state * * @return string */ public function get_media_state() { return $this->_media_state; } /** * Stops using a media query. * * @see start_media_query() * * @since 1.1 * @return $this */ public function stop_media_query() { return $this->start_media_query( null ); } /** * Gets the media query if it exists in the class * * @since 1.1 * @return string|int|null */ public function get_media_query() { return $this->_media_query; } /** * Checks if there is a media query present in the class * * @since 1.1 * @return boolean */ public function has_media_query() { if ( ! empty( $this->get_media_query() ) ) { return true; } return false; } /** * Adds the current media query's rules to the class' output variable * * @since 1.1 * @return $this */ private function add_media_query_rules_to_output() { if ( ! empty( $this->_media_query_output ) ) { $this->_output .= sprintf( '@media all and %1$s{%2$s}', $this->get_media_query(), $this->_media_query_output ); // Reset the media query output string. $this->_media_query_output = ''; } return $this; } /** * Adds the current selector rules to the output variable * * @access private * @since 1.0 * * @return $this */ private function add_selector_rules_to_output() { if ( ! empty( $this->_css ) ) { $this->prepare_selector_output(); $selector_output = sprintf( '%1$s{%2$s}', $this->_selector_output, $this->_css ); if ( $this->has_media_query() ) { $this->_media_query_output .= $selector_output; $this->reset_css(); } else { $this->_output .= $selector_output; } // Reset the css. $this->reset_css(); } return $this; } /** * Prepares the $_selector_output variable for rendering * * @access private * @since 1.0 * * @return $this */ private function prepare_selector_output() { if ( ! empty( $this->_selector_states ) ) { // Create a new variable to store all of the states. $new_selector = ''; foreach ( (array) $this->_selector_states as $state ) { $format = end( $this->_selector_states ) === $state ? '%1$s%2$s' : '%1$s%2$s,'; $new_selector .= sprintf( $format, $this->_selector, $state ); } $this->_selector_output = $new_selector; } else { $this->_selector_output = $this->_selector; } return $this; } /** * Generates the font family output. * * @param array $font an array of font settings. * @return string */ public function render_font_family( $font_name, $google = false, $variant = null, $subset = null ) { if ( empty( $font_name ) ) { return false; } if ( 'inherit' === $font_name ) { $font_string = 'inherit'; } else { $font_string = $font_name; } if ( isset( $google ) && true === $google ) { $this->maybe_add_google_font( $font_name, $variant, $subset ); } if ( strpos( $font_string, '"') === false && strpos( $font_string, ',') === false && strpos( $font_string, ' ' ) !== false ) { $font_string = "'" . $font_string . "'"; } return apply_filters( 'kadence_blocks_font_family_string', $font_string, $font_name ); } /** * Generates the font family output. * * @param array $font an array of font settings. * @return string */ public function render_font_weight( $weight, $google = true ) { if ( empty( $weight ) ) { return false; } if ( 'inherit' === $weight ) { return false; } if ( 'regular' === $weight && $google ) { $weight_string = 'normal'; } elseif ( 'regular' === $weight && ! $google ) { $weight_string = false; } else { $weight_string = $weight; } return $weight_string; } /** * Generates the font output. * * @param array $attributes an array of attributes. * @param string $name the key for attributes of font. * @param string $inherit an string to determine if the font should inherit. * @return string */ public function render_typography( $attributes, $name = 'typography', $inherit = null ) { if ( empty( $attributes ) ) { return false; } if ( ! empty( $name ) && ! isset( $attributes[ $name ] ) ) { return false; } if ( ! empty( $name ) ) { $font = $attributes[ $name ]; } elseif ( empty( $name ) ) { $font = $attributes; } if ( empty( $font ) ) { return false; } if ( ! is_array( $font ) ) { return false; } if ( isset( $font[0] ) && is_array( $font[0] ) && ! empty( $font[0] ) ) { $font = $font[0]; } $size_type = ( isset( $font['sizeType'] ) && ! empty( $font['sizeType'] ) ? $font['sizeType'] : 'px' ); $line_type = ( isset( $font['lineType'] ) ? $font['lineType'] : '' ); $line_type = ( '-' !== $line_type ? $line_type : '' ); $letter_type = ( isset( $font['letterSpacingType'] ) && ! empty( $font['letterSpacingType'] ) ? $font['letterSpacingType'] : isset( $font['letterType'] ) && ! empty( $font['letterType'] ) ) ? $font['letterType'] : 'px'; if ( isset( $font['size'] ) && isset( $font['size'][0] ) && ! empty( $font['size'][0] ) ) { $this->add_property( 'font-size', $this->get_font_size( $font['size'][0], $size_type ) ); } if ( isset( $font['lineHeight'] ) && isset( $font['lineHeight']['desktop'] ) && ! empty( $font['lineHeight']['desktop'] ) ) { $this->add_property( 'line-height', $font['lineHeight']['desktop'] . $line_type ); } // Numeric array. if ( isset( $font['lineHeight'] ) && isset( $font['lineHeight'][0] ) && ! empty( $font['lineHeight'][0] ) ) { $this->add_property( 'line-height', $font['lineHeight'][0] . $line_type ); } if ( isset( $font['letterSpacing'] ) && is_array( $font['letterSpacing'] ) ) { if ( isset( $font['letterSpacing']['desktop'] ) && is_numeric( $font['letterSpacing']['desktop'] ) ) { $this->add_property( 'letter-spacing', $font['letterSpacing']['desktop'] . $letter_type ); } if ( isset( $font['letterSpacing'][0] ) && is_numeric( $font['letterSpacing'][0] ) ) { $this->add_property( 'letter-spacing', $font['letterSpacing'][0] . $letter_type ); } } elseif ( isset( $font['letterSpacing'] ) && is_numeric( $font['letterSpacing'] ) ) { $this->add_property( 'letter-spacing', $font['letterSpacing'] . $letter_type ); } $family = ( isset( $font['family'] ) && ! empty( $font['family'] ) && 'inherit' !== $font['family'] ? $font['family'] : '' ); $is_google = false; if ( ! empty( $family ) ) { $is_google = isset( $font['google'] ) && $font['google'] ? true : false; $google = $is_google && ( isset( $font['loadGoogle'] ) && $font['loadGoogle'] || ! isset( $font['loadGoogle'] ) ) ? true : false; $this->add_property( 'font-family', $this->render_font_family( $font['family'], $google, ( isset( $font['variant'] ) ? $font['variant'] : '' ), ( isset( $font['subset'] ) ? $font['subset'] : '' ) ) ); if ( isset( $font['style'] ) && ! empty( $font['style'] ) && 'normal' !== $font['style'] ) { $this->add_property( 'font-style', $font['style'] ); } } if ( isset( $font['weight'] ) && ! empty( $font['weight'] ) ) { $this->add_property( 'font-weight', $this->render_font_weight( $font['weight'], $is_google ) ); } if ( isset( $font['textTransform'] ) && ! empty( $font['textTransform'] ) ) { $this->add_property( 'text-transform', $font['textTransform'] ); } if ( isset( $font['color'] ) && ! empty( $font['color'] ) ) { $this->add_property( 'color', $this->sanitize_color( $font['color'] ) ); } // Tablet. $this->set_media_state( 'tablet' ); if ( isset( $font['size'] ) && isset( $font['size'][1] ) && ! empty( $font['size'][1] ) ) { $this->add_property( 'font-size', $this->get_font_size( $font['size'][1], $size_type ) ); } if ( isset( $font['lineHeight'] ) && isset( $font['lineHeight']['tablet'] ) && ! empty( $font['lineHeight']['tablet'] ) ) { $this->add_property( 'line-height', $font['lineHeight']['tablet'] . $line_type ); } if ( isset( $font['lineHeight'] ) && isset( $font['lineHeight'][1] ) && ! empty( $font['lineHeight'][1] ) ) { $this->add_property( 'line-height', $font['lineHeight'][1] . $line_type ); } if ( isset( $font['letterSpacing'] ) && isset( $font['letterSpacing']['tablet'] ) && is_numeric( $font['letterSpacing']['tablet'] ) ) { $this->add_property( 'letter-spacing', $font['letterSpacing']['tablet'] . $letter_type ); } if ( isset( $font['letterSpacing'] ) && isset( $font['letterSpacing'][1] ) && is_numeric( $font['letterSpacing'][1] ) ) { $this->add_property( 'letter-spacing', $font['letterSpacing'][1] . $letter_type ); } // Mobile. $this->set_media_state( 'mobile' ); if ( isset( $font['size'] ) && isset( $font['size'][2] ) && ! empty( $font['size'][2] ) ) { $this->add_property( 'font-size', $this->get_font_size( $font['size'][2], $size_type ) ); } if ( isset( $font['lineHeight'] ) && isset( $font['lineHeight']['mobile'] ) && ! empty( $font['lineHeight']['mobile'] ) ) { $this->add_property( 'line-height', $font['lineHeight']['mobile'] . $line_type ); } if ( isset( $font['lineHeight'] ) && isset( $font['lineHeight'][2] ) && ! empty( $font['lineHeight'][2] ) ) { $this->add_property( 'line-height', $font['lineHeight'][2] . $line_type ); } if ( isset( $font['letterSpacing'] ) && isset( $font['letterSpacing']['mobile'] ) && is_numeric( $font['letterSpacing']['mobile'] ) ) { $this->add_property( 'letter-spacing', $font['letterSpacing']['mobile'] . $letter_type ); } if ( isset( $font['letterSpacing'] ) && isset( $font['letterSpacing'][2] ) && is_numeric( $font['letterSpacing'][2] ) ) { $this->add_property( 'letter-spacing', $font['letterSpacing'][2] . $letter_type ); } $this->set_media_state( 'desktop' ); } /** * Generates the font output. * * @param array $font an array of font settings. * @param object $css an object of css output. * @param string $inherit an string to determine if the font should inherit. * @return string */ public function get_font_size( $size, $unit ) { if ( $this->is_variable_font_size_value( $size ) ) { return $this->get_variable_font_size_value( $size ); } return $size . $unit; } /** * Generates the font output. * * @param array $typography an array of font settings. */ public function render_font( $typography ) { $attributes = array( 'typography' => $typography ); $this->render_typography( $attributes ); } /** * Generates the font height output. * * @param array $font an array of font settings. * @param string $device the device this is showing on. * @return string */ public function render_font_height( $font, $device ) { if ( empty( $font ) ) { return false; } if ( ! is_array( $font ) ) { return false; } if ( ! isset( $font['lineHeight'] ) ) { return false; } if ( ! is_array( $font['lineHeight'] ) ) { return false; } if ( ! isset( $font['lineHeight'][ $device ] ) ) { return false; } if ( empty( $font['lineHeight'][ $device ] ) ) { return false; } $font_string = $font['lineHeight'][ $device ] . ( isset( $font['lineType'] ) && ! empty( $font['lineType'] ) ? $font['lineType'] : 'px' ); return $font_string; } /** * Outputs a string if set. * * @param array $string a string setting. * @param string $unit if needed add unit. * @return string */ public function render_string( $string = null, $unit = null ) { if ( empty( $string ) ) { return false; } $string = $string . ( isset( $unit ) && ! empty( $unit ) ? $unit : '' ); return $string; } /** * Outputs a string if set. * * @param array $number a string setting. * @param string $unit if needed add unit. * @return string */ public function render_number( $number = null, $unit = null ) { if ( ! is_numeric( $number ) ) { return false; } $number = $number . ( isset( $unit ) && ! empty( $unit ) ? $unit : '' ); return $number; } /** * Generates the color output. * * @param string $color any color attribute. * @return string */ public function render_color( $color, $opacity = null ) { if ( empty( $color ) ) { return false; } if ( ! is_array( $color ) && strpos( $color, 'palette' ) === 0 ) { switch ( $color ) { case 'palette2': $fallback = '#2B6CB0'; break; case 'palette3': $fallback = '#1A202C'; break; case 'palette4': $fallback = '#2D3748'; break; case 'palette5': $fallback = '#4A5568'; break; case 'palette6': $fallback = '#718096'; break; case 'palette7': $fallback = '#EDF2F7'; break; case 'palette8': $fallback = '#F7FAFC'; break; case 'palette9': $fallback = '#ffffff'; break; default: $fallback = '#3182CE'; break; } $color = 'var(--global-' . $color . ', ' . $fallback . ')'; } elseif ( isset( $opacity ) && is_numeric( $opacity ) && 1 !== (int) $opacity ) { $color = kadence_blocks_hex2rgba( $color, $opacity ); } return $color; } /** * Generates the color output. * * @param string $color any color attribute. * @return string */ public function sanitize_color( $color, $opacity = null ) { if ( empty( $color ) ) { return false; } if ( ! is_array( $color ) && strpos( $color, 'palette' ) === 0 ) { switch ( $color ) { case 'palette2': $fallback = '#2B6CB0'; break; case 'palette3': $fallback = '#1A202C'; break; case 'palette4': $fallback = '#2D3748'; break; case 'palette5': $fallback = '#4A5568'; break; case 'palette6': $fallback = '#718096'; break; case 'palette7': $fallback = '#EDF2F7'; break; case 'palette8': $fallback = '#F7FAFC'; break; case 'palette9': $fallback = '#ffffff'; break; default: $fallback = '#3182CE'; break; } $color = 'var(--global-' . $color . ', ' . $fallback . ')'; } elseif ( isset( $opacity ) && is_numeric( $opacity ) && 1 !== (int) $opacity ) { $color = $this->convert_hex( $color, $opacity ); } return $color; } /** * Generates the color output. * * @param array $attributes an array of attributes * @param string $name Name of the color attribute * @param string $field Name of CSS property to use * @param string $opacityKey Key of opacity value in passed $attributes * * @return string */ public function render_color_output( $attributes, $name = 'color', $field = 'color', $opacityKey = '' ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } if ( ! empty( $attributes[ $name ] ) && isset( $attributes[ $opacityKey ] ) ) { $this->add_property( $field, $this->sanitize_color( $attributes[ $name ], $attributes[ $opacityKey ] ) ); } else if ( ! empty( $attributes[ $name ] ) ) { $this->add_property( $field, $this->sanitize_color( $attributes[ $name ] ) ); } } /** * Hex to RGBA * * @param string $hex string hex code. * @param number $alpha alpha number. */ public function convert_hex( $hex, $alpha ) { if ( empty( $hex ) ) { return ''; } if ( 'transparent' === $hex ) { return $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 ) ); } $rgba = 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $alpha . ')'; return $rgba; } /** * Generates the size output. * * @param array $size an array of size settings. * @param string $device the device this is showing on. * @param bool $render_zero if 0 should be rendered or not. * @return string */ public function render_range( $attributes, $name = 'width', $property = 'width', $unit = 'px', $render_zero = true ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } if ( ! isset( $attributes[ $name ] ) ) { return false; } if ( $render_zero ) { if ( ! is_numeric( $attributes[ $name ] ) ) { return false; } } else { if ( empty( $attributes[ $name ] ) ) { return false; } } $this->add_property( $property, $attributes[ $name ] . $unit ); } /** * Generates the measure range output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @param string $property for the css string. * @param string $unit the unit to use. * @param array $args an array of settings. * @param bool $render_zero if 0 should be rendered or not. * @return string */ public function render_measure_range( $attributes, $name = 'width', $property = 'width', $unit = 'px', $args = array(), $render_zero = true ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } if ( ! isset( $attributes[ $name ] ) ) { return false; } switch ( $property ) { case 'border-width': $prop_args = array( 'first_prop' => 'border-top-width', 'second_prop' => 'border-right-width', 'third_prop' => 'border-bottom-width', 'fourth_prop' => 'border-left-width', ); break; case 'border-radius': $prop_args = array( 'first_prop' => 'border-top-left-radius', 'second_prop' => 'border-top-right-radius', 'third_prop' => 'border-bottom-right-radius', 'fourth_prop' => 'border-bottom-left-radius', ); break; case 'position': $prop_args = array( 'first_prop' => 'top', 'second_prop' => 'right', 'third_prop' => 'bottom', 'fourth_prop' => 'left', ); break; default: $prop_args = array( 'first_prop' => $property . '-top', 'second_prop' => $property . '-right', 'third_prop' => $property . '-bottom', 'fourth_prop' => $property . '-left', ); break; } $defaults = array( 'unit_key' => $name . 'Type', 'first_prop' => $prop_args['first_prop'], 'second_prop' => $prop_args['second_prop'], 'third_prop' => $prop_args['third_prop'], 'fourth_prop' => $prop_args['fourth_prop'], ); $args = wp_parse_args( $args, $defaults ); $unit = ! empty( $attributes[ $args['unit_key'] ] ) ? $attributes[ $args['unit_key'] ] : $unit; if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( $render_zero && is_numeric( $attributes[ $name ][0] ) ) { $this->add_property( $args['first_prop'], $attributes[ $name ][0] . $unit ); } else if ( ! $render_zero && ! empty( $attributes[ $name ][0] ) ) { $this->add_property( $args['first_prop'], $attributes[ $name ][0] . $unit ); } if ( $render_zero && is_numeric( $attributes[ $name ][1] ) ) { $this->add_property( $args['second_prop'], $attributes[ $name ][1] . $unit ); } else if ( ! $render_zero && ! empty( $attributes[ $name ][1] ) ) { $this->add_property( $args['second_prop'], $attributes[ $name ][1] . $unit ); } if ( $render_zero && is_numeric( $attributes[ $name ][2] ) ) { $this->add_property( $args['third_prop'], $attributes[ $name ][2] . $unit ); } else if ( ! $render_zero && ! empty( $attributes[ $name ][2] ) ) { $this->add_property( $args['third_prop'], $attributes[ $name ][2] . $unit ); } if ( $render_zero && is_numeric( $attributes[ $name ][3] ) ) { $this->add_property( $args['fourth_prop'], $attributes[ $name ][3] . $unit ); } else if ( ! $render_zero && ! empty( $attributes[ $name ][3] ) ) { $this->add_property( $args['fourth_prop'], $attributes[ $name ][3] . $unit ); } } } /** * Generates the gap output. * * @param array $attributes an array of spacing settings. * @return string */ public function render_gap( $attributes, $name = 'gap', $property = 'gap', $unit_name = 'gapUnit', $args = array() ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } $unit = ! empty( $attributes[ $unit_name ] ) ? $attributes[ $unit_name ] : 'px'; $defaults = array( 'desktop_key' => '', 'tablet_key' => '', 'mobile_key' => '', 'renderAsVars' => false, 'varBase' => '--kb-' ); $args = wp_parse_args( $args, $defaults ); $name = $args['desktop_key'] ? $args['desktop_key'] : $name; $property_prefix = $args['renderAsVars'] ? $args['varBase'] : ''; if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { $attribute = isset( $attributes[ $name ][0] ) ? $attributes[ $name ][0] : ''; $attributeTablet = isset( $attributes[ $name ][1] ) ? $attributes[ $name ][1] : ''; $attributeMobile = isset( $attributes[ $name ][2] ) ? $attributes[ $name ][2] : ''; } else { $attribute = isset( $attributes[ $args['desktop_key'] ] ) ? $attributes[ $args['desktop_key'] ] : ''; $attributeTablet = isset( $attributes[ $args['tablet_key'] ] ) ? $attributes[ $args['tablet_key'] ] : ''; $attributeMobile = isset( $attributes[ $args['mobile_key'] ] ) ? $attributes[ $args['mobile_key'] ] : ''; } if ( '' !== $attribute && ! is_array( $attribute ) ) { $this->add_property( $property_prefix . $property, $this->get_gap_size( $attribute, $unit ) ); } if ( '' !== $attributeTablet && ! is_array( $attributeTablet ) ) { $this->set_media_state( 'tablet' ); $this->add_property( $property_prefix . $property, $this->get_gap_size( $attributeTablet, $unit ) ); } if ( '' !== $attributeMobile && ! is_array( $attributeMobile ) ) { $this->set_media_state( 'mobile' ); $this->add_property( $property_prefix . $property, $this->get_gap_size( $attributeMobile, $unit ) ); } $this->set_media_state( 'desktop' ); } /** * Generates the shadow output. * * @param array $shadow an array of shadow settings. * @return string */ public function render_row_gap( $attributes, $name = array( 'gap', 'tabletGap', 'mobileGap' ), $property = 'gap', $custom = '', $unit_name = 'gapUnit' ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } $unit = ! empty( $attributes[ $unit_name ] ) ? $attributes[ $unit_name ] : 'px'; if ( is_array( $name ) && ! empty( $attributes[ $name[0] ] ) ) { if ( $attributes[ $name[0] ] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][0] ) ) { $this->add_property( $property, $attributes[ $custom ][0] . $unit ); } } else { $this->add_property( $property, $this->get_variable_gap_value( $attributes[ $name[0] ] ) ); } } elseif ( ! is_array( $name ) && ! empty( $attributes[ $name ][0] ) ) { if ( $attributes[ $name ][0] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][0] ) ) { $this->add_property( $property, $attributes[ $custom ][0] . $unit ); } } else { $this->add_property( $property, $this->get_variable_gap_value( $attributes[ $name ][0] ) ); } } if ( ! empty( $attributes[ $name[1] ] ) ) { $this->set_media_state( 'tablet' ); if ( is_array( $name ) && $attributes[ $name[1] ] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][1] ) ) { $this->add_property( $property, $attributes[ $custom ][1] . $unit ); } } else { $this->add_property( $property, $this->get_variable_gap_value( $attributes[ $name[1] ] ) ); } } elseif ( ! is_array( $name ) && ! empty( $attributes[ $name ][1] ) ) { $this->set_media_state( 'tablet' ); if ( $attributes[ $name ][1] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][1] ) ) { $this->add_property( $property, $attributes[ $custom ][1] . $unit ); } } else { $this->add_property( $property, $this->get_variable_gap_value( $attributes[ $name ][1] ) ); } } if ( is_array( $name ) && ! empty( $attributes[ $name[2] ] ) ) { $this->set_media_state( 'mobile' ); if ( $attributes[ $name[2] ] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][2] ) ) { $this->add_property( $property, $attributes[ $custom ][2] . $unit ); } } else { $this->add_property( $property, $this->get_variable_gap_value( $attributes[ $name[2] ] ) ); } } elseif ( ! is_array( $name ) && ! empty( $attributes[ $name ][2] ) ) { $this->set_media_state( 'mobile' ); if ( $attributes[ $name ][2] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][2] ) ) { $this->add_property( $property, $attributes[ $custom ][2] . $unit ); } } else { $this->add_property( $property, $this->get_variable_gap_value( $attributes[ $name ][2] ) ); } } $this->set_media_state( 'desktop' ); } /** * Generates the gutter gap output. * */ public function render_row_gap_property( $attributes, $name = array( 'gap', 'tabletGap', 'mobileGap' ), $device = 'desktop', $custom = '', $unit_name = 'gapUnit' ) { if ( empty( $attributes ) || empty( $name ) ) { return ''; } if ( ! is_array( $attributes ) ) { return ''; } $unit = ! empty( $attributes[ $unit_name ] ) ? $attributes[ $unit_name ] : 'px'; // inherit tablet and mobile values if ( is_array( $name ) && ! empty( $attributes[ $name[0] ] ) ) { if ( empty( $attributes[ $name[1] ] ) ) { $attributes[ $name[1] ] = $attributes[ $name[0] ]; } if ( empty( $attributes[ $name[2] ] ) ) { $attributes[ $name[2] ] = $attributes[ $name[1] ]; } if ( $attributes[ $name[1] ] === 'custom' && empty( $attributes[ $custom ][1] ) ) { $attributes[$custom][1] = isset($attributes[$custom][0]) ? $attributes[$custom][0] : ''; } if ( $attributes[ $name[2] ] === 'custom' && empty( $attributes[ $custom ][2] ) ) { $attributes[ $custom ][2] = $attributes[ $custom ][1]; } } switch ( $device ) { case 'tablet': if ( ! empty( $attributes[ $name[1] ] ) ) { if ( is_array( $name ) && $attributes[ $name[1] ] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][1] ) ) { return $attributes[ $custom ][1] . $unit; } } else { return $this->get_variable_gap_value( $attributes[ $name[1] ] ); } } elseif ( ! is_array( $name ) && ! empty( $attributes[ $name ][1] ) ) { if ( $attributes[ $name ][1] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][1] ) ) { return $attributes[ $custom ][1] . $unit; } } else { return $this->get_variable_gap_value( $attributes[ $name ][1] ); } } break; case 'mobile': if ( is_array( $name ) && ! empty( $attributes[ $name[2] ] ) ) { if ( $attributes[ $name[2] ] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][2] ) ) { return $attributes[ $custom ][2] . $unit; } } else { return $this->get_variable_gap_value( $attributes[ $name[2] ] ); } } elseif ( ! is_array( $name ) && ! empty( $attributes[ $name ][2] ) ) { if ( $attributes[ $name ][2] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][2] ) ) { return $attributes[ $custom ][2] . $unit; } } else { return $this->get_variable_gap_value( $attributes[ $name ][2] ); } } break; default: if ( is_array( $name ) && ! empty( $attributes[ $name[0] ] ) ) { if ( $attributes[ $name[0] ] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][0] ) ) { return $attributes[ $custom ][0] . $unit; } } else { return $this->get_variable_gap_value( $attributes[ $name[0] ] ); } } elseif ( ! is_array( $name ) && ! empty( $attributes[ $name ][0] ) ) { if ( $attributes[ $name ][0] === 'custom' ) { if ( $this->is_number( $attributes[ $custom ][0] ) ) { return $attributes[ $custom ][0] . $unit; } } else { return $this->get_variable_gap_value( $attributes[ $name ][0] ); } } break; } return ''; } /** * Generates the shadow output. * * @param array $shadow an array of shadow settings. * @return string */ public function render_shadow( $shadow ) { if ( empty( $shadow ) ) { return false; } if ( ! is_array( $shadow ) ) { return false; } if ( ! isset( $shadow['color'] ) ) { return false; } if ( ! isset( $shadow['opacity'] ) ) { return false; } if ( ! isset( $shadow['hOffset'] ) ) { return false; } if ( ! isset( $shadow['vOffset'] ) ) { return false; } if ( ! isset( $shadow['blur'] ) ) { return false; } if ( ! isset( $shadow['spread'] ) ) { return false; } if ( ! isset( $shadow['inset'] ) ) { return false; } if ( $shadow['inset'] ) { $shadow_string = 'inset ' . ( ! empty( $shadow['hOffset'] ) ? $shadow['hOffset'] : '0' ) . 'px ' . ( ! empty( $shadow['vOffset'] ) ? $shadow['vOffset'] : '0' ) . 'px ' . ( ! empty( $shadow['blur'] ) ? $shadow['blur'] : '0' ) . 'px ' . ( ! empty( $shadow['spread'] ) ? $shadow['spread'] : '0' ) . 'px ' . ( ! empty( $shadow['color'] ) ? $this->render_color( $shadow['color'], $shadow['opacity'] ) : $this->render_color( '#000000', $shadow['opacity'] ) ); } else { $shadow_string = ( ! empty( $shadow['hOffset'] ) ? $shadow['hOffset'] : '0' ) . 'px ' . ( ! empty( $shadow['vOffset'] ) ? $shadow['vOffset'] : '0' ) . 'px ' . ( ! empty( $shadow['blur'] ) ? $shadow['blur'] : '0' ) . 'px ' . ( ! empty( $shadow['spread'] ) ? $shadow['spread'] : '0' ) . 'px ' . ( ! empty( $shadow['color'] ) ? $this->render_color( $shadow['color'], $shadow['opacity'] ) : $this->render_color( '#000000', $shadow['opacity'] ) ); } return $shadow_string; } /** * Generates the border radius color output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @return string */ public function render_border_radius( $attributes, $name = 'borderRadius', $unit = 'px' ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( isset( $attributes[ $name ][0] ) && is_numeric( $attributes[ $name ][0] ) ) { $this->add_property( 'border-top-left-radius', $attributes[ $name ][0] . $unit ); } if ( isset( $attributes[ $name ][1] ) && is_numeric( $attributes[ $name ][1] ) ) { $this->add_property( 'border-top-right-radius', $attributes[ $name ][1] . $unit ); } if ( isset( $attributes[ $name ][2] ) && is_numeric( $attributes[ $name ][2] ) ) { $this->add_property( 'border-bottom-right-radius', $attributes[ $name ][2] . $unit ); } if ( isset( $attributes[ $name ][3] ) && is_numeric( $attributes[ $name ][3] ) ) { $this->add_property( 'border-bottom-left-radius', $attributes[ $name ][3] . $unit ); } } } /** * Generates the border color output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @return string */ public function render_border_color( $attributes, $name = 'border' ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( ! empty( $attributes[ $name ][0] ) ) { $this->add_property( 'border-top-color', $this->sanitize_color( $attributes[ $name ][0] ) ); } if ( ! empty( $attributes[ $name ][1] ) ) { $this->add_property( 'border-right-color', $this->sanitize_color( $attributes[ $name ][1] ) ); } if ( ! empty( $attributes[ $name ][2] ) ) { $this->add_property( 'border-bottom-color', $this->sanitize_color( $attributes[ $name ][2] ) ); } if ( ! empty( $attributes[ $name ][3] ) ) { $this->add_property( 'border-left-color', $this->sanitize_color( $attributes[ $name ][3] ) ); } } } /** * Generates the align output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @return string */ public function render_align_by_margin( $attributes, $name = 'textAlign' ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( ! empty( $attributes[ $name ][0] ) ) { switch ( $attributes[ $name ][0] ) { case 'left': $this->add_property( 'margin-left', '0px' ); $this->add_property( 'margin-right', 'auto' ); break; case 'center': $this->add_property( 'margin-left', 'auto' ); $this->add_property( 'margin-right', 'auto' ); break; case 'right': $this->add_property( 'margin-left', 'auto' ); $this->add_property( 'margin-right', '0px' ); break; } } if ( ! empty( $attributes[ $name ][1] ) ) { $this->set_media_state( 'tablet' ); switch ( $attributes[ $name ][1] ) { case 'left': $this->add_property( 'margin-left', '0px' ); $this->add_property( 'margin-right', 'auto' ); break; case 'center': $this->add_property( 'margin-left', 'auto' ); $this->add_property( 'margin-right', 'auto' ); break; case 'right': $this->add_property( 'margin-left', 'auto' ); $this->add_property( 'margin-right', '0px' ); break; } } if ( ! empty( $attributes[ $name ][2] ) ) { $this->set_media_state( 'mobile' ); switch ( $attributes[ $name ][2] ) { case 'left': $this->add_property( 'margin-left', '0px' ); $this->add_property( 'margin-right', 'auto' ); break; case 'center': $this->add_property( 'margin-left', 'auto' ); $this->add_property( 'margin-right', 'auto' ); break; case 'right': $this->add_property( 'margin-left', 'auto' ); $this->add_property( 'margin-right', '0px' ); break; } } $this->set_media_state( 'desktop' ); } } /** * Generates the text align output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @return string */ public function render_text_align( $attributes, $name = 'textAlign', $args = array() ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } $defaults = array( 'desktop_key' => '', 'tablet_key' => '', 'mobile_key' => '', ); $args = wp_parse_args( $args, $defaults ); if ( ! empty( $args['desktop_key'] ) && isset( $attributes[ $args['desktop_key'] ] ) ) { if ( ! empty( $attributes[ $args['desktop_key'] ] ) ) { $this->add_property( 'text-align', $attributes[ $args['desktop_key'] ] ); } } else if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( ! empty( $attributes[ $name ][0] ) ) { $this->add_property( 'text-align', $attributes[ $name ][0] ); } } if ( ! empty( $args['tablet_key'] ) && isset( $attributes[ $args['tablet_key'] ] ) ) { if ( ! empty( $attributes[ $args['tablet_key'] ] ) ) { $this->set_media_state( 'tablet' ); $this->add_property( 'text-align', $attributes[ $args['tablet_key'] ] ); } } else if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( ! empty( $attributes[ $name ][1] ) ) { $this->set_media_state( 'tablet' ); $this->add_property( 'text-align', $attributes[ $name ][1] ); } } if ( ! empty( $args['mobile_key'] ) && isset( $attributes[ $args['mobile_key'] ] ) ) { if ( ! empty( $attributes[ $args['mobile_key'] ] ) ) { $this->set_media_state( 'mobile' ); $this->add_property( 'text-align', $attributes[ $args['mobile_key'] ] ); } } else if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( ! empty( $attributes[ $name ][2] ) ) { $this->set_media_state( 'mobile' ); $this->add_property( 'text-align', $attributes[ $name ][2] ); } } $this->set_media_state( 'desktop' ); } /** * Generates the responsive range output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @param string $property an string of the attribute name. * @param string $unit an string of the attribute name. * @return string */ public function render_responsive_range( $attributes, $name = 'width', $property = 'width', $unit = '' ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } if ( empty( $unit ) ) { $unit = $name . 'Type'; } $unit = ! empty( $attributes[ $unit ] ) ? $attributes[ $unit ] : 'px'; if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( isset( $attributes[ $name ][0] ) && is_numeric( $attributes[ $name ][0] ) ) { $this->add_property( $property, $attributes[ $name ][0] . $unit ); } if ( isset( $attributes[ $name ][1] ) && is_numeric( $attributes[ $name ][1] ) ){ $this->set_media_state( 'tablet' ); $this->add_property( $property, $attributes[ $name ][1] . $unit ); } if ( isset( $attributes[ $name ][2] ) && is_numeric( $attributes[ $name ][2] ) ) { $this->set_media_state( 'mobile' ); $this->add_property( $property, $attributes[ $name ][2] . $unit ); } $this->set_media_state( 'desktop' ); } } /** * Generates the responsive size output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @param string $property an string of the attribute name. * @param string $unit an string of the attribute name. * @param string $defaults Optional defaults to fallback if the responsive value is empty. * @return string */ public function render_responsive_size( $attributes, $name = array( 'width', 'tabletWidth', 'mobileWidth' ), $property = 'width', $unit = '', $defaults = array( '', '', '' ) ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } if ( empty( $unit ) ) { $unit = $name[0] . 'Type'; } $unit = ! empty( $attributes[ $unit ] ) ? $attributes[ $unit ] : 'px'; $this->set_media_state( 'desktop' ); if ( isset( $attributes[ $name[0] ] ) && '' !== $attributes[ $name[0] ] ) { $this->add_property( $property, $attributes[ $name[0] ] . $unit ); } else if ( $defaults[0] ) { $this->add_property( $property, $defaults[0] . $unit ); } $this->set_media_state( 'tablet' ); if ( isset( $attributes[ $name[1] ] ) && '' !== $attributes[ $name[1] ] ) { $this->add_property( $property, $attributes[ $name[1] ] . $unit ); } else if ( $defaults[1] ) { $this->add_property( $property, $defaults[1] . $unit ); } $this->set_media_state( 'mobile' ); if ( isset( $attributes[ $name[2] ] ) && '' !== $attributes[ $name[2] ] ) { $this->add_property( $property, $attributes[ $name[2] ] . $unit ); } else if ( $defaults[2] ) { $this->add_property( $property, $defaults[2] . $unit ); } $this->set_media_state( 'desktop' ); } /** * Generates the flex align output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @return string */ public function render_flex_align( $attributes, $name = 'textAlign', $args = array() ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } $defaults = array( 'desktop_key' => '', 'tablet_key' => '', 'mobile_key' => '', ); $args = wp_parse_args( $args, $defaults ); if ( ! empty( $args['desktop_key'] ) && isset( $attributes[ $args['desktop_key'] ] ) ) { if ( ! empty( $attributes[ $args['desktop_key'] ] ) ) { switch ( $attributes[ $args['desktop_key'] ] ) { case 'left': $this->add_property( 'justify-content', 'flex-start' ); break; case 'center': $this->add_property( 'justify-content', 'center' ); break; case 'right': $this->add_property( 'justify-content', 'flex-end' ); break; case 'space-between': $this->add_property( 'justify-content', 'space-between' ); break; } } } else if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( ! empty( $attributes[ $name ][0] ) ) { switch ( $attributes[ $name ][0] ) { case 'left': $this->add_property( 'justify-content', 'flex-start' ); break; case 'center': $this->add_property( 'justify-content', 'center' ); break; case 'right': $this->add_property( 'justify-content', 'flex-end' ); break; case 'space-between': $this->add_property( 'justify-content', 'space-between' ); break; } } } if ( ! empty( $args['tablet_key'] ) && isset( $attributes[ $args['tablet_key'] ] ) ) { if ( ! empty( $attributes[ $args['tablet_key'] ] ) ) { $this->set_media_state( 'tablet' ); switch ( $attributes[ $args['tablet_key'] ] ) { case 'left': $this->add_property( 'justify-content', 'flex-start' ); break; case 'center': $this->add_property( 'justify-content', 'center' ); break; case 'right': $this->add_property( 'justify-content', 'flex-end' ); break; case 'space-between': $this->add_property( 'justify-content', 'space-between' ); break; } } } else if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( ! empty( $attributes[ $name ][1] ) ) { $this->set_media_state( 'tablet' ); switch ( $attributes[ $name ][1] ) { case 'left': $this->add_property( 'justify-content', 'flex-start' ); break; case 'center': $this->add_property( 'justify-content', 'center' ); break; case 'right': $this->add_property( 'justify-content', 'flex-end' ); break; case 'space-between': $this->add_property( 'justify-content', 'space-between' ); break; } } } if ( ! empty( $args['mobile_key'] ) && isset( $attributes[ $args['mobile_key'] ] ) ) { if ( ! empty( $attributes[ $args['mobile_key'] ] ) ) { $this->set_media_state( 'mobile' ); switch ( $attributes[ $args['mobile_key'] ] ) { case 'left': $this->add_property( 'justify-content', 'flex-start' ); break; case 'center': $this->add_property( 'justify-content', 'center' ); break; case 'right': $this->add_property( 'justify-content', 'flex-end' ); break; case 'space-between': $this->add_property( 'justify-content', 'space-between' ); break; } } } else if ( isset( $attributes[ $name ] ) && is_array( $attributes[ $name ] ) ) { if ( ! empty( $attributes[ $name ][2] ) ) { $this->set_media_state( 'mobile' ); switch ( $attributes[ $name ][2] ) { case 'left': $this->add_property( 'justify-content', 'flex-start' ); break; case 'center': $this->add_property( 'justify-content', 'center' ); break; case 'right': $this->add_property( 'justify-content', 'flex-end' ); break; case 'space-between': $this->add_property( 'justify-content', 'space-between' ); break; } } } $this->set_media_state( 'desktop' ); } /** * Generates a border string for a single side at a single screen size. * * @param array $border an array of border settings. * @return string */ public function render_border( $border, $side = 'top' ) { if ( empty( $border ) || empty( $border[0] ) ) { return false; } if ( ! is_array( $border[0] ) ) { return false; } if ( ! isset( $border[0][ $side ] ) ) { return false; } $border_side = $border[0][ $side ]; if ( ! isset( $border_side[2] ) || ( isset( $border_side[2] ) && empty( $border_side[2] ) && ! is_numeric($border_side[2]) ) ) { return false; } $border_string = ''; $style = ( isset( $border_side[1] ) && ! empty( $border_side[1] ) ? $border_side[1] : 'solid' ); $width = ( isset( $border_side[2] ) && ! empty( $border_side[2] ) ? $border_side[2] : '0' ); $unit = ( isset( $border[0]['unit'] ) && ! empty( $border[0]['unit'] ) ? $border[0]['unit'] : 'px' ); $color = ( isset( $border_side[0] ) && ! empty( $border_side[0] ) ? $border_side[0] : 'transparent' ); $border_string = $width . $unit . ' ' . $style . ' ' . $this->render_color( $color ); return $border_string; } /** * Generates the border styles output. * * @param array $attributes an array of attributes. * @param string $name an string of the attribute name. * @param boolean $single_styles if property values should be calculated to be output alone. * @param array $args an array of settings. * @return string */ public function render_border_styles( $attributes, $name = 'borderStyle', $single_styles = false, $args = array() ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } $defaults = array( 'desktop_key' => $name, 'tablet_key' => 'tablet' . ucfirst( $name ), 'mobile_key' => 'mobile' . ucfirst( $name ), 'unit_key' => 'unit', 'first_prop' => 'border-top', 'second_prop' => 'border-right', 'third_prop' => 'border-bottom', 'fourth_prop' => 'border-left', 'sides_prop_keys' => array( 'top' => 'first_prop', 'right' => 'second_prop', 'bottom' => 'third_prop', 'left' => 'fourth_prop', ), 'renderAsVars' => false, 'varBase' => '--kb-', ); $args = wp_parse_args( $args, $defaults ); $sizes = array( 'desktop', 'tablet', 'mobile', ); $property_prefix = $args['renderAsVars'] ? $args['varBase'] : ''; foreach ( $sizes as $size ) { $this->set_media_state( $size ); foreach ( $args['sides_prop_keys'] as $side => $prop_key ) { $width = $this->get_border_value( $attributes, $args, $side, $size, 'width', $single_styles ); $color = $this->get_border_value( $attributes, $args, $side, $size, 'color', $single_styles ); $style = $this->get_border_value( $attributes, $args, $side, $size, 'style', $single_styles ); if ( $width ) { $this->add_property( $property_prefix . $args[ $prop_key ], $width . ' ' . $style . ' ' . $color ); } elseif ( $single_styles && $color ) { $this->add_property( $property_prefix . $args[ $prop_key ] . '-color', $color ); if ( $style ) { $this->add_property( $property_prefix . $args[ $prop_key ] . '-style', $style ); } } elseif ( $single_styles && $style ) { $desktop_width = $this->get_border_value( $attributes, $args, $side, 'desktop', 'width', $single_styles ); $tablet_width = $this->get_border_value( $attributes, $args, $side, 'tablet', 'width', $single_styles ); // Only need to output *just* the border-style if we're inheriting a width if( ( $size === 'tablet' && !empty( $desktop_width ) ) || ( $size === 'mobile' && !empty( $desktop_width ) && !empty( $tablet_width ) ) ) { $this->add_property( $property_prefix . $args[ $prop_key ] . '-style', $style ); } } } } $this->set_media_state( 'desktop' ); } /** * Gets a border value for a side and size. * Checks for values in sizes above itself if the given size has none * * @param array $attributes an array of attributes. * @param array $args an array of settings. * @param string $given_side the side to retrieve a value for (desktop, tablet, mobile). * @param string $given_size the size to retrieve a value for (top, right, bottom, left). * @param string $given_value the name of the value to retreive (color, style, width). * @param string $single_styles if this value is being calculated to be output alone. * @return string */ public function get_border_value( $attributes, $args, $given_side, $given_size, $given_value, $single_styles ) { //border styles come in an array like this: // [ // "top": [ {{color}}, {{style}}, {{width}} ], // "right": [ {{color}}, {{style}}, {{width}} ], // "bottom": [ {{color}}, {{style}}, {{width}} ], // "left": [ {{color}}, {{style}}, {{width}} ], // "unit": "px" // ] // one for each size // key setup. $value_positions = array( 'color' => 0, 'style' => 1, 'width' => 2, ); $value_defaults = array( 'color' => 'transparent', 'style' => 'solid', 'width' => '', ); $size_keys = array( 'mobile' => 'mobile_key', 'tablet' => 'tablet_key', 'desktop' => 'desktop_key', ); $sized_values = array( 'mobile' => '', 'tablet' => '', 'desktop' => '', ); $sized_units = array( 'mobile' => '', 'tablet' => '', 'desktop' => '', ); // get the value for the given side for each size, load into array. foreach ($size_keys as $size => $size_key) { if ( isset( $attributes[ $args[$size_key] ][0] ) && is_array( $attributes[ $args[$size_key] ][0] ) ) { $border_values = $attributes[ $args[$size_key] ][0]; $border_unit = ( ! empty( $border_values[$args['unit_key']] ) ? $border_values[$args['unit_key']] : '' ); $border_value = ( $border_values[$given_side][$value_positions[$given_value]] ?? '' ); $sized_units[$size] = $border_unit; $sized_values[$size] = $border_value; } } // return the value/unit for this size or a size above it. // if none is found return a default value. switch ( $given_size ) { case 'desktop': $return_value = $sized_values[$given_size]; $return_unit= $sized_units[$given_size]; break; case 'tablet': if( $given_value === 'width'){ $return_value = $this->is_number( $sized_values[$given_size] ) ? $sized_values[$given_size] : $sized_values['desktop']; } else { $return_value = $sized_values[$given_size] ?: $sized_values['desktop']; } $return_unit = $sized_units[$given_size] ?: $sized_units['desktop']; break; default: if( $given_value === 'width') { $return_value = $this->is_number( $sized_values[ $given_size ] ) ? $sized_values[ $given_size ] : ( $sized_values['tablet'] ?: $sized_values['desktop'] ); } else { $return_value = $sized_values[$given_size] ?: $sized_values['tablet'] ?: $sized_values['desktop']; } $return_unit = $sized_units[$given_size] ?: $sized_units['tablet'] ?: $sized_units['desktop']; break; } // if color is not set and single styles is selected, don't return the default, instead return blank as to not override some inherited styles. if ( $given_value == 'color' && ! $return_value && $single_styles) { return ''; } $return_value = '' !== $return_value ? $return_value : $value_defaults[ $given_value ]; $return_unit = $return_unit ? $return_unit : 'px'; // extra processing for specific values. if( $given_value == 'color') { $return_value = $this->sanitize_color($return_value); } if( $given_value == 'width') { $return_value = $this->is_number($return_value) ? $return_value . $return_unit : ''; } return $return_value; } /** * Generates styles for the attributes in the button style controls with states component. * Attributes must be in the format {attributeBase}{state}{size} e.g. linkColorHoverTablet * * @param array $args an array of settings. * @param array $attributes an array of attributes. * @return void */ public function render_button_styles_with_states( $args, $attributes ) { $default_args = array( 'colorBase' => '', 'backgroundBase' => '', 'backgroundTypeBase' => '', 'backgroundGradientBase' => '', 'borderBase' => '', 'borderRadiusBase' => '', 'borderRadiusUnitBase' => '', 'shadowBase' => '', 'selector' => '', 'selectorHover' => '', 'selectorActive' => '', 'renderAsVars' => false, 'varBase' => '--kb-', ); $args = array_merge( $default_args, $args ); $color_base = $args['colorBase']; $background_base = $args['backgroundBase']; $background_type_base = $args['backgroundTypeBase']; $background_gradient_base = $args['backgroundGradientBase']; $border_base = $args['borderBase']; $border_radius_base = $args['borderRadiusBase']; $border_radius_unit_base = $args['borderRadiusUnitBase']; $shadow_base = $args['shadowBase']; $states = array( '', 'Hover', 'Active' ); $sizes = array( '', 'Tablet', 'Mobile' ); $property_prefix = $args['renderAsVars'] ? $args['varBase'] : ''; foreach ( $states as $state ) { if ( $args[ 'selector' . $state ] || $args['renderAsVars'] ) { $state_selector = $args[ 'selector' . $state ]; $property_suffix = $args['renderAsVars'] ? ( $state ? '-' . strtolower($state) : '' ) : ''; $property_addition = $args['renderAsVars'] ? ( $state ? strtolower($state) . '-' : '' ) : ''; if ( ! $args['renderAsVars'] ) { $this->set_selector( $state_selector ); } foreach ( $sizes as $size ) { $this->set_media_state( $size ? lcfirst( $size ) : 'desktop' ); $color_value = $color_base ? $attributes[ $color_base . $state . $size ] : ''; $background_value = $background_base ? $attributes[ $background_base . $state . $size ] : ''; $background_type_value = $background_type_base ? $attributes[ $background_type_base . $state ] : ''; $background_gradient_value = $background_gradient_base ? $attributes[ $background_gradient_base . $state ] : ''; $border_value = $border_base ? $attributes[ $border_base . $state . $size ] : ''; $border_radius_value = $border_radius_base ? $attributes[ $border_radius_base . $state . $size ] : ''; $border_radius_unit_value = $border_radius_unit_base ? $attributes[ $border_radius_unit_base . $state ] : ''; $shadow_value = $shadow_base ? $attributes[ $shadow_base . $state ] : ''; $this->add_property( $property_prefix . 'color' . $property_suffix, $this->render_color( $color_value ) ); if ( 'gradient' === $background_type_value && ! empty( $background_gradient_value ) ) { $this->add_property( $property_prefix . 'background' . $property_suffix, $background_gradient_value ); } else { $this->add_property( $property_prefix . 'background' . $property_suffix, $this->render_color( $background_value ) ); } } $this->set_media_state( 'desktop' ); $border_radius_base_args = array( 'desktop_key' => $border_radius_base . $state, 'tablet_key' => $border_radius_base . $state . 'Tablet', 'mobile_key' => $border_radius_base . $state . 'Mobile', 'unit_key' => $border_radius_unit_base . $state, ); $border_radius_args = $args['renderAsVars'] ? array_merge($border_radius_base_args, [ 'first_prop' => $property_prefix . $property_addition . 'border-top-left-radius', 'second_prop' => $property_prefix . $property_addition . 'border-top-right-radius', 'third_prop' => $property_prefix . $property_addition . 'border-bottom-right-radius', 'fourth_prop' => $property_prefix . $property_addition . 'border-bottom-left-radius' ]) : $border_radius_base_args; $border_args = [ 'renderAsVars' => $args['renderAsVars'], 'desktop_key' => $border_base . $state, 'tablet_key' => $border_base . $state . 'Tablet', 'mobile_key' => $border_base . $state . 'Mobile', 'varBase' => $property_prefix . $property_addition ]; $this->render_measure_output( $attributes, $border_radius_base . $state, 'border-radius', $border_radius_args ); $this->render_border_styles( $attributes, $border_base . $state, false, $border_args ); if ( $shadow_value && isset( $shadow_value[0] ) && $shadow_value[0]['enable'] ) { $this->add_property( $property_prefix . 'box-shadow' . $property_suffix, $this->render_shadow( $shadow_value[0] ) ); } } } } /** * Generates the measure output. * * @param array $attributes an array of attributes. * @param string $name a string of the block attribute name. * @param string $property a string of the css propery name. * @param array $args an array of settings. * @return string */ public function render_measure_output( $attributes, $name = 'padding', $property = 'padding', $args = array() ) { if ( empty( $attributes ) || empty( $name ) ) { return false; } if ( ! is_array( $attributes ) ) { return false; } switch ( $property ) { case 'border-width': $prop_args = array( 'first_prop' => 'border-top-width', 'second_prop' => 'border-right-width', 'third_prop' => 'border-bottom-width', 'fourth_prop' => 'border-left-width', ); break; case 'border-radius': $prop_args = array( 'first_prop' => 'border-top-left-radius', 'second_prop' => 'border-top-right-radius', 'third_prop' => 'border-bottom-right-radius', 'fourth_prop' => 'border-bottom-left-radius', ); break; case 'position': $prop_args = array( 'first_prop' => 'top', 'second_prop' => 'right', 'third_prop' => 'bottom', 'fourth_prop' => 'left', ); break; default: $prop_args = array( 'first_prop' => $property . '-top', 'second_prop' => $property . '-right', 'third_prop' => $property . '-bottom', 'fourth_prop' => $property . '-left', ); break; } $defaults = array( 'desktop_key' => $name, 'tablet_key' => 'tablet' . ucfirst( $name ), 'mobile_key' => 'mobile' . ucfirst( $name ), 'unit_key' => $name . 'Type', 'first_prop' => $prop_args['first_prop'], 'second_prop' => $prop_args['second_prop'], 'third_prop' => $prop_args['third_prop'], 'fourth_prop' => $prop_args['fourth_prop'], ); $args = wp_parse_args( $args, $defaults ); $unit = ! empty( $attributes[ $args['unit_key'] ] ) ? $attributes[ $args['unit_key'] ] : 'px'; if ( isset( $attributes[ $args['desktop_key'] ] ) && is_array( $attributes[ $args['desktop_key'] ] ) ) { if ( $this->is_number( $attributes[ $args['desktop_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $attributes[ $args['desktop_key'] ][0] . $unit ); } else if ( 'position' === $property && ! empty( $attributes[ $args['desktop_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $attributes[ $args['desktop_key'] ][0] ); } else if ( ! empty( $attributes[ $args['desktop_key'] ][0] ) && $this->is_variable_value( $attributes[ $args['desktop_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $this->get_variable_value( $attributes[ $args['desktop_key'] ][0] ) ); } if ( isset( $attributes[ $args['desktop_key'] ][1] ) && is_numeric( $attributes[ $args['desktop_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $attributes[ $args['desktop_key'] ][1] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['desktop_key'] ][1] ) && ! empty( $attributes[ $args['desktop_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $attributes[ $args['desktop_key'] ][1] ); } else if ( ! empty( $attributes[ $args['desktop_key'] ][1] ) && $this->is_variable_value( $attributes[ $args['desktop_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $this->get_variable_value( $attributes[ $args['desktop_key'] ][1] ) ); } if ( isset( $attributes[ $args['desktop_key'] ][2] ) && is_numeric( $attributes[ $args['desktop_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $attributes[ $args['desktop_key'] ][2] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['desktop_key'] ][2] ) && ! empty( $attributes[ $args['desktop_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $attributes[ $args['desktop_key'] ][2] ); } else if ( ! empty( $attributes[ $args['desktop_key'] ][2] ) && $this->is_variable_value( $attributes[ $args['desktop_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $this->get_variable_value( $attributes[ $args['desktop_key'] ][2] ) ); } if ( isset( $attributes[ $args['desktop_key'] ][3] ) && is_numeric( $attributes[ $args['desktop_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $attributes[ $args['desktop_key'] ][3] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['desktop_key'] ][3] ) && ! empty( $attributes[ $args['desktop_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $attributes[ $args['desktop_key'] ][3] ); } else if ( ! empty( $attributes[ $args['desktop_key'] ][3] ) && $this->is_variable_value( $attributes[ $args['desktop_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $this->get_variable_value( $attributes[ $args['desktop_key'] ][3] ) ); } } $this->set_media_state( 'tablet' ); if ( isset( $attributes[ $args['tablet_key'] ] ) && is_array( $attributes[ $args['tablet_key'] ] ) ) { if ( isset( $attributes[ $args['tablet_key'] ][0] ) && is_numeric( $attributes[ $args['tablet_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $attributes[ $args['tablet_key'] ][0] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['tablet_key'] ][0] ) && ! empty( $attributes[ $args['tablet_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $attributes[ $args['tablet_key'] ][0] ); } else if ( ! empty( $attributes[ $args['tablet_key'] ][0] ) && $this->is_variable_value( $attributes[ $args['tablet_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $this->get_variable_value( $attributes[ $args['tablet_key'] ][0] ) ); } if ( isset( $attributes[ $args['tablet_key'] ][1] ) && is_numeric( $attributes[ $args['tablet_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $attributes[ $args['tablet_key'] ][1] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['tablet_key'] ][1] ) && ! empty( $attributes[ $args['tablet_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $attributes[ $args['tablet_key'] ][1] ); } else if ( ! empty( $attributes[ $args['tablet_key'] ][1] ) && $this->is_variable_value( $attributes[ $args['tablet_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $this->get_variable_value( $attributes[ $args['tablet_key'] ][1] ) ); } if ( isset( $attributes[ $args['tablet_key'] ][2] ) && is_numeric( $attributes[ $args['tablet_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $attributes[ $args['tablet_key'] ][2] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['tablet_key'] ][2] ) && ! empty( $attributes[ $args['tablet_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $attributes[ $args['tablet_key'] ][2] ); } else if ( ! empty( $attributes[ $args['tablet_key'] ][2] ) && $this->is_variable_value( $attributes[ $args['tablet_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $this->get_variable_value( $attributes[ $args['tablet_key'] ][2] ) ); } if ( isset( $attributes[ $args['tablet_key'] ][3] ) && is_numeric( $attributes[ $args['tablet_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $attributes[ $args['tablet_key'] ][3] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['tablet_key'] ][3] ) && ! empty( $attributes[ $args['tablet_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $attributes[ $args['tablet_key'] ][3] ); } else if ( ! empty( $attributes[ $args['tablet_key'] ][3] ) && $this->is_variable_value( $attributes[ $args['tablet_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $this->get_variable_value( $attributes[ $args['tablet_key'] ][3] ) ); } } $this->set_media_state( 'mobile' ); if ( isset( $attributes[ $args['mobile_key'] ] ) && is_array( $attributes[ $args['mobile_key'] ] ) ) { if ( isset( $attributes[ $args['mobile_key'] ][0] ) && is_numeric( $attributes[ $args['mobile_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $attributes[ $args['mobile_key'] ][0] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['mobile_key'] ][0] ) && ! empty( $attributes[ $args['mobile_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $attributes[ $args['mobile_key'] ][0] ); } else if ( ! empty( $attributes[ $args['mobile_key'] ][0] ) && $this->is_variable_value( $attributes[ $args['mobile_key'] ][0] ) ) { $this->add_property( $args['first_prop'], $this->get_variable_value( $attributes[ $args['mobile_key'] ][0] ) ); } if ( isset( $attributes[ $args['mobile_key'] ][1] ) && is_numeric( $attributes[ $args['mobile_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $attributes[ $args['mobile_key'] ][1] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['mobile_key'] ][1] ) && ! empty( $attributes[ $args['mobile_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $attributes[ $args['mobile_key'] ][1] ); } else if ( ! empty( $attributes[ $args['mobile_key'] ][1] ) && $this->is_variable_value( $attributes[ $args['mobile_key'] ][1] ) ) { $this->add_property( $args['second_prop'], $this->get_variable_value( $attributes[ $args['mobile_key'] ][1] ) ); } if ( isset( $attributes[ $args['mobile_key'] ][2] ) && is_numeric( $attributes[ $args['mobile_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $attributes[ $args['mobile_key'] ][2] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['mobile_key'] ][2] ) && ! empty( $attributes[ $args['mobile_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $attributes[ $args['mobile_key'] ][2] ); } else if ( ! empty( $attributes[ $args['mobile_key'] ][2] ) && $this->is_variable_value( $attributes[ $args['mobile_key'] ][2] ) ) { $this->add_property( $args['third_prop'], $this->get_variable_value( $attributes[ $args['mobile_key'] ][2] ) ); } if ( isset( $attributes[ $args['mobile_key'] ][3] ) && is_numeric( $attributes[ $args['mobile_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $attributes[ $args['mobile_key'] ][3] . $unit ); } else if ( 'position' === $property && isset( $attributes[ $args['mobile_key'] ][3] ) && ! empty( $attributes[ $args['mobile_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $attributes[ $args['mobile_key'] ][3] ); } else if ( ! empty( $attributes[ $args['mobile_key'] ][3] ) && $this->is_variable_value( $attributes[ $args['mobile_key'] ][3] ) ) { $this->add_property( $args['fourth_prop'], $this->get_variable_value( $attributes[ $args['mobile_key'] ][3] ) ); } } $this->set_media_state( 'desktop' ); } /** * Generates the measure output. * * @param array $measure an array of font settings. * @return string */ public function render_measure( $measure, $unit = 'px' ) { if ( empty( $measure ) ) { return false; } if ( ! is_array( $measure ) ) { return false; } if ( ! isset( $measure[0] ) ) { return false; } if ( ! is_numeric( $measure[0] ) && ! is_numeric( $measure[1] ) && ! is_numeric( $measure[2] ) && ! is_numeric( $measure[3] ) ) { return false; } $size_string = ( is_numeric( $measure[0] ) ? $measure[0] : '0' ) . $unit . ' ' . ( is_numeric( $measure[1] ) ? $measure[1] : '0' ) . $unit . ' ' . ( is_numeric( $measure[2] ) ? $measure[2] : '0' ) . $unit . ' ' . ( is_numeric( $measure[3] ) ? $measure[3] : '0' ) . $unit; return $size_string; } /** * Generates the opacity css output. * * @param array $attributes an array of attributes. * @param null|integer $name name of opacity attribute. */ public function render_opacity_from_100( $attributes, $name = null ) { if ( ! isset( $attributes[ $name ] ) || ! $this->is_number( $attributes[ $name ] ) ) { return; } if ( $attributes[ $name ] < 10 ) { $this->add_property( 'opacity', '0.0' . $attributes[ $name ] ); } elseif ( $attributes[ $name ] >= 100 ) { $this->add_property( 'opacity', '1' ); } else { $this->add_property( 'opacity', '0.' . $attributes[ $name ] ); } } /** * Generates the background output. * * @param array $background an array of background settings. * @param object $css an object of css output. */ public function render_background( $background, $css, $property = 'normal' ) { if ( empty( $background ) ) { return false; } if ( ! is_array( $background ) ) { return false; } $type = ( isset( $background['type'] ) && ! empty( $background['type'] ) ? $background['type'] : 'normal' ); if ( 'normal' === $type ) { if ( $property !== 'normal' ) { $background_color = ( ! empty( $background['color'] ) ? $background['color'] : '' ); $image_url = ( ! empty( $background['image'] ) ? 'url("' . $background['image'] . '")' : '' ); if ( ! empty( $image_url ) ) { $background_size = ( ! empty( $background['size'] ) ? $background['size'] : '' ); $background_position = ( ! empty( $background['position'] ) ? $background['position'] : 'center center' ); $background_attachment = ( ! empty( $background['attachment'] ) ? $background['attachment'] : 'scroll' ); $background_repeat = ( ! empty( $background['repeat'] ) ? $background['repeat'] : 'no-repeat' ); $css->add_property( $property, ( ! empty( $background_color ) ? $this->render_color( $background_color ) . ' ' : '' ) . $image_url . ' ' . $background_repeat . ' ' . $background_position . ( ! empty( $background_size ) ? ' / ' . $background_size : '' ) . ' ' . $background_attachment ); } else { $css->add_property( $property, $this->render_color( $background_color ) ); } } else { if ( ! empty( $background['color'] ) ) { $css->add_property( 'background-color', $this->render_color( $background['color'] ) ); } $image_url = ( ! empty( $background['image'] ) ? 'url("' . $background['image'] . '")' : '' ); if ( ! empty( $image_url ) ) { $css->add_property( 'background-image', $image_url ); $css->add_property( 'background-size', ( ! empty( $background['size'] ) ? $background['size'] : 'cover' ) ); $css->add_property( 'background-position', ( ! empty( $background['position'] ) ? $background['position'] : 'center center' ) ); $css->add_property( 'background-attachment', ( ! empty( $background['attachment'] ) ? $background['attachment'] : 'scroll' ) ); $css->add_property( 'background-repeat', ( ! empty( $background['repeat'] ) ? $background['repeat'] : 'no-repeat' ) ); } } } elseif ( 'gradient' === $type && isset( $background['gradient'] ) && ! empty( $background['gradient'] ) ) { if ( $property !== 'normal' ) { $css->add_property( $property, $this->render_gradient( $background['gradient'] ) ); } else { $css->add_property( 'background', $this->render_gradient( $background['gradient'] ) ); } } } /** * Sanitizes a gradient value. * * @param string $gradient an string of gradient markup. * @return string */ public function render_gradient( $gradient ) { if ( empty( $gradient ) ) { return false; } $gradient = str_replace( 'var(u002du002dglobal', 'var(--global', $gradient ); return $gradient; } /** * Generates the size output. * * @param array $size an array of size settings. * @return string */ public function render_half_size( $size, $unit = 'px' ) { if ( empty( $size ) && $size != 0 && $size != '0' ) { return false; } $size_number = $size ? $size : '0'; $size_unit = $unit ? $unit : 'em'; $size_string = 'calc(' . $size_number . $size_unit . ' / 2)'; return $size_string; } /** * Generates the size output. * * @param array $size an array of size settings. * @return string */ public function render_size( $size, $unit = 'px' ) { if ( empty( $size ) ) { return false; } $size_number = $size ? $size : '0'; $size_unit = $unit ? $unit : 'em'; $size_string = $size_number . $size_unit; return $size_string; } /** * Add google font to array. * * @param string $font_name the font name. * @param string $variant the font variant. * @param string $subset the font subset. */ public function maybe_add_google_font( $font_name, $font_variant = null, $subset = null ) { // Prevent empty array in google fonts. if ( empty( $font_name ) ) { return; } // Check if the font has been added yet. if ( ! array_key_exists( $font_name, self::$google_fonts ) ) { $add_font = array( 'fontfamily' => $font_name, 'fontvariants' => ( isset( $font_variant ) && ! empty( $font_variant ) ? array( $font_variant ) : array() ), 'fontsubsets' => ( isset( $subset ) && ! empty( $subset ) ? array( $subset ) : array() ), ); self::$google_fonts[ $font_name ] = $add_font; } else { if ( ! in_array( $font_variant, self::$google_fonts[ $font_name ]['fontvariants'], true ) ) { array_push( self::$google_fonts[ $font_name ]['fontvariants'], $font_variant ); } } } /** * Resets the css variable * * @access private * @since 1.1 * * @return void */ private function reset_css() { $this->_css = ''; return; } /** * Resets the css variable * * @access private * @since 1.1 * * @return void */ public function render_media_queries() { if ( isset( $this->_desktop_only_media_query ) && is_array( $this->_desktop_only_media_query ) && ! empty( $this->_desktop_only_media_query ) ) { $this->start_media_query( $this->get_media_queries( 'desktop' ) ); foreach ( $this->_desktop_only_media_query as $selector => $string ) { $this->set_selector( $selector ); $this->_css .= $string; } $this->stop_media_query(); } if ( isset( $this->_tablet_pro_media_query ) && is_array( $this->_tablet_pro_media_query ) && ! empty( $this->_tablet_pro_media_query ) ) { foreach ( $this->_tablet_pro_media_query as $selector => $string ) { $this->start_media_query( $this->get_media_queries( 'tabletPro' ) ); $this->set_selector( $selector ); $this->_css .= $string; } $this->stop_media_query(); } if ( isset( $this->_tablet_media_query ) && is_array( $this->_tablet_media_query ) && ! empty( $this->_tablet_media_query ) ) { foreach ( $this->_tablet_media_query as $selector => $string ) { $this->start_media_query( $this->get_media_queries( 'tablet' ) ); $this->set_selector( $selector ); $this->_css .= $string; } $this->stop_media_query(); } if ( isset( $this->_tablet_only_pro_media_query ) && is_array( $this->_tablet_only_pro_media_query ) && ! empty( $this->_tablet_only_pro_media_query ) ) { $this->start_media_query( $this->get_media_queries( 'tabletOnlyPro' ) ); foreach ( $this->_tablet_only_pro_media_query as $selector => $string ) { $this->set_selector( $selector ); $this->_css .= $string; } $this->stop_media_query(); } if ( isset( $this->_tablet_only_media_query ) && is_array( $this->_tablet_only_media_query ) && ! empty( $this->_tablet_only_media_query ) ) { $this->start_media_query( $this->get_media_queries( 'tabletOnly' ) ); foreach ( $this->_tablet_only_media_query as $selector => $string ) { $this->set_selector( $selector ); $this->_css .= $string; } $this->stop_media_query(); } if ( isset( $this->_mobile_media_query ) && is_array( $this->_mobile_media_query ) && ! empty( $this->_mobile_media_query ) ) { $this->start_media_query( $this->get_media_queries( 'mobile' ) ); foreach ( $this->_mobile_media_query as $selector => $string ) { $this->set_selector( $selector ); $this->_css .= $string; } $this->stop_media_query(); } } /** * Returns the google fonts array from the compiled css. * * @access public * @since 1.0 * * @return string */ public function fonts_output() { return self::$google_fonts; } /** * Clears everything. * * @access public * @since 1.0 * * @return string */ public function clear() { $this->_selector = ''; self::$google_fonts = array(); $this->_selector_output = ''; $this->_selector_states = array(); $this->_tablet_media_query = array(); $this->_tablet_pro_media_query = array(); $this->_desktop_only_media_query = array(); $this->_tablet_only_media_query = array(); $this->_tablet_only_pro_media_query = array(); $this->_mobile_media_query = array(); $this->_media_state = 'desktop'; $this->_css = ''; $this->_css_string = ''; $this->_output = ''; $this->_media_query = null; $this->_media_query_output = ''; $this->media_queries = null; } /** * Returns the minified css in the $_output variable * * @access public * @since 1.0 * * @return string */ public function css_output() { if ( apply_filters( 'kadence_blocks_css_output_media_queries', true ) ) { $this->render_media_queries(); } // Add current selector's rules to output $this->add_selector_rules_to_output(); if ( class_exists( 'Kadence_Blocks_Google_Fonts' ) ) { $fonts_instance = Kadence_Blocks_Google_Fonts::get_instance(); $fonts_instance->add_fonts( $this->fonts_output() ); } // Output minified css. self::$styles[ $this->_style_id ] = $this->_output; if ( ! empty( $this->_css_string ) ) { if ( ! isset( self::$custom_styles[ $this->_style_id ] ) ) { self::$custom_styles[ $this->_style_id ] = ''; } self::$custom_styles[ $this->_style_id ] = $this->_css_string; } $this->clear(); return self::$styles[ $this->_style_id ] . ( isset( self::$custom_styles[ $this->_style_id ] ) ? self::$custom_styles[ $this->_style_id ] : '' ); } /** * Generates the gap output. * * @param string $size a string or number with the gap size. * @param string $unit a string with the unit type. * @return string */ public function get_gap_size( $size, $unit ) { if ( $this->is_variable_gap_value( $size ) ) { return $this->get_variable_gap_value( $size ); } return $size . $unit; } /** * @param $value * * @return bool */ public function is_variable_gap_value( $value ) { return isset( $this->gap_sizes[ $value ] ); } /** * @param $value * * @return bool|string */ public function get_variable_gap_value( $value ) { if ( $this->is_variable_gap_value( $value ) ) { return $this->gap_sizes[ $value ]; } return false; } /** * @param $value * * @return bool */ public function is_variable_font_size_value( $value ) { return is_string( $value ) && isset( $this->font_sizes[ $value ] ); } /** * @param $value * * @return bool|string */ public function get_variable_font_size_value( $value ) { if ( $this->is_variable_font_size_value( $value ) ) { return $this->font_sizes[ $value ]; } return false; } /** * @param $value * * @return bool */ public function is_variable_value( $value ) { return is_string( $value ) && isset( $this->spacing_sizes[ $value ] ); } /** * @param $value * * @return int|string */ public function get_variable_value( $value ) { if( $this->is_variable_value( $value) ) { return $this->spacing_sizes[$value]; } return 0; } /** * @param array $sizes * * @return void */ public function set_spacing_sizes( $sizes ) { $this->spacing_sizes = $sizes; } /** * Get the value for a responsive attribute considering inheritance. * * @param mixed $value The desktop value. * @param mixed $value_tablet The tablet value. * @param mixed $value_mobile The mobile value. * @param string $size The size. * @param boolean $check_array if you should check if an array has any values. * @return mixed */ public function get_inherited_value( $value, $value_tablet, $value_mobile, $size = 'Desktop', $check_array = false ) { if ( ! $check_array ) { if ( $size === 'Mobile' ) { if ( ( isset( $value_mobile ) && $value_mobile !== '' ) || ( is_array( $value_mobile ) && ! empty( $value_mobile ) ) ) { return $value_mobile; } else if ( ( isset( $value_tablet ) && $value_tablet !== '' ) || ( is_array( $value_tablet ) && ! empty( $value_tablet ) ) ) { return $value_tablet; } } else if ( $size === 'Tablet' ) { if ( ( isset( $value_tablet ) && $value_tablet !== '' ) || ( is_array( $value_tablet ) && ! empty( $value_tablet ) ) ) { return $value_tablet; } } } else { if ( $size === 'Mobile' ) { if ( ! $this->empty_but_check_array( $value_mobile ) ) { return $value_mobile; } else if ( ! $this->empty_but_check_array( $value_tablet ) ) { return $value_tablet; } } else if ( $size === 'Tablet' ) { if ( ! $this->empty_but_check_array( $value_tablet ) ) { return $value_tablet; } } } return $value; } /** * Does a check to see if any of the values in this array are not empty. * * @param mixed $value the array. * @return boolean */ public function empty_but_check_array( $value ) { $has_value = false; if ( ! is_array( $value ) ) { return ! ( isset( $value ) && $value !== '' ); } foreach ( $value as $array_value ) { if ( is_array( $array_value ) ) { $has_value = ! $this->empty_but_check_array( $array_value ); } else if ( ( isset( $array_value ) && $array_value !== '' ) || ( is_array( $array_value ) && ! empty( $array_value ) ) ) { $has_value = true; } } return ! $has_value; } /** * Returns a copy of an attributes array, attempts to make values in the form {attribute}Tablet, {attribute}Mobile inherit. * * @param array $attributes the attributes. * @return array */ public function auto_inherit_attribtues( $attributes ) { $inherit_array = array(); foreach ( $attributes as $key => $value ) { $is_tablet_key = str_ends_with( $key, 'Tablet' ); $is_mobile_key = str_ends_with( $key, 'Mobile' ); if ( $is_tablet_key || $is_mobile_key ) { $desktop_key = substr( $key, 0, -6 ); $tablet_key = $desktop_key . 'Tablet'; $mobile_key = $desktop_key . 'Mobile'; if ( array_key_exists( $desktop_key, $attributes ) && array_key_exists( $tablet_key, $attributes ) && array_key_exists( $mobile_key, $attributes ) ) { $inherit_array[ $key ] = $this->get_inherited_value( $attributes[ $desktop_key ], $attributes[ $tablet_key ], $attributes[ $mobile_key ], $is_tablet_key ? 'Tablet' : 'Mobile', true ); } else { $inherit_array[ $key ] = $value; } } else { $inherit_array[ $key ] = $value; } } return $inherit_array; } /** * Reduces attributes in an array of the form {attribute}Tablet, {attribute}Mobile down to their base (desktop) key given a size. * * @param array $attributes the attributes. * @param string $key the key. * @param string $size the size. * @param boolean $inherit if the attribute should inherit. * @return mixed */ public function get_sized_attribute( $attributes, $key, $size = 'Desktop', $inherit = true ) { $sized_key = $size == 'Desktop' ? $key : $key . $size; if ( array_key_exists( $sized_key, $attributes ) ) { $desktop_key = $key; $tablet_key = $desktop_key . 'Tablet'; $mobile_key = $desktop_key . 'Mobile'; if ( array_key_exists( $desktop_key, $attributes ) && array_key_exists( $tablet_key, $attributes ) && array_key_exists( $mobile_key, $attributes ) && $inherit ) { return $this->get_inherited_value( $attributes[ $desktop_key ], $attributes[ $tablet_key ], $attributes[ $mobile_key ], $size, true ); } return $attributes[ $sized_key ]; } else if ( array_key_exists( $key, $attributes ) ) { return $attributes[ $key ]; } return null; } /** * Gets an Attribute for a given responsive size base on the form {attribute}Tablet, {attribute}Mobile. * * @param array $attributes the attributes. * @param string $size the size. * @param boolean $inherit if the attribute should inherit. * @return mixed */ public function get_sized_attributes_auto( $attributes, $size = 'Desktop', $inherit = true, $special_keys = array() ) { $sized_array = array(); $found_for_this_size = array(); foreach ( $attributes as $key => $value ) { $is_tablet_key = str_ends_with( $key, 'Tablet' ); $is_mobile_key = str_ends_with( $key, 'Mobile' ); $is_special_key = array_key_exists( $key, $special_keys ); //if we've already found this attribute for this size and it's already set, we don't need to process this again //this condition would occur if we've already processed iconColorTablet and set the iconColor attribute in $sized_array //Now we come back and find iconColor (the desktop attribute). We don't need to process it again because we've already run get_sized_attribute for it. if ( array_key_exists( $key, $found_for_this_size ) && array_key_exists( $key, $sized_array ) ) { continue; } if ( $is_tablet_key || $is_mobile_key ) { $desktop_key = substr( $key, 0, -6 ); $tablet_key = $desktop_key . 'Tablet'; $mobile_key = $desktop_key . 'Mobile'; if ( array_key_exists( $desktop_key, $attributes ) && array_key_exists( $tablet_key, $attributes ) && array_key_exists( $mobile_key, $attributes ) ) { $sized_array[ $desktop_key ] = $this->get_sized_attribute( $attributes, $desktop_key, $size, $inherit ); $found_for_this_size[$desktop_key] = true; } } else if ( $is_special_key ) { $desktop_value = $special_keys[ $key ]['Desktop']; $tablet_value = $special_keys[ $key ]['Tablet']; $mobile_value = $special_keys[ $key ]['Mobile']; $sized_array[ $key ] = $this->get_inherited_value( $desktop_value, $tablet_value, $mobile_value, $size, true ); } else { $sized_array[ $key ] = $value; } } return $sized_array; } } Kadence_Blocks_CSS::get_instance();