PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.49
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.49
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 / Event_Calendar / Event_Calendar.php

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

798 lines 24.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Event Calendar Widget (Free).
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons;
9
10 use Elementor\Controls_Manager;
11 use Elementor\Group_Control_Border;
12 use Elementor\Group_Control_Box_Shadow;
13 use Elementor\Group_Control_Typography;
14 use Elementor\Repeater;
15 use Elementor\Widget_Base;
16
17 if (!defined('ABSPATH')) {
18 exit;
19 }
20
21 /**
22 * Renders an event calendar list.
23 */
24 class Event_Calendar extends Widget_Base
25 {
26 /**
27 * Widget slug.
28 *
29 * @return string
30 */
31 public function get_name(): string
32 {
33 return 'king-addons-event-calendar';
34 }
35
36 /**
37 * Widget title.
38 *
39 * @return string
40 */
41 public function get_title(): string
42 {
43 return esc_html__('Event Calendar', 'king-addons');
44 }
45
46 /**
47 * Widget icon.
48 *
49 * @return string
50 */
51 public function get_icon(): string
52 {
53 return 'king-addons-icon king-addons-event-calendar';
54 }
55
56 /**
57 * Style dependencies.
58 *
59 * @return array<int, string>
60 */
61 public function get_style_depends(): array
62 {
63 return [
64 KING_ADDONS_ASSETS_UNIQUE_KEY . '-event-calendar-style',
65 ];
66 }
67
68 /**
69 * Script dependencies.
70 *
71 * @return array<int, string>
72 */
73 public function get_script_depends(): array
74 {
75 return [
76 KING_ADDONS_ASSETS_UNIQUE_KEY . '-event-calendar-script',
77 ];
78 }
79
80 /**
81 * Categories.
82 *
83 * @return array<int, string>
84 */
85 public function get_categories(): array
86 {
87 return ['king-addons'];
88 }
89
90 /**
91 * Keywords.
92 *
93 * @return array<int, string>
94 */
95 public function get_keywords(): array
96 {
97 return ['event', 'calendar', 'schedule', 'list'];
98 }
99
100 /**
101 * Register controls.
102 *
103 * @return void
104 */
105 public function register_controls(): void
106 {
107 $this->register_content_controls();
108 $this->register_layout_controls();
109 $this->register_style_card_controls();
110 $this->register_style_text_controls();
111 $this->register_style_badge_controls();
112 $this->register_pro_controls();
113 $this->register_pro_notice_controls();
114 }
115
116 /**
117 * Register Pro-only controls placeholder.
118 *
119 * The Pro version overrides this method to add premium controls without
120 * overriding the full `register_controls()` flow.
121 *
122 * @return void
123 */
124 public function register_pro_controls(): void
125 {
126 // Intentionally empty in Free.
127 }
128
129 /**
130 * Filter wrapper attributes for the widget output.
131 *
132 * @param array<string, string> $attributes Wrapper attributes.
133 * @param array<string, mixed> $settings Widget settings.
134 * @param array<int, array<string, mixed>> $events Events list.
135 *
136 * @return array<string, string>
137 */
138 public function filter_wrapper_attributes(array $attributes, array $settings, array $events): array
139 {
140 return $attributes;
141 }
142
143 /**
144 * Render Pro-only header content placeholder.
145 *
146 * @param array<string, mixed> $settings Widget settings.
147 * @param array<int, array<string, mixed>> $events Events list.
148 *
149 * @return void
150 */
151 public function render_pro_header(array $settings, array $events): void
152 {
153 // Intentionally empty in Free.
154 }
155
156 /**
157 * Render widget output.
158 *
159 * @return void
160 */
161 public function render(): void
162 {
163 $settings = $this->get_settings_for_display();
164 $events = $this->get_events($settings);
165
166 if (empty($events)) {
167 return;
168 }
169
170 $attributes = [
171 'class' => 'king-addons-event-calendar',
172 'data-has-filters' => 'no',
173 ];
174 $attributes = $this->filter_wrapper_attributes($attributes, $settings, $events);
175
176 $attr_pairs = [];
177 foreach ($attributes as $key => $value) {
178 $attr_pairs[] = esc_attr($key) . '="' . esc_attr($value) . '"';
179 }
180
181 ?>
182 <div <?php echo implode(' ', $attr_pairs); ?>>
183 <?php $this->render_pro_header($settings, $events); ?>
184 <div class="king-addons-event-calendar__list">
185 <?php foreach ($events as $event) : ?>
186 <?php $this->render_event($event, $settings); ?>
187 <?php endforeach; ?>
188 </div>
189 </div>
190 <?php
191 }
192
193 /**
194 * Content controls.
195 *
196 * @return void
197 */
198 protected function register_content_controls(): void
199 {
200 $this->start_controls_section(
201 'kng_events_section',
202 [
203 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Events', 'king-addons'),
204 'tab' => Controls_Manager::TAB_CONTENT,
205 ]
206 );
207
208 $repeater = new Repeater();
209
210 $repeater->add_control(
211 'kng_event_title',
212 [
213 'label' => esc_html__('Title', 'king-addons'),
214 'type' => Controls_Manager::TEXT,
215 'default' => esc_html__('Event title', 'king-addons'),
216 ]
217 );
218
219 $repeater->add_control(
220 'kng_event_date',
221 [
222 'label' => esc_html__('Start Date & Time', 'king-addons'),
223 'type' => Controls_Manager::DATE_TIME,
224 'picker_options' => ['enableTime' => true],
225 ]
226 );
227
228 $repeater->add_control(
229 'kng_event_end_date',
230 [
231 'label' => esc_html__('End Date & Time', 'king-addons'),
232 'type' => Controls_Manager::DATE_TIME,
233 'picker_options' => ['enableTime' => true],
234 ]
235 );
236
237 $repeater->add_control(
238 'kng_event_time_label',
239 [
240 'label' => esc_html__('Time Label', 'king-addons'),
241 'type' => Controls_Manager::TEXT,
242 'placeholder' => esc_html__('10:00 - 12:00', 'king-addons'),
243 ]
244 );
245
246 $repeater->add_control(
247 'kng_event_location',
248 [
249 'label' => esc_html__('Location', 'king-addons'),
250 'type' => Controls_Manager::TEXT,
251 'placeholder' => esc_html__('Main Hall', 'king-addons'),
252 ]
253 );
254
255 $repeater->add_control(
256 'kng_event_category',
257 [
258 'label' => esc_html__('Category', 'king-addons'),
259 'type' => Controls_Manager::TEXT,
260 'placeholder' => esc_html__('Conference', 'king-addons'),
261 ]
262 );
263
264 $repeater->add_control(
265 'kng_event_color',
266 [
267 'label' => esc_html__('Category Color', 'king-addons'),
268 'type' => Controls_Manager::COLOR,
269 ]
270 );
271
272 $repeater->add_control(
273 'kng_event_description',
274 [
275 'label' => esc_html__('Description', 'king-addons'),
276 'type' => Controls_Manager::TEXTAREA,
277 'rows' => 3,
278 ]
279 );
280
281 $repeater->add_control(
282 'kng_event_link',
283 [
284 'label' => esc_html__('Event Link', 'king-addons'),
285 'type' => Controls_Manager::URL,
286 'placeholder' => esc_html__('https://', 'king-addons'),
287 ]
288 );
289
290 $this->add_control(
291 'kng_events',
292 [
293 'label' => esc_html__('Events', 'king-addons'),
294 'type' => Controls_Manager::REPEATER,
295 'fields' => $repeater->get_controls(),
296 'default' => [],
297 ]
298 );
299
300 $this->add_control(
301 'kng_cta_text',
302 [
303 'label' => esc_html__('Button Text', 'king-addons'),
304 'type' => Controls_Manager::TEXT,
305 'default' => esc_html__('View details', 'king-addons'),
306 ]
307 );
308
309 $this->add_control(
310 'kng_show_button',
311 [
312 'label' => esc_html__('Show Button', 'king-addons'),
313 'type' => Controls_Manager::SWITCHER,
314 'return_value' => 'yes',
315 'default' => 'yes',
316 ]
317 );
318
319 $this->end_controls_section();
320 }
321
322 /**
323 * Layout controls.
324 *
325 * @return void
326 */
327 protected function register_layout_controls(): void
328 {
329 $this->start_controls_section(
330 'kng_layout_section',
331 [
332 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Layout', 'king-addons'),
333 'tab' => Controls_Manager::TAB_CONTENT,
334 ]
335 );
336
337 $this->add_control(
338 'kng_show_description',
339 [
340 'label' => esc_html__('Show Description', 'king-addons'),
341 'type' => Controls_Manager::SWITCHER,
342 'return_value' => 'yes',
343 'default' => 'yes',
344 ]
345 );
346
347 $this->add_control(
348 'kng_show_location',
349 [
350 'label' => esc_html__('Show Location', 'king-addons'),
351 'type' => Controls_Manager::SWITCHER,
352 'return_value' => 'yes',
353 'default' => 'yes',
354 ]
355 );
356
357 $this->add_control(
358 'kng_show_time',
359 [
360 'label' => esc_html__('Show Time', 'king-addons'),
361 'type' => Controls_Manager::SWITCHER,
362 'return_value' => 'yes',
363 'default' => 'yes',
364 ]
365 );
366
367 $this->end_controls_section();
368 }
369
370 /**
371 * Card style controls.
372 *
373 * @return void
374 */
375 protected function register_style_card_controls(): void
376 {
377 $this->start_controls_section(
378 'kng_style_card_section',
379 [
380 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Card', 'king-addons'),
381 'tab' => Controls_Manager::TAB_STYLE,
382 ]
383 );
384
385 $this->add_control(
386 'kng_card_bg',
387 [
388 'label' => esc_html__('Background', 'king-addons'),
389 'type' => Controls_Manager::COLOR,
390 'selectors' => [
391 '{{WRAPPER}} .king-addons-event-calendar__card' => 'background-color: {{VALUE}};',
392 ],
393 ]
394 );
395
396 $this->add_group_control(
397 Group_Control_Border::get_type(),
398 [
399 'name' => 'kng_card_border',
400 'selector' => '{{WRAPPER}} .king-addons-event-calendar__card',
401 ]
402 );
403
404 $this->add_control(
405 'kng_card_radius',
406 [
407 'label' => esc_html__('Border Radius', 'king-addons'),
408 'type' => Controls_Manager::SLIDER,
409 'size_units' => ['px', '%'],
410 'range' => [
411 'px' => ['min' => 0, 'max' => 40],
412 '%' => ['min' => 0, 'max' => 100],
413 ],
414 'selectors' => [
415 '{{WRAPPER}} .king-addons-event-calendar__card' => 'border-radius: {{SIZE}}{{UNIT}};',
416 ],
417 ]
418 );
419
420 $this->add_group_control(
421 Group_Control_Box_Shadow::get_type(),
422 [
423 'name' => 'kng_card_shadow',
424 'selector' => '{{WRAPPER}} .king-addons-event-calendar__card',
425 ]
426 );
427
428 $this->add_responsive_control(
429 'kng_card_padding',
430 [
431 'label' => esc_html__('Padding', 'king-addons'),
432 'type' => Controls_Manager::DIMENSIONS,
433 'size_units' => ['px', 'em'],
434 'selectors' => [
435 '{{WRAPPER}} .king-addons-event-calendar__card' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
436 ],
437 ]
438 );
439
440 $this->end_controls_section();
441 }
442
443 /**
444 * Text style controls.
445 *
446 * @return void
447 */
448 protected function register_style_text_controls(): void
449 {
450 $this->start_controls_section(
451 'kng_style_text_section',
452 [
453 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Text', 'king-addons'),
454 'tab' => Controls_Manager::TAB_STYLE,
455 ]
456 );
457
458 $this->add_group_control(
459 Group_Control_Typography::get_type(),
460 [
461 'name' => 'kng_title_typography',
462 'selector' => '{{WRAPPER}} .king-addons-event-calendar__title',
463 ]
464 );
465
466 $this->add_control(
467 'kng_title_color',
468 [
469 'label' => esc_html__('Title Color', 'king-addons'),
470 'type' => Controls_Manager::COLOR,
471 'selectors' => [
472 '{{WRAPPER}} .king-addons-event-calendar__title' => 'color: {{VALUE}};',
473 ],
474 ]
475 );
476
477 $this->add_group_control(
478 Group_Control_Typography::get_type(),
479 [
480 'name' => 'kng_meta_typography',
481 'selector' => '{{WRAPPER}} .king-addons-event-calendar__meta',
482 ]
483 );
484
485 $this->add_control(
486 'kng_meta_color',
487 [
488 'label' => esc_html__('Meta Color', 'king-addons'),
489 'type' => Controls_Manager::COLOR,
490 'selectors' => [
491 '{{WRAPPER}} .king-addons-event-calendar__meta' => 'color: {{VALUE}};',
492 ],
493 ]
494 );
495
496 $this->add_group_control(
497 Group_Control_Typography::get_type(),
498 [
499 'name' => 'kng_desc_typography',
500 'selector' => '{{WRAPPER}} .king-addons-event-calendar__description',
501 ]
502 );
503
504 $this->add_control(
505 'kng_desc_color',
506 [
507 'label' => esc_html__('Description Color', 'king-addons'),
508 'type' => Controls_Manager::COLOR,
509 'selectors' => [
510 '{{WRAPPER}} .king-addons-event-calendar__description' => 'color: {{VALUE}};',
511 ],
512 ]
513 );
514
515 $this->add_group_control(
516 Group_Control_Typography::get_type(),
517 [
518 'name' => 'kng_button_typography',
519 'selector' => '{{WRAPPER}} .king-addons-event-calendar__button',
520 ]
521 );
522
523 $this->add_control(
524 'kng_button_color',
525 [
526 'label' => esc_html__('Button Text Color', 'king-addons'),
527 'type' => Controls_Manager::COLOR,
528 'selectors' => [
529 '{{WRAPPER}} .king-addons-event-calendar__button' => 'color: {{VALUE}};',
530 ],
531 ]
532 );
533
534 $this->add_control(
535 'kng_button_bg',
536 [
537 'label' => esc_html__('Button Background', 'king-addons'),
538 'type' => Controls_Manager::COLOR,
539 'selectors' => [
540 '{{WRAPPER}} .king-addons-event-calendar__button' => 'background-color: {{VALUE}};',
541 ],
542 ]
543 );
544
545 $this->add_control(
546 'kng_button_radius',
547 [
548 'label' => esc_html__('Button Radius', 'king-addons'),
549 'type' => Controls_Manager::SLIDER,
550 'size_units' => ['px', '%'],
551 'range' => [
552 'px' => ['min' => 0, 'max' => 40],
553 '%' => ['min' => 0, 'max' => 100],
554 ],
555 'selectors' => [
556 '{{WRAPPER}} .king-addons-event-calendar__button' => 'border-radius: {{SIZE}}{{UNIT}};',
557 ],
558 ]
559 );
560
561 $this->end_controls_section();
562 }
563
564 /**
565 * Badge style controls.
566 *
567 * @return void
568 */
569 protected function register_style_badge_controls(): void
570 {
571 $this->start_controls_section(
572 'kng_style_badge_section',
573 [
574 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Date Badge', 'king-addons'),
575 'tab' => Controls_Manager::TAB_STYLE,
576 ]
577 );
578
579 $this->add_group_control(
580 Group_Control_Typography::get_type(),
581 [
582 'name' => 'kng_badge_typography',
583 'selector' => '{{WRAPPER}} .king-addons-event-calendar__badge',
584 ]
585 );
586
587 $this->add_control(
588 'kng_badge_text_color',
589 [
590 'label' => esc_html__('Text Color', 'king-addons'),
591 'type' => Controls_Manager::COLOR,
592 'selectors' => [
593 '{{WRAPPER}} .king-addons-event-calendar__badge' => 'color: {{VALUE}};',
594 ],
595 ]
596 );
597
598 $this->add_control(
599 'kng_badge_bg',
600 [
601 'label' => esc_html__('Background', 'king-addons'),
602 'type' => Controls_Manager::COLOR,
603 'selectors' => [
604 '{{WRAPPER}} .king-addons-event-calendar__badge' => 'background-color: {{VALUE}};',
605 ],
606 ]
607 );
608
609 $this->add_control(
610 'kng_badge_radius',
611 [
612 'label' => esc_html__('Radius', 'king-addons'),
613 'type' => Controls_Manager::SLIDER,
614 'size_units' => ['px', '%'],
615 'range' => [
616 'px' => ['min' => 0, 'max' => 30],
617 '%' => ['min' => 0, 'max' => 100],
618 ],
619 'selectors' => [
620 '{{WRAPPER}} .king-addons-event-calendar__badge' => 'border-radius: {{SIZE}}{{UNIT}};',
621 ],
622 ]
623 );
624
625 $this->end_controls_section();
626 }
627
628 /**
629 * Render pro notice.
630 *
631 * @return void
632 */
633 public function register_pro_notice_controls(): void
634 {
635 if (!king_addons_can_use_pro()) {
636 Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'event-calendar', [
637 'Filters (category, search, upcoming only)',
638 'Date range filter and compact layout',
639 'Hover animations and category chips',
640 'Highlight ongoing events',
641 ]);
642 }
643 }
644
645 /**
646 * Get events parsed and sorted.
647 *
648 * @param array<string, mixed> $settings Settings.
649 *
650 * @return array<int, array<string, mixed>>
651 */
652 protected function get_events(array $settings): array
653 {
654 $events = [];
655 if (empty($settings['kng_events']) || !is_array($settings['kng_events'])) {
656 return $events;
657 }
658
659 foreach ($settings['kng_events'] as $item) {
660 $start = isset($item['kng_event_date']) ? strtotime((string) $item['kng_event_date']) : null;
661 $end = isset($item['kng_event_end_date']) ? strtotime((string) $item['kng_event_end_date']) : null;
662
663 $events[] = [
664 'title' => $item['kng_event_title'] ?? '',
665 'start' => $start,
666 'end' => $end,
667 'time_label' => $item['kng_event_time_label'] ?? '',
668 'location' => $item['kng_event_location'] ?? '',
669 'category' => $item['kng_event_category'] ?? '',
670 'color' => $item['kng_event_color'] ?? '',
671 'description' => $item['kng_event_description'] ?? '',
672 'link' => $item['kng_event_link'] ?? [],
673 ];
674 }
675
676 usort(
677 $events,
678 static function ($a, $b) {
679 return ($a['start'] ?? 0) <=> ($b['start'] ?? 0);
680 }
681 );
682
683 return $events;
684 }
685
686 /**
687 * Render single event card.
688 *
689 * @param array<string, mixed> $event Event data.
690 * @param array<string, mixed> $settings Settings.
691 *
692 * @return void
693 */
694 protected function render_event(array $event, array $settings): void
695 {
696 $this->render_event_base($event, $settings);
697 }
698
699 /**
700 * Render single event card base implementation.
701 *
702 * This method exists to allow the Pro version to extend event rendering
703 * without calling `parent::` methods.
704 *
705 * @param array<string, mixed> $event Event data.
706 * @param array<string, mixed> $settings Settings.
707 *
708 * @return void
709 */
710 protected function render_event_base(array $event, array $settings): void
711 {
712 $start_ts = $event['start'] ?? null;
713 $end_ts = $event['end'] ?? null;
714 $date_day = $start_ts ? date_i18n('d', $start_ts) : '';
715 $date_month = $start_ts ? date_i18n('M', $start_ts) : '';
716 $time_label = $event['time_label'] ?: ($start_ts ? date_i18n('H:i', $start_ts) : '');
717
718 $link = $event['link']['url'] ?? '';
719 $link_attrs = '';
720 if (!empty($link)) {
721 $is_external = !empty($event['link']['is_external']);
722 $nofollow = !empty($event['link']['nofollow']);
723 $rels = [];
724 if ($is_external) {
725 $rels[] = 'noopener';
726 $rels[] = 'noreferrer';
727 }
728 if ($nofollow) {
729 $rels[] = 'nofollow';
730 }
731 $rel_attr = !empty($rels) ? ' rel="' . esc_attr(implode(' ', array_unique($rels))) . '"' : '';
732 $target_attr = $is_external ? ' target="_blank"' : '';
733 $link_attrs = 'href="' . esc_url($link) . '"' . $target_attr . $rel_attr;
734 }
735
736 $item_classes = $event['item_classes'] ?? ['king-addons-event-calendar__item'];
737 $card_classes = $event['card_classes'] ?? ['king-addons-event-calendar__card'];
738 ?>
739 <article class="<?php echo esc_attr(implode(' ', $item_classes)); ?>"
740 data-date-start="<?php echo esc_attr($start_ts ?? ''); ?>"
741 data-date-end="<?php echo esc_attr($end_ts ?? ''); ?>"
742 data-category="<?php echo esc_attr($event['category']); ?>"
743 data-title="<?php echo esc_attr($event['title']); ?>">
744 <div class="<?php echo esc_attr(implode(' ', $card_classes)); ?>">
745 <div class="king-addons-event-calendar__badge" style="<?php echo $event['color'] ? 'background-color:' . esc_attr($event['color']) . ';' : ''; ?>">
746 <span class="king-addons-event-calendar__badge-day"><?php echo esc_html($date_day); ?></span>
747 <span class="king-addons-event-calendar__badge-month"><?php echo esc_html($date_month); ?></span>
748 </div>
749 <div class="king-addons-event-calendar__body">
750 <div class="king-addons-event-calendar__header">
751 <h3 class="king-addons-event-calendar__title"><?php echo esc_html($event['title']); ?></h3>
752 <?php if (!empty($event['category'])) : ?>
753 <span class="king-addons-event-calendar__chip" style="<?php echo $event['color'] ? 'color:' . esc_attr($event['color']) . ';border-color:' . esc_attr($event['color']) . ';' : ''; ?>">
754 <?php echo esc_html($event['category']); ?>
755 </span>
756 <?php endif; ?>
757 </div>
758 <div class="king-addons-event-calendar__meta">
759 <?php if (($settings['kng_show_time'] ?? 'yes') === 'yes' && ($time_label || $end_ts)) : ?>
760 <span class="king-addons-event-calendar__meta-item">
761 <?php echo esc_html($time_label); ?>
762 <?php if ($end_ts) : ?>
763 <?php echo ' - ' . esc_html(date_i18n('H:i', $end_ts)); ?>
764 <?php endif; ?>
765 </span>
766 <?php endif; ?>
767 <?php if (($settings['kng_show_location'] ?? 'yes') === 'yes' && !empty($event['location'])) : ?>
768 <span class="king-addons-event-calendar__meta-item">
769 <?php echo esc_html($event['location']); ?>
770 </span>
771 <?php endif; ?>
772 </div>
773 <?php if (($settings['kng_show_description'] ?? 'yes') === 'yes' && !empty($event['description'])) : ?>
774 <div class="king-addons-event-calendar__description">
775 <?php echo esc_html($event['description']); ?>
776 </div>
777 <?php endif; ?>
778 <?php if (($settings['kng_show_button'] ?? 'yes') === 'yes' && !empty($link_attrs)) : ?>
779 <div class="king-addons-event-calendar__actions">
780 <a class="king-addons-event-calendar__button" <?php echo $link_attrs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
781 <?php echo esc_html($settings['kng_cta_text'] ?? esc_html__('View details', 'king-addons')); ?>
782 </a>
783 </div>
784 <?php endif; ?>
785 </div>
786 </div>
787 </article>
788 <?php
789 }
790 }
791
792
793
794
795
796
797
798