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 / Quick_Post_Slider / Quick_Post_Slider.php

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

1,817 lines 61.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Quick Post Slider 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_Image_Size;
14 use Elementor\Group_Control_Typography;
15 use Elementor\Utils;
16 use Elementor\Widget_Base;
17 use WP_Query;
18
19 if (!defined('ABSPATH')) {
20 exit;
21 }
22
23 /**
24 * Renders the Quick Post Slider widget.
25 */
26 class Quick_Post_Slider extends Widget_Base
27 {
28 /**
29 * Widget slug.
30 */
31 public function get_name(): string
32 {
33 return 'king-addons-quick-post-slider';
34 }
35
36 /**
37 * Widget title.
38 */
39 public function get_title(): string
40 {
41 return esc_html__('Quick Post Slider', 'king-addons');
42 }
43
44 /**
45 * Widget icon.
46 */
47 public function get_icon(): string
48 {
49 return 'king-addons-icon king-addons-simple-post-slider';
50 }
51
52 /**
53 * Scripts used.
54 *
55 * @return array<string>
56 */
57 public function get_script_depends(): array
58 {
59 return [
60 KING_ADDONS_ASSETS_UNIQUE_KEY . '-swiper-swiper',
61 KING_ADDONS_ASSETS_UNIQUE_KEY . '-quick-post-slider-script',
62 ];
63 }
64
65 /**
66 * Styles used.
67 *
68 * @return array<string>
69 */
70 public function get_style_depends(): array
71 {
72 return [
73 KING_ADDONS_ASSETS_UNIQUE_KEY . '-swiper-swiper',
74 KING_ADDONS_ASSETS_UNIQUE_KEY . '-quick-post-slider-style',
75 ];
76 }
77
78 /**
79 * Widget categories.
80 */
81 public function get_categories(): array
82 {
83 return ['king-addons'];
84 }
85
86 /**
87 * Widget keywords.
88 */
89 public function get_keywords(): array
90 {
91 return ['posts', 'slider', 'carousel', 'blog', 'king-addons'];
92 }
93
94 /**
95 * Register controls.
96 */
97 public function register_controls(): void
98 {
99 $this->register_query_controls();
100 $this->register_slider_controls();
101 $this->register_interaction_controls();
102 $this->register_navigation_controls();
103 $this->register_pagination_controls();
104 $this->register_style_card_controls();
105 $this->register_style_text_controls();
106 $this->register_style_meta_controls();
107 $this->register_style_button_controls();
108 $this->register_pro_notice_controls();
109 }
110
111 /**
112 * Register Pro-only interaction controls placeholder.
113 *
114 * The Pro version overrides this method to add additional interaction
115 * controls without overriding the full `register_controls()` flow.
116 *
117 * @return void
118 */
119 public function register_interaction_controls(): void
120 {
121 // Intentionally empty in Free.
122 }
123
124 /**
125 * Render widget on frontend.
126 */
127 public function render(): void
128 {
129 $settings = $this->get_settings_for_display();
130 $this->render_output($settings);
131 }
132
133 /**
134 * Render output with settings.
135 *
136 * @param array<string, mixed> $settings settings.
137 */
138 public function render_output(array $settings): void
139 {
140 $query = $this->build_query($settings);
141
142 if (!$query->have_posts()) {
143 wp_reset_postdata();
144 return;
145 }
146
147 $wrapper_classes = $this->get_wrapper_classes($settings);
148 $wrapper_styles = $this->get_wrapper_style_attributes($settings);
149 $data_attributes = $this->get_slider_data_attributes($settings);
150
151 $show_navigation = ($settings['kng_show_navigation'] ?? '') === 'yes';
152 $show_pagination = ($settings['kng_show_pagination'] ?? '') === 'yes';
153
154 ?>
155 <div class="<?php echo esc_attr(implode(' ', $wrapper_classes)); ?>"<?php echo $wrapper_styles; ?>>
156 <div class="king-addons-post-slider__track swiper" <?php echo $data_attributes; ?>>
157 <div class="king-addons-post-slider__wrapper swiper-wrapper">
158 <?php
159 while ($query->have_posts()) :
160 $query->the_post();
161 $this->render_slide($settings);
162 endwhile;
163 ?>
164 </div>
165 <?php if ($show_pagination) : ?>
166 <div class="king-addons-post-slider__pagination swiper-pagination" aria-label="<?php echo esc_attr__('Slider pagination', 'king-addons'); ?>"></div>
167 <?php endif; ?>
168 </div>
169 <?php if ($show_navigation) : ?>
170 <div class="king-addons-post-slider__navigation" aria-label="<?php echo esc_attr__('Slider navigation', 'king-addons'); ?>">
171 <button type="button" class="king-addons-post-slider__arrow king-addons-post-slider__arrow--prev swiper-button-prev" aria-label="<?php echo esc_attr__('Previous slide', 'king-addons'); ?>">
172 <span class="king-addons-post-slider__arrow-icon" aria-hidden="true"></span>
173 </button>
174 <button type="button" class="king-addons-post-slider__arrow king-addons-post-slider__arrow--next swiper-button-next" aria-label="<?php echo esc_attr__('Next slide', 'king-addons'); ?>">
175 <span class="king-addons-post-slider__arrow-icon" aria-hidden="true"></span>
176 </button>
177 </div>
178 <?php endif; ?>
179 </div>
180 <?php
181 wp_reset_postdata();
182 }
183
184 public function add_pro_posts_number_controls(): void
185 {
186 $this->add_control(
187 'kng_posts_per_page',
188 [
189 'label' => esc_html__('Posts Number', 'king-addons'),
190 'type' => Controls_Manager::NUMBER,
191 'min' => 1,
192 'max' => 6,
193 'step' => 1,
194 'default' => 6,
195 'description' => esc_html__('Free version is limited to 6 posts.', 'king-addons'),
196 ]
197 );
198 }
199
200 /**
201 * Query controls.
202 */
203 protected function register_query_controls(): void
204 {
205 $this->start_controls_section(
206 'kng_query_section',
207 [
208 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Query', 'king-addons'),
209 'tab' => Controls_Manager::TAB_CONTENT,
210 ]
211 );
212
213 $this->add_pro_posts_number_controls();
214
215 $this->add_control(
216 'kng_orderby',
217 [
218 'label' => esc_html__('Order By', 'king-addons'),
219 'type' => Controls_Manager::SELECT,
220 'default' => 'date',
221 'options' => [
222 'date' => esc_html__('Date', 'king-addons'),
223 'title' => esc_html__('Title', 'king-addons'),
224 'rand' => esc_html__('Random', 'king-addons'),
225 'menu_order' => esc_html__('Menu Order', 'king-addons'),
226 ],
227 ]
228 );
229
230 $this->add_control(
231 'kng_order',
232 [
233 'label' => esc_html__('Order', 'king-addons'),
234 'type' => Controls_Manager::SELECT,
235 'default' => 'DESC',
236 'options' => [
237 'DESC' => esc_html__('Descending', 'king-addons'),
238 'ASC' => esc_html__('Ascending', 'king-addons'),
239 ],
240 ]
241 );
242
243 $this->add_control_categories();
244
245 $this->add_control(
246 'kng_exclude_sticky',
247 [
248 'label' => esc_html__('Ignore Sticky Posts', 'king-addons'),
249 'type' => Controls_Manager::SWITCHER,
250 'return_value' => 'yes',
251 'default' => 'yes',
252 ]
253 );
254
255 $this->add_control(
256 'kng_show_image',
257 [
258 'label' => esc_html__('Show Featured Image', 'king-addons'),
259 'type' => Controls_Manager::SWITCHER,
260 'return_value' => 'yes',
261 'default' => 'yes',
262 ]
263 );
264
265 $this->add_group_control(
266 Group_Control_Image_Size::get_type(),
267 [
268 'name' => 'kng_image_size',
269 'default' => 'medium',
270 'condition' => [
271 'kng_show_image' => 'yes',
272 ],
273 ]
274 );
275
276 $this->add_control(
277 'kng_image_ratio',
278 [
279 'label' => esc_html__('Image Ratio', 'king-addons'),
280 'type' => Controls_Manager::SELECT,
281 'default' => 'original',
282 'options' => [
283 'original' => esc_html__('Original', 'king-addons'),
284 'square' => esc_html__('1:1', 'king-addons'),
285 '4-3' => esc_html__('4:3', 'king-addons'),
286 '3-2' => esc_html__('3:2', 'king-addons'),
287 '16-9' => esc_html__('16:9', 'king-addons'),
288 ],
289 'condition' => [
290 'kng_show_image' => 'yes',
291 ],
292 ]
293 );
294
295 $this->add_control(
296 'kng_image_fit',
297 [
298 'label' => esc_html__('Image Fit', 'king-addons'),
299 'type' => Controls_Manager::SELECT,
300 'default' => 'cover',
301 'options' => [
302 'cover' => esc_html__('Cover', 'king-addons'),
303 'contain' => esc_html__('Contain', 'king-addons'),
304 ],
305 'condition' => [
306 'kng_show_image' => 'yes',
307 ],
308 'selectors' => [
309 '{{WRAPPER}} .king-addons-post-slider' => '--kng-post-slider-image-fit: {{VALUE}};',
310 ],
311 ]
312 );
313
314 $this->add_responsive_control(
315 'kng_image_radius',
316 [
317 'label' => esc_html__('Image Border Radius', 'king-addons'),
318 'type' => Controls_Manager::SLIDER,
319 'size_units' => ['px', '%'],
320 'range' => [
321 'px' => ['min' => 0, 'max' => 60],
322 '%' => ['min' => 0, 'max' => 100],
323 ],
324 'condition' => [
325 'kng_show_image' => 'yes',
326 ],
327 'selectors' => [
328 '{{WRAPPER}} .king-addons-post-slider__media' => 'border-radius: {{SIZE}}{{UNIT}};',
329 ],
330 ]
331 );
332
333 $this->add_responsive_control(
334 'kng_image_spacing',
335 [
336 'label' => esc_html__('Image Bottom Spacing', 'king-addons'),
337 'type' => Controls_Manager::SLIDER,
338 'size_units' => ['px'],
339 'range' => [
340 'px' => ['min' => 0, 'max' => 80],
341 ],
342 'condition' => [
343 'kng_show_image' => 'yes',
344 ],
345 'selectors' => [
346 '{{WRAPPER}} .king-addons-post-slider__media' => 'margin-bottom: {{SIZE}}{{UNIT}};',
347 ],
348 ]
349 );
350
351 $this->add_control(
352 'kng_show_meta',
353 [
354 'label' => esc_html__('Show Meta', 'king-addons'),
355 'type' => Controls_Manager::SWITCHER,
356 'return_value' => 'yes',
357 'default' => 'yes',
358 ]
359 );
360
361 $this->add_control(
362 'kng_show_author',
363 [
364 'label' => esc_html__('Show Author', 'king-addons'),
365 'type' => Controls_Manager::SWITCHER,
366 'return_value' => 'yes',
367 'default' => 'yes',
368 'condition' => [
369 'kng_show_meta' => 'yes',
370 ],
371 ]
372 );
373
374 $this->add_control(
375 'kng_show_date',
376 [
377 'label' => esc_html__('Show Date', 'king-addons'),
378 'type' => Controls_Manager::SWITCHER,
379 'return_value' => 'yes',
380 'default' => 'yes',
381 'condition' => [
382 'kng_show_meta' => 'yes',
383 ],
384 ]
385 );
386
387 $this->add_control(
388 'kng_meta_separator',
389 [
390 'label' => esc_html__('Meta Separator', 'king-addons'),
391 'type' => Controls_Manager::TEXT,
392 'default' => '',
393 'condition' => [
394 'kng_show_meta' => 'yes',
395 ],
396 ]
397 );
398
399 $this->add_control(
400 'kng_show_excerpt',
401 [
402 'label' => esc_html__('Show Excerpt', 'king-addons'),
403 'type' => Controls_Manager::SWITCHER,
404 'return_value' => 'yes',
405 'default' => 'yes',
406 ]
407 );
408
409 $this->add_control(
410 'kng_excerpt_length',
411 [
412 'label' => esc_html__('Excerpt Length (words)', 'king-addons'),
413 'type' => Controls_Manager::NUMBER,
414 'min' => 5,
415 'max' => 80,
416 'step' => 1,
417 'default' => 18,
418 'condition' => [
419 'kng_show_excerpt' => 'yes',
420 ],
421 ]
422 );
423
424 $this->add_control(
425 'kng_show_read_more',
426 [
427 'label' => esc_html__('Show Read More', 'king-addons'),
428 'type' => Controls_Manager::SWITCHER,
429 'return_value' => 'yes',
430 'default' => 'yes',
431 ]
432 );
433
434 $this->add_control(
435 'kng_read_more_text',
436 [
437 'label' => esc_html__('Read More Text', 'king-addons'),
438 'type' => Controls_Manager::TEXT,
439 'default' => esc_html__('Read more', 'king-addons'),
440 'condition' => [
441 'kng_show_read_more' => 'yes',
442 ],
443 ]
444 );
445
446 $this->add_control(
447 'kng_card_linkable',
448 [
449 'label' => esc_html__('Make Card Clickable', 'king-addons'),
450 'type' => Controls_Manager::SWITCHER,
451 'label_on' => esc_html__('Yes', 'king-addons'),
452 'label_off' => esc_html__('No', 'king-addons'),
453 'return_value' => 'yes',
454 'default' => '',
455 'description' => esc_html__('Card click is disabled inside the Elementor editor to avoid interfering with editing.', 'king-addons'),
456 ]
457 );
458
459 $this->add_control(
460 'kng_card_link_new_tab',
461 [
462 'label' => esc_html__('Open Card in New Tab', 'king-addons'),
463 'type' => Controls_Manager::SWITCHER,
464 'return_value' => 'yes',
465 'default' => '',
466 'condition' => [
467 'kng_card_linkable' => 'yes',
468 ],
469 ]
470 );
471
472 $this->end_controls_section();
473 }
474
475 /**
476 * Categories control (Pro-only entry point).
477 *
478 * @return void
479 */
480 protected function add_control_categories(): void
481 {
482 $this->add_control(
483 'kng_categories',
484 [
485 'label' => sprintf(__('Categories %s', 'king-addons'), '<i class="eicon-pro-icon"></i>'),
486 'type' => Controls_Manager::TEXT,
487 'description' => esc_html__('Enter category slugs separated by commas.', 'king-addons'),
488 'placeholder' => esc_html__('news,features', 'king-addons'),
489 'classes' => 'king-addons-pro-control no-distance',
490 ]
491 );
492 }
493
494 /**
495 * Slider controls.
496 */
497 protected function register_slider_controls(): void
498 {
499 $this->start_controls_section(
500 'kng_slider_section',
501 [
502 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Slider Settings', 'king-addons'),
503 'tab' => Controls_Manager::TAB_CONTENT,
504 ]
505 );
506
507 $this->add_control(
508 'kng_slides_per_view',
509 [
510 'label' => esc_html__('Slides Per View', 'king-addons'),
511 'type' => Controls_Manager::NUMBER,
512 'min' => 1,
513 'max' => 6,
514 'step' => 1,
515 'default' => 3,
516 ]
517 );
518
519 $this->add_control(
520 'kng_slides_per_view_tablet',
521 [
522 'label' => esc_html__('Slides Per View (Tablet)', 'king-addons'),
523 'type' => Controls_Manager::NUMBER,
524 'min' => 1,
525 'max' => 6,
526 'step' => 1,
527 'default' => 2,
528 ]
529 );
530
531 $this->add_control(
532 'kng_slides_per_view_mobile',
533 [
534 'label' => esc_html__('Slides Per View (Mobile)', 'king-addons'),
535 'type' => Controls_Manager::NUMBER,
536 'min' => 1,
537 'max' => 6,
538 'step' => 1,
539 'default' => 1,
540 ]
541 );
542
543 $this->add_control(
544 'kng_space_between',
545 [
546 'label' => esc_html__('Space Between (px)', 'king-addons'),
547 'type' => Controls_Manager::SLIDER,
548 'size_units' => ['px'],
549 'range' => [
550 'px' => [
551 'min' => 0,
552 'max' => 80,
553 ],
554 ],
555 'default' => [
556 'size' => 20,
557 'unit' => 'px',
558 ],
559 ]
560 );
561
562 $this->add_control(
563 'kng_loop',
564 [
565 'label' => esc_html__('Loop', 'king-addons'),
566 'type' => Controls_Manager::SWITCHER,
567 'label_on' => esc_html__('Yes', 'king-addons'),
568 'label_off' => esc_html__('No', 'king-addons'),
569 'return_value' => 'yes',
570 'default' => 'yes',
571 ]
572 );
573
574 $this->add_control(
575 'kng_autoplay',
576 [
577 'label' => esc_html__('Autoplay', 'king-addons'),
578 'type' => Controls_Manager::SWITCHER,
579 'label_on' => esc_html__('Yes', 'king-addons'),
580 'label_off' => esc_html__('No', 'king-addons'),
581 'return_value' => 'yes',
582 'default' => 'yes',
583 ]
584 );
585
586 $this->add_control(
587 'kng_autoplay_delay',
588 [
589 'label' => esc_html__('Autoplay Delay (ms)', 'king-addons'),
590 'type' => Controls_Manager::NUMBER,
591 'min' => 100,
592 'step' => 100,
593 'default' => 3200,
594 'condition' => [
595 'kng_autoplay' => 'yes',
596 ],
597 ]
598 );
599
600 $this->add_control(
601 'kng_autoplay_pause_on_hover',
602 [
603 'label' => esc_html__('Pause on Hover', 'king-addons'),
604 'type' => Controls_Manager::SWITCHER,
605 'return_value' => 'yes',
606 'default' => '',
607 'condition' => [
608 'kng_autoplay' => 'yes',
609 ],
610 ]
611 );
612
613 $this->add_control(
614 'kng_autoplay_stop_on_interaction',
615 [
616 'label' => esc_html__('Stop on Interaction', 'king-addons'),
617 'type' => Controls_Manager::SWITCHER,
618 'return_value' => 'yes',
619 'default' => '',
620 'condition' => [
621 'kng_autoplay' => 'yes',
622 ],
623 ]
624 );
625
626 $this->add_control(
627 'kng_speed',
628 [
629 'label' => esc_html__('Transition Speed (ms)', 'king-addons'),
630 'type' => Controls_Manager::NUMBER,
631 'min' => 100,
632 'step' => 50,
633 'default' => 600,
634 ]
635 );
636
637 $this->end_controls_section();
638 }
639
640 /**
641 * Navigation controls.
642 */
643 protected function register_navigation_controls(): void
644 {
645 $this->start_controls_section(
646 'kng_navigation_section',
647 [
648 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Navigation', 'king-addons'),
649 'tab' => Controls_Manager::TAB_CONTENT,
650 ]
651 );
652
653 $this->add_control(
654 'kng_show_navigation',
655 [
656 'label' => esc_html__('Show Arrows', 'king-addons'),
657 'type' => Controls_Manager::SWITCHER,
658 'return_value' => 'yes',
659 'default' => 'yes',
660 ]
661 );
662
663 $this->add_control(
664 'kng_navigation_position',
665 [
666 'label' => esc_html__('Position', 'king-addons'),
667 'type' => Controls_Manager::SELECT,
668 'default' => 'outside',
669 'options' => [
670 'outside' => esc_html__('Outside', 'king-addons'),
671 'inside' => esc_html__('Inside', 'king-addons'),
672 ],
673 'condition' => [
674 'kng_show_navigation' => 'yes',
675 ],
676 ]
677 );
678
679 $this->add_control(
680 'kng_navigation_alignment',
681 [
682 'label' => esc_html__('Alignment', 'king-addons'),
683 'type' => Controls_Manager::CHOOSE,
684 'options' => [
685 'flex-start' => [
686 'title' => esc_html__('Top', 'king-addons'),
687 'icon' => 'eicon-v-align-top',
688 ],
689 'center' => [
690 'title' => esc_html__('Center', 'king-addons'),
691 'icon' => 'eicon-v-align-middle',
692 ],
693 'flex-end' => [
694 'title' => esc_html__('Bottom', 'king-addons'),
695 'icon' => 'eicon-v-align-bottom',
696 ],
697 ],
698 'toggle' => false,
699 'default' => 'center',
700 'condition' => [
701 'kng_show_navigation' => 'yes',
702 ],
703 ]
704 );
705
706 $this->add_responsive_control(
707 'kng_navigation_offset',
708 [
709 'label' => esc_html__('Offset', 'king-addons'),
710 'type' => Controls_Manager::SLIDER,
711 'size_units' => ['px'],
712 'range' => [
713 'px' => [
714 'min' => 0,
715 'max' => 80,
716 ],
717 ],
718 'default' => [
719 'size' => 25,
720 'unit' => 'px',
721 ],
722 'condition' => [
723 'kng_show_navigation' => 'yes',
724 ],
725 'selectors' => [
726 '{{WRAPPER}} .king-addons-post-slider' => '--kng-post-slider-nav-offset: {{SIZE}}{{UNIT}};',
727 ],
728 ]
729 );
730
731 $this->add_control(
732 'kng_navigation_gap',
733 [
734 'label' => esc_html__('Arrows Gap', 'king-addons'),
735 'type' => Controls_Manager::SLIDER,
736 'size_units' => ['px'],
737 'range' => [
738 'px' => [
739 'min' => 4,
740 'max' => 80,
741 ],
742 ],
743 'default' => [
744 'size' => 12,
745 'unit' => 'px',
746 ],
747 'condition' => [
748 'kng_show_navigation' => 'yes',
749 ],
750 'selectors' => [
751 '{{WRAPPER}} .king-addons-post-slider' => '--kng-post-slider-nav-gap: {{SIZE}}{{UNIT}};',
752 ],
753 ]
754 );
755
756 $this->add_control(
757 'kng_navigation_hide_tablet',
758 [
759 'label' => esc_html__('Hide on Tablet', 'king-addons'),
760 'type' => Controls_Manager::SWITCHER,
761 'label_on' => esc_html__('Yes', 'king-addons'),
762 'label_off' => esc_html__('No', 'king-addons'),
763 'return_value' => 'yes',
764 'condition' => [
765 'kng_show_navigation' => 'yes',
766 ],
767 ]
768 );
769
770 $this->add_control(
771 'kng_navigation_hide_mobile',
772 [
773 'label' => esc_html__('Hide on Mobile', 'king-addons'),
774 'type' => Controls_Manager::SWITCHER,
775 'label_on' => esc_html__('Yes', 'king-addons'),
776 'label_off' => esc_html__('No', 'king-addons'),
777 'return_value' => 'yes',
778 'condition' => [
779 'kng_show_navigation' => 'yes',
780 ],
781 ]
782 );
783
784 $this->add_pro_navigation_controls();
785
786 $this->end_controls_section();
787 }
788
789 /**
790 * Pagination controls.
791 */
792 protected function register_pagination_controls(): void
793 {
794 $this->start_controls_section(
795 'kng_pagination_section',
796 [
797 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Pagination', 'king-addons'),
798 'tab' => Controls_Manager::TAB_CONTENT,
799 ]
800 );
801
802 $this->add_control(
803 'kng_show_pagination',
804 [
805 'label' => esc_html__('Show Pagination', 'king-addons'),
806 'type' => Controls_Manager::SWITCHER,
807 'return_value' => 'yes',
808 'default' => 'yes',
809 ]
810 );
811
812 $this->add_control(
813 'kng_pagination_position',
814 [
815 'label' => esc_html__('Position', 'king-addons'),
816 'type' => Controls_Manager::SELECT,
817 'default' => 'outside',
818 'options' => [
819 'outside' => esc_html__('Outside', 'king-addons'),
820 'inside' => esc_html__('Inside', 'king-addons'),
821 ],
822 'condition' => [
823 'kng_show_pagination' => 'yes',
824 ],
825 ]
826 );
827
828 $this->add_control(
829 'kng_pagination_alignment',
830 [
831 'label' => esc_html__('Alignment', 'king-addons'),
832 'type' => Controls_Manager::CHOOSE,
833 'options' => [
834 'flex-start' => [
835 'title' => esc_html__('Start', 'king-addons'),
836 'icon' => 'eicon-h-align-left',
837 ],
838 'center' => [
839 'title' => esc_html__('Center', 'king-addons'),
840 'icon' => 'eicon-h-align-center',
841 ],
842 'flex-end' => [
843 'title' => esc_html__('End', 'king-addons'),
844 'icon' => 'eicon-h-align-right',
845 ],
846 ],
847 'toggle' => false,
848 'default' => 'center',
849 'condition' => [
850 'kng_show_pagination' => 'yes',
851 ],
852 ]
853 );
854
855 $this->add_responsive_control(
856 'kng_pagination_offset',
857 [
858 'label' => esc_html__('Offset', 'king-addons'),
859 'type' => Controls_Manager::SLIDER,
860 'size_units' => ['px'],
861 'range' => [
862 'px' => [
863 'min' => 0,
864 'max' => 80,
865 ],
866 ],
867 'default' => [
868 'size' => 14,
869 'unit' => 'px',
870 ],
871 'condition' => [
872 'kng_show_pagination' => 'yes',
873 ],
874 'selectors' => [
875 '{{WRAPPER}} .king-addons-post-slider' => '--kng-post-slider-pagination-offset: {{SIZE}}{{UNIT}};',
876 ],
877 ]
878 );
879
880 $this->add_responsive_control(
881 'kng_pagination_gap',
882 [
883 'label' => esc_html__('Dots Gap', 'king-addons'),
884 'type' => Controls_Manager::SLIDER,
885 'size_units' => ['px'],
886 'range' => [
887 'px' => [
888 'min' => 2,
889 'max' => 36,
890 ],
891 ],
892 'default' => [
893 'size' => 10,
894 'unit' => 'px',
895 ],
896 'condition' => [
897 'kng_show_pagination' => 'yes',
898 ],
899 'selectors' => [
900 '{{WRAPPER}} .king-addons-post-slider' => '--kng-post-slider-pagination-gap: {{SIZE}}{{UNIT}};',
901 ],
902 ]
903 );
904
905 $this->add_pro_pagination_controls();
906
907 $this->end_controls_section();
908 }
909
910 /**
911 * Card style controls.
912 */
913 protected function register_style_card_controls(): void
914 {
915 $this->start_controls_section(
916 'kng_style_card_section',
917 [
918 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Card', 'king-addons'),
919 'tab' => Controls_Manager::TAB_STYLE,
920 ]
921 );
922
923 $this->add_responsive_control(
924 'kng_track_padding',
925 [
926 'label' => esc_html__('Track Padding', 'king-addons'),
927 'type' => Controls_Manager::DIMENSIONS,
928 'size_units' => ['px', '%', 'em'],
929 'selectors' => [
930 '{{WRAPPER}} .king-addons-post-slider__track' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
931 ],
932 ]
933 );
934
935 $this->add_responsive_control(
936 'kng_card_padding',
937 [
938 'label' => esc_html__('Card Padding', 'king-addons'),
939 'type' => Controls_Manager::DIMENSIONS,
940 'size_units' => ['px', '%', 'em'],
941 'selectors' => [
942 '{{WRAPPER}} .king-addons-post-slider__card' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
943 ],
944 ]
945 );
946
947 $this->add_control(
948 'kng_card_background',
949 [
950 'label' => esc_html__('Background', 'king-addons'),
951 'type' => Controls_Manager::COLOR,
952 'selectors' => [
953 '{{WRAPPER}} .king-addons-post-slider__card' => 'background-color: {{VALUE}};',
954 ],
955 ]
956 );
957
958 $this->add_control(
959 'kng_card_background_hover',
960 [
961 'label' => esc_html__('Background Hover', 'king-addons'),
962 'type' => Controls_Manager::COLOR,
963 'selectors' => [
964 '{{WRAPPER}} .king-addons-post-slider__card:hover' => 'background-color: {{VALUE}};',
965 ],
966 ]
967 );
968
969 $this->add_group_control(
970 Group_Control_Border::get_type(),
971 [
972 'name' => 'kng_card_border',
973 'selector' => '{{WRAPPER}} .king-addons-post-slider__card',
974 ]
975 );
976
977 $this->add_control(
978 'kng_card_border_color_hover',
979 [
980 'label' => esc_html__('Border Color Hover', 'king-addons'),
981 'type' => Controls_Manager::COLOR,
982 'selectors' => [
983 '{{WRAPPER}} .king-addons-post-slider__card:hover' => 'border-color: {{VALUE}};',
984 ],
985 ]
986 );
987
988 $this->add_control(
989 'kng_card_radius',
990 [
991 'label' => esc_html__('Border Radius', 'king-addons'),
992 'type' => Controls_Manager::SLIDER,
993 'size_units' => ['px', '%'],
994 'range' => [
995 'px' => [
996 'min' => 0,
997 'max' => 60,
998 ],
999 '%' => [
1000 'min' => 0,
1001 'max' => 100,
1002 ],
1003 ],
1004 'selectors' => [
1005 '{{WRAPPER}} .king-addons-post-slider__card' => 'border-radius: {{SIZE}}{{UNIT}};',
1006 ],
1007 ]
1008 );
1009
1010 $this->add_group_control(
1011 Group_Control_Box_Shadow::get_type(),
1012 [
1013 'name' => 'kng_card_shadow',
1014 'selector' => '{{WRAPPER}} .king-addons-post-slider__card',
1015 ]
1016 );
1017
1018 $this->add_group_control(
1019 Group_Control_Box_Shadow::get_type(),
1020 [
1021 'name' => 'kng_card_shadow_hover',
1022 'selector' => '{{WRAPPER}} .king-addons-post-slider__card:hover',
1023 ]
1024 );
1025
1026 $this->add_control(
1027 'kng_card_shadow_disable',
1028 [
1029 'label' => esc_html__('Disable Box Shadow', 'king-addons'),
1030 'type' => Controls_Manager::SWITCHER,
1031 'label_on' => esc_html__('Yes', 'king-addons'),
1032 'label_off' => esc_html__('No', 'king-addons'),
1033 'return_value' => 'yes',
1034 'default' => '',
1035 'selectors' => [
1036 '{{WRAPPER}} .king-addons-post-slider__card' => 'box-shadow: none !important;',
1037 ],
1038 ]
1039 );
1040
1041 $this->add_control(
1042 'kng_card_shadow_hover_disable',
1043 [
1044 'label' => esc_html__('Disable Box Shadow on Hover', 'king-addons'),
1045 'type' => Controls_Manager::SWITCHER,
1046 'label_on' => esc_html__('Yes', 'king-addons'),
1047 'label_off' => esc_html__('No', 'king-addons'),
1048 'return_value' => 'yes',
1049 'default' => '',
1050 'selectors' => [
1051 '{{WRAPPER}} .king-addons-post-slider__card:hover' => 'box-shadow: none !important;',
1052 ],
1053 ]
1054 );
1055
1056 $this->end_controls_section();
1057 }
1058
1059 /**
1060 * Text style controls.
1061 */
1062 protected function register_style_text_controls(): void
1063 {
1064 $this->start_controls_section(
1065 'kng_style_text_section',
1066 [
1067 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Text', 'king-addons'),
1068 'tab' => Controls_Manager::TAB_STYLE,
1069 ]
1070 );
1071
1072 $this->add_group_control(
1073 Group_Control_Typography::get_type(),
1074 [
1075 'name' => 'kng_title_typography',
1076 'selector' => '{{WRAPPER}} .king-addons-post-slider__title',
1077 ]
1078 );
1079
1080 $this->add_control(
1081 'kng_title_color',
1082 [
1083 'label' => esc_html__('Title Color', 'king-addons'),
1084 'type' => Controls_Manager::COLOR,
1085 'selectors' => [
1086 '{{WRAPPER}} .king-addons-post-slider__title a' => 'color: {{VALUE}};',
1087 ],
1088 ]
1089 );
1090
1091 $this->add_responsive_control(
1092 'kng_title_spacing',
1093 [
1094 'label' => esc_html__('Title Bottom Spacing', 'king-addons'),
1095 'type' => Controls_Manager::SLIDER,
1096 'size_units' => ['px'],
1097 'range' => [
1098 'px' => ['min' => 0, 'max' => 60],
1099 ],
1100 'selectors' => [
1101 '{{WRAPPER}} .king-addons-post-slider__title' => 'margin-bottom: {{SIZE}}{{UNIT}};',
1102 ],
1103 ]
1104 );
1105
1106 $this->add_group_control(
1107 Group_Control_Typography::get_type(),
1108 [
1109 'name' => 'kng_excerpt_typography',
1110 'selector' => '{{WRAPPER}} .king-addons-post-slider__excerpt',
1111 ]
1112 );
1113
1114 $this->add_control(
1115 'kng_excerpt_color',
1116 [
1117 'label' => esc_html__('Excerpt Color', 'king-addons'),
1118 'type' => Controls_Manager::COLOR,
1119 'selectors' => [
1120 '{{WRAPPER}} .king-addons-post-slider__excerpt' => 'color: {{VALUE}};',
1121 ],
1122 ]
1123 );
1124
1125 $this->add_responsive_control(
1126 'kng_excerpt_spacing',
1127 [
1128 'label' => esc_html__('Excerpt Bottom Spacing', 'king-addons'),
1129 'type' => Controls_Manager::SLIDER,
1130 'size_units' => ['px'],
1131 'range' => [
1132 'px' => ['min' => 0, 'max' => 80],
1133 ],
1134 'selectors' => [
1135 '{{WRAPPER}} .king-addons-post-slider__excerpt' => 'margin-bottom: {{SIZE}}{{UNIT}};',
1136 ],
1137 ]
1138 );
1139
1140 $this->add_control(
1141 'kng_text_alignment',
1142 [
1143 'label' => esc_html__('Text Alignment', 'king-addons'),
1144 'type' => Controls_Manager::CHOOSE,
1145 'options' => [
1146 'left' => [
1147 'title' => esc_html__('Left', 'king-addons'),
1148 'icon' => 'eicon-text-align-left',
1149 ],
1150 'center' => [
1151 'title' => esc_html__('Center', 'king-addons'),
1152 'icon' => 'eicon-text-align-center',
1153 ],
1154 'right' => [
1155 'title' => esc_html__('Right', 'king-addons'),
1156 'icon' => 'eicon-text-align-right',
1157 ],
1158 ],
1159 'toggle' => false,
1160 'default' => 'left',
1161 'prefix_class' => 'king-addons-post-slider--text-align-',
1162 ]
1163 );
1164
1165 $this->end_controls_section();
1166 }
1167
1168 /**
1169 * Meta style controls.
1170 */
1171 protected function register_style_meta_controls(): void
1172 {
1173 $this->start_controls_section(
1174 'kng_style_meta_section',
1175 [
1176 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Meta', 'king-addons'),
1177 'tab' => Controls_Manager::TAB_STYLE,
1178 'condition' => [
1179 'kng_show_meta' => 'yes',
1180 ],
1181 ]
1182 );
1183
1184 $this->add_group_control(
1185 Group_Control_Typography::get_type(),
1186 [
1187 'name' => 'kng_meta_typography',
1188 'selector' => '{{WRAPPER}} .king-addons-post-slider__meta',
1189 ]
1190 );
1191
1192 $this->add_control(
1193 'kng_meta_color',
1194 [
1195 'label' => esc_html__('Meta Color', 'king-addons'),
1196 'type' => Controls_Manager::COLOR,
1197 'selectors' => [
1198 '{{WRAPPER}} .king-addons-post-slider__meta' => 'color: {{VALUE}};',
1199 ],
1200 ]
1201 );
1202
1203 $this->add_responsive_control(
1204 'kng_meta_spacing',
1205 [
1206 'label' => esc_html__('Meta Bottom Spacing', 'king-addons'),
1207 'type' => Controls_Manager::SLIDER,
1208 'size_units' => ['px'],
1209 'range' => [
1210 'px' => ['min' => 0, 'max' => 60],
1211 ],
1212 'selectors' => [
1213 '{{WRAPPER}} .king-addons-post-slider__meta' => 'margin-bottom: {{SIZE}}{{UNIT}};',
1214 ],
1215 ]
1216 );
1217
1218 $this->end_controls_section();
1219 }
1220
1221 /**
1222 * Button style controls.
1223 */
1224 protected function register_style_button_controls(): void
1225 {
1226 $this->start_controls_section(
1227 'kng_style_button_section',
1228 [
1229 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Button', 'king-addons'),
1230 'tab' => Controls_Manager::TAB_STYLE,
1231 'condition' => [
1232 'kng_show_read_more' => 'yes',
1233 ],
1234 ]
1235 );
1236
1237 $this->add_control(
1238 'kng_button_alignment',
1239 [
1240 'label' => esc_html__('Button Alignment', 'king-addons'),
1241 'type' => Controls_Manager::CHOOSE,
1242 'options' => [
1243 'left' => [
1244 'title' => esc_html__('Left', 'king-addons'),
1245 'icon' => 'eicon-h-align-left',
1246 ],
1247 'center' => [
1248 'title' => esc_html__('Center', 'king-addons'),
1249 'icon' => 'eicon-h-align-center',
1250 ],
1251 'right' => [
1252 'title' => esc_html__('Right', 'king-addons'),
1253 'icon' => 'eicon-h-align-right',
1254 ],
1255 ],
1256 'toggle' => false,
1257 'default' => 'left',
1258 'prefix_class' => 'king-addons-post-slider--button-align-',
1259 ]
1260 );
1261
1262 $this->add_control(
1263 'kng_button_text_alignment',
1264 [
1265 'label' => esc_html__('Button Text Alignment', 'king-addons'),
1266 'type' => Controls_Manager::CHOOSE,
1267 'options' => [
1268 'left' => [
1269 'title' => esc_html__('Left', 'king-addons'),
1270 'icon' => 'eicon-h-align-left',
1271 ],
1272 'center' => [
1273 'title' => esc_html__('Center', 'king-addons'),
1274 'icon' => 'eicon-h-align-center',
1275 ],
1276 'right' => [
1277 'title' => esc_html__('Right', 'king-addons'),
1278 'icon' => 'eicon-h-align-right',
1279 ],
1280 ],
1281 'toggle' => false,
1282 'default' => 'center',
1283 'prefix_class' => 'king-addons-post-slider--button-text-align-',
1284 ]
1285 );
1286
1287 $this->add_control(
1288 'kng_button_full_width',
1289 [
1290 'label' => esc_html__('Full Width', 'king-addons'),
1291 'type' => Controls_Manager::SWITCHER,
1292 'return_value' => 'yes',
1293 'default' => '',
1294 'selectors' => [
1295 '{{WRAPPER}} .king-addons-post-slider__button' => 'width: 100%;',
1296 ],
1297 ]
1298 );
1299
1300 $this->add_group_control(
1301 Group_Control_Typography::get_type(),
1302 [
1303 'name' => 'kng_button_typography',
1304 'selector' => '{{WRAPPER}} .king-addons-post-slider__button',
1305 ]
1306 );
1307
1308 $this->start_controls_tabs('kng_button_tabs');
1309
1310 $this->start_controls_tab(
1311 'kng_button_tab_normal',
1312 [
1313 'label' => esc_html__('Normal', 'king-addons'),
1314 ]
1315 );
1316
1317 $this->add_control(
1318 'kng_button_text_color',
1319 [
1320 'label' => esc_html__('Text Color', 'king-addons'),
1321 'type' => Controls_Manager::COLOR,
1322 'selectors' => [
1323 '{{WRAPPER}} .king-addons-post-slider__button' => 'color: {{VALUE}};',
1324 ],
1325 ]
1326 );
1327
1328 $this->add_control(
1329 'kng_button_background',
1330 [
1331 'label' => esc_html__('Background', 'king-addons'),
1332 'type' => Controls_Manager::COLOR,
1333 'selectors' => [
1334 '{{WRAPPER}} .king-addons-post-slider__button' => 'background-color: {{VALUE}};',
1335 ],
1336 ]
1337 );
1338
1339 $this->add_group_control(
1340 Group_Control_Border::get_type(),
1341 [
1342 'name' => 'kng_button_border',
1343 'selector' => '{{WRAPPER}} .king-addons-post-slider__button',
1344 ]
1345 );
1346
1347 $this->add_group_control(
1348 Group_Control_Box_Shadow::get_type(),
1349 [
1350 'name' => 'kng_button_shadow',
1351 'selector' => '{{WRAPPER}} .king-addons-post-slider__button',
1352 ]
1353 );
1354
1355 $this->end_controls_tab();
1356
1357 $this->start_controls_tab(
1358 'kng_button_tab_hover',
1359 [
1360 'label' => esc_html__('Hover', 'king-addons'),
1361 ]
1362 );
1363
1364 $this->add_control(
1365 'kng_button_text_color_hover',
1366 [
1367 'label' => esc_html__('Text Color', 'king-addons'),
1368 'type' => Controls_Manager::COLOR,
1369 'selectors' => [
1370 '{{WRAPPER}} .king-addons-post-slider__button:hover' => 'color: {{VALUE}};',
1371 ],
1372 ]
1373 );
1374
1375 $this->add_control(
1376 'kng_button_background_hover',
1377 [
1378 'label' => esc_html__('Background', 'king-addons'),
1379 'type' => Controls_Manager::COLOR,
1380 'selectors' => [
1381 '{{WRAPPER}} .king-addons-post-slider__button:hover' => 'background-color: {{VALUE}};',
1382 ],
1383 ]
1384 );
1385
1386 $this->add_control(
1387 'kng_button_border_color_hover',
1388 [
1389 'label' => esc_html__('Border Color', 'king-addons'),
1390 'type' => Controls_Manager::COLOR,
1391 'selectors' => [
1392 '{{WRAPPER}} .king-addons-post-slider__button:hover' => 'border-color: {{VALUE}};',
1393 ],
1394 ]
1395 );
1396
1397 $this->add_group_control(
1398 Group_Control_Box_Shadow::get_type(),
1399 [
1400 'name' => 'kng_button_shadow_hover',
1401 'selector' => '{{WRAPPER}} .king-addons-post-slider__button:hover',
1402 ]
1403 );
1404
1405 $this->end_controls_tab();
1406
1407 $this->end_controls_tabs();
1408
1409 $this->add_responsive_control(
1410 'kng_button_spacing',
1411 [
1412 'label' => esc_html__('Button Top Spacing', 'king-addons'),
1413 'type' => Controls_Manager::SLIDER,
1414 'size_units' => ['px'],
1415 'range' => [
1416 'px' => ['min' => 0, 'max' => 80],
1417 ],
1418 'selectors' => [
1419 '{{WRAPPER}} .king-addons-post-slider__button' => 'margin-top: {{SIZE}}{{UNIT}};',
1420 ],
1421 'separator' => 'before',
1422 ]
1423 );
1424
1425 $this->add_responsive_control(
1426 'kng_button_padding',
1427 [
1428 'label' => esc_html__('Padding', 'king-addons'),
1429 'type' => Controls_Manager::DIMENSIONS,
1430 'size_units' => ['px', '%', 'em'],
1431 'selectors' => [
1432 '{{WRAPPER}} .king-addons-post-slider__button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1433 ],
1434 'separator' => 'before',
1435 ]
1436 );
1437
1438 $this->add_control(
1439 'kng_button_radius',
1440 [
1441 'label' => esc_html__('Border Radius', 'king-addons'),
1442 'type' => Controls_Manager::SLIDER,
1443 'size_units' => ['px', '%'],
1444 'range' => [
1445 'px' => ['min' => 0, 'max' => 80],
1446 '%' => ['min' => 0, 'max' => 100],
1447 ],
1448 'selectors' => [
1449 '{{WRAPPER}} .king-addons-post-slider__button' => 'border-radius: {{SIZE}}{{UNIT}};',
1450 ],
1451 ]
1452 );
1453
1454 $this->add_control(
1455 'kng_button_shadow_disable',
1456 [
1457 'label' => esc_html__('Disable Box Shadow', 'king-addons'),
1458 'type' => Controls_Manager::SWITCHER,
1459 'label_on' => esc_html__('Yes', 'king-addons'),
1460 'label_off' => esc_html__('No', 'king-addons'),
1461 'return_value' => 'yes',
1462 'default' => '',
1463 'selectors' => [
1464 '{{WRAPPER}} .king-addons-post-slider__button' => 'box-shadow: none !important;',
1465 ],
1466 ]
1467 );
1468
1469 $this->add_control(
1470 'kng_button_shadow_hover_disable',
1471 [
1472 'label' => esc_html__('Disable Box Shadow on Hover', 'king-addons'),
1473 'type' => Controls_Manager::SWITCHER,
1474 'label_on' => esc_html__('Yes', 'king-addons'),
1475 'label_off' => esc_html__('No', 'king-addons'),
1476 'return_value' => 'yes',
1477 'default' => '',
1478 'selectors' => [
1479 '{{WRAPPER}} .king-addons-post-slider__button:hover' => 'box-shadow: none !important;',
1480 ],
1481 ]
1482 );
1483
1484 $this->end_controls_section();
1485 }
1486
1487 /**
1488 * Build WP query.
1489 *
1490 * @param array<string, mixed> $settings settings.
1491 */
1492 protected function build_query(array $settings): WP_Query
1493 {
1494 $per_page = !empty($settings['kng_posts_per_page']) ? (int) $settings['kng_posts_per_page'] : 6;
1495 $order = strtoupper((string) ($settings['kng_order'] ?? 'DESC'));
1496 $order = in_array($order, ['ASC', 'DESC'], true) ? $order : 'DESC';
1497
1498 $allowed_orderby = ['date', 'title', 'rand', 'menu_order'];
1499 $orderby = (string) ($settings['kng_orderby'] ?? 'date');
1500 $orderby = in_array($orderby, $allowed_orderby, true) ? $orderby : 'date';
1501
1502 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
1503 $per_page = min($per_page, 6);
1504 }
1505
1506 $args = [
1507 'post_type' => 'post',
1508 'posts_per_page' => $per_page,
1509 'order' => $order,
1510 'orderby' => $orderby,
1511 ];
1512
1513 if (!empty($settings['kng_categories']) && king_addons_freemius()->can_use_premium_code__premium_only()) {
1514 $slugs = array_filter(array_map('sanitize_title', array_map('trim', explode(',', (string) $settings['kng_categories']))));
1515 if (!empty($slugs)) {
1516 $args['category_name'] = implode(',', $slugs);
1517 }
1518 }
1519
1520 if (!empty($settings['kng_exclude_sticky'])) {
1521 $args['ignore_sticky_posts'] = true;
1522 }
1523
1524 return new WP_Query($args);
1525 }
1526
1527 /**
1528 * Render single slide.
1529 *
1530 * @param array<string, mixed> $settings settings.
1531 */
1532 protected function render_slide(array $settings): void
1533 {
1534 $show_image = ($settings['kng_show_image'] ?? '') === 'yes';
1535 $show_meta = ($settings['kng_show_meta'] ?? '') === 'yes';
1536 $show_author = ($settings['kng_show_author'] ?? 'yes') === 'yes';
1537 $show_date = ($settings['kng_show_date'] ?? 'yes') === 'yes';
1538 $show_excerpt = ($settings['kng_show_excerpt'] ?? '') === 'yes';
1539 $show_read_more = ($settings['kng_show_read_more'] ?? '') === 'yes';
1540 $card_linkable = ($settings['kng_card_linkable'] ?? '') === 'yes';
1541
1542 $title = get_the_title();
1543 $permalink = get_permalink();
1544 $image_html = '';
1545
1546 if ($show_image) {
1547 if (has_post_thumbnail()) {
1548 $image_html = wp_get_attachment_image(
1549 get_post_thumbnail_id(),
1550 $settings['kng_image_size_size'] ?? 'medium',
1551 false,
1552 [
1553 'alt' => esc_attr($title),
1554 ]
1555 );
1556 }
1557
1558 if (empty($image_html)) {
1559 $image_html = '<img src="' . esc_url(Utils::get_placeholder_image_src()) . '" alt="' . esc_attr($title) . '"/>';
1560 }
1561 }
1562
1563 $excerpt_length = !empty($settings['kng_excerpt_length']) ? (int) $settings['kng_excerpt_length'] : 18;
1564 $excerpt_text = $show_excerpt ? wp_trim_words(get_the_excerpt(), $excerpt_length) : '';
1565
1566 $meta_parts = [];
1567 if ($show_meta) {
1568 if ($show_date) {
1569 $meta_parts[] = get_the_date();
1570 }
1571 if ($show_author) {
1572 $meta_parts[] = get_the_author();
1573 }
1574 }
1575
1576 $meta_separator = isset($settings['kng_meta_separator']) ? trim((string) $settings['kng_meta_separator']) : '';
1577 $meta_glue = $meta_separator === '' ? ' ' : ' ' . $meta_separator . ' ';
1578
1579 $card_attributes = [];
1580 if ($card_linkable && !empty($permalink)) {
1581 $card_attributes[] = 'data-card-link="' . esc_url($permalink) . '"';
1582 if (($settings['kng_card_link_new_tab'] ?? '') === 'yes') {
1583 $card_attributes[] = 'data-card-link-target="_blank"';
1584 }
1585 $card_attributes[] = 'tabindex="0"';
1586 $card_attributes[] = 'role="link"';
1587 $card_attributes[] = 'aria-label="' . esc_attr(sprintf(__('Open %s', 'king-addons'), $title)) . '"';
1588 }
1589
1590 ?>
1591 <div class="king-addons-post-slider__slide swiper-slide"<?php echo !empty($card_attributes) ? ' ' . implode(' ', $card_attributes) : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1592 <article class="king-addons-post-slider__card">
1593 <?php if (!empty($image_html)) : ?>
1594 <div class="king-addons-post-slider__media">
1595 <a href="<?php the_permalink(); ?>" class="king-addons-post-slider__media-link">
1596 <?php echo $image_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
1597 </a>
1598 </div>
1599 <?php endif; ?>
1600
1601 <div class="king-addons-post-slider__body">
1602 <h3 class="king-addons-post-slider__title">
1603 <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
1604 </h3>
1605
1606 <?php if (!empty($meta_parts)) : ?>
1607 <div class="king-addons-post-slider__meta">
1608 <?php echo esc_html(implode($meta_glue, $meta_parts)); ?>
1609 </div>
1610 <?php endif; ?>
1611
1612 <?php if (!empty($excerpt_text)) : ?>
1613 <div class="king-addons-post-slider__excerpt"><?php echo esc_html($excerpt_text); ?></div>
1614 <?php endif; ?>
1615
1616 <?php if ($show_read_more) : ?>
1617 <a class="king-addons-post-slider__button" href="<?php the_permalink(); ?>">
1618 <?php echo esc_html($settings['kng_read_more_text'] ?? esc_html__('Read more', 'king-addons')); ?>
1619 </a>
1620 <?php endif; ?>
1621 </div>
1622 </article>
1623 </div>
1624 <?php
1625 }
1626
1627 /**
1628 * Data attributes for JS.
1629 *
1630 * @param array<string, mixed> $settings settings.
1631 */
1632 protected function get_slider_data_attributes(array $settings): string
1633 {
1634 $slides = !empty($settings['kng_slides_per_view']) ? (int) $settings['kng_slides_per_view'] : 1;
1635 $slides_tablet = !empty($settings['kng_slides_per_view_tablet']) ? (int) $settings['kng_slides_per_view_tablet'] : $slides;
1636 $slides_mobile = !empty($settings['kng_slides_per_view_mobile']) ? (int) $settings['kng_slides_per_view_mobile'] : $slides_tablet;
1637 $space_between = isset($settings['kng_space_between']['size']) ? (int) $settings['kng_space_between']['size'] : 20;
1638 $autoplay = ($settings['kng_autoplay'] ?? '') === 'yes' ? 'yes' : 'no';
1639 $autoplay_delay = !empty($settings['kng_autoplay_delay']) ? (int) $settings['kng_autoplay_delay'] : 3200;
1640 $autoplay_pause_on_hover = ($settings['kng_autoplay_pause_on_hover'] ?? '') === 'yes' ? 'yes' : 'no';
1641 $autoplay_stop_on_interaction = ($settings['kng_autoplay_stop_on_interaction'] ?? '') === 'yes' ? 'yes' : 'no';
1642 $loop = ($settings['kng_loop'] ?? '') === 'yes' ? 'yes' : 'no';
1643 $speed = !empty($settings['kng_speed']) ? (int) $settings['kng_speed'] : 600;
1644
1645 $show_navigation = ($settings['kng_show_navigation'] ?? '') === 'yes' ? 'yes' : 'no';
1646 $show_pagination = ($settings['kng_show_pagination'] ?? '') === 'yes' ? 'yes' : 'no';
1647
1648 $attributes = [
1649 'data-slides-per-view' => $slides,
1650 'data-slides-per-view-tablet' => $slides_tablet,
1651 'data-slides-per-view-mobile' => $slides_mobile,
1652 'data-space-between' => $space_between,
1653 'data-autoplay' => $autoplay,
1654 'data-autoplay-delay' => $autoplay_delay,
1655 'data-autoplay-pause-on-hover' => $autoplay_pause_on_hover,
1656 'data-autoplay-stop-on-interaction' => $autoplay_stop_on_interaction,
1657 'data-loop' => $loop,
1658 'data-speed' => $speed,
1659 'data-navigation' => $show_navigation,
1660 'data-pagination' => $show_pagination,
1661 ];
1662
1663 $output = [];
1664
1665 foreach ($attributes as $key => $value) {
1666 $output[] = esc_attr($key) . '="' . esc_attr((string) $value) . '"';
1667 }
1668
1669 return implode(' ', $output);
1670 }
1671
1672 /**
1673 * Wrapper classes.
1674 *
1675 * @param array<string, mixed> $settings settings.
1676 */
1677 protected function get_wrapper_classes(array $settings): array
1678 {
1679 return $this->get_wrapper_classes_base($settings);
1680 }
1681
1682 /**
1683 * Base wrapper classes builder.
1684 *
1685 * This method exists to allow the Pro version to extend wrapper classes
1686 * without calling `parent::` methods.
1687 *
1688 * @param array<string, mixed> $settings settings.
1689 *
1690 * @return array<int, string>
1691 */
1692 protected function get_wrapper_classes_base(array $settings): array
1693 {
1694 $classes = ['king-addons-post-slider'];
1695
1696 $image_ratio = $settings['kng_image_ratio'] ?? 'original';
1697 if ($image_ratio !== 'original') {
1698 $classes[] = 'king-addons-post-slider--image-ratio-' . sanitize_html_class((string) $image_ratio);
1699 }
1700
1701 $nav_position = $settings['kng_navigation_position'] ?? 'outside';
1702 $classes[] = 'king-addons-post-slider--nav-' . sanitize_html_class((string) $nav_position);
1703
1704 $nav_alignment = $settings['kng_navigation_alignment'] ?? 'center';
1705 $classes[] = 'king-addons-post-slider--nav-align-' . sanitize_html_class((string) $nav_alignment);
1706
1707 $pagination_position = $settings['kng_pagination_position'] ?? 'outside';
1708 $classes[] = 'king-addons-post-slider--pagination-' . sanitize_html_class((string) $pagination_position);
1709
1710 $pagination_alignment = $settings['kng_pagination_alignment'] ?? 'center';
1711 $classes[] = 'king-addons-post-slider--pagination-align-' . sanitize_html_class((string) $pagination_alignment);
1712
1713 if (!empty($settings['kng_navigation_hide_tablet'])) {
1714 $classes[] = 'king-addons-post-slider--nav-hide-tablet';
1715 }
1716
1717 if (!empty($settings['kng_navigation_hide_mobile'])) {
1718 $classes[] = 'king-addons-post-slider--nav-hide-mobile';
1719 }
1720
1721 return array_filter($classes);
1722 }
1723
1724 /**
1725 * Wrapper inline styles.
1726 *
1727 * @param array<string, mixed> $settings settings.
1728 */
1729 protected function get_wrapper_style_attributes(array $settings): string
1730 {
1731 $styles = [];
1732
1733 if (isset($settings['kng_pagination_offset']['size'])) {
1734 $styles[] = '--kng-post-slider-pagination-offset: ' . (float) $settings['kng_pagination_offset']['size'] . $settings['kng_pagination_offset']['unit'] . ';';
1735 }
1736
1737 if (isset($settings['kng_pagination_gap']['size'])) {
1738 $styles[] = '--kng-post-slider-pagination-gap: ' . (float) $settings['kng_pagination_gap']['size'] . $settings['kng_pagination_gap']['unit'] . ';';
1739 }
1740
1741 if (isset($settings['kng_navigation_gap']['size'])) {
1742 $styles[] = '--kng-post-slider-nav-gap: ' . (float) $settings['kng_navigation_gap']['size'] . $settings['kng_navigation_gap']['unit'] . ';';
1743 }
1744
1745 $style_string = '';
1746
1747 if (!empty($styles)) {
1748 $style_string = ' style="' . esc_attr(implode(' ', $styles)) . '"';
1749 }
1750
1751 return $style_string;
1752 }
1753
1754 /**
1755 * Pro nav placeholder.
1756 */
1757 public function add_pro_navigation_controls(): void
1758 {
1759 $this->add_control(
1760 'kng_navigation_skin',
1761 [
1762 'label' => sprintf(__('Arrow Style %s', 'king-addons'), '<i class="eicon-pro-icon"></i>'),
1763 'type' => Controls_Manager::SELECT,
1764 'default' => 'elevated',
1765 'options' => [
1766 'elevated' => esc_html__('Elevated', 'king-addons'),
1767 'pro-solid' => esc_html__('Solid (Pro)', 'king-addons'),
1768 'pro-ghost' => esc_html__('Ghost (Pro)', 'king-addons'),
1769 'pro-minimal' => esc_html__('Minimal (Pro)', 'king-addons'),
1770 ],
1771 'condition' => [
1772 'kng_show_navigation' => 'yes',
1773 ],
1774 ]
1775 );
1776 }
1777
1778 /**
1779 * Pro pagination placeholder.
1780 */
1781 public function add_pro_pagination_controls(): void
1782 {
1783 $this->add_control(
1784 'kng_pagination_skin',
1785 [
1786 'label' => sprintf(__('Dots Style %s', 'king-addons'), '<i class="eicon-pro-icon"></i>'),
1787 'type' => Controls_Manager::SELECT,
1788 'default' => 'dot',
1789 'options' => [
1790 'dot' => esc_html__('Dots', 'king-addons'),
1791 'pro-pill' => esc_html__('Pill (Pro)', 'king-addons'),
1792 'pro-outlined' => esc_html__('Outlined (Pro)', 'king-addons'),
1793 ],
1794 'condition' => [
1795 'kng_show_pagination' => 'yes',
1796 ],
1797 ]
1798 );
1799 }
1800
1801 /**
1802 * Pro notice section.
1803 */
1804 public function register_pro_notice_controls(): void
1805 {
1806 if (!king_addons_can_use_pro()) {
1807 Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'quick-post-slider', [
1808 'Navigation and pagination style presets',
1809 'Extended placement and offset controls',
1810 'Advanced hover animations',
1811 'Unlimited posts per page',
1812 'Category filtering',
1813 ]);
1814 }
1815 }
1816 }
1817