PluginProbe
Elementor Website Builder – more than just a page builder / 3.1.0-dev2
Elementor Website Builder – more than just a page builder v3.1.0-dev2
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / includes / widgets / star-rating.php

star-rating.php in Elementor Website Builder – more than just a page builder 3.1.0-dev2, at includes/widgets/star-rating.php

476 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
9 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
10
11 /**
12 * Elementor star rating widget.
13 *
14 * Elementor widget that displays star rating.
15 *
16 * @since 2.3.0
17 */
18 class Widget_Star_Rating extends Widget_Base {
19
20 /**
21 * Get widget name.
22 *
23 * Retrieve star rating widget name.
24 *
25 * @since 2.3.0
26 * @access public
27 *
28 * @return string Widget name.
29 */
30 public function get_name() {
31 return 'star-rating';
32 }
33
34 /**
35 * Get widget title.
36 *
37 * Retrieve star rating widget title.
38 *
39 * @since 2.3.0
40 * @access public
41 *
42 * @return string Widget title.
43 */
44 public function get_title() {
45 return __( 'Star Rating', 'elementor' );
46 }
47
48 /**
49 * Get widget icon.
50 *
51 * Retrieve star rating widget icon.
52 *
53 * @since 2.3.0
54 * @access public
55 *
56 * @return string Widget icon.
57 */
58 public function get_icon() {
59 return 'eicon-rating';
60 }
61
62 /**
63 * Get widget keywords.
64 *
65 * Retrieve the list of keywords the widget belongs to.
66 *
67 * @since 2.3.0
68 * @access public
69 *
70 * @return array Widget keywords.
71 */
72 public function get_keywords() {
73 return [ 'star', 'rating', 'rate', 'review' ];
74 }
75
76 /**
77 * Register star rating widget controls.
78 *
79 * Adds different input fields to allow the user to change and customize the widget settings.
80 *
81 * @since 2.3.0
82 * @access protected
83 */
84 protected function _register_controls() {
85 $this->start_controls_section(
86 'section_rating',
87 [
88 'label' => __( 'Rating', 'elementor' ),
89 ]
90 );
91
92 $this->add_control(
93 'rating_scale',
94 [
95 'label' => __( 'Rating Scale', 'elementor' ),
96 'type' => Controls_Manager::SELECT,
97 'options' => [
98 '5' => '0-5',
99 '10' => '0-10',
100 ],
101 'default' => '5',
102 ]
103 );
104
105 $this->add_control(
106 'rating',
107 [
108 'label' => __( 'Rating', 'elementor' ),
109 'type' => Controls_Manager::NUMBER,
110 'min' => 0,
111 'max' => 10,
112 'step' => 0.1,
113 'default' => 5,
114 'dynamic' => [
115 'active' => true,
116 ],
117 ]
118 );
119
120 $this->add_control(
121 'star_style',
122 [
123 'label' => __( 'Icon', 'elementor' ),
124 'type' => Controls_Manager::SELECT,
125 'options' => [
126 'star_fontawesome' => 'Font Awesome',
127 'star_unicode' => 'Unicode',
128 ],
129 'default' => 'star_fontawesome',
130 'render_type' => 'template',
131 'prefix_class' => 'elementor--star-style-',
132 'separator' => 'before',
133 ]
134 );
135
136 $this->add_control(
137 'unmarked_star_style',
138 [
139 'label' => __( 'Unmarked Style', 'elementor' ),
140 'type' => Controls_Manager::CHOOSE,
141 'options' => [
142 'solid' => [
143 'title' => __( 'Solid', 'elementor' ),
144 'icon' => 'eicon-star',
145 ],
146 'outline' => [
147 'title' => __( 'Outline', 'elementor' ),
148 'icon' => 'eicon-star-o',
149 ],
150 ],
151 'default' => 'solid',
152 ]
153 );
154
155 $this->add_control(
156 'title',
157 [
158 'label' => __( 'Title', 'elementor' ),
159 'type' => Controls_Manager::TEXT,
160 'separator' => 'before',
161 'dynamic' => [
162 'active' => true,
163 ],
164 ]
165 );
166
167 $this->add_responsive_control(
168 'align',
169 [
170 'label' => __( 'Alignment', 'elementor' ),
171 'type' => Controls_Manager::CHOOSE,
172 'options' => [
173 'left' => [
174 'title' => __( 'Left', 'elementor' ),
175 'icon' => 'eicon-text-align-left',
176 ],
177 'center' => [
178 'title' => __( 'Center', 'elementor' ),
179 'icon' => 'eicon-text-align-center',
180 ],
181 'right' => [
182 'title' => __( 'Right', 'elementor' ),
183 'icon' => 'eicon-text-align-right',
184 ],
185 'justify' => [
186 'title' => __( 'Justified', 'elementor' ),
187 'icon' => 'eicon-text-align-justify',
188 ],
189 ],
190 'prefix_class' => 'elementor-star-rating%s--align-',
191 'selectors' => [
192 '{{WRAPPER}}' => 'text-align: {{VALUE}}',
193 ],
194 ]
195 );
196
197 $this->end_controls_section();
198
199 $this->start_controls_section(
200 'section_title_style',
201 [
202 'label' => __( 'Title', 'elementor' ),
203 'tab' => Controls_Manager::TAB_STYLE,
204 'condition' => [
205 'title!' => '',
206 ],
207 ]
208 );
209
210 $this->add_control(
211 'title_color',
212 [
213 'label' => __( 'Text Color', 'elementor' ),
214 'type' => Controls_Manager::COLOR,
215 'global' => [
216 'default' => Global_Colors::COLOR_TEXT,
217 ],
218 'selectors' => [
219 '{{WRAPPER}} .elementor-star-rating__title' => 'color: {{VALUE}}',
220 ],
221 ]
222 );
223
224 $this->add_group_control(
225 Group_Control_Typography::get_type(),
226 [
227 'name' => 'title_typography',
228 'selector' => '{{WRAPPER}} .elementor-star-rating__title',
229 'global' => [
230 'default' => Global_Typography::TYPOGRAPHY_TEXT,
231 ],
232 ]
233 );
234
235 $this->add_responsive_control(
236 'title_gap',
237 [
238 'label' => __( 'Gap', 'elementor' ),
239 'type' => Controls_Manager::SLIDER,
240 'range' => [
241 'px' => [
242 'min' => 0,
243 'max' => 50,
244 ],
245 ],
246 'selectors' => [
247 'body:not(.rtl) {{WRAPPER}}:not(.elementor-star-rating--align-justify) .elementor-star-rating__title' => 'margin-right: {{SIZE}}{{UNIT}}',
248 'body.rtl {{WRAPPER}}:not(.elementor-star-rating--align-justify) .elementor-star-rating__title' => 'margin-left: {{SIZE}}{{UNIT}}',
249 ],
250 ]
251 );
252
253 $this->end_controls_section();
254
255 $this->start_controls_section(
256 'section_stars_style',
257 [
258 'label' => __( 'Stars', 'elementor' ),
259 'tab' => Controls_Manager::TAB_STYLE,
260 ]
261 );
262
263 $this->add_responsive_control(
264 'icon_size',
265 [
266 'label' => __( 'Size', 'elementor' ),
267 'type' => Controls_Manager::SLIDER,
268 'range' => [
269 'px' => [
270 'min' => 0,
271 'max' => 100,
272 ],
273 ],
274 'selectors' => [
275 '{{WRAPPER}} .elementor-star-rating' => 'font-size: {{SIZE}}{{UNIT}}',
276 ],
277 ]
278 );
279
280 $this->add_responsive_control(
281 'icon_space',
282 [
283 'label' => __( 'Spacing', 'elementor' ),
284 'type' => Controls_Manager::SLIDER,
285 'range' => [
286 'px' => [
287 'min' => 0,
288 'max' => 50,
289 ],
290 ],
291 'selectors' => [
292 'body:not(.rtl) {{WRAPPER}} .elementor-star-rating i:not(:last-of-type)' => 'margin-right: {{SIZE}}{{UNIT}}',
293 'body.rtl {{WRAPPER}} .elementor-star-rating i:not(:last-of-type)' => 'margin-left: {{SIZE}}{{UNIT}}',
294 ],
295 ]
296 );
297
298 $this->add_control(
299 'stars_color',
300 [
301 'label' => __( 'Color', 'elementor' ),
302 'type' => Controls_Manager::COLOR,
303 'selectors' => [
304 '{{WRAPPER}} .elementor-star-rating i:before' => 'color: {{VALUE}}',
305 ],
306 'separator' => 'before',
307 ]
308 );
309
310 $this->add_control(
311 'stars_unmarked_color',
312 [
313 'label' => __( 'Unmarked Color', 'elementor' ),
314 'type' => Controls_Manager::COLOR,
315 'selectors' => [
316 '{{WRAPPER}} .elementor-star-rating i' => 'color: {{VALUE}}',
317 ],
318 ]
319 );
320
321 $this->end_controls_section();
322 }
323
324 /**
325 * @since 2.3.0
326 * @access protected
327 */
328 protected function get_rating() {
329 $settings = $this->get_settings_for_display();
330 $rating_scale = (int) $settings['rating_scale'];
331 $rating = (float) $settings['rating'] > $rating_scale ? $rating_scale : $settings['rating'];
332
333 return [ $rating, $rating_scale ];
334 }
335
336 /**
337 * Print the actual stars and calculate their filling.
338 *
339 * Rating type is float to allow stars-count to be a fraction.
340 * Floored-rating type is int, to represent the rounded-down stars count.
341 * In the `for` loop, the index type is float to allow comparing with the rating value.
342 *
343 * @since 2.3.0
344 * @access protected
345 */
346 protected function render_stars( $icon ) {
347 $rating_data = $this->get_rating();
348 $rating = (float) $rating_data[0];
349 $floored_rating = floor( $rating );
350 $stars_html = '';
351
352 for ( $stars = 1.0; $stars <= $rating_data[1]; $stars++ ) {
353 if ( $stars <= $floored_rating ) {
354 $stars_html .= '<i class="elementor-star-full">' . $icon . '</i>';
355 } elseif ( $floored_rating + 1 === $stars && $rating !== $floored_rating ) {
356 $stars_html .= '<i class="elementor-star-' . ( $rating - $floored_rating ) * 10 . '">' . $icon . '</i>';
357 } else {
358 $stars_html .= '<i class="elementor-star-empty">' . $icon . '</i>';
359 }
360 }
361
362 return $stars_html;
363 }
364
365 /**
366 * @since 2.3.0
367 * @access protected
368 */
369 protected function render() {
370 $settings = $this->get_settings_for_display();
371 $rating_data = $this->get_rating();
372 $textual_rating = $rating_data[0] . '/' . $rating_data[1];
373 $icon = '&#xE934;';
374
375 if ( 'star_fontawesome' === $settings['star_style'] ) {
376 if ( 'outline' === $settings['unmarked_star_style'] ) {
377 $icon = '&#xE933;';
378 }
379 } elseif ( 'star_unicode' === $settings['star_style'] ) {
380 $icon = '&#9733;';
381
382 if ( 'outline' === $settings['unmarked_star_style'] ) {
383 $icon = '&#9734;';
384 }
385 }
386
387 $this->add_render_attribute( 'icon_wrapper', [
388 'class' => 'elementor-star-rating',
389 'title' => $textual_rating,
390 'itemtype' => 'http://schema.org/Rating',
391 'itemscope' => '',
392 'itemprop' => 'reviewRating',
393 ] );
394
395 $schema_rating = '<span itemprop="ratingValue" class="elementor-screen-only">' . $textual_rating . '</span>';
396 $stars_element = '<div ' . $this->get_render_attribute_string( 'icon_wrapper' ) . '>' . $this->render_stars( $icon ) . ' ' . $schema_rating . '</div>';
397 ?>
398
399 <div class="elementor-star-rating__wrapper">
400 <?php if ( ! Utils::is_empty( $settings['title'] ) ) : ?>
401 <div class="elementor-star-rating__title"><?php echo $settings['title']; ?></div>
402 <?php endif; ?>
403 <?php echo $stars_element; ?>
404 </div>
405 <?php
406 }
407
408 /**
409 * @since 2.9.0
410 * @access protected
411 */
412 protected function content_template() {
413 ?>
414 <#
415 var getRating = function() {
416 var ratingScale = parseInt( settings.rating_scale, 10 ),
417 rating = settings.rating > ratingScale ? ratingScale : settings.rating;
418
419 return [ rating, ratingScale ];
420 },
421 ratingData = getRating(),
422 rating = ratingData[0],
423 textualRating = ratingData[0] + '/' + ratingData[1],
424 renderStars = function( icon ) {
425 var starsHtml = '',
426 flooredRating = Math.floor( rating );
427
428 for ( var stars = 1; stars <= ratingData[1]; stars++ ) {
429 if ( stars <= flooredRating ) {
430 starsHtml += '<i class="elementor-star-full">' + icon + '</i>';
431 } else if ( flooredRating + 1 === stars && rating !== flooredRating ) {
432 starsHtml += '<i class="elementor-star-' + ( rating - flooredRating ).toFixed( 1 ) * 10 + '">' + icon + '</i>';
433 } else {
434 starsHtml += '<i class="elementor-star-empty">' + icon + '</i>';
435 }
436 }
437
438 return starsHtml;
439 },
440 icon = '&#xE934;';
441
442 if ( 'star_fontawesome' === settings.star_style ) {
443 if ( 'outline' === settings.unmarked_star_style ) {
444 icon = '&#xE933;';
445 }
446 } else if ( 'star_unicode' === settings.star_style ) {
447 icon = '&#9733;';
448
449 if ( 'outline' === settings.unmarked_star_style ) {
450 icon = '&#9734;';
451 }
452 }
453
454 view.addRenderAttribute( 'iconWrapper', 'class', 'elementor-star-rating' );
455 view.addRenderAttribute( 'iconWrapper', 'itemtype', 'http://schema.org/Rating' );
456 view.addRenderAttribute( 'iconWrapper', 'title', textualRating );
457 view.addRenderAttribute( 'iconWrapper', 'itemscope', '' );
458 view.addRenderAttribute( 'iconWrapper', 'itemprop', 'reviewRating' );
459
460 var stars = renderStars( icon );
461 #>
462
463 <div class="elementor-star-rating__wrapper">
464 <# if ( ! _.isEmpty( settings.title ) ) { #>
465 <div class="elementor-star-rating__title">{{ settings.title }}</div>
466 <# } #>
467 <div {{{ view.getRenderAttributeString( 'iconWrapper' ) }}} >
468 {{{ stars }}}
469 <span itemprop="ratingValue" class="elementor-screen-only">{{ textualRating }}</span>
470 </div>
471 </div>
472
473 <?php
474 }
475 }
476