PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.82
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.82
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / widgets / Countdown / Countdown.php

Countdown.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.82, at includes/widgets/Countdown/Countdown.php

1,166 lines 36.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace King_Addons;
4
5 use Elementor\Controls_Manager;
6 use Elementor\Group_Control_Typography;
7 use Elementor\Group_Control_Background;
8 use Elementor\Group_Control_Border;
9 use Elementor\Group_Control_Box_Shadow;
10 use Elementor\Plugin;
11 use Elementor\Widget_Base;
12 use Elementor\Utils;
13
14 if (!defined('ABSPATH')) {
15 exit;
16 }
17
18 class Countdown extends Widget_Base
19 {
20
21
22
23 public function get_name()
24 {
25 return 'king-addons-countdown';
26 }
27
28 public function get_title()
29 {
30 return esc_html__('Countdown & Timer', 'king-addons');
31 }
32
33 public function get_icon()
34 {
35 return 'king-addons-icon king-addons-countdown';
36 }
37
38 public function get_categories()
39 {
40 return ['king-addons'];
41 }
42
43 public function get_keywords()
44 {
45 return ['king addons', 'king', 'addons', 'kingaddons', 'king-addons', 'evergreen', 'countdown', 'timer',
46 'time', 'counter', 'clock', 'date', 'evergreen countdown timer'];
47 }
48
49 public function get_script_depends()
50 {
51 return [KING_ADDONS_ASSETS_UNIQUE_KEY . '-countdown-script'];
52 }
53
54 public function get_style_depends()
55 {
56 return [
57 KING_ADDONS_ASSETS_UNIQUE_KEY . '-countdown-style',
58 KING_ADDONS_ASSETS_UNIQUE_KEY . '-general-general',
59 ];
60 }
61
62 public function get_custom_help_url()
63 {
64 return 'mailto:bug@kingaddons.com?subject=Bug Report - King Addons&body=Please describe the issue';
65 }
66
67 public function is_reload_preview_required()
68 {
69 return true;
70 }
71
72 public function has_widget_inner_wrapper(): bool {
73 return true;
74 }
75
76 public function add_control_countdown_type()
77 {
78 $this->add_control(
79 'countdown_type',
80 [
81 'label' => esc_html__('Type', 'king-addons'),
82 'type' => Controls_Manager::SELECT,
83 'default' => 'due-date',
84 'options' => [
85 'due-date' => esc_html__('Due Date', 'king-addons'),
86 'pro-eg' => esc_html__('Evergreen (Pro)', 'king-addons'),
87 ],
88 ]
89 );
90 }
91
92 public function add_control_evergreen_days()
93 {
94 }
95
96 public function add_control_evergreen_hours()
97 {
98 }
99
100 public function add_control_evergreen_minutes()
101 {
102 }
103
104 public function add_control_evergreen_seconds()
105 {
106 }
107
108 public function add_control_evergreen_show_again_delay()
109 {
110 }
111
112 public function add_control_evergreen_stop_after_date()
113 {
114 $this->add_control(
115 'evergreen_stop_after_date',
116 [
117 'label' => sprintf(__('Stop Showing After Date %s', 'king-addons'), '<i class="eicon-pro-icon"></i>'),
118 'type' => Controls_Manager::SWITCHER,
119 'separator' => 'before',
120 'classes' => 'king-addons-pro-control'
121 ]
122 );
123 }
124
125 public function add_control_evergreen_stop_after_date_select()
126 {
127 }
128
129 protected function register_controls()
130 {
131
132
133 $this->start_controls_section(
134 'section_countdown',
135 [
136 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('General', 'king-addons'),
137 ]
138 );
139
140
141 $this->add_control_countdown_type();
142
143
144 Core::renderUpgradeProNotice($this, Controls_Manager::RAW_HTML, 'countdown', 'countdown_type', ['pro-eg']);
145
146 $due_date_default = date(
147 'Y-m-d H:i', strtotime('+1 month') + (get_option('gmt_offset') * HOUR_IN_SECONDS)
148 );
149
150 $this->add_control(
151 'due_date',
152 [
153 'label' => esc_html__('Due Date', 'king-addons'),
154 'type' => Controls_Manager::DATE_TIME,
155 'default' => $due_date_default,
156 'description' => sprintf(
157 esc_html__('Date set according to your timezone: %s.', 'king-addons'),
158 Utils::get_timezone_string()
159 ),
160 'dynamic' => [
161 'active' => true,
162 ],
163 'separator' => 'before',
164 'condition' => [
165 'countdown_type' => 'due-date',
166 ],
167 ]
168 );
169
170 $this->add_control_evergreen_days();
171
172 $this->add_control_evergreen_hours();
173
174 $this->add_control_evergreen_minutes();
175
176 $this->add_control_evergreen_seconds();
177
178 $this->add_control_evergreen_show_again_delay();
179
180 $this->add_control_evergreen_stop_after_date();
181
182 $this->add_control_evergreen_stop_after_date_select();
183
184 $this->add_control(
185 'countdown_editor_notice',
186 [
187 'type' => Controls_Manager::RAW_HTML,
188 'raw' => '<strong>Please Note:</strong> Countdown timer does not work in the Editor, please click on Preview Changes icon to see it in action.',
189 'separator' => 'before',
190 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
191 ]
192 );
193
194 $this->end_controls_section();
195
196
197 $this->start_controls_section(
198 'section_content',
199 [
200 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Content', 'king-addons'),
201 ]
202 );
203
204 $this->add_control(
205 'show_days',
206 [
207 'label' => esc_html__('Show Days', 'king-addons'),
208 'type' => Controls_Manager::SWITCHER,
209 'default' => 'yes',
210 'separator' => 'before',
211 ]
212 );
213
214 $this->add_control(
215 'show_hours',
216 [
217 'label' => esc_html__('Show Hours', 'king-addons'),
218 'type' => Controls_Manager::SWITCHER,
219 'default' => 'yes'
220 ]
221 );
222
223 $this->add_control(
224 'show_minutes',
225 [
226 'label' => esc_html__('Show Minutes', 'king-addons'),
227 'type' => Controls_Manager::SWITCHER,
228 'default' => 'yes'
229 ]
230 );
231
232 $this->add_control(
233 'show_seconds',
234 [
235 'label' => esc_html__('Show Seconds', 'king-addons'),
236 'type' => Controls_Manager::SWITCHER,
237 'default' => 'yes'
238 ]
239 );
240
241 $this->add_control(
242 'show_labels',
243 [
244 'label' => esc_html__('Show Labels', 'king-addons'),
245 'type' => Controls_Manager::SWITCHER,
246 'default' => 'yes',
247 'separator' => 'before',
248 ]
249 );
250
251 $this->add_control(
252 'labels_position',
253 [
254 'label' => esc_html__('Display', 'king-addons'),
255 'type' => Controls_Manager::SELECT,
256 'default' => 'block',
257 'options' => [
258 'block' => esc_html__('Block', 'king-addons'),
259 'inline' => esc_html__('Inline', 'king-addons'),
260 ],
261 'selectors_dictionary' => [
262 'inline' => 'inline-block',
263 'block' => 'block'
264 ],
265 'selectors' => [
266 '{{WRAPPER}} .king-addons-countdown-number' => 'display: {{VALUE}}',
267 '{{WRAPPER}} .king-addons-countdown-label' => 'display: {{VALUE}}',
268 ],
269 'separator' => 'after',
270 'condition' => [
271 'show_labels' => 'yes',
272 ],
273 ]
274 );
275
276 $this->add_control(
277 'labels_days_singular',
278 [
279 'label' => esc_html__('Day', 'king-addons'),
280 'type' => Controls_Manager::TEXT,
281 'dynamic' => [
282 'active' => true,
283 ],
284 'default' => 'Day',
285 'condition' => [
286 'show_labels' => 'yes',
287 ],
288 ]
289 );
290
291 $this->add_control(
292 'labels_days_plural',
293 [
294 'label' => esc_html__('Days', 'king-addons'),
295 'type' => Controls_Manager::TEXT,
296 'dynamic' => [
297 'active' => true,
298 ],
299 'default' => 'Days',
300 'condition' => [
301 'show_labels' => 'yes',
302 ],
303 ]
304 );
305
306 $this->add_control(
307 'labels_hours_singular',
308 [
309 'label' => esc_html__('Hour', 'king-addons'),
310 'type' => Controls_Manager::TEXT,
311 'dynamic' => [
312 'active' => true,
313 ],
314 'default' => 'Hour',
315 'condition' => [
316 'show_labels' => 'yes',
317 ],
318 ]
319 );
320
321 $this->add_control(
322 'labels_hours_plural',
323 [
324 'label' => esc_html__('Hours', 'king-addons'),
325 'type' => Controls_Manager::TEXT,
326 'dynamic' => [
327 'active' => true,
328 ],
329 'default' => 'Hours',
330 'condition' => [
331 'show_labels' => 'yes',
332 ],
333 ]
334 );
335
336 $this->add_control(
337 'labels_minutes_singular',
338 [
339 'label' => esc_html__('Minute', 'king-addons'),
340 'type' => Controls_Manager::TEXT,
341 'dynamic' => [
342 'active' => true,
343 ],
344 'default' => 'Minute',
345 'condition' => [
346 'show_labels' => 'yes',
347 ],
348 ]
349 );
350
351 $this->add_control(
352 'labels_minutes_plural',
353 [
354 'label' => esc_html__('Minutes', 'king-addons'),
355 'type' => Controls_Manager::TEXT,
356 'dynamic' => [
357 'active' => true,
358 ],
359 'default' => 'Minutes',
360 'condition' => [
361 'show_labels' => 'yes',
362 ],
363 ]
364 );
365
366 $this->add_control(
367 'labels_seconds_plural',
368 [
369 'label' => esc_html__('Seconds', 'king-addons'),
370 'type' => Controls_Manager::TEXT,
371 'dynamic' => [
372 'active' => true,
373 ],
374 'default' => 'Seconds',
375 'condition' => [
376 'show_labels' => 'yes',
377 ],
378 ]
379 );
380
381 $this->add_control(
382 'show_separator',
383 [
384 'label' => esc_html__('Show Separators', 'king-addons'),
385 'type' => Controls_Manager::SWITCHER,
386 'separator' => 'before',
387 ]
388 );
389
390 $this->end_controls_section();
391
392
393 $this->start_controls_section(
394 'section_actions',
395 [
396 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Expire Actions', 'king-addons'),
397 ]
398 );
399
400 $this->add_control(
401 'timer_actions',
402 [
403 'label' => esc_html__('Actions After Timer Expires', 'king-addons'),
404 'label_block' => true,
405 'type' => Controls_Manager::SELECT2,
406 'options' => [
407 'hide-timer' => esc_html__('Hide Timer', 'king-addons'),
408 'hide-element' => esc_html__('Hide Element', 'king-addons'),
409 'message' => esc_html__('Display Message', 'king-addons'),
410 'redirect' => esc_html__('Redirect', 'king-addons'),
411 'load-template' => esc_html__('Load Template', 'king-addons'),
412 ],
413 'multiple' => true,
414 'separator' => 'before',
415 ]
416 );
417
418 $this->add_control(
419 'hide_element_selector',
420 [
421 'label' => esc_html__('CSS Selector to Hide Element', 'king-addons'),
422 'label_block' => true,
423 'type' => Controls_Manager::TEXT,
424 'dynamic' => [
425 'active' => true,
426 ],
427 'default' => '',
428 'separator' => 'before',
429 'condition' => [
430 'timer_actions' => 'hide-element',
431 ],
432 ]
433 );
434
435 $this->add_control(
436 'display_message_text',
437 [
438 'label' => esc_html__('Display Message', 'king-addons'),
439 'type' => Controls_Manager::WYSIWYG,
440 'default' => '',
441 'separator' => 'before',
442 'condition' => [
443 'timer_actions' => 'message',
444 ],
445 ]
446 );
447
448 $this->add_control(
449 'redirect_url',
450 [
451 'label' => esc_html__('Redirect URL', 'king-addons'),
452 'label_block' => true,
453 'type' => Controls_Manager::TEXT,
454 'dynamic' => [
455 'active' => true,
456 ],
457 'default' => '',
458 'separator' => 'before',
459 'condition' => [
460 'timer_actions' => 'redirect',
461 ],
462 ]
463 );
464
465 $this->add_control(
466 'load_template',
467 [
468 'label' => esc_html__('Select Template', 'king-addons'),
469 'type' => 'king-addons-ajax-select2',
470 'options' => 'ajaxselect2/getElementorTemplates',
471 'label_block' => true,
472 'separator' => 'before',
473 'condition' => [
474 'timer_actions' => 'load-template',
475 ],
476 ]
477 );
478
479
480 wp_reset_postdata();
481
482 $this->end_controls_section();
483
484 Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'countdown', [
485 'Evergreen Timer (Endless Timer)',
486 'Stop Showing After Date',
487 ]);
488
489 $this->start_controls_section(
490 'section_style_general',
491 [
492 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('General', 'king-addons'),
493 'tab' => Controls_Manager::TAB_STYLE,
494 ]
495 );
496
497 $this->add_group_control(
498 Group_Control_Background::get_type(),
499 [
500 'name' => 'general_bg_color',
501 'label' => esc_html__('Background', 'king-addons'),
502 'types' => ['classic', 'gradient'],
503 'fields_options' => [
504 'color' => [
505 'default' => '#5B03FF',
506 ],
507 ],
508 'selector' => '{{WRAPPER}} .king-addons-countdown-item'
509 ]
510 );
511
512 $this->add_responsive_control(
513 'general_width',
514 [
515 'label' => esc_html__('Width', 'king-addons'),
516 'type' => Controls_Manager::SLIDER,
517 'size_units' => ['%', 'px'],
518 'range' => [
519 '%' => [
520 'min' => 0,
521 'max' => 100,
522 ],
523 'px' => [
524 'min' => 0,
525 'max' => 800,
526 ],
527 ],
528 'default' => [
529 'unit' => '%',
530 'size' => 100,
531 ],
532 'selectors' => [
533 '{{WRAPPER}} .king-addons-countdown-wrap' => 'max-width: {{SIZE}}{{UNIT}};',
534 ],
535 'separator' => 'before',
536 ]
537 );
538
539 $this->add_responsive_control(
540 'general_gutter',
541 [
542 'label' => esc_html__('Gutter', 'king-addons'),
543 'type' => Controls_Manager::SLIDER,
544 'size_units' => ['px'],
545 'range' => [
546 'px' => [
547 'min' => 0,
548 'max' => 100,
549 ],
550 ],
551 'default' => [
552 'unit' => 'px',
553 'size' => 20,
554 ],
555 'selectors' => [
556 '{{WRAPPER}} .king-addons-countdown-item' => 'margin-left: calc({{SIZE}}px/2);margin-right: calc({{SIZE}}px/2);',
557 ],
558 ]
559 );
560
561 $this->add_responsive_control(
562 'general_padding',
563 [
564 'label' => esc_html__('Padding', 'king-addons'),
565 'type' => Controls_Manager::DIMENSIONS,
566 'default' => [
567 'top' => 5,
568 'right' => 5,
569 'bottom' => 5,
570 'left' => 5,
571 ],
572 'size_units' => ['px'],
573 'selectors' => [
574 '{{WRAPPER}} .king-addons-countdown-item' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
575 ],
576 'separator' => 'before',
577 ]
578 );
579
580 $this->add_group_control(
581 Group_Control_Border::get_type(),
582 [
583 'name' => 'general_border',
584 'label' => esc_html__('Border', 'king-addons'),
585 'fields_options' => [
586 'color' => [
587 'default' => '#E8E8E8',
588 ],
589 'width' => [
590 'default' => [
591 'top' => '1',
592 'right' => '1',
593 'bottom' => '1',
594 'left' => '1',
595 'isLinked' => true,
596 ],
597 ],
598 ],
599 'selector' => '{{WRAPPER}} .king-addons-countdown-item',
600 'separator' => 'before',
601 ]
602 );
603
604 $this->add_control(
605 'general_border_radius',
606 [
607 'label' => esc_html__('Border Radius', 'king-addons'),
608 'type' => Controls_Manager::DIMENSIONS,
609 'size_units' => ['px', '%'],
610 'default' => [
611 'top' => 5,
612 'right' => 5,
613 'bottom' => 5,
614 'left' => 5,
615 ],
616 'selectors' => [
617 '{{WRAPPER}} .king-addons-countdown-item' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
618 ],
619 'separator' => 'before',
620 ]
621 );
622
623 $this->add_control(
624 'general_box_shadow_divider',
625 [
626 'type' => Controls_Manager::DIVIDER,
627 'style' => 'thick',
628 ]
629 );
630
631 $this->add_group_control(
632 Group_Control_Box_Shadow::get_type(),
633 [
634 'name' => 'general_box_shadow',
635 'selector' => '{{WRAPPER}} .king-addons-countdown-item',
636 ]
637 );
638
639 $this->end_controls_section();
640
641
642 $this->start_controls_section(
643 'section_style_content',
644 [
645 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Content', 'king-addons'),
646 'tab' => Controls_Manager::TAB_STYLE,
647 ]
648 );
649
650 $this->add_responsive_control(
651 'content_align',
652 [
653 'label' => esc_html__('Alignment', 'king-addons'),
654 'type' => Controls_Manager::CHOOSE,
655 'label_block' => false,
656 'default' => 'center',
657 'options' => [
658 'left' => [
659 'title' => esc_html__('Left', 'king-addons'),
660 'icon' => 'eicon-h-align-left',
661 ],
662 'center' => [
663 'title' => esc_html__('Center', 'king-addons'),
664 'icon' => 'eicon-h-align-center',
665 ],
666 'right' => [
667 'title' => esc_html__('Right', 'king-addons'),
668 'icon' => 'eicon-h-align-right',
669 ]
670 ],
671 'selectors' => [
672 '{{WRAPPER}} .king-addons-countdown-item' => 'text-align: {{VALUE}}',
673 ],
674 'separator' => 'after'
675 ]
676 );
677
678 $this->add_control(
679 'numbers_color',
680 [
681 'label' => esc_html__('Numbers Color', 'king-addons'),
682 'type' => Controls_Manager::COLOR,
683 'default' => '#ffffff',
684 'selectors' => [
685 '{{WRAPPER}} .king-addons-countdown-number' => 'color: {{VALUE}};',
686 ],
687 ]
688 );
689
690 $this->add_control(
691 'numbers_bg_color',
692 [
693 'label' => esc_html__('Numbers Background Color', 'king-addons'),
694 'type' => Controls_Manager::COLOR,
695 'selectors' => [
696 '{{WRAPPER}} .king-addons-countdown-number' => 'background-color: {{VALUE}};',
697 ],
698 ]
699 );
700
701 $this->add_group_control(
702 Group_Control_Typography::get_type(),
703 [
704 'name' => 'numbers_typography',
705 'selector' => '{{WRAPPER}} .king-addons-countdown-number',
706 ]
707 );
708
709 $this->add_responsive_control(
710 'numbers_padding',
711 [
712 'label' => esc_html__('Numbers Padding', 'king-addons'),
713 'type' => Controls_Manager::DIMENSIONS,
714 'default' => [
715 'top' => 40,
716 'right' => 10,
717 'bottom' => 10,
718 'left' => 10,
719 ],
720 'size_units' => ['px'],
721 'selectors' => [
722 '{{WRAPPER}} .king-addons-countdown-number' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
723 ],
724 ]
725 );
726
727 $this->add_control(
728 'labels_color',
729 [
730 'label' => esc_html__('Labels Color', 'king-addons'),
731 'type' => Controls_Manager::COLOR,
732 'default' => '#ffffff',
733 'selectors' => [
734 '{{WRAPPER}} .king-addons-countdown-label' => 'color: {{VALUE}};',
735 ],
736 'separator' => 'before'
737 ]
738 );
739
740 $this->add_control(
741 'labels_bg_color',
742 [
743 'label' => esc_html__('Labels Background Color', 'king-addons'),
744 'type' => Controls_Manager::COLOR,
745 'selectors' => [
746 '{{WRAPPER}} .king-addons-countdown-label' => 'background-color: {{VALUE}};',
747 ],
748 ]
749 );
750
751 $this->add_group_control(
752 Group_Control_Typography::get_type(),
753 [
754 'name' => 'labels_typography',
755 'selector' => '{{WRAPPER}} .king-addons-countdown-label',
756 ]
757 );
758
759 $this->add_responsive_control(
760 'labels_padding',
761 [
762 'label' => esc_html__('Labels Padding', 'king-addons'),
763 'type' => Controls_Manager::DIMENSIONS,
764 'default' => [
765 'top' => 10,
766 'right' => 10,
767 'bottom' => 10,
768 'left' => 10,
769 ],
770 'size_units' => ['px'],
771 'selectors' => [
772 '{{WRAPPER}} .king-addons-countdown-label' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
773 ],
774 ]
775 );
776
777 $this->add_control(
778 'separator_color',
779 [
780 'label' => esc_html__('Separator Color', 'king-addons'),
781 'type' => Controls_Manager::COLOR,
782 'default' => '#5B03FF',
783 'selectors' => [
784 '{{WRAPPER}} .king-addons-countdown-separator span' => 'background: {{VALUE}};',
785 ],
786 'separator' => 'before',
787 ]
788 );
789
790 $this->add_responsive_control(
791 'separator_size',
792 [
793 'label' => esc_html__('Separator Size', 'king-addons'),
794 'type' => Controls_Manager::SLIDER,
795 'size_units' => ['px'],
796 'range' => [
797 'px' => [
798 'min' => 1,
799 'max' => 50,
800 ],
801 ],
802 'default' => [
803 'unit' => 'px',
804 'size' => 6,
805 ],
806 'selectors' => [
807 '{{WRAPPER}} .king-addons-countdown-separator span' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
808 ],
809 'condition' => [
810 'show_separator' => 'yes',
811 ],
812 ]
813 );
814
815 $this->add_responsive_control(
816 'separator_margin',
817 [
818 'label' => esc_html__('Dots Margin', 'king-addons'),
819 'type' => Controls_Manager::SLIDER,
820 'size_units' => ['px'],
821 'range' => [
822 'px' => [
823 'min' => 1,
824 'max' => 50,
825 ],
826 ],
827 'default' => [
828 'unit' => 'px',
829 'size' => 12,
830 ],
831 'selectors' => [
832 '{{WRAPPER}} .king-addons-countdown-separator span:first-child' => 'margin-bottom: {{SIZE}}{{UNIT}};',
833 ],
834 'condition' => [
835 'show_separator' => 'yes',
836 ],
837 ]
838 );
839
840 $this->add_control(
841 'separator_circle',
842 [
843 'label' => esc_html__('Separator Border Radius', 'king-addons'),
844 'type' => Controls_Manager::SWITCHER,
845 'default' => 'yes',
846 'selectors_dictionary' => [
847 'yes' => '50%;',
848 '' => 'none'
849 ],
850 'selectors' => [
851 '{{WRAPPER}} .king-addons-countdown-separator span' => 'border-radius: {{VALUE}};',
852 ],
853 ]
854 );
855
856 $this->end_controls_section();
857
858
859 $this->start_controls_section(
860 'section_style_message',
861 [
862 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Message', 'king-addons'),
863 'tab' => Controls_Manager::TAB_STYLE,
864 'condition' => [
865 'timer_actions' => 'message',
866 ],
867 ]
868 );
869
870 $this->add_responsive_control(
871 'message_align',
872 [
873 'label' => esc_html__('Alignment', 'king-addons'),
874 'type' => Controls_Manager::CHOOSE,
875 'label_block' => false,
876 'default' => 'center',
877 'options' => [
878 'left' => [
879 'title' => esc_html__('Left', 'king-addons'),
880 'icon' => 'eicon-h-align-left',
881 ],
882 'center' => [
883 'title' => esc_html__('Center', 'king-addons'),
884 'icon' => 'eicon-h-align-center',
885 ],
886 'right' => [
887 'title' => esc_html__('Right', 'king-addons'),
888 'icon' => 'eicon-h-align-right',
889 ]
890 ],
891 'selectors' => [
892 '{{WRAPPER}} .king-addons-countdown-message' => 'text-align: {{VALUE}}',
893 ],
894 ]
895 );
896
897 $this->add_control(
898 'message_color',
899 [
900 'label' => esc_html__('Color', 'king-addons'),
901 'type' => Controls_Manager::COLOR,
902 'default' => '#ffffff',
903 'selectors' => [
904 '{{WRAPPER}} .king-addons-countdown-message' => 'color: {{VALUE}};',
905 ],
906 'separator' => 'before'
907 ]
908 );
909
910 $this->add_control(
911 'message_bg_color',
912 [
913 'label' => esc_html__('Background Color', 'king-addons'),
914 'type' => Controls_Manager::COLOR,
915 'selectors' => [
916 '{{WRAPPER}} .king-addons-countdown-message' => 'background-color: {{VALUE}};',
917 ],
918 ]
919 );
920
921 $this->add_group_control(
922 Group_Control_Typography::get_type(),
923 [
924 'name' => 'message_typography',
925 'selector' => '{{WRAPPER}} .king-addons-countdown-message',
926 ]
927 );
928
929 $this->add_responsive_control(
930 'message_padding',
931 [
932 'label' => esc_html__('Padding', 'king-addons'),
933 'type' => Controls_Manager::DIMENSIONS,
934 'default' => [
935 'top' => 0,
936 'right' => 0,
937 'bottom' => 0,
938 'left' => 0,
939 ],
940 'size_units' => ['px'],
941 'selectors' => [
942 '{{WRAPPER}} .king-addons-countdown-message' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
943 ],
944 'separator' => 'before',
945 ]
946 );
947
948 $this->add_responsive_control(
949 'message_top_distance',
950 [
951 'label' => esc_html__('Top Distance', 'king-addons'),
952 'type' => Controls_Manager::SLIDER,
953 'size_units' => ['px'],
954 'range' => [
955 'px' => [
956 'min' => 0,
957 'max' => 100,
958 ],
959 ],
960 'default' => [
961 'unit' => 'px',
962 'size' => 20,
963 ],
964 'selectors' => [
965 '{{WRAPPER}} .king-addons-countdown-message' => 'margin-top: {{SIZE}}{{UNIT}};',
966 ],
967 ]
968 );
969
970
971
972
973 $this->end_controls_section();
974
975
976
977 }
978
979 public function get_due_date_interval($date)
980 {
981 return strtotime($date) - (get_option('gmt_offset') * HOUR_IN_SECONDS);
982 }
983
984 public function get_evergreen_interval($settings)
985 {
986 // Returning '0' by default
987 return '0';
988 }
989
990 public function get_countdown_attributes($settings)
991 {
992 // Force non-premium users into 'due-date' mode
993 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
994 $settings['countdown_type'] = 'due-date';
995 $settings['evergreen_show_again_delay'] = '0';
996 }
997
998 $type = esc_attr($settings['countdown_type']);
999 $showAgain = esc_attr($settings['evergreen_show_again_delay']);
1000 $actions = esc_attr($this->get_expired_actions_json($settings));
1001 $interval = ($type === 'evergreen')
1002 ? $this->get_evergreen_interval($settings)
1003 : $this->get_due_date_interval($settings['due_date']);
1004
1005 return sprintf(
1006 ' data-type="%s" data-show-again="%s" data-actions="%s" data-interval="%s"',
1007 $type,
1008 $showAgain,
1009 $actions,
1010 esc_attr($interval)
1011 );
1012 }
1013
1014 public function get_countdown_class($settings)
1015 {
1016 // Force non-premium users to disable "stop after date"
1017 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
1018 $settings['evergreen_stop_after_date'] = '';
1019 $settings['evergreen_stop_after_date_select'] = '';
1020 }
1021
1022 $class = 'king-addons-countdown-wrap elementor-clearfix';
1023
1024 if ($settings['evergreen_stop_after_date'] === 'yes') {
1025 $current_time = time() + get_option('gmt_offset') * HOUR_IN_SECONDS;
1026 if ($current_time > strtotime($settings['evergreen_stop_after_date_select'])) {
1027 $class = ' king-addons-hidden-element';
1028 }
1029 }
1030
1031 return $class;
1032 }
1033
1034 public function sanitize_no_js($input)
1035 {
1036 // Remove potential JS injection points
1037 $patterns = [
1038 '#<script(.*?)>(.*?)</script>#is',
1039 '#<iframe(.*?)>(.*?)</iframe>#is',
1040 '#on\w+="[^"]*"#i',
1041 "#on\w+='[^']*'#i",
1042 '#on\w+=\S+#i',
1043 '#style="[^"]*javascript:[^"]*"#i',
1044 "#style='[^']*javascript:[^']*'#i",
1045 ];
1046
1047 foreach ($patterns as $pattern) {
1048 $input = preg_replace($pattern, '', $input);
1049 }
1050
1051 return $input;
1052 }
1053
1054 public function get_expired_actions_json($settings)
1055 {
1056 $actions = [];
1057 $allowed_html = [
1058 'a' => ['href' => [], 'title' => [], 'target' => []],
1059 'h1' => [], 'h2' => [], 'h3' => [], 'h4' => [], 'h5' => [], 'h6' => [],
1060 'b' => [], 'strong' => [], 'i' => [], 'em' => [], 'p' => [], 'br' => [],
1061 'ul' => [], 'ol' => [], 'li' => [], 'span' => [],
1062 'div' => ['class' => []],
1063 'img' => ['src' => [], 'alt' => [], 'width' => [], 'height' => []],
1064 ];
1065
1066 if (!empty($settings['timer_actions'])) {
1067 foreach ($settings['timer_actions'] as $value) {
1068 switch ($value) {
1069 case 'hide-timer':
1070 $actions['hide-timer'] = '';
1071 break;
1072 case 'hide-element':
1073 $actions['hide-element'] = $settings['hide_element_selector'];
1074 break;
1075 case 'message':
1076 $actions['message'] = $this->sanitize_no_js(
1077 wp_kses($settings['display_message_text'], $allowed_html)
1078 );
1079 break;
1080 case 'redirect':
1081 // Use '#' as fallback if `redirect_url` is empty
1082 $actions['redirect'] = esc_url($settings['redirect_url'] ?: '#');
1083 break;
1084 case 'load-template':
1085 $actions['load-template'] = $settings['load_template'];
1086 break;
1087 }
1088 }
1089 }
1090
1091 return json_encode($actions);
1092 }
1093
1094 public function render_countdown_item($settings, $item)
1095 {
1096 $html = '<div class="king-addons-countdown-item">';
1097 $html .= '<span class="king-addons-countdown-number king-addons-countdown-' . esc_attr($item)
1098 . '" data-item="' . esc_attr($item) . '"></span>';
1099
1100 if ($settings['show_labels'] === 'yes') {
1101 if ($item !== 'seconds') {
1102 $labels = [
1103 'singular' => $settings['labels_' . $item . '_singular'],
1104 'plural' => $settings['labels_' . $item . '_plural'],
1105 ];
1106 $html .= '<span class="king-addons-countdown-label" data-text="'
1107 . esc_attr(json_encode($labels)) . '">'
1108 . esc_html($settings['labels_' . $item . '_plural']) . '</span>';
1109 } else {
1110 $html .= '<span class="king-addons-countdown-label">'
1111 . esc_html($settings['labels_' . $item . '_plural']) . '</span>';
1112 }
1113 }
1114 $html .= '</div>';
1115
1116 if (!empty($settings['show_separator'])) {
1117 $html .= '<span class="king-addons-countdown-separator">'
1118 . '<span></span><span></span></span>';
1119 }
1120
1121 echo $html;
1122 }
1123
1124 public function render_countdown_items($settings)
1125 {
1126 // More concise iteration over possible segments
1127 $items = [
1128 'days' => $settings['show_days'],
1129 'hours' => $settings['show_hours'],
1130 'minutes' => $settings['show_minutes'],
1131 'seconds' => $settings['show_seconds'],
1132 ];
1133
1134 foreach ($items as $item => $showIt) {
1135 if ($showIt) {
1136 $this->render_countdown_item($settings, $item);
1137 }
1138 }
1139 }
1140
1141 public function load_elementor_template($settings)
1142 {
1143 if (Plugin::$instance->editor->is_edit_mode()) {
1144 return;
1145 }
1146
1147 // Only load the template if 'redirect' isn't in actions and 'load-template' is
1148 if (!empty($settings['timer_actions'])
1149 && !in_array('redirect', $settings['timer_actions'], true)
1150 && in_array('load-template', $settings['timer_actions'], true)
1151 ) {
1152 echo Plugin::instance()->frontend->get_builder_content($settings['load_template']);
1153 }
1154 }
1155
1156 protected function render()
1157 {
1158 $settings = Core::displaySettings($this);
1159 echo '<div class="' . esc_attr($this->get_countdown_class($settings)) . '"'
1160 . $this->get_countdown_attributes($settings) . '>';
1161 $this->render_countdown_items($settings);
1162 echo '</div>';
1163
1164 $this->load_elementor_template($settings);
1165 }
1166 }