Repository URL to install this package:
|
Version:
2.0.9 ▾
|
<?php
/**
* Define CSS functions callbacks
*/
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
if ( ! class_exists( 'CX_Dynamic_CSS_Utilities' ) ) {
/**
* Define CX_Dynamic_CSS_Utilities class
*/
class CX_Dynamic_CSS_Utilities {
/**
* A reference to an instance of this class.
*
* @since 1.0.0
* @var object
*/
private static $instance = null;
/**
* Make passed color darken.
*
* @since 1.0.0
* @param [string] $color HEX or RGB(A) color value.
* @param [float] $darken Darken percent (0-100).
* @return string Processed color.
*/
public function color_darken( $color, $darken = 0 ) {
if ( ! $color ) {
return false;
}
$prepared_data = $this->prepare_color_mod( $color, $darken );
if ( ! $prepared_data || ! is_array( $prepared_data ) ) {
return false;
}
$r = $prepared_data['r'];
$g = $prepared_data['g'];
$b = $prepared_data['b'];
$a = $prepared_data['a'];
$percent = $prepared_data['percent'];
// Calc darken vals.
$r = round( $r - 255 * $percent, 0 );
$g = round( $g - 255 * $percent, 0 );
$b = round( $b - 255 * $percent, 0 );
$r = $r < 0 ? 0 : $r;
$g = $g < 0 ? 0 : $g;
$b = $b < 0 ? 0 : $b;
if ( false !== $a ) {
return sprintf( 'rgba(%s,%s,%s,%s)', $r, $g, $b, $a );
} else {
return sprintf( 'rgb(%s,%s,%s)', $r, $g, $b );
}
}
/**
* Make passed color lighten.
*
* @since 1.0.0
* @param [string] $color HEX or RGB(A) color value.
* @param [float] $lighten Lighten percent (0-100).
* @return string Processed color.
*/
public function color_lighten( $color, $lighten = 0 ) {
if ( ! $color ) {
return false;
}
$prepared_data = $this->prepare_color_mod( $color, $lighten );
if ( ! $prepared_data || ! is_array( $prepared_data ) ) {
return false;
}
$r = $prepared_data['r'];
$g = $prepared_data['g'];
$b = $prepared_data['b'];
$a = $prepared_data['a'];
$percent = $prepared_data['percent'];
// Calc lighten vals
$r = round( $r + 255 * $percent, 0 );
$g = round( $g + 255 * $percent, 0 );
$b = round( $b + 255 * $percent, 0 );
$r = $r > 255 ? 255 : $r;
$g = $g > 255 ? 255 : $g;
$b = $b > 255 ? 255 : $b;
if ( false !== $a ) {
return sprintf( 'rgba(%s,%s,%s,%s)', $r, $g, $b, $a );
} else {
return sprintf( 'rgb(%s,%s,%s)', $r, $g, $b );
}
}
/**
* Convert passed color into RGBa with passed opacity.
*
* @since 1.0.0
* @param [string] $color Color to convert.
* @param [integer] $opacity Opacity.
* @return string
*/
public function color_alpha( $color, $opacity = 100 ) {
if ( ! $color ) {
return false;
}
$prepared_data = $this->prepare_color_mod( $color, 100 );
if ( ! $prepared_data || ! is_array( $prepared_data ) ) {
return false;
}
$r = $prepared_data['r'];
$g = $prepared_data['g'];
$b = $prepared_data['b'];
$a = intval( $opacity ) / 100;
return sprintf( 'rgba(%s,%s,%s,%s)', $r, $g, $b, $a );
}
/**
* Select contrast color for passed from 2 proposed.
*
* 1st proposed color must be light - it will selected if passed color is dark,
* 2nd selected if passed is light, so it must be darken.
*
* @since 1.0.0
* @param [string] $color Color to get contrast for.
* @param [string] $if_dark Return this if we had dark color.
* @param [string] $if_light Return this if we had light color.
* @return string Color.
*/
public function color_contrast( $color, $if_dark = '#ffffff', $if_light = '#000000' ) {
if ( ! $color ) {
return false;
}
$prepared_data = $this->prepare_color_mod( $color, 100 );
if ( ! $prepared_data || ! is_array( $prepared_data ) ) {
return false;
}
$r = $prepared_data['r'];
$g = $prepared_data['g'];
$b = $prepared_data['b'];
$luminance = 0.299 * $r + 0.587 * $g + 0.114 * $b;
if ( $luminance >= 128 ) {
return $if_light;
} else {
return $if_dark;
}
}
/**
* Prepare color to modify.
*
* Bring passed color and change percent to array
* with R, G, B color values, opacity (if provided)
* and change percentage.
*
* @since 1.0.0
* @param [string] $color HEX or RGB(A) color value.
* @param [float] $percent Modify percent (0-100).
* @return array Prepared color and modify percent.
*/
public function prepare_color_mod( $color, $percent = 0 ) {
$is_rgba = ( false !== strpos( $color, 'rgba' ) ) ? true : false;
$is_rgb = ( false !== strpos( $color, 'rgb' ) && false === $is_rgba ) ? true : false;
$is_hex = ( false === $is_rgba && false === $is_rgb ) ? true : false;
$percent = round( (double) $percent / 100, 4 );
if ( $is_hex && '#' == $color[0] ) {
$color = substr( $color, 1 );
}
// Prepare hex color.
if ( $is_hex && strlen( $color ) == 6 ) {
list( $r, $g, $b ) = array( $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] );
} elseif ( $is_hex && strlen( $color ) == 3 ) {
list( $r, $g, $b ) = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] );
} elseif ( $is_hex ) {
return false;
}
if ( $is_hex ) {
$r = hexdec( $r );
$g = hexdec( $g );
$b = hexdec( $b );
}
$color = str_replace( ' ', '', $color );
// Prepare RGBA.
if ( $is_rgba ) {
preg_match( '/rgba\((.*)\)/', $color, $matches );
if ( ! is_array( $matches ) || empty( $matches[1] ) ) {
return false;
}
list( $r, $g, $b, $a ) = explode( ',', $matches[1] );
}
// Prepare RGB.
if ( $is_rgb ) {
preg_match( '/rgb\((.*)\)/', $color, $matches );
if ( ! is_array( $matches ) || empty( $matches[1] ) ) {
return false;
}
list( $r, $g, $b ) = explode( ',', $matches[1] );
}
$result = array(
'r' => $r,
'g' => $g,
'b' => $b,
'a' => isset( $a ) ? $a : false,
'percent' => $percent,
);
return $result;
}
/**
* Get background-image CSS property CSS by url.
*
* @param [string] $url url-value.
* @return string
*/
public function background_url( $url = '' ) {
if ( empty( $url ) ) {
return;
}
$result = 'background-image: url(' . esc_url( $url ) . ')';
return $result;
}
/**
* Get background CSS by bg data from options and selector.
* If passed multiplie images - returns retina ready CSS.
*
* @since 1.0.0
* @param [string] $selector CSS selector to apply bg for.
* @param [array] $data data-array from options.
* @return string
*/
public function get_background_css( $selector, $data ) {
if ( ! $selector ) {
return;
}
if ( ! is_array( $data ) ) {
return;
}
if ( empty( $data['image'] ) && empty( $data['color'] ) ) {
return;
}
$standard_bg = cherry_prepare_background( $data );
if ( empty( $data['image'] ) ) {
$standard_bg .= 'background-image:none;';
return $selector . '{' . $standard_bg . '}';
}
$images = explode( ',', $data['image'] );
$property_format = "%1$s {background-image: url(%2$s);%3$s}";
if ( 1 == count( $images ) && wp_attachment_is_image( $images[0] ) ) {
$img = wp_get_attachment_image_src( $images[0], 'full' );
$result = sprintf( $property_format, $selector, $img[0], $standard_bg );
return $result;
}
$img1x = null;
$img2x = null;
$width1x = 0;
$count = 2;
for ( $i = 0; $i < $count; $i++ ) {
if ( ( ! isset( $images[ $i ] ) ) || ( ! wp_attachment_is_image( $images[ $i ] ) ) ) {
continue;
}
$img = wp_get_attachment_image_src( $images[ $i ], 'full' );
if ( ! is_array( $img ) ) {
continue;
}
$img_url = $img[0];
$img_width = intval( $img[1] );
if ( null == $img1x ) {
$img1x = $img_url;
$img2x = $img_url;
$width1x = $img_width;
} elseif ( $img_width > $width1x ) {
$img2x = $img_url;
} else {
$img1x = $img_url;
}
}
$bg1 = sprintf( $property_format, $selector, $img1x, $standard_bg );
$bg2 = sprintf( $property_format, $selector, $img2x, '' );
$result = $bg1 . ' @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {' . $bg2 . '}';
return $result;
}
/**
* Sanitizes a hex color.
*
* Always adds hash to color use `sanitize_hex_color` if exist.
*
* @since 1.0.0
* @param [string] $color Maybe HEX color.
* @return string|null Sanitized color.
*/
public function sanitize_hex_color( $color ) {
$color = ltrim( $color, '#' );
$color = '#' . $color;
if ( '' === $color ) {
return '';
}
if ( function_exists( 'sanitize_hex_color' ) ) {
return sanitize_hex_color( $color );
}
// 3 or 6 hex digits, or the empty string.
if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) {
return $color;
}
return null;
}
/**
* Implode background properties array into CSS string.
*
* @since 1.0.0
* @param [array] $data Background data-array.
* @return string Set of background rules.
*/
public function prepare_background( $data ) {
if ( ! is_array( $data ) ) {
return;
}
unset( $data['image'] );
$result = '';
$format = 'background-%s:%s;';
foreach ( $data as $prop => $value ) {
if ( ! $value ) {
continue;
}
switch ( $prop ) {
case 'color':
$value = $this->sanitize_hex_color( $value );
break;
case 'position':
$value = str_replace( '-', ' ', $value );
break;
}
$result .= sprintf( $format, $prop, $value );
}
return $result;
}
/**
* Implode typography data array from options into CSS string.
*
* @since 1.0.0
* @param [array] $data Typography parameters array from options.
* @param [array] $mod Optional parameter - pass function name and arg to modify values inside typography array.
* @return string Font, letter-spacing, text-align, color CSS properties string.
*/
public function cherry_get_typography_css( $data, $mod = array() ) {
if ( ! is_array( $data ) || empty( $data ) ) {
return;
}
$defaults = array(
'family' => '',
'style' => '',
'color' => '',
'size' => '',
'lineheight' => '',
'letterspacing' => '',
'align' => '',
);
$data = wp_parse_args( $data, $defaults );
$result = array();
if ( '' !== $data['letterspacing'] ) {
$units = '0' != $data['letterspacing'] ? 'px' : '';
$result[] = 'letter-spacing:' . $data['letterspacing'] . $units;
}
if ( 'notdefined' != $data['align'] ) {
$result[] = 'text-align:' . $data['align'];
}
if ( '' != $data['color'] ) {
$color = $this->sanitize_hex_color( $data['color'] );
if ( 1 < count( $mod ) && ( in_array( $mod[0], array( 'cherry_colors_lighten', 'cherry_colors_darken' ) ) ) ) {
$color = $mod[0]( $color, $mod[1] );
}
$result[] = 'color:' . $color;
}
$family = stripcslashes( $data['family'] );
$family = explode( ',', $family );
array_walk( $family, array( $this, 'typography_prepare_family' ) );
$family[] = ! empty( $data['category'] ) ? $data['category'] : 'sans-serif';
$family = array_unique( $family );
$font_style = false;
$font_weight = false;
$font_size = $data['size'] . 'px';
$line_height = $data['lineheight'] . 'px';
$font_family = implode( ', ', $family );
preg_match( '/^(\d*)(\w*)/i', $data['style'], $matches );
if ( is_array( $matches ) ) {
$font_style = ( 'regular' != $matches[2] ) ? $matches[2] : false;
$font_weight = $matches[1];
}
$font = array(
$font_style,
$font_weight,
$font_size . '/' . $line_height,
$font_family,
);
$font = implode( ' ', array_filter( $font ) );
$result[] = 'font:' . ltrim( $font );
$result = implode( ';', $result ) . ';';
return $result;
}
/**
* Prepare font family for passing into typography function.
*
* @since 1.0.0
* @param [string] $item Array item.
* @param [int] $index Array item index.
* @return void
*/
public function typography_prepare_family( &$item, $index ) {
$item = trim( $item );
if ( strpos( $item, ' ' ) ) {
$item = '"' . $item . '"';
}
}
/**
* Get box model CSS from layout editor option.
*
* @since 1.0.0
* @param [array] $data Layout parameters array from options.
* @param [array] $mod Optional parameter - pass function name and arg to modify values inside layout array.
* @return string Indents, border etc.
*/
public function cherry_get_box_model_css( $data, $mod = array() ) {
if ( ! is_array( $data ) || empty( $data ) ) {
return;
}
$defaults = array(
'position' => array(),
'margin' => array(),
'border' => array(),
'padding' => array(),
'container' => array(),
);
$box_defaults = array(
'top' => '',
'right' => '',
'bottom' => '',
'left' => '',
);
$data = wp_parse_args( $data, $defaults );
$result = '';
// Prepare postion
$data['position'] = array_filter( $data['position'] );
if ( ! empty( $data['position'] ) ) {
$data['position'] = array_intersect_key( $data['position'], $box_defaults );
$parser_data = array(
'prefix' => '',
'allowed' => $box_defaults,
);
array_walk( $data['position'], 'cherry_prepare_box_item', $parser_data );
$result .= implode( ';', array_filter( $data['position'] ) ) . ';';
}
// Prepare indents.
$result .= cherry_prepare_css_indents( $data['margin'], 'margin' );
$result .= cherry_prepare_css_indents( $data['padding'], 'padding' );
// Prepare borders
if ( ! empty( $data['border'] ) ) {
$border_style = ! empty( $data['border']['style'] ) ? $data['border']['style'] : '';
$border_color = ! empty( $data['border']['color'] ) ? $data['border']['color'] : '';
$border_radius = ! empty( $data['border']['radius'] ) ? $data['border']['radius'] : '';
if ( '' != $border_radius ) {
$result .= 'border-radius:' . $border_radius . ';';
}
$border_format = 'border-%1$s:%2$s %3$s %4$s;';
foreach ( $data['border'] as $property => $value ) {
if ( ! array_key_exists( $property, $box_defaults ) ) {
continue;
}
if ( empty( $value ) ) {
continue;
}
$result .= sprintf(
$border_format,
$property, $value, $border_style, $border_color
);
}
}
// Prepare dimensions.
if ( ! empty( $data['container']['width'] ) ) {
$result .= 'width:' . $data['container']['width'] . ';';
}
if ( ! empty( $data['container']['height'] ) ) {
$result .= 'height:' . $data['container']['height'] . ';';
}
return $result;
}
/**
* Service function to grab CSS indents from data array into string.
*
* @since 1.0.0
* @param [array] $data data-array.
* @param [string] $property CSS property.
* @return string
*/
public function cherry_prepare_css_indents( $data, $property ) {
if ( empty( $data ) ) {
return;
}
$box_defaults = array(
'top' => '',
'right' => '',
'bottom' => '',
'left' => '',
);
$data = array_intersect_key( $data, $box_defaults );
$data = array_filter( $data );
if ( 4 == count( $data ) ) {
$result = $property . ':' . implode( ' ', $data ) . ';';
return $result;
}
$parser_data = array(
'prefix' => $property,
'allowed' => $box_defaults,
);
array_walk( $data, 'cherry_prepare_box_item', $parser_data );
$result = implode( ';', array_filter( $data ) ) . ';';
return $result;
}
/**
* Service callback function for.
*
* @since 1.0.0
* @param [string] $item Position value.
* @param [string] $key Position key.
* @param [array] $data Array of allowed positions and property prefix.
* @return void
*/
public function cherry_prepare_box_item( &$item, $key, $data ) {
if ( ! array_key_exists( $key, $data['allowed'] ) ) {
$item = false;
return;
}
if ( empty( $item ) ) {
$item = false;
return;
}
$prefix = '';
if ( ! empty( $data['prefix'] ) ) {
$prefix = $data['prefix'] . '-';
}
$item = $prefix . $key . ':' . $item;
}
/**
* Prepare font family to the using in CSS.
*
* @since 1.0.1
* @param [string] $font_family Font name.
* @return string
*/
public function typography_font_family( $font_family ) {
$font_family = trim( $font_family );
$family_args = explode( ',', $font_family );
$names = '';
$type = end( $family_args );
$type = trim( $type );
for ( $i = 0; $i < count( $family_args ) - 1; $i++ ) {
if ( strpos( $family_args[ $i ], ' ' ) ) {
$names .= "'" . $family_args[ $i ] . "',";
} else {
$names .= $family_args[ $i ] . ',';
}
}
return sprintf( '%1$s, %2$s', trim( $names, ',' ), $type );
}
/**
* Make float size.
*
* @since 1.0.0
* @param [double] $size Font size.
* @param [string] $operation Arithmetic operator (multiple, addition).
* @param [string] $func Function name (floor, ceil, round, abs).
* @param [double] $percent Font size in percent.
* @return double Size.
*/
public function typography_size( $size, $operation = ' ', $func = 'round', $percent ) {
if ( ! $size ) {
return false;
}
switch ( $operation ) {
case 'multiple' :
$size = (double) $size * (double) $percent;
break;
case 'addition' :
$size = (double) $size + (double) $percent;
break;
}
switch ( $func ) {
case 'floor' :
$size = floor( $size );
break;
case 'ceil' :
$size = ceil( $size );
break;
case 'round' :
$size = round( $size );
break;
case 'abs' :
$size = abs( $size );
break;
}
return $size;
}
/**
* Build a CSS-rule.
*
* @since 1.0.0
* @param [string|int] $value CSS-proterty value.
* @param [string] $rule CSS-proterty name.
* @return string CSS-rule.
*/
public function empty_value( $value, $rule ) {
if ( '' == $value || 'notdefined' == $value ) {
return;
}
echo $rule . ': ' . $value;
if ( is_numeric( $value ) ) {
echo 'px; ';
} else {
echo '; ';
}
}
/**
* Set element emphasis.
*
* @since 1.0.0
* @param [string] $parent Parent selector.
* @param [string] $color Color.
* @param [string] $property To define.
*/
public function element_emphasis( $parent, $color, $property ) {
$result = $parent . ' {' . $property . ':' . $color . ';}';
$result .= $parent . ':hover {' . $property . ':' . $this->color_darken( $color, 10 ) . ';}';
return $result;
}
/**
* Return width value for container.
*
* @since 1.0.0
* @param [int] $container_width A container width value.
* @param [int] $element_width Some-block (parent-block for container) width value.
* @return int Width value.
*/
public function container_width_compare( $container_width, $element_width ) {
return ( $container_width > $element_width ) ? $element_width : $container_width;
}
/**
* Sum of $a and $b.
*
* @since 1.0.0
* @param [int] $a Operand 1.
* @param [int] $b Operand 2.
* @return int Addition.
*/
public function simple_sum( $a, $b ) {
return intval( $a ) + intval( $b );
}
/**
* Difference of $a and $b.
*
* @since 1.0.0
* @param [int] $a Operand 1.
* @param [int] $b Operand 2.
* @return int Subtraction.
*/
public function simple_diff( $a, $b ) {
return intval( $a ) - intval( $b );
}
/**
* Retrieve a width to swith on mobile menu from.
*
* @since 1.0.0
* @return int Width value.
*/
public function menu_toogle_endpoint() {
/**
* Filters a value when mobile menu switched.
*
* @since 1.0.0
* @param int $value Width value.
*/
return apply_filters( 'cx_dynamic_css/utilites/menu_toogle_endpoint', 600 );
}
/**
* Returns the instance.
*
* @since 1.0.0
* @return object
*/
public static function get_instance() {
// If the single instance hasn't been set, set it now.
if ( null == self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
}
}