Dashboard
PHP:
8.4.22
OS:
Linux
User:
provencez
/
/
home
/
provencez
/
www
/
wp-content
/
plugins
/
flexa-block
/
build
/
blocks
/
testimonial
📤 Upload
📝 New File
📁 New Folder
Close
Editing: render.php
<?php /** * Testimonial block — server-side render. * * CSS is generated at save time by Testimonial_CSS and printed inline on the * front end. This file outputs the card: an optional star rating, the headline, * the quote and the author block (avatar + name + role). All text is escaped * (wp_kses with a small inline whitelist); the star markup is static. The card * inherits the theme's typography unless the user overrode it. * * @package Flexa\Block * * @var array $attributes Block attributes. * @var string $content Save content (unused — dynamic block). * @var WP_Block $block Block instance. */ if ( ! defined( 'ABSPATH' ) ) { exit; } // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- $attributes provided by WP block API. use Flexa\Block\HTML_Helpers; $block_id = $attributes['blockId'] ?? ''; $anchor = $attributes['anchor'] ?? ''; $html_tag = HTML_Helpers::get_html_tag( $attributes ); $author_layout = 'stacked' === ( $attributes['authorLayout'] ?? 'inline' ) ? 'stacked' : 'inline'; $show_rating = false !== ( $attributes['showRating'] ?? true ); $rating = (int) round( (float) ( $attributes['rating'] ?? 5 ) ); $rating = max( 0, min( 5, $rating ) ); $show_avatar = false !== ( $attributes['showAvatar'] ?? true ); $avatar = $attributes['authorImage'] ?? []; $avatar_url = (string) ( $avatar['url'] ?? '' ); $avatar_alt = (string) ( $avatar['alt'] ?? '' ); $title = (string) ( $attributes['title'] ?? '' ); $quote = (string) ( $attributes['quote'] ?? '' ); $name = (string) ( $attributes['authorName'] ?? '' ); $job = (string) ( $attributes['authorJob'] ?? '' ); // Inline formatting allowed inside each text field. $inline_allowed = [ 'strong' => [], 'em' => [], 'b' => [], 'i' => [], 'br' => [], 'span' => [], ]; $quote_allowed = $inline_allowed + [ 'a' => [ 'href' => true, 'target' => true, 'rel' => true ] ]; // Star rating — static markup (no user input), so it is safe to echo directly. $rating_html = ''; if ( $show_rating ) { $star = '<svg class="%s" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M12 2.6l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5-5.8-3-5.8 3 1.1-6.5L3.6 9.4l6.5-.9L12 2.6Z" fill="currentColor"/></svg>'; $stars = ''; for ( $i = 0; $i < 5; $i++ ) { $cls = $i < $rating ? 'flexa-testimonial__star' : 'flexa-testimonial__star flexa-testimonial__star--empty'; $stars .= sprintf( $star, esc_attr( $cls ) ); } $label = sprintf( /* translators: %d: star rating out of five. */ esc_attr__( 'Rated %d out of 5', 'flexa-block' ), $rating ); $rating_html = '<div class="flexa-testimonial__rating" role="img" aria-label="' . $label . '">' . $stars . '</div>'; } // Title + quote. $title_html = '' !== trim( $title ) ? '<p class="flexa-testimonial__title">' . wp_kses( $title, $inline_allowed ) . '</p>' : ''; $quote_html = '' !== trim( $quote ) ? '<blockquote class="flexa-testimonial__quote">' . wp_kses( $quote, $quote_allowed ) . '</blockquote>' : ''; // Author block. $avatar_html = ''; if ( $show_avatar && '' !== $avatar_url ) { $avatar_html = '<img class="flexa-testimonial__avatar" src="' . esc_url( $avatar_url ) . '" alt="' . esc_attr( $avatar_alt ) . '" loading="lazy" decoding="async" />'; } $name_html = '' !== trim( $name ) ? '<span class="flexa-testimonial__name">' . wp_kses( $name, $inline_allowed ) . '</span>' : ''; $job_html = '' !== trim( $job ) ? '<span class="flexa-testimonial__job">' . wp_kses( $job, $inline_allowed ) . '</span>' : ''; $author_html = ''; if ( '' !== $avatar_html || '' !== $name_html || '' !== $job_html ) { $author_html = '<div class="flexa-testimonial__author">'; $author_html .= $avatar_html; if ( '' !== $name_html || '' !== $job_html ) { $author_html .= '<div class="flexa-testimonial__author-text">' . $name_html . $job_html . '</div>'; } $author_html .= '</div>'; } $inner = $rating_html . $title_html . $quote_html . $author_html; if ( '' === $inner ) { return; } // Wrapper classes + attributes. $classes = [ 'flexa-testimonial', 'flexa-testimonial--author-' . $author_layout ]; if ( '' !== $block_id ) { $classes[] = 'flexa-testimonial-' . sanitize_html_class( $block_id ); } $classes = HTML_Helpers::build_wrapper_classes( $classes, $attributes ); $wrapper_args = [ 'class' => implode( ' ', $classes ) ]; if ( $anchor ) { $wrapper_args['id'] = sanitize_html_class( $anchor ); } $wrapper_attributes = get_block_wrapper_attributes( $wrapper_args ); $data_attrs = HTML_Helpers::build_data_attrs( $attributes ); // Lazy background: mark the wrapper so view.js reveals the image near the viewport. $background = $attributes['background'] ?? []; $is_lazy_bg = ! empty( $background['lazyLoad'] ) && 'image' === ( $background['type'] ?? 'none' ) && '' !== ( $background['image']['url'] ?? '' ); $lazy_marker = $is_lazy_bg ? ' data-flexa-lazy-bg' : ''; printf( '<%1$s %2$s%3$s%4$s>%5$s</%1$s>', esc_html( $html_tag ), $wrapper_attributes, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- built via get_block_wrapper_attributes. $data_attrs, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- keys sanitized, values escaped in helper. $lazy_marker, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static literal. $inner // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- star markup static, text wp_kses'd, avatar src/alt escaped above. );
Save
Cancel