PluginProbe
Elementor Website Builder – more than just a page builder / 3.24.4
Elementor Website Builder – more than just a page builder v3.24.4
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 / counter.php

counter.php in Elementor Website Builder – more than just a page builder 3.24.4, at includes/widgets/counter.php

710 lines 17.2 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 counter widget.
13 *
14 * Elementor widget that displays stats and numbers in an escalating manner.
15 *
16 * @since 1.0.0
17 */
18 class Widget_Counter extends Widget_Base {
19
20 /**
21 * Get widget name.
22 *
23 * Retrieve counter widget name.
24 *
25 * @since 1.0.0
26 * @access public
27 *
28 * @return string Widget name.
29 */
30 public function get_name() {
31 return 'counter';
32 }
33
34 /**
35 * Get widget title.
36 *
37 * Retrieve counter widget title.
38 *
39 * @since 1.0.0
40 * @access public
41 *
42 * @return string Widget title.
43 */
44 public function get_title() {
45 return esc_html__( 'Counter', 'elementor' );
46 }
47
48 /**
49 * Get widget icon.
50 *
51 * Retrieve counter widget icon.
52 *
53 * @since 1.0.0
54 * @access public
55 *
56 * @return string Widget icon.
57 */
58 public function get_icon() {
59 return 'eicon-counter';
60 }
61
62 /**
63 * Retrieve the list of scripts the counter widget depended on.
64 *
65 * Used to set scripts dependencies required to run the widget.
66 *
67 * @since 1.3.0
68 * @access public
69 *
70 * @return array Widget scripts dependencies.
71 */
72 public function get_script_depends() {
73 return [ 'jquery-numerator' ];
74 }
75
76 /**
77 * Get widget keywords.
78 *
79 * Retrieve the list of keywords the widget belongs to.
80 *
81 * @since 2.1.0
82 * @access public
83 *
84 * @return array Widget keywords.
85 */
86 public function get_keywords() {
87 return [ 'counter' ];
88 }
89
90 protected function is_dynamic_content(): bool {
91 return false;
92 }
93
94 /**
95 * Get style dependencies.
96 *
97 * Retrieve the list of style dependencies the widget requires.
98 *
99 * @since 3.24.0
100 * @access public
101 *
102 * @return array Widget style dependencies.
103 */
104 public function get_style_depends(): array {
105 return [ 'widget-counter' ];
106 }
107
108 /**
109 * Register counter widget controls.
110 *
111 * Adds different input fields to allow the user to change and customize the widget settings.
112 *
113 * @since 3.1.0
114 * @access protected
115 */
116 protected function register_controls() {
117 $start = is_rtl() ? 'right' : 'left';
118 $end = ! is_rtl() ? 'right' : 'left';
119
120 $this->start_controls_section(
121 'section_counter',
122 [
123 'label' => esc_html__( 'Counter', 'elementor' ),
124 ]
125 );
126
127 $this->add_control(
128 'starting_number',
129 [
130 'label' => esc_html__( 'Starting Number', 'elementor' ),
131 'type' => Controls_Manager::NUMBER,
132 'default' => 0,
133 'dynamic' => [
134 'active' => true,
135 ],
136 ]
137 );
138
139 $this->add_control(
140 'ending_number',
141 [
142 'label' => esc_html__( 'Ending Number', 'elementor' ),
143 'type' => Controls_Manager::NUMBER,
144 'default' => 100,
145 'dynamic' => [
146 'active' => true,
147 ],
148 ]
149 );
150
151 $this->add_control(
152 'prefix',
153 [
154 'label' => esc_html__( 'Number Prefix', 'elementor' ),
155 'type' => Controls_Manager::TEXT,
156 'dynamic' => [
157 'active' => true,
158 ],
159 'ai' => [
160 'active' => false,
161 ],
162 'default' => '',
163 ]
164 );
165
166 $this->add_control(
167 'suffix',
168 [
169 'label' => esc_html__( 'Number Suffix', 'elementor' ),
170 'type' => Controls_Manager::TEXT,
171 'dynamic' => [
172 'active' => true,
173 ],
174 'ai' => [
175 'active' => false,
176 ],
177 'default' => '',
178 ]
179 );
180
181 $this->add_control(
182 'duration',
183 [
184 'label' => esc_html__( 'Animation Duration', 'elementor' ) . ' (ms)',
185 'type' => Controls_Manager::NUMBER,
186 'default' => 2000,
187 'min' => 100,
188 'step' => 100,
189 ]
190 );
191
192 $this->add_control(
193 'thousand_separator',
194 [
195 'label' => esc_html__( 'Thousand Separator', 'elementor' ),
196 'type' => Controls_Manager::SWITCHER,
197 'default' => 'yes',
198 'label_on' => esc_html__( 'Show', 'elementor' ),
199 'label_off' => esc_html__( 'Hide', 'elementor' ),
200 ]
201 );
202
203 $this->add_control(
204 'thousand_separator_char',
205 [
206 'label' => esc_html__( 'Separator', 'elementor' ),
207 'type' => Controls_Manager::SELECT,
208 'condition' => [
209 'thousand_separator' => 'yes',
210 ],
211 'options' => [
212 '' => 'Default',
213 '.' => 'Dot',
214 ' ' => 'Space',
215 '_' => 'Underline',
216 "'" => 'Apostrophe',
217 ],
218 ]
219 );
220
221 $this->add_control(
222 'title',
223 [
224 'label' => esc_html__( 'Title', 'elementor' ),
225 'type' => Controls_Manager::TEXT,
226 'label_block' => true,
227 'separator' => 'before',
228 'dynamic' => [
229 'active' => true,
230 ],
231 'default' => esc_html__( 'Cool Number', 'elementor' ),
232 ]
233 );
234
235 $this->add_control(
236 'title_tag',
237 [
238 'label' => esc_html__( 'Title HTML Tag', 'elementor' ),
239 'type' => Controls_Manager::SELECT,
240 'options' => [
241 'h1' => 'H1',
242 'h2' => 'H2',
243 'h3' => 'H3',
244 'h4' => 'H4',
245 'h5' => 'H5',
246 'h6' => 'H6',
247 'div' => 'div',
248 'span' => 'span',
249 'p' => 'p',
250 ],
251 'default' => 'div',
252 'condition' => [
253 'title!' => '',
254 ],
255 ]
256 );
257
258 $this->end_controls_section();
259
260 $this->start_controls_section(
261 'section_counter_style',
262 [
263 'label' => esc_html__( 'Counter', 'elementor' ),
264 'tab' => Controls_Manager::TAB_STYLE,
265 ]
266 );
267
268 $this->add_responsive_control(
269 'title_position',
270 [
271 'label' => esc_html__( 'Title Position', 'elementor' ),
272 'type' => Controls_Manager::CHOOSE,
273 'options' => [
274 'before' => [
275 'title' => esc_html__( 'Before', 'elementor' ),
276 'icon' => 'eicon-v-align-top',
277 ],
278 'after' => [
279 'title' => esc_html__( 'After', 'elementor' ),
280 'icon' => 'eicon-v-align-bottom',
281 ],
282
283 'start' => [
284 'title' => esc_html__( 'Start', 'elementor' ),
285 'icon' => "eicon-h-align-$start",
286 ],
287 'end' => [
288 'title' => esc_html__( 'End', 'elementor' ),
289 'icon' => "eicon-h-align-$end",
290 ],
291 ],
292 'selectors_dictionary' => [
293 'before' => 'flex-direction: column;',
294 'after' => 'flex-direction: column-reverse;',
295 'start' => 'flex-direction: row;',
296 'end' => 'flex-direction: row-reverse;',
297 ],
298 'selectors' => [
299 '{{WRAPPER}} .elementor-counter' => '{{VALUE}}',
300 ],
301 'condition' => [
302 'title!' => '',
303 ],
304 ]
305 );
306
307 $this->add_responsive_control(
308 'title_horizontal_alignment',
309 [
310 'label' => esc_html__( 'Title Horizontal Alignment', 'elementor' ),
311 'type' => Controls_Manager::CHOOSE,
312 'options' => [
313 'start' => [
314 'title' => esc_html__( 'Start', 'elementor' ),
315 'icon' => "eicon-h-align-$start",
316 ],
317 'center' => [
318 'title' => esc_html__( 'Center', 'elementor' ),
319 'icon' => 'eicon-h-align-center',
320 ],
321 'end' => [
322 'title' => esc_html__( 'End', 'elementor' ),
323 'icon' => "eicon-h-align-$end",
324 ],
325 ],
326 'separator' => 'before',
327 'selectors' => [
328 '{{WRAPPER}} .elementor-counter-title' => 'justify-content: {{VALUE}};',
329 ],
330 'condition' => [
331 'title!' => '',
332 ],
333 ]
334 );
335
336 $this->add_responsive_control(
337 'title_vertical_alignment',
338 [
339 'label' => esc_html__( 'Title Vertical Alignment', 'elementor' ),
340 'type' => Controls_Manager::CHOOSE,
341 'options' => [
342 'start' => [
343 'title' => esc_html__( 'Top', 'elementor' ),
344 'icon' => 'eicon-v-align-top',
345 ],
346 'center' => [
347 'title' => esc_html__( 'Middle', 'elementor' ),
348 'icon' => 'eicon-v-align-middle',
349 ],
350 'end' => [
351 'title' => esc_html__( 'Bottom', 'elementor' ),
352 'icon' => 'eicon-v-align-bottom',
353 ],
354 ],
355 'selectors' => [
356 '{{WRAPPER}} .elementor-counter-title' => 'align-items: {{VALUE}};',
357 ],
358 'condition' => [
359 'title!' => '',
360 'title_position' => [ 'start', 'end' ],
361 ],
362 ]
363 );
364
365 $this->add_responsive_control(
366 'title_gap',
367 [
368 'label' => esc_html__( 'Title Gap', 'elementor' ),
369 'type' => Controls_Manager::SLIDER,
370 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
371 'selectors' => [
372 '{{WRAPPER}} .elementor-counter' => 'gap: {{SIZE}}{{UNIT}};',
373 ],
374 'condition' => [
375 'title!' => '',
376 'title_position' => [ '', 'before', 'after' ],
377 ],
378 ]
379 );
380
381 $this->add_responsive_control(
382 'number_position',
383 [
384 'label' => esc_html__( 'Number Position', 'elementor' ),
385 'type' => Controls_Manager::CHOOSE,
386 'options' => [
387 'start' => [
388 'title' => esc_html__( 'Start', 'elementor' ),
389 'icon' => "eicon-h-align-$start",
390 ],
391 'center' => [
392 'title' => esc_html__( 'Center', 'elementor' ),
393 'icon' => 'eicon-h-align-center',
394 ],
395 'end' => [
396 'title' => esc_html__( 'End', 'elementor' ),
397 'icon' => "eicon-h-align-$end",
398 ],
399 'stretch' => [
400 'title' => esc_html__( 'Stretch', 'elementor' ),
401 'icon' => 'eicon-grow',
402 ],
403 ],
404 'selectors_dictionary' => [
405 'start' => 'text-align: {{VALUE}}; --counter-prefix-grow: 0; --counter-suffix-grow: 1; --counter-number-grow: 0;',
406 'center' => 'text-align: {{VALUE}}; --counter-prefix-grow: 1; --counter-suffix-grow: 1; --counter-number-grow: 0;',
407 'end' => 'text-align: {{VALUE}}; --counter-prefix-grow: 1; --counter-suffix-grow: 0; --counter-number-grow: 0;',
408 'stretch' => '--counter-prefix-grow: 0; --counter-suffix-grow: 0; --counter-number-grow: 1;',
409 ],
410 'selectors' => [
411 '{{WRAPPER}} .elementor-counter-number-wrapper' => '{{VALUE}}',
412 ],
413 'separator' => 'before',
414 ]
415 );
416
417 $this->add_responsive_control(
418 'number_alignment',
419 [
420 'label' => esc_html__( 'Number Alignment', 'elementor' ),
421 'type' => Controls_Manager::CHOOSE,
422 'options' => [
423 'start' => [
424 'title' => esc_html__( 'Start', 'elementor' ),
425 'icon' => "eicon-text-align-$start",
426 ],
427 'center' => [
428 'title' => esc_html__( 'Center', 'elementor' ),
429 'icon' => 'eicon-text-align-center',
430 ],
431 'end' => [
432 'title' => esc_html__( 'End', 'elementor' ),
433 'icon' => "eicon-text-align-$end",
434 ],
435 ],
436 'selectors' => [
437 '{{WRAPPER}} .elementor-counter-number' => 'text-align: {{VALUE}};',
438 ],
439 'condition' => [
440 'number_position' => 'stretch',
441 ],
442 ]
443 );
444
445 $this->add_responsive_control(
446 'number_gap',
447 [
448 'label' => esc_html__( 'Number Gap', 'elementor' ),
449 'type' => Controls_Manager::SLIDER,
450 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
451 'selectors' => [
452 '{{WRAPPER}} .elementor-counter-number-wrapper' => 'gap: {{SIZE}}{{UNIT}};',
453 ],
454 'conditions' => [
455 'relation' => 'and',
456 'terms' => [
457 [
458 'name' => 'number_position',
459 'operator' => '!==',
460 'value' => 'stretch',
461 ],
462 [
463 'relation' => 'or',
464 'terms' => [
465 [
466 'name' => 'prefix',
467 'operator' => '!==',
468 'value' => '',
469 ],
470 [
471 'name' => 'suffix',
472 'operator' => '!==',
473 'value' => '',
474 ],
475 ],
476 ],
477 ],
478 ],
479 ]
480 );
481
482 $this->end_controls_section();
483
484 $this->start_controls_section(
485 'section_number',
486 [
487 'label' => esc_html__( 'Number', 'elementor' ),
488 'tab' => Controls_Manager::TAB_STYLE,
489 ]
490 );
491
492 $this->add_control(
493 'number_color',
494 [
495 'label' => esc_html__( 'Text Color', 'elementor' ),
496 'type' => Controls_Manager::COLOR,
497 'global' => [
498 'default' => Global_Colors::COLOR_PRIMARY,
499 ],
500 'selectors' => [
501 '{{WRAPPER}} .elementor-counter-number-wrapper' => 'color: {{VALUE}};',
502 ],
503 ]
504 );
505
506 $this->add_group_control(
507 Group_Control_Typography::get_type(),
508 [
509 'name' => 'typography_number',
510 'global' => [
511 'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
512 ],
513 'selector' => '{{WRAPPER}} .elementor-counter-number-wrapper',
514 ]
515 );
516
517 $this->add_group_control(
518 Group_Control_Text_Stroke::get_type(),
519 [
520 'name' => 'number_stroke',
521 'selector' => '{{WRAPPER}} .elementor-counter-number-wrapper',
522 ]
523 );
524
525 $this->add_group_control(
526 Group_Control_Text_Shadow::get_type(),
527 [
528 'name' => 'number_shadow',
529 'selector' => '{{WRAPPER}} .elementor-counter-number-wrapper',
530 ]
531 );
532
533 $this->end_controls_section();
534
535 $this->start_controls_section(
536 'section_title',
537 [
538 'label' => esc_html__( 'Title', 'elementor' ),
539 'tab' => Controls_Manager::TAB_STYLE,
540 'condition' => [
541 'title!' => '',
542 ],
543 ]
544 );
545
546 $this->add_control(
547 'title_color',
548 [
549 'label' => esc_html__( 'Text Color', 'elementor' ),
550 'type' => Controls_Manager::COLOR,
551 'global' => [
552 'default' => Global_Colors::COLOR_SECONDARY,
553 ],
554 'selectors' => [
555 '{{WRAPPER}} .elementor-counter-title' => 'color: {{VALUE}};',
556 ],
557 'condition' => [
558 'title!' => '',
559 ],
560 ]
561 );
562
563 $this->add_group_control(
564 Group_Control_Typography::get_type(),
565 [
566 'name' => 'typography_title',
567 'global' => [
568 'default' => Global_Typography::TYPOGRAPHY_SECONDARY,
569 ],
570 'selector' => '{{WRAPPER}} .elementor-counter-title',
571 'condition' => [
572 'title!' => '',
573 ],
574 ]
575 );
576
577 $this->add_group_control(
578 Group_Control_Text_Stroke::get_type(),
579 [
580 'name' => 'title_stroke',
581 'selector' => '{{WRAPPER}} .elementor-counter-title',
582 'condition' => [
583 'title!' => '',
584 ],
585 ]
586 );
587
588 $this->add_group_control(
589 Group_Control_Text_Shadow::get_type(),
590 [
591 'name' => 'title_shadow',
592 'selector' => '{{WRAPPER}} .elementor-counter-title',
593 'condition' => [
594 'title!' => '',
595 ],
596 ]
597 );
598
599 $this->end_controls_section();
600 }
601
602 /**
603 * Render counter widget output in the editor.
604 *
605 * Written as a Backbone JavaScript template and used to generate the live preview.
606 *
607 * @since 2.9.0
608 * @access protected
609 */
610 protected function content_template() {
611 ?>
612 <#
613 view.addRenderAttribute( 'elementor-counter', 'class', 'elementor-counter' );
614
615 view.addRenderAttribute( 'counter-number', 'class', 'elementor-counter-number-wrapper' );
616
617 view.addRenderAttribute(
618 'counter',
619 {
620 'class': 'elementor-counter-number',
621 'data-duration': settings.duration,
622 'data-to-value': settings.ending_number,
623 'data-from-value': settings.starting_number,
624 }
625 );
626
627 if ( settings.thousand_separator ) {
628 const delimiter = settings.thousand_separator_char ? settings.thousand_separator_char : ',';
629 view.addRenderAttribute( 'counter', 'data-delimiter', delimiter );
630 }
631
632 view.addRenderAttribute( 'prefix', 'class', 'elementor-counter-number-prefix' );
633
634 view.addRenderAttribute( 'suffix', 'class', 'elementor-counter-number-suffix' );
635
636 view.addRenderAttribute( 'counter-title', 'class', 'elementor-counter-title' );
637
638 view.addInlineEditingAttributes( 'counter-title' );
639
640 const titleTag = elementor.helpers.validateHTMLTag( settings.title_tag );
641 #>
642 <div {{{ view.getRenderAttributeString( 'elementor-counter' ) }}}>
643 <# if ( settings.title ) {
644 #><{{ titleTag }} {{{ view.getRenderAttributeString( 'counter-title' ) }}}>{{{ elementor.helpers.sanitize( settings.title, { ALLOW_DATA_ATTR: false } ) }}}</{{ titleTag }}><#
645 } #>
646 <div {{{ view.getRenderAttributeString( 'counter-number' ) }}}>
647 <span {{{ view.getRenderAttributeString( 'prefix' ) }}}>{{{ settings.prefix }}}</span>
648 <span {{{ view.getRenderAttributeString( 'counter' ) }}}>{{{ settings.starting_number }}}</span>
649 <span {{{ view.getRenderAttributeString( 'suffix' ) }}}>{{{ settings.suffix }}}</span>
650 </div>
651 </div>
652 <?php
653 }
654
655 /**
656 * Render counter widget output on the frontend.
657 *
658 * Written in PHP and used to generate the final HTML.
659 *
660 * @since 1.0.0
661 * @access protected
662 */
663 protected function render() {
664 $settings = $this->get_settings_for_display();
665
666 $this->add_render_attribute( 'elementor-counter', 'class', 'elementor-counter' );
667
668 $this->add_render_attribute( 'counter-number', 'class', 'elementor-counter-number-wrapper' );
669
670 $this->add_render_attribute(
671 'counter',
672 [
673 'class' => 'elementor-counter-number',
674 'data-duration' => $settings['duration'],
675 'data-to-value' => $settings['ending_number'],
676 'data-from-value' => $settings['starting_number'],
677 ]
678 );
679
680 if ( ! empty( $settings['thousand_separator'] ) ) {
681 $delimiter = empty( $settings['thousand_separator_char'] ) ? ',' : $settings['thousand_separator_char'];
682 $this->add_render_attribute( 'counter', 'data-delimiter', $delimiter );
683 }
684
685 $this->add_render_attribute( 'prefix', 'class', 'elementor-counter-number-prefix' );
686
687 $this->add_render_attribute( 'suffix', 'class', 'elementor-counter-number-suffix' );
688
689 $this->add_render_attribute( 'counter-title', 'class', 'elementor-counter-title' );
690
691 $this->add_inline_editing_attributes( 'counter-title' );
692
693 $title_tag = Utils::validate_html_tag( $settings['title_tag'] );
694 ?>
695 <div <?php $this->print_render_attribute_string( 'elementor-counter' ); ?>>
696 <?php
697 if ( $settings['title'] ) :
698 ?><<?php Utils::print_validated_html_tag( $title_tag ); ?> <?php $this->print_render_attribute_string( 'counter-title' ); ?>><?php echo wp_kses_post( $this->get_settings_for_display( 'title' ) ); ?></<?php Utils::print_validated_html_tag( $title_tag ); ?>><?php
699 endif;
700 ?>
701 <div <?php $this->print_render_attribute_string( 'counter-number' ); ?>>
702 <span <?php $this->print_render_attribute_string( 'prefix' ); ?>><?php $this->print_unescaped_setting( 'prefix' ); ?></span>
703 <span <?php $this->print_render_attribute_string( 'counter' ); ?>><?php $this->print_unescaped_setting( 'starting_number' ); ?></span>
704 <span <?php $this->print_render_attribute_string( 'suffix' ); ?>><?php $this->print_unescaped_setting( 'suffix' ); ?></span>
705 </div>
706 </div>
707 <?php
708 }
709 }
710