- WordPress 6.9.4 (es_ES) with Kadence theme - Homepage: Hero, La Asociación, Pilares, Beneficios, Eventos, Miembros, Hazte Miembro, Contacto - Brand identity: #13294b navy, #a12932 burgundy, #c69c48 gold - Fonts: Raleway (headings) + Source Sans 3 (body) + Lato (UI) - Plugins: Kadence Blocks, Polylang, Contact Form 7 - Custom CSS with full brand styling and responsive layout - HTTPS enforced via wp-config.php proxy detection
274 lines
8.7 KiB
PHP
274 lines
8.7 KiB
PHP
<?php
|
|
/**
|
|
* Render an SVG given a key.
|
|
*
|
|
* @since 2.4.0
|
|
* @package Kadence Blocks
|
|
*/
|
|
|
|
// Exit if accessed directly.
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Class to Enqueue CSS/JS of all the blocks.
|
|
*
|
|
* @category class
|
|
*/
|
|
class Kadence_Blocks_Svg_Render {
|
|
|
|
/**
|
|
* Instance of this class
|
|
*
|
|
* @var null
|
|
*/
|
|
private static $instance = null;
|
|
|
|
/**
|
|
* All SVG Icons
|
|
*
|
|
* @var null
|
|
*/
|
|
private static $all_icons = null;
|
|
|
|
/*
|
|
* Cache rendered SVG elements
|
|
*/
|
|
private static $cached_render = [];
|
|
|
|
/**
|
|
* 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_filter( 'render_block', array( $this, 'render_icons_dynamically' ), 10, 2 );
|
|
if ( apply_filters( 'kadence_blocks_fix_svg_dimensions', false ) ) {
|
|
add_filter( 'wp_get_attachment_image_src', array( $this, 'fix_wp_get_attachment_image_svg' ), 10, 4 );
|
|
}
|
|
}
|
|
/**
|
|
* On build convert icons into svgs.
|
|
*
|
|
* @param string $block_content the name of the svg.
|
|
* @param object $block the block data.
|
|
*
|
|
* @return string|void
|
|
*/
|
|
public function render_icons_dynamically( $block_content, $block ) {
|
|
if ( is_admin() ) {
|
|
return $block_content;
|
|
}
|
|
if ( ! empty( $block_content ) ) {
|
|
$replaced_block_content = preg_replace_callback(
|
|
'/<span\s+((?:data-[\w\-]+=["\']+.*["\']+[\s]+)+)class=["\'].*kadence-dynamic-icon.*["\']\s*>(.*)<\/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 '<span class="kb-svg-icon-wrap kb-svg-icon-' . esc_attr( $args['name'] ) . ( ! empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '' ) . '"' . $extras . '>' . $svg . '</span>';
|
|
},
|
|
$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 .= '<svg viewBox="' . $vb . '" ' . $preserve . ' fill="' . esc_attr( $fill ) . '"' . ( ! empty( $stroke_width ) ? ' stroke="currentColor" stroke-width="' . esc_attr( $stroke_width ) . '" stroke-linecap="round" stroke-linejoin="round"' : '' ) . ' xmlns="http://www.w3.org/2000/svg" ' . ( ! empty( $extras ) ? ' ' . $extras : '' ) . ( $hidden ? ' aria-hidden="true"' : ' role="img"' ) . '>';
|
|
if ( ! empty( $title ) ) {
|
|
$svg .= '<title>' . $title . '</title>';
|
|
}
|
|
if ( ! empty( $icon['cD'] ) ) {
|
|
$svg .= self::generate_svg_elements($icon['cD']);
|
|
}
|
|
|
|
$svg .= '</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();
|