PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.83
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.83, at includes/widgets/Quick_Post_Slider/Quick_Post_Slider.php

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