File: /var/www/html/triad-infosec/wp-content/plugins/fusion-builder/shortcodes/fusion-star-rating.php
<?php
/**
* Add the rating element to fusion-builder.
*
* @package fusion-builder
* @since 3.5
*/
if ( fusion_is_element_enabled( 'fusion_star_rating' ) ) {
if ( ! class_exists( 'FusionSC_Star_Rating' ) ) {
/**
* Shortcode class.
*
* @since 3.5
*/
class FusionSC_Star_Rating extends Fusion_Element {
/**
* The number of instance of this element. Working as an id.
*
* @since 3.5
* @var int
*/
protected $element_counter = 1;
/**
* Constructor.
*
* @access public
* @since 3.5
*/
public function __construct() {
parent::__construct();
add_filter( 'fusion_attr_star-rating-element-attr', [ $this, 'element_attr' ] );
add_filter( 'fusion_attr_star-rating-icon-attr', [ $this, 'icon_attr' ] );
add_filter( 'fusion_attr_star-rating-partial-filled-icon-attr', [ $this, 'partial_filled_icon_attr' ] );
add_shortcode( 'fusion_star_rating', [ $this, 'render' ] );
}
/**
* Render the shortcode.
*
* @access public
* @since 3.5
* @param array $args Shortcode parameters.
* @return string HTML output.
*/
public function render( $args ) {
$this->defaults = self::get_element_defaults();
$this->args = FusionBuilder::set_shortcode_defaults( self::get_element_defaults(), $args, 'fusion_star_rating' );
$rating = $this->get_rating();
$maximum_rating = $this->args['maximum_rating'];
if ( $rating > $maximum_rating ) {
$rating = $maximum_rating;
}
if ( 'hide' === $this->args['display_empty_rating'] && 0 >= $rating ) {
return '';
}
$html = '<div ' . FusionBuilder::attributes( 'star-rating-element-attr' ) . '>';
$html .= '<div class="awb-stars-rating-icons-wrapper">';
$html .= $this->get_icons_html();
$html .= '</div>';
if ( 'yes' === $this->args['display_rating_text'] ) {
$html .= '<div class="awb-stars-rating-text">';
$html .= $this->get_rating_text_html();
$html .= '</div>';
}
$html .= '</div>';
if ( $rating > 0 ) {
if ( '0decimals' === $this->args['rating_number_rounding'] ) {
$schema_rating = (string) round( $rating, 0 );
} elseif ( '1decimal' === $this->args['rating_number_rounding'] ) {
$schema_rating = (string) round( $rating, 1 );
} else {
$schema_rating = (string) round( $rating, 2 );
}
// Add the schema for this element.
new Fusion_JSON_LD(
'fusion-star-rating',
[
'@context' => 'https://schema.org',
'@type' => 'Rating',
'ratingValue' => $schema_rating,
'bestRating' => $maximum_rating,
]
);
}
$this->element_counter++;
return $html;
}
/**
* Get the HTML of the icons.
*
* @since 3.5
* @return string
*/
protected function get_icons_html() {
$html = '';
$rating = $this->get_rating();
if ( '0decimals' === $this->args['rating_number_rounding'] && 'yes' === $this->args['display_rating_text'] ) {
$rating = intval( round( $rating, 0 ) );
}
$maximum_rating = $this->args['maximum_rating'];
$is_perfect_round_average = ( intval( $rating ) === $rating );
$current_star = 1;
while ( $current_star <= $maximum_rating ) {
$html .= '<i ' . FusionBuilder::attributes( 'star-rating-icon-attr', $current_star ) . '>';
if ( ! $is_perfect_round_average && ( intval( $rating ) + 1 ) === $current_star ) {
$html .= '<i ' . FusionBuilder::attributes( 'star-rating-partial-filled-icon-attr' ) . '></i>';
}
$html .= '</i>';
$current_star++;
}
return $html;
}
/**
* Get the HTML of the rating text.
*
* @since 3.5
* @return string
*/
protected function get_rating_text_html() {
$rating = $this->get_rating();
$maximum_rating = $this->args['maximum_rating'];
$html = $before = $after = '';
if ( $rating > $maximum_rating ) {
$rating = $maximum_rating;
}
// Dynamic data before/after.
if ( is_string( $this->args['rating'] ) && ! is_numeric( str_replace( ',', '.', $this->args['rating'] ) ) ) {
$before_after = explode( $this->get_rating( false ), $this->args['rating'] );
$before = ' ' !== $before_after[0] ? $before_after[0] : '';
$after = isset( $before_after[1] ) ? $before_after[1] : '';
}
$html .= $before . '<span>' . number_format_i18n( $rating, $this->get_number_to_round( $rating ) ) . '</span> / <span>' . $maximum_rating . '</span>' . $after;
return $html;
}
/**
* Get the attributes of the main element HTML tag.
*
* @since 3.5
* @return array
*/
public function element_attr() {
$attr = [
'style' => $this->get_inline_style(),
'role' => 'img',
'class' => 'awb-stars-rating awb-stars-rating-' . $this->element_counter,
];
$attr = fusion_builder_visibility_atts( $this->args['hide_on_mobile'], $attr );
if ( 'no' === $this->args['display_rating_text'] ) {
$attr['class'] .= ' awb-stars-rating-no-text';
}
if ( $this->args['class'] ) {
$attr['class'] .= ' ' . $this->args['class'];
}
if ( $this->args['id'] ) {
$attr['id'] = $this->args['id'];
}
if ( $this->args['animation_type'] ) {
$attr = Fusion_Builder_Animation_Helper::add_animation_attributes( $this->args, $attr );
}
// Add aria label for accessibility.
$rating = $this->get_rating();
$maximum_rating = $this->args['maximum_rating'];
if ( $rating > $maximum_rating ) {
$rating = $maximum_rating;
}
if ( '0decimals' === $this->args['rating_number_rounding'] ) {
$rating_label = intval( round( $rating, 0 ) );
} elseif ( '1decimal' === $this->args['rating_number_rounding'] ) {
$rating_label = number_format_i18n( $rating, 1 );
} else {
$rating_label = number_format_i18n( $rating, 2 );
}
/* translators: %1$s: The average rating, %1$s: The maximum rating. */
$aria_label = sprintf( esc_attr__( 'Rating: %1$s out of %2$s', 'fusion-builder' ), $rating_label, $maximum_rating );
$attr['aria-label'] = $aria_label;
return $attr;
}
/**
* Get the attributes of the icon tag.
*
* @since 3.5
* @param int $current_icon_num The number of the current icon.
* @return array
*/
public function icon_attr( $current_icon_num ) {
$attr = [
'class' => fusion_font_awesome_name_handler( $this->args['icon'] ),
];
$rating = $this->get_rating();
if ( '0decimals' === $this->args['rating_number_rounding'] && 'yes' === $this->args['display_rating_text'] ) {
$rating = intval( round( $rating, 0 ) );
}
$is_perfect_round_average = ( intval( $rating ) === $rating );
$icon_is_partially_filled = ( ( intval( $rating ) + 1 ) === $current_icon_num );
if ( $current_icon_num <= $rating ) {
$attr['class'] .= ' awb-stars-rating-filled-icon';
} elseif ( ! $is_perfect_round_average && $icon_is_partially_filled ) {
$attr['class'] .= ' awb-stars-rating-partial-icon-wrapper';
} else {
$attr['class'] .= ' awb-stars-rating-empty-icon';
}
return $attr;
}
/**
* Get the attributes of the partial filled icon tag.
*
* @since 3.5
* @return array
*/
public function partial_filled_icon_attr() {
$attr = [
'class' => fusion_font_awesome_name_handler( $this->args['icon'] ) . ' awb-stars-rating-partial-icon',
];
$rating = $this->get_rating();
$decimals = $rating - intval( $rating );
$width_percent = intval( $decimals * 100 ) . '%';
$attr['style'] = 'width:' . $width_percent . ';';
return $attr;
}
/**
* Get inline style.
*
* @since 3.9
* @return string
*/
public function get_inline_style() {
$css_vars_options = [
'icon_font_size',
'active_color',
'inactive_color',
'icons_distance',
'alignment',
'margin_top',
'margin_right',
'margin_bottom',
'margin_left',
];
if ( 'yes' === $this->args['display_rating_text'] ) {
$css_vars_options[] = 'text_font_size';
$css_vars_options[] = 'text_font_color';
$css_vars_options[] = 'icons_text_distance';
}
return $this->get_css_vars_for_options( $css_vars_options );
}
/**
* Get the average rating number.
*
* @since 3.5
* @param bool $number_conversion Flag to have rating converted to int|float.
* @return int|float|string
*/
public function get_rating( $number_conversion = true ) {
$avg = $this->args['rating'];
// Let the users use ',' as decimal separator.
if ( is_string( $avg ) ) {
$avg = str_replace( [ ',', ' ' ], [ '.', '' ], $avg );
}
if ( ! is_numeric( $avg ) ) {
$avg = preg_replace( '/[^.|0-9]/', '', $avg );
}
if ( ! $number_conversion ) {
return $avg;
}
if ( is_numeric( $avg ) ) {
$avg = + $avg;
} else {
$avg = 0;
}
return $avg;
}
/**
* Get the number of decimals to round the rating.
*
* @since 3.7
* @param int|string $rating The rating to calculate how much decimals to round.
* @return int
*/
public function get_number_to_round( $rating ) {
if ( '0decimals' === $this->args['rating_number_rounding'] ) {
return 0;
} elseif ( '1decimal' === $this->args['rating_number_rounding'] ) {
return 1;
} elseif ( '2decimals' === $this->args['rating_number_rounding'] ) {
return 2;
}
// 'rating_number_rounding' is set to 'auto' if here.
$number_of_decimals = strlen( substr( strrchr( (string) floatval( $rating ), '.' ), 1 ) );
if ( 0 === $number_of_decimals ) {
return 0;
} elseif ( 1 === $number_of_decimals ) {
return 1;
} else {
return 2;
}
}
/**
* Gets the default values.
*
* @since 3.5
* @return array
*/
public static function get_element_defaults() {
$fusion_settings = awb_get_fusion_settings();
return [
'maximum_rating' => '5',
'rating' => '3',
'display_empty_rating' => 'show',
'hide_on_mobile' => fusion_builder_default_visibility( 'string' ),
'class' => '',
'id' => '',
'icon' => 'fa-star fas',
'active_color' => '',
'inactive_color' => '',
'icons_distance' => '',
'display_rating_text' => 'yes',
'alignment' => '',
'icon_font_size' => '',
'text_font_size' => '',
'text_font_color' => '',
'rating_number_rounding' => 'auto',
'icons_text_distance' => '',
'margin_top' => '',
'margin_right' => '',
'margin_bottom' => '',
'margin_left' => '',
'animation_direction' => 'left',
'animation_offset' => $fusion_settings->get( 'animation_offset' ),
'animation_speed' => '',
'animation_delay' => '',
'animation_type' => '',
'animation_color' => '',
];
}
/**
* Load base CSS.
*
* @since 3.5
*/
public function add_css_files() {
FusionBuilder()->add_element_css( FUSION_BUILDER_PLUGIN_DIR . 'assets/css/shortcodes/star-rating.min.css' );
}
}
new FusionSC_Star_Rating();
}
}
/**
* Map shortcode to Avada Builder.
*
* @since 3.5
*/
function fusion_element_star_rating() {
fusion_builder_map(
fusion_builder_frontend_data(
'FusionSC_Star_Rating',
[
'name' => esc_attr__( 'Star Rating', 'fusion-builder' ),
'shortcode' => 'fusion_star_rating',
'icon' => 'fusiona-af-rating',
'params' => [
[
'type' => 'range',
'heading' => esc_attr__( 'Maximum Rating', 'fusion-builder' ),
'description' => esc_html__( 'Select the maximum possible rating.', 'fusion-builder' ),
'param_name' => 'maximum_rating',
'value' => '5',
'min' => '1',
'max' => '10',
'step' => '1',
],
[
'type' => 'textfield',
'heading' => esc_attr__( 'Rating', 'fusion-builder' ),
'description' => esc_html__( 'Enter the rating.', 'fusion-builder' ),
'param_name' => 'rating',
'dynamic_data' => true,
'value' => '3',
],
[
'type' => 'radio_button_set',
'heading' => esc_attr__( 'Display Empty Rating', 'fusion-builder' ),
'description' => esc_attr__( 'Select whether to display the rating if no rating is present (eg. 0/5), or to completely hide it. Note: In the live editor the element will be always be displayed.', 'fusion-builder' ),
'param_name' => 'display_empty_rating',
'default' => 'show',
'value' => [
'show' => esc_html__( 'Show', 'fusion-builder' ),
'hide' => esc_html__( 'Hide', 'fusion-builder' ),
],
],
[
'type' => 'checkbox_button_set',
'heading' => esc_attr__( 'Element Visibility', 'fusion-builder' ),
'param_name' => 'hide_on_mobile',
'value' => fusion_builder_visibility_options( 'full' ),
'default' => fusion_builder_default_visibility( 'array' ),
'description' => esc_html__( 'Choose to show or hide the element on small, medium or large screens. You can choose more than one at a time.', 'fusion-builder' ),
],
[
'type' => 'textfield',
'heading' => esc_attr__( 'CSS Class', 'fusion-builder' ),
'param_name' => 'class',
'value' => '',
'description' => esc_html__( 'Add a class to the wrapping HTML element.', 'fusion-builder' ),
],
[
'type' => 'textfield',
'heading' => esc_attr__( 'CSS ID', 'fusion-builder' ),
'param_name' => 'id',
'value' => '',
'description' => esc_html__( 'Add an ID to the wrapping HTML element.', 'fusion-builder' ),
],
[
'type' => 'iconpicker',
'heading' => esc_attr__( 'Icon', 'fusion-builder' ),
'param_name' => 'icon',
'value' => 'fa-star fas',
'description' => esc_html__( 'Click an icon to select, click again to deselect.', 'fusion-builder' ),
'group' => esc_attr__( 'Design', 'fusion-builder' ),
],
[
'type' => 'textfield',
'heading' => esc_attr__( 'Icon Size', 'fusion-builder' ),
'description' => esc_html__( 'Enter value including any valid CSS unit, ex: 20px.', 'fusion-builder' ),
'param_name' => 'icon_font_size',
'value' => '',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
],
[
'type' => 'colorpickeralpha',
'heading' => esc_attr__( 'Filled Icon Color', 'fusion-builder' ),
'description' => esc_html__( 'Select the color of the filled icons.', 'fusion-builder' ),
'param_name' => 'active_color',
'value' => '',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
],
[
'type' => 'colorpickeralpha',
'heading' => esc_attr__( 'Empty Icon Color', 'fusion-builder' ),
'description' => esc_html__( 'Select the color of the empty icons.', 'fusion-builder' ),
'param_name' => 'inactive_color',
'value' => '',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
],
[
'type' => 'textfield',
'heading' => esc_attr__( 'Icon Spacing', 'fusion-builder' ),
'description' => esc_html__( 'Control the spacing between the icons. Enter value including any valid CSS unit, ex: 15px.', 'fusion-builder' ),
'param_name' => 'icons_distance',
'value' => '',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
],
[
'type' => 'radio_button_set',
'heading' => esc_attr__( 'Display Rating Text', 'fusion-builder' ),
'description' => esc_attr__( 'Select whether or not to display the rating text next to the icons.', 'fusion-builder' ),
'param_name' => 'display_rating_text',
'default' => 'yes',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
'value' => [
'yes' => esc_html__( 'Yes', 'fusion-builder' ),
'no' => esc_html__( 'No', 'fusion-builder' ),
],
],
[
'type' => 'textfield',
'heading' => esc_attr__( 'Rating Font Size', 'fusion-builder' ),
'description' => esc_html__( 'Control the rating font size. Enter value including any valid CSS unit, ex: 20px.', 'fusion-builder' ),
'param_name' => 'text_font_size',
'value' => '',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
'dependency' => [
[
'element' => 'display_rating_text',
'value' => 'yes',
'operator' => '==',
],
],
],
[
'type' => 'colorpickeralpha',
'heading' => esc_attr__( 'Rating Text Color', 'fusion-builder' ),
'description' => esc_html__( 'Select the color of the rating text.', 'fusion-builder' ),
'param_name' => 'text_font_color',
'value' => '',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
'dependency' => [
[
'element' => 'display_rating_text',
'value' => 'yes',
'operator' => '==',
],
],
],
[
'type' => 'radio_button_set',
'heading' => esc_attr__( 'Rating Number Rounding', 'fusion-builder' ),
'description' => esc_html__( "Select how the rating number should be rounded. The 'auto' option will round to 2 decimals if needed or display the number until the left-most significant '0' decimal(Eg: instead of 4.70 will display 4.7).", 'fusion-builder' ),
'param_name' => 'rating_number_rounding',
'default' => 'auto',
'value' => [
'auto' => esc_html__( 'Auto', 'fusion-builder' ),
'0decimals' => esc_html__( 'No Decimals', 'fusion-builder' ),
'1decimal' => esc_html__( '1 Decimal', 'fusion-builder' ),
'2decimals' => esc_html__( '2 Decimals', 'fusion-builder' ),
],
'group' => esc_attr__( 'Design', 'fusion-builder' ),
'dependency' => [
[
'element' => 'display_rating_text',
'value' => 'yes',
'operator' => '==',
],
],
],
[
'type' => 'textfield',
'heading' => esc_attr__( 'Icon/Text Spacing', 'fusion-builder' ),
'description' => esc_html__( 'Control the spacing between the icons and the rating text. Enter value including any valid CSS unit, ex: 15px.', 'fusion-builder' ),
'param_name' => 'icons_text_distance',
'value' => '',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
'dependency' => [
[
'element' => 'display_rating_text',
'value' => 'yes',
'operator' => '==',
],
],
],
[
'type' => 'radio_button_set',
'heading' => esc_attr__( 'Alignment', 'fusion-builder' ),
'description' => esc_html__( 'Select the alignment of the icons and the text.', 'fusion-builder' ),
'param_name' => 'alignment',
'default' => '',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
'value' => [
'' => esc_attr__( 'Text Flow', 'fusion-builder' ),
'flex-start' => esc_attr__( 'Left', 'fusion-builder' ),
'center' => esc_attr__( 'Center', 'fusion-builder' ),
'flex-end' => esc_attr__( 'Right', 'fusion-builder' ),
],
],
'fusion_margin_placeholder' => [
'param_name' => 'margin',
'group' => esc_attr__( 'Design', 'fusion-builder' ),
'value' => [
'margin_top' => '',
'margin_right' => '',
'margin_bottom' => '',
'margin_left' => '',
],
],
'fusion_animation_placeholder' => [
'preview_selector' => '.awb-stars-rating',
],
],
]
)
);
}
add_action( 'fusion_builder_before_init', 'fusion_element_star_rating' );