| 1 |
<?php |
| 2 |
/** |
| 3 |
* Easy Quotes Stars |
| 4 |
* |
| 5 |
* Handles rendering star ratings with SVG graphics, including partial stars. |
| 6 |
* Uses a static tracking mechanism to ensure SVG definitions are only included once per page. |
| 7 |
* |
| 8 |
* @package Easy_Quotes |
| 9 |
*/ |
| 10 |
|
| 11 |
// Exit if accessed directly. |
| 12 |
if (!defined('ABSPATH')) { |
| 13 |
exit; |
| 14 |
} |
| 15 |
|
| 16 |
/** |
| 17 |
* Class Easy_Quotes_Stars |
| 18 |
* |
| 19 |
* Renders star ratings using SVG for optimal visual quality at any size. |
| 20 |
* Features support for partial stars and consistent styling across the site. |
| 21 |
* |
| 22 |
*/ |
| 23 |
class Easy_Quotes_Stars |
| 24 |
{ |
| 25 |
/** |
| 26 |
* Tracks whether SVG definitions have been output to the page. |
| 27 |
* |
| 28 |
* @var boolean |
| 29 |
*/ |
| 30 |
private static $svg_defs_rendered = false; |
| 31 |
|
| 32 |
/** |
| 33 |
* Generates SVG definitions for stars and gradients. |
| 34 |
* |
| 35 |
* These definitions are used by all star instances and only need to be |
| 36 |
* included once per page. They define the star shape and various gradient |
| 37 |
* patterns used for partial star rendering. |
| 38 |
* |
| 39 |
* @return string SVG definitions markup |
| 40 |
*/ |
| 41 |
public static function get_star_svg_definitions() { |
| 42 |
ob_start(); |
| 43 |
?> |
| 44 |
<svg style="position: absolute; height: 0; width: 0;" aria-hidden="true"> |
| 45 |
<defs> |
| 46 |
<polygon |
| 47 |
id="star" |
| 48 |
points="0,36.3 38.2,36.3 50,0 61.8,36.3 100,36.3 69.1,58.8 80.9,95.1 50,72.7 19.1,95.1 30.9,58.8" |
| 49 |
stroke="rgb(221,168,33)" |
| 50 |
stroke-width="8" |
| 51 |
clip-path="url(#strokeInside)" |
| 52 |
></polygon> |
| 53 |
<clipPath id="strokeInside"> |
| 54 |
<use xlink:href="#star"></use> |
| 55 |
</clipPath> |
| 56 |
<linearGradient id="partialFill" x1="0%" y1="0%" x2="100%" y2="0%"> |
| 57 |
<stop offset="0%" style="stop-color:rgb(229,187,79); stop-opacity:1"></stop> |
| 58 |
<stop offset="100%" style="stop-color:rgb(255,255,255); stop-opacity:1"></stop> |
| 59 |
</linearGradient> |
| 60 |
<linearGradient id="partialFill-1" xlink:href="#partialFill" x1="26%" x2="26.1%"></linearGradient> |
| 61 |
<linearGradient id="partialFill-2" xlink:href="#partialFill" x1="32%" x2="32.1%"></linearGradient> |
| 62 |
<linearGradient id="partialFill-3" xlink:href="#partialFill" x1="38%" x2="38.1%"></linearGradient> |
| 63 |
<linearGradient id="partialFill-4" xlink:href="#partialFill" x1="44%" x2="44.1%"></linearGradient> |
| 64 |
<linearGradient id="partialFill-5" xlink:href="#partialFill" x1="50%" x2="50.1%"></linearGradient> |
| 65 |
<linearGradient id="partialFill-6" xlink:href="#partialFill" x1="56%" x2="56.1%"></linearGradient> |
| 66 |
<linearGradient id="partialFill-7" xlink:href="#partialFill" x1="62%" x2="62.1%"></linearGradient> |
| 67 |
<linearGradient id="partialFill-8" xlink:href="#partialFill" x1="68%" x2="68.1%"></linearGradient> |
| 68 |
<linearGradient id="partialFill-9" xlink:href="#partialFill" x1="74%" x2="74.1%"></linearGradient> |
| 69 |
</defs> |
| 70 |
</svg> |
| 71 |
<?php |
| 72 |
return ob_get_clean(); |
| 73 |
} |
| 74 |
|
| 75 |
/** |
| 76 |
* Generates a single star SVG element with the appropriate fill. |
| 77 |
* |
| 78 |
* Determines the proper fill color or gradient based on the star's position |
| 79 |
* relative to the given rating value. |
| 80 |
* |
| 81 |
* @param integer $index Position of this star (0-4) |
| 82 |
* @param float $rating Rating value (0-5) |
| 83 |
* @return string SVG markup for a single star |
| 84 |
*/ |
| 85 |
private static function get_star($index, $rating) |
| 86 |
{ |
| 87 |
// Determine the appropriate fill for this star |
| 88 |
$fill = ""; |
| 89 |
|
| 90 |
if ($index < floor($rating)) { |
| 91 |
// Full star - filled with solid color |
| 92 |
$fill = "rgb(229,187,79)"; |
| 93 |
} else if (($index == floor($rating)) && ($rating - floor($rating) > 0)) { |
| 94 |
// Partial star - use appropriate gradient based on decimal portion |
| 95 |
$fraction = round(($rating - floor($rating)) * 10, 0); |
| 96 |
$fill = "url(#partialFill-" . $fraction . ")"; |
| 97 |
} else { |
| 98 |
// Empty star - white fill |
| 99 |
$fill = "rgb(255,255,255)"; |
| 100 |
} |
| 101 |
|
| 102 |
// Return the star SVG use element with proper positioning and fill |
| 103 |
return ' |
| 104 |
<use href="#star" |
| 105 |
class="star" |
| 106 |
x="' . esc_attr($index * 100) . '" |
| 107 |
fill="' . esc_attr($fill) . '" |
| 108 |
></use>'; |
| 109 |
} |
| 110 |
|
| 111 |
/** |
| 112 |
* Renders a complete star rating display. |
| 113 |
* |
| 114 |
* Generates SVG markup for a 5-star rating display. On first call per page load, |
| 115 |
* also includes the required SVG definitions automatically. |
| 116 |
* |
| 117 |
* @param float $rating Rating value between 0-5 |
| 118 |
* @return string Complete SVG markup for star rating display |
| 119 |
*/ |
| 120 |
public static function get_stars($rating) |
| 121 |
{ |
| 122 |
// Include definitions if this is the first time stars are rendered on this page |
| 123 |
$defs = ''; |
| 124 |
if (!self::$svg_defs_rendered) { |
| 125 |
$defs = self::get_star_svg_definitions(); |
| 126 |
self::$svg_defs_rendered = true; |
| 127 |
} |
| 128 |
|
| 129 |
// Ensure rating is within valid range (0-5) |
| 130 |
$rating = max(0.0, min(5.0, $rating)); |
| 131 |
|
| 132 |
// Generate all 5 stars |
| 133 |
$stars = ""; |
| 134 |
for ($i = 0; $i < 5; $i++) { |
| 135 |
$stars .= self::get_star($i, $rating); |
| 136 |
} |
| 137 |
|
| 138 |
// Return complete SVG with optional definitions - exactly matching the editor version |
| 139 |
return $defs . ' |
| 140 |
<svg class="la-rating-stars" viewBox="0 0 500 100"> |
| 141 |
' . $stars . ' |
| 142 |
Sorry, your browser does not support inline SVG. |
| 143 |
</svg>'; |
| 144 |
} |
| 145 |
} |
| 146 |
|