(.*)<\/span>/U',
function ( $matches ) {
$options = explode( ' ', str_replace( 'data-', '', $matches[1] ) );
$args = array( 'title' => '' );
foreach ( $options as $key => $value ) {
$value = trim( $value );
if ( empty( $value ) ) {
continue;
}
$data_split = explode( '=', $value, 2 );
if ( ! empty( $data_split[0] ) && ( $data_split[0] === 'title' || $data_split[0] === 'class' ) ) {
if ( ! empty( $data_split[1] ) ) {
$data_split[1] = str_replace( '_', ' ', $data_split[1] );
}
}
if ( ! empty( $data_split[1] ) ) {
$args[ $data_split[0] ] = str_replace( '"', '', $data_split[1] );
}
}
$type = substr( $args['name'] , 0, 2 );
$line_icon = ( ! empty( $type ) && 'fe' == $type ? true : false );
$fill = ( $line_icon ? 'none' : 'currentColor' );
$stroke_width = false;
if ( $line_icon ) {
$stroke_width = ( ! empty( $args['stroke'] ) ? $args['stroke'] : 2 );
}
$hidden = empty( $args['title'] );
$extras = '';
if ( ! empty( $args['tooltip-id'] ) ) {
$extras = 'data-tooltip-id="' . esc_attr( $args['tooltip-id'] ) . '"';
if ( ! empty( $args['tooltip-placement'] ) ) {
$extras .= ' data-tooltip-placement="' . esc_attr( $args['tooltip-placement'] ) . '"';
}
}
$svg = self::render( $args['name'], $fill, $stroke_width, $args['title'], $hidden );
return '' . $svg . '';
},
$block_content
);
// if the regex errored out, don't replace the $block_content.
$block_content = is_null( $replaced_block_content ) ? $block_content : $replaced_block_content;
}
return $block_content;
}
/**
* Return or echo an SVG icon matching the provided key
*
* @param $name
* @param $fill
* @param $stroke_width
* @param $title
* @param $hidden
* @param $extras string Escape any attributes passed to this
* @param $echo
*
* @return string|void
*/
public static function render( $name, $fill = 'currentColor', $stroke_width = false, $title = '', $hidden = true, $extras = '', $echo = false ) {
if ( null === self::$all_icons ) {
self::$all_icons = self::get_icons();
}
$svg = '';
if ( 'fa_facebook' === $name ) {
$name = 'fa_facebook-n';
}
$key = md5( $name . $fill . $stroke_width . $title . $hidden . $extras );
if( !empty( self::$cached_render[$key] ) ) {
return self::$cached_render[$key];
}
// Custom SVGs
$is_custom_svg = strpos($name, 'kb-custom-') === 0;
if ( $is_custom_svg && !isset( self::$all_icons[ $name ] ) ) {
$custom_post = get_post( str_replace('kb-custom-', '', $name) );
if ( ! empty( $custom_post ) && ! is_wp_error( $custom_post ) && 'kadence_custom_svg' === $custom_post->post_type && 'publish' === $custom_post->post_status ) {
self::$all_icons[ $name ] = json_decode( $custom_post->post_content, true );
}
}
if ( ! empty( self::$all_icons[ $name ] ) ) {
$icon = self::$all_icons[ $name ];
$vb = ( ! empty( $icon['vB'] ) ? $icon['vB'] : '0 0 24 24' );
$preserve = '';
$vb_array = explode( ' ', $vb );
$typeL = substr( $name, 0, 3 );
// This is added because some people upload icons that have negative values in the viewbox which cause part of the icons to get cut off unless this is added.
if ( $typeL && 'fas' !== $typeL && 'fe_' !== $typeL && 'ic_' !== $typeL && ( ( isset( $vb_array[0] ) && absint( $vb_array[0] ) > 0 ) || ( isset( $vb_array[1] ) && absint( $vb_array[1] ) > 0 ) ) ) {
$preserve = 'preserveAspectRatio="xMinYMin meet"';
}
$svg .= '';
}
self::$cached_render[$key] = $svg;
if ( $echo ) {
echo $svg;
return;
}
return $svg;
}
/**
* Recursively generate SVG elements
* Out native SVGs do not have children, but user uploaded SVGs in pro can contain children elements.
*
* @param $elements
*
* @return string
*/
private static function generate_svg_elements( $elements ) {
$output = '';
foreach ( $elements as $element ) {
$nE = $element['nE'];
$aBs = $element['aBs'];
$children = ! empty( $element['children'] ) ? $element['children'] : [];
$tmpAttr = array();
foreach ( $aBs as $key => $attribute ) {
if ( ! in_array( $key, array( 'fill', 'stroke', 'none' ) ) ) {
$tmpAttr[ $key ] = $key . '="' . esc_attr( $attribute ) . '"';
}
}
if ( isset( $aBs['fill'], $aBs['stroke'] ) && $aBs['fill'] === 'none' ) {
$tmpAttr['stroke'] = 'stroke="currentColor"';
}
$output .= '<' . $nE . ' ' . implode( ' ', $tmpAttr );
if ( ! empty( $children ) ) {
$output .= '>' . self::generate_svg_elements( $children ) . '' . $nE . '>';
} else {
$output .= '/>';
}
}
return $output;
}
/**
* Return an array of icons.
*
* @return array();
*/
private static function get_icons() {
$ico = include KADENCE_BLOCKS_PATH . 'includes/icons-ico-array.php';
$faico = include KADENCE_BLOCKS_PATH . 'includes/icons-array.php';
$kbcustom = include KADENCE_BLOCKS_PATH . 'includes/icons-kbcustom-array.php';
return apply_filters( 'kadence_svg_icons', array_merge( $ico, $faico, $kbcustom ) );
}
/**
* Fix an issue where wp_get_attachment_source returns non-values for width and height on svg's
*
* @param string $image the image retrieved.
* @param boolean $attachment_id The attachment id.
* @param boolean $size The size request.
* @param boolean $icon If it was requested as an icon.
*
* @return array|boolean
*/
public function fix_wp_get_attachment_image_svg( $image, $attachment_id, $size, $icon ) {
// If the image requested is an svg and the width is unset (1 or less in this case).
if ( is_array( $image ) && preg_match( '/\.svg$/i', $image[0] ) && $image[1] <= 1 ) {
// Use the requested size's dimensions first if available.
if ( is_array( $size ) ) {
$image[1] = $size[0];
$image[2] = $size[1];
} elseif ( ini_get( 'allow_url_fopen' ) && ( $xml = simplexml_load_file( $image[0], SimpleXMLElement::class, LIBXML_NOWARNING ) ) !== false ) {
$attr = $xml->attributes();
$viewbox = explode( ' ', $attr->viewBox );
$image[1] = isset( $attr->width ) && preg_match( '/\d+/', $attr->width, $value ) ? (int) $value[0] : ( count( $viewbox ) == 4 ? (int) $viewbox[2] : null );
$image[2] = isset( $attr->height ) && preg_match( '/\d+/', $attr->height, $value ) ? (int) $value[0] : ( count( $viewbox ) == 4 ? (int) $viewbox[3] : null );
} else {
$image[1] = null;
$image[2] = null;
}
}
return $image;
}
}
Kadence_Blocks_Svg_Render::get_instance();