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

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

4,521 lines 166.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /** @noinspection SpellCheckingInspection, DuplicatedCode, PhpUnused */
4
5 namespace King_Addons;
6
7 use Elementor\Controls_Manager;
8 use Elementor\Group_Control_Background;
9 use Elementor\Group_Control_Border;
10 use Elementor\Group_Control_Box_Shadow;
11 use Elementor\Group_Control_Typography;
12 use Elementor\Widget_Base;
13
14 if (!defined('ABSPATH')) {
15 exit; // Exit if accessed directly.
16 }
17
18 /**
19 * Dynamic Posts Grid Widget
20 *
21 * Creates a dynamic grid of posts with AJAX filtering, search, and load more functionality.
22 * Features different post types, color coding, and responsive design.
23 */
24 class Dynamic_Posts_Grid extends Widget_Base
25 {
26 /**
27 * Allow Pro to fully override widget output without using parent::render().
28 *
29 * Pro can return true to indicate it rendered the widget output completely.
30 *
31 * @param array<string, mixed> $settings Widget settings for display.
32 * @return bool Whether Pro rendered output.
33 */
34 public function maybe_render_pro(array $settings): bool
35 {
36 return false;
37 }
38
39
40 /**
41 * Get widget name.
42 *
43 * @return string Widget name.
44 */
45 public function get_name(): string
46 {
47 return 'king-addons-dynamic-posts-grid';
48 }
49
50 /**
51 * Get widget title.
52 *
53 * @return string Widget title.
54 */
55 public function get_title(): string
56 {
57 return esc_html__('Dynamic Posts Grid', 'king-addons');
58 }
59
60 /**
61 * Get widget icon.
62 *
63 * @return string Widget icon.
64 */
65 public function get_icon(): string
66 {
67 return 'king-addons-icon king-addons-dynamic-posts-grid';
68 }
69
70 /**
71 * Get widget style dependencies.
72 *
73 * @return array Style dependencies.
74 */
75 public function get_style_depends(): array
76 {
77 return [KING_ADDONS_ASSETS_UNIQUE_KEY . '-dynamic-posts-grid-style'];
78 }
79
80 /**
81 * Get widget script dependencies.
82 *
83 * @return array Script dependencies.
84 */
85 public function get_script_depends(): array
86 {
87 return [
88 KING_ADDONS_ASSETS_UNIQUE_KEY . '-dompurify-purify.min',
89 KING_ADDONS_ASSETS_UNIQUE_KEY . '-dynamic-posts-grid-script'
90 ];
91 }
92
93 /**
94 * Get widget categories.
95 *
96 * @return array Widget categories.
97 */
98 public function get_categories(): array
99 {
100 return ['king-addons'];
101 }
102
103 /**
104 * Get widget keywords.
105 *
106 * @return array Widget keywords.
107 */
108 public function get_keywords(): array
109 {
110 return [
111 'posts',
112 'grid',
113 'dynamic',
114 'ajax',
115 'filter',
116 'search',
117 'load more',
118 'pagination',
119 'isotope',
120 'masonry',
121 'blog',
122 'news',
123 'articles',
124 'content',
125 'king',
126 'addons',
127 'kingaddons',
128 'king-addons'
129 ];
130 }
131
132 /**
133 * Get widget help URL.
134 *
135 * @return string Help URL.
136 */
137 public function get_custom_help_url()
138 {
139 return 'mailto:bug@kingaddons.com?subject=Bug Report - King Addons&body=Please describe the issue';
140 }
141
142 /**
143 * Register widget controls.
144 */
145 protected function register_controls(): void
146 {
147 // START TAB: CONTENT
148 $this->register_content_controls();
149
150 // START TAB: STYLE
151 $this->register_style_controls();
152 }
153
154 /**
155 * Register content controls.
156 */
157 private function register_content_controls(): void
158 {
159 // Content Section
160 $this->start_controls_section(
161 'kng_dynamic_posts_grid_content_section',
162 [
163 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Content', 'king-addons'),
164 'tab' => Controls_Manager::TAB_CONTENT,
165 ]
166 );
167
168 // Editor notice
169 $this->add_control(
170 'kng_dynamic_posts_editor_notice',
171 [
172 'type' => Controls_Manager::RAW_HTML,
173 'raw' => '<div style="background: #e3f2fd; border: 1px solid #2196f3; border-radius: 4px; padding: 12px; margin-bottom: 15px; color: #1565c0;">
174 <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
175 <i class="eicon-info-circle" style="color: #2196f3;"></i>
176 <strong>' . esc_html__('Editor Notice', 'king-addons') . '</strong>
177 </div>
178 <p style="margin: 0; font-size: 13px; line-height: 1.4;">' .
179 esc_html__('Dynamic features (filtering, search, load more) work only on the live site and will not function in the Elementor editor preview.', 'king-addons') .
180 '</p>
181 </div>',
182 ]
183 );
184
185 // PRO: Widget Mode Control
186 $this->add_control_widget_mode();
187
188 // Post Types (shown only in Default mode)
189 $this->add_control(
190 'kng_dynamic_posts_post_types',
191 [
192 'label' => esc_html__('Post Types', 'king-addons'),
193 'type' => Controls_Manager::SELECT2,
194 'multiple' => true,
195 'options' => $this->get_post_types(),
196 'default' => ['post'],
197 'description' => esc_html__('Select post types to display', 'king-addons'),
198 'condition' => [
199 'kng_dynamic_posts_widget_mode' => ['', 'default'],
200 ],
201 ]
202 );
203
204 // PRO: Custom Post Types Control
205 $this->add_control_custom_post_types();
206
207 // Posts per page
208 $this->add_control(
209 'kng_dynamic_posts_per_page',
210 [
211 'label' => esc_html__('Posts Per Page', 'king-addons'),
212 'type' => Controls_Manager::NUMBER,
213 'min' => 1,
214 'max' => 100,
215 'step' => 1,
216 'default' => 12,
217 'description' => esc_html__('Number of posts to display initially', 'king-addons'),
218 ]
219 );
220
221 // Order by
222 $this->add_control(
223 'kng_dynamic_posts_orderby',
224 [
225 'label' => esc_html__('Order By', 'king-addons'),
226 'type' => Controls_Manager::SELECT,
227 'options' => [
228 'date' => esc_html__('Date', 'king-addons'),
229 'title' => esc_html__('Title', 'king-addons'),
230 'menu_order' => esc_html__('Menu Order', 'king-addons'),
231 'rand' => esc_html__('Random', 'king-addons'),
232 'comment_count' => esc_html__('Comment Count', 'king-addons'),
233 ],
234 'default' => 'date',
235 ]
236 );
237
238 // Order
239 $this->add_control(
240 'kng_dynamic_posts_order',
241 [
242 'label' => esc_html__('Order', 'king-addons'),
243 'type' => Controls_Manager::SELECT,
244 'options' => [
245 'DESC' => esc_html__('Descending', 'king-addons'),
246 'ASC' => esc_html__('Ascending', 'king-addons'),
247 ],
248 'default' => 'DESC',
249 'condition' => [
250 'kng_dynamic_posts_orderby!' => 'rand',
251 ],
252 ]
253 );
254
255 $this->end_controls_section();
256
257 // Filtering Section
258 $this->start_controls_section(
259 'kng_dynamic_posts_filtering_section',
260 [
261 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Filtering & Search', 'king-addons'),
262 'tab' => Controls_Manager::TAB_CONTENT,
263 ]
264 );
265
266 // Enable filters
267 $this->add_control(
268 'kng_dynamic_posts_enable_filters',
269 [
270 'label' => esc_html__('Enable Filters', 'king-addons'),
271 'type' => Controls_Manager::SWITCHER,
272 'label_on' => esc_html__('Yes', 'king-addons'),
273 'label_off' => esc_html__('No', 'king-addons'),
274 'return_value' => 'yes',
275 'default' => 'yes',
276 ]
277 );
278
279 // Filter title text
280 $this->add_control(
281 'kng_dynamic_posts_filter_title_text',
282 [
283 'label' => esc_html__('Filter Title Text', 'king-addons'),
284 'type' => Controls_Manager::TEXT,
285 'default' => esc_html__('Filter', 'king-addons'),
286 'placeholder' => esc_html__('Enter filter title', 'king-addons'),
287 'condition' => [
288 'kng_dynamic_posts_enable_filters' => 'yes',
289 ],
290 ]
291 );
292
293 // Filter taxonomy (shown only in Default mode)
294 $this->add_control(
295 'kng_dynamic_posts_filter_taxonomy',
296 [
297 'label' => esc_html__('Filter Taxonomy', 'king-addons'),
298 'type' => Controls_Manager::SELECT,
299 'options' => $this->get_taxonomies(),
300 'default' => 'category',
301 'condition' => [
302 'kng_dynamic_posts_enable_filters' => 'yes',
303 'kng_dynamic_posts_widget_mode' => ['', 'default'],
304 ],
305 ]
306 );
307
308 // Enable search
309 $this->add_control(
310 'kng_dynamic_posts_enable_search',
311 [
312 'label' => esc_html__('Enable Search', 'king-addons'),
313 'type' => Controls_Manager::SWITCHER,
314 'label_on' => esc_html__('Yes', 'king-addons'),
315 'label_off' => esc_html__('No', 'king-addons'),
316 'return_value' => 'yes',
317 'default' => 'yes',
318 ]
319 );
320
321 // Search placeholder
322 $this->add_control(
323 'kng_dynamic_posts_search_placeholder',
324 [
325 'label' => esc_html__('Search Placeholder', 'king-addons'),
326 'type' => Controls_Manager::TEXT,
327 'default' => esc_html__('Search by keyword', 'king-addons'),
328 'condition' => [
329 'kng_dynamic_posts_enable_search' => 'yes',
330 ],
331 ]
332 );
333
334 $this->end_controls_section();
335
336 // Grid Layout Section
337 $this->start_controls_section(
338 'kng_dynamic_posts_layout_section',
339 [
340 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Grid Layout', 'king-addons'),
341 'tab' => Controls_Manager::TAB_CONTENT,
342 ]
343 );
344
345 // Columns
346 $this->add_responsive_control(
347 'kng_dynamic_posts_columns',
348 [
349 'label' => esc_html__('Columns', 'king-addons'),
350 'type' => Controls_Manager::SELECT,
351 'default' => '3',
352 'tablet_default' => '2',
353 'mobile_default' => '1',
354 'options' => [
355 '1' => '1',
356 '2' => '2',
357 '3' => '3',
358 '4' => '4',
359 '5' => '5',
360 '6' => '6',
361 ],
362 'selectors' => [
363 '{{WRAPPER}} .king-addons-dpg-grid' => 'grid-template-columns: repeat({{VALUE}}, 1fr);',
364 ],
365 ]
366 );
367
368 // Grid gap
369 $this->add_responsive_control(
370 'kng_dynamic_posts_grid_gap',
371 [
372 'label' => esc_html__('Grid Gap', 'king-addons'),
373 'type' => Controls_Manager::SLIDER,
374 'size_units' => ['px', 'em', 'rem'],
375 'range' => [
376 'px' => [
377 'min' => 0,
378 'max' => 100,
379 ],
380 ],
381 'default' => [
382 'size' => 20,
383 'unit' => 'px',
384 ],
385 'selectors' => [
386 '{{WRAPPER}} .king-addons-dpg-grid' => 'gap: {{SIZE}}{{UNIT}};',
387 ],
388 ]
389 );
390
391 $this->end_controls_section();
392
393 // Grid Spacing
394 $this->start_controls_section(
395 'kng_dynamic_posts_grid_spacing_section',
396 [
397 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Grid Spacing', 'king-addons'),
398 'tab' => Controls_Manager::TAB_CONTENT,
399 ]
400 );
401
402 // Grid margin bottom
403 $this->add_responsive_control(
404 'kng_dynamic_posts_grid_margin_bottom',
405 [
406 'label' => esc_html__('Grid Bottom Margin', 'king-addons'),
407 'type' => Controls_Manager::SLIDER,
408 'size_units' => ['px', 'em', 'rem'],
409 'range' => [
410 'px' => [
411 'min' => 0,
412 'max' => 100,
413 ],
414 ],
415 'default' => [
416 'size' => 50,
417 'unit' => 'px',
418 ],
419 'selectors' => [
420 '{{WRAPPER}} .king-addons-dpg-grid' => 'margin-bottom: {{SIZE}}{{UNIT}};',
421 ],
422 ]
423 );
424
425 $this->end_controls_section();
426
427 // Load More Section
428 $this->start_controls_section(
429 'kng_dynamic_posts_load_more_section',
430 [
431 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Load More', 'king-addons'),
432 'tab' => Controls_Manager::TAB_CONTENT,
433 ]
434 );
435
436 // Enable load more
437 $this->add_control(
438 'kng_dynamic_posts_enable_load_more',
439 [
440 'label' => esc_html__('Enable Load More', 'king-addons'),
441 'type' => Controls_Manager::SWITCHER,
442 'label_on' => esc_html__('Yes', 'king-addons'),
443 'label_off' => esc_html__('No', 'king-addons'),
444 'return_value' => 'yes',
445 'default' => 'yes',
446 ]
447 );
448
449 // Load more text
450 $this->add_control(
451 'kng_dynamic_posts_load_more_text',
452 [
453 'label' => esc_html__('Load More Text', 'king-addons'),
454 'type' => Controls_Manager::TEXT,
455 'default' => esc_html__('LOAD MORE', 'king-addons'),
456 'condition' => [
457 'kng_dynamic_posts_enable_load_more' => 'yes',
458 ],
459 ]
460 );
461
462 // Loading text
463 $this->add_control(
464 'kng_dynamic_posts_loading_text',
465 [
466 'label' => esc_html__('Loading Text', 'king-addons'),
467 'type' => Controls_Manager::TEXT,
468 'default' => esc_html__('Loading...', 'king-addons'),
469 'condition' => [
470 'kng_dynamic_posts_enable_load_more' => 'yes',
471 ],
472 ]
473 );
474
475 // PRO: Pagination Type Control
476 $this->add_control_pagination_type();
477
478 // PRO: Scroll Threshold Control
479 $this->add_control_scroll_threshold();
480
481 $this->end_controls_section();
482
483 // PRO: CPT Actions Section
484 $this->start_controls_section(
485 'kng_dynamic_posts_cpt_actions_section',
486 [
487 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('CPT Action Types', 'king-addons') . ' ' . esc_html__('(PRO)', 'king-addons'),
488 'tab' => Controls_Manager::TAB_CONTENT,
489 'condition' => [
490 'kng_dynamic_posts_widget_mode' => 'custom_cpt',
491 ],
492 ]
493 );
494
495 // PRO: CPT Actions Control
496 $this->add_control_cpt_actions();
497
498 $this->end_controls_section();
499
500 // PRO: Meta Fields Section
501 $this->start_controls_section(
502 'kng_dynamic_posts_meta_fields_section',
503 [
504 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Meta Fields', 'king-addons') . ' ' . esc_html__('(PRO)', 'king-addons'),
505 'tab' => Controls_Manager::TAB_CONTENT,
506 ]
507 );
508
509 // PRO: Show Meta Control
510 $this->add_control_show_meta();
511
512 // PRO: Meta Fields Control
513 $this->add_control_meta_fields();
514
515 $this->end_controls_section();
516
517 // Category Colors Section
518 $this->start_controls_section(
519 'kng_dynamic_posts_category_colors_section',
520 [
521 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Category Colors', 'king-addons'),
522 'tab' => Controls_Manager::TAB_CONTENT,
523 'condition' => [
524 'kng_dynamic_posts_widget_mode' => ['', 'default']
525 ]
526 ]
527 );
528
529 // Get categories dynamically
530 $this->add_dynamic_category_colors();
531
532 $this->end_controls_section();
533
534 // CPT Colors Section (PRO)
535 $this->start_controls_section(
536 'kng_dynamic_posts_cpt_colors_section',
537 [
538 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('CPT Colors', 'king-addons'),
539 'tab' => Controls_Manager::TAB_CONTENT,
540 'condition' => [
541 'kng_dynamic_posts_widget_mode' => 'custom_cpt'
542 ]
543 ]
544 );
545
546 // PRO: CPT Colors
547 $this->add_control_cpt_colors();
548
549 $this->end_controls_section();
550
551 $this->start_controls_section(
552 'kng_dynamic_posts_category_button_colors_section',
553 [
554 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Category Button Colors', 'king-addons'),
555 'tab' => Controls_Manager::TAB_CONTENT,
556 'condition' => [
557 'kng_dynamic_posts_widget_mode' => ['', 'default']
558 ]
559 ]
560 );
561
562 // Dynamic category button colors
563 $this->add_dynamic_category_button_colors();
564
565 $this->end_controls_section();
566
567 // CPT Button Colors Section (PRO)
568 $this->start_controls_section(
569 'kng_dynamic_posts_cpt_button_colors_section',
570 [
571 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('CPT Button Colors', 'king-addons'),
572 'tab' => Controls_Manager::TAB_CONTENT,
573 'condition' => [
574 'kng_dynamic_posts_widget_mode' => 'custom_cpt'
575 ]
576 ]
577 );
578
579 // PRO: CPT Button Colors
580 $this->add_control_cpt_button_colors();
581
582 $this->end_controls_section();
583
584
585
586 // Category CTAs Section
587 $this->start_controls_section(
588 'kng_dynamic_posts_ctas_section',
589 [
590 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Category Button Text', 'king-addons'),
591 'tab' => Controls_Manager::TAB_CONTENT,
592 'condition' => [
593 'kng_dynamic_posts_widget_mode' => ['', 'default']
594 ]
595 ]
596 );
597
598 // Get categories dynamically
599 $this->add_dynamic_category_ctas();
600
601 $this->end_controls_section();
602
603 // CPT Button Text Section (PRO)
604 $this->start_controls_section(
605 'kng_dynamic_posts_cpt_ctas_section',
606 [
607 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('CPT Button Text', 'king-addons'),
608 'tab' => Controls_Manager::TAB_CONTENT,
609 'condition' => [
610 'kng_dynamic_posts_widget_mode' => 'custom_cpt'
611 ]
612 ]
613 );
614
615 // PRO: CPT Button Text
616 $this->add_control_cpt_ctas();
617
618 $this->end_controls_section();
619
620 // Category Icons Section
621 $this->start_controls_section(
622 'kng_dynamic_posts_icons_section',
623 [
624 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Category Icons', 'king-addons'),
625 'tab' => Controls_Manager::TAB_CONTENT,
626 'condition' => [
627 'kng_dynamic_posts_widget_mode' => ['', 'default']
628 ]
629 ]
630 );
631
632 // Get categories dynamically
633 $this->add_dynamic_category_icons();
634
635 $this->end_controls_section();
636
637 // CPT Icons Section (PRO)
638 $this->start_controls_section(
639 'kng_dynamic_posts_cpt_icons_section',
640 [
641 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('CPT Icons', 'king-addons'),
642 'tab' => Controls_Manager::TAB_CONTENT,
643 'condition' => [
644 'kng_dynamic_posts_widget_mode' => 'custom_cpt'
645 ]
646 ]
647 );
648
649 // PRO: CPT Icons
650 $this->add_control_cpt_icons();
651
652 $this->end_controls_section();
653
654 // Pro Features Section
655 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
656 Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'dynamic-posts-grid', [
657 'Advanced Query Builder',
658 'Custom Meta Fields Display',
659 'Advanced Filtering Options',
660 'Infinite Scroll',
661 'Custom Post Type Support',
662 'Advanced Search with Meta Fields',
663 'Custom Date Range Filters',
664 'Author-based Filtering'
665 ]);
666 }
667
668 // PRO extension point to append content controls without duplicating base controls
669 // Pro content controls are added via add_control_* method calls above
670 }
671
672 /**
673 * Register style controls.
674 */
675 private function register_style_controls(): void
676 {
677 // Filter Title Style
678 $this->start_controls_section(
679 'kng_dynamic_posts_filter_title_style_section',
680 [
681 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Filter Title', 'king-addons'),
682 'tab' => Controls_Manager::TAB_STYLE,
683 'condition' => [
684 'kng_dynamic_posts_enable_filters' => 'yes',
685 ],
686 ]
687 );
688
689 // Filter title typography
690 $this->add_group_control(
691 Group_Control_Typography::get_type(),
692 [
693 'name' => 'kng_dynamic_posts_filter_title_typography',
694 'label' => esc_html__('Typography', 'king-addons'),
695 'selector' => '{{WRAPPER}} .king-addons-dpg-filter-title',
696 'fields_options' => [
697 'typography' => [
698 'default' => 'yes',
699 ],
700 'font_size' => [
701 'default' => [
702 'size' => 36,
703 'unit' => 'px',
704 ],
705 ],
706 'font_weight' => [
707 'default' => '600',
708 ],
709 ],
710 ]
711 );
712
713 // Filter title color
714 $this->add_control(
715 'kng_dynamic_posts_filter_title_color',
716 [
717 'label' => esc_html__('Text Color', 'king-addons'),
718 'type' => Controls_Manager::COLOR,
719 'default' => '#2c3e50',
720 'selectors' => [
721 '{{WRAPPER}} .king-addons-dpg-filter-title' => 'color: {{VALUE}};',
722 ],
723 ]
724 );
725
726 // Filter title spacing
727 $this->add_responsive_control(
728 'kng_dynamic_posts_filter_title_margin',
729 [
730 'label' => esc_html__('Margin', 'king-addons'),
731 'type' => Controls_Manager::DIMENSIONS,
732 'size_units' => ['px', 'em', '%'],
733 'default' => [
734 'top' => 0,
735 'right' => 0,
736 'bottom' => 20,
737 'left' => 0,
738 'unit' => 'px',
739 ],
740 'selectors' => [
741 '{{WRAPPER}} .king-addons-dpg-filter-title' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
742 ],
743 ]
744 );
745
746 $this->end_controls_section();
747
748 // Filter Bar Style
749 $this->start_controls_section(
750 'kng_dynamic_posts_filter_style_section',
751 [
752 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Filter Bar', 'king-addons'),
753 'tab' => Controls_Manager::TAB_STYLE,
754 ]
755 );
756
757 // Filter bar background
758 $this->add_group_control(
759 Group_Control_Background::get_type(),
760 [
761 'name' => 'kng_dynamic_posts_filter_background',
762 'label' => esc_html__('Background', 'king-addons'),
763 'types' => ['classic', 'gradient'],
764 'selector' => '{{WRAPPER}} .king-addons-dpg-filter-bar',
765 ]
766 );
767
768 // Filter bar padding
769 $this->add_responsive_control(
770 'kng_dynamic_posts_filter_padding',
771 [
772 'label' => esc_html__('Padding', 'king-addons'),
773 'type' => Controls_Manager::DIMENSIONS,
774 'size_units' => ['px', 'em', '%'],
775 'selectors' => [
776 '{{WRAPPER}} .king-addons-dpg-filter-bar' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
777 ],
778 ]
779 );
780
781 // Filter bar border
782 $this->add_group_control(
783 Group_Control_Border::get_type(),
784 [
785 'name' => 'kng_dynamic_posts_filter_border',
786 'label' => esc_html__('Border', 'king-addons'),
787 'selector' => '{{WRAPPER}} .king-addons-dpg-filter-bar',
788 ]
789 );
790
791 $this->end_controls_section();
792
793 // Filter Section Spacing
794 $this->start_controls_section(
795 'kng_dynamic_posts_filter_spacing_style_section',
796 [
797 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Filter Section Spacing', 'king-addons'),
798 'tab' => Controls_Manager::TAB_STYLE,
799 'condition' => [
800 'kng_dynamic_posts_enable_filters' => 'yes',
801 ],
802 ]
803 );
804
805 // Filter bar margin bottom
806 $this->add_responsive_control(
807 'kng_dynamic_posts_filter_bar_margin_bottom',
808 [
809 'label' => esc_html__('Filter Bar Bottom Margin', 'king-addons'),
810 'type' => Controls_Manager::SLIDER,
811 'size_units' => ['px', 'em', 'rem'],
812 'range' => [
813 'px' => [
814 'min' => 0,
815 'max' => 100,
816 ],
817 ],
818 'default' => [
819 'size' => 40,
820 'unit' => 'px',
821 ],
822 'selectors' => [
823 '{{WRAPPER}} .king-addons-dpg-filter-bar' => 'margin-bottom: {{SIZE}}{{UNIT}};',
824 ],
825 ]
826 );
827
828 // Filter header margin bottom
829 $this->add_responsive_control(
830 'kng_dynamic_posts_filter_header_margin_bottom',
831 [
832 'label' => esc_html__('Filter Header Bottom Margin', 'king-addons'),
833 'type' => Controls_Manager::SLIDER,
834 'size_units' => ['px', 'em', 'rem'],
835 'range' => [
836 'px' => [
837 'min' => 0,
838 'max' => 50,
839 ],
840 ],
841 'default' => [
842 'size' => 20,
843 'unit' => 'px',
844 ],
845 'selectors' => [
846 '{{WRAPPER}} .king-addons-dpg-filter-header' => 'margin-bottom: {{SIZE}}{{UNIT}};',
847 ],
848 ]
849 );
850
851 // Filter controls gap
852 $this->add_responsive_control(
853 'kng_dynamic_posts_filter_controls_gap',
854 [
855 'label' => esc_html__('Controls Gap', 'king-addons'),
856 'type' => Controls_Manager::SLIDER,
857 'size_units' => ['px', 'em', 'rem'],
858 'range' => [
859 'px' => [
860 'min' => 0,
861 'max' => 60,
862 ],
863 ],
864 'default' => [
865 'size' => 30,
866 'unit' => 'px',
867 ],
868 'selectors' => [
869 '{{WRAPPER}} .king-addons-dpg-filter-controls' => 'gap: {{SIZE}}{{UNIT}};',
870 ],
871 ]
872 );
873
874 // Filter controls alignment
875 $this->add_responsive_control(
876 'kng_dynamic_posts_filter_controls_alignment',
877 [
878 'label' => esc_html__('Controls Alignment', 'king-addons'),
879 'type' => Controls_Manager::SELECT,
880 'default' => 'space-between',
881 'options' => [
882 'flex-start' => esc_html__('Start', 'king-addons'),
883 'center' => esc_html__('Center', 'king-addons'),
884 'flex-end' => esc_html__('End', 'king-addons'),
885 'space-between' => esc_html__('Space Between', 'king-addons'),
886 ],
887 'selectors' => [
888 '{{WRAPPER}} .king-addons-dpg-filter-controls' => 'justify-content: {{VALUE}};',
889 ],
890 ]
891 );
892
893 $this->end_controls_section();
894
895 // Filter Controls Style
896 $this->start_controls_section(
897 'kng_dynamic_posts_filter_controls_style_section',
898 [
899 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Filter Controls', 'king-addons'),
900 'tab' => Controls_Manager::TAB_STYLE,
901 'condition' => [
902 'kng_dynamic_posts_enable_filters' => 'yes',
903 ],
904 ]
905 );
906
907 // Filter dropdown styles
908 $this->add_control(
909 'kng_dynamic_posts_filter_dropdown_heading',
910 [
911 'label' => esc_html__('Filter Dropdown', 'king-addons'),
912 'type' => Controls_Manager::HEADING,
913 'separator' => 'before',
914 ]
915 );
916
917 // Filter dropdown typography
918 $this->add_group_control(
919 Group_Control_Typography::get_type(),
920 [
921 'name' => 'kng_dynamic_posts_filter_dropdown_typography',
922 'label' => esc_html__('Typography', 'king-addons'),
923 'selector' => '{{WRAPPER}} .king-addons-dpg-posts-filter',
924 'fields_options' => [
925 'typography' => [
926 'default' => 'yes',
927 ],
928 'font_size' => [
929 'default' => [
930 'size' => 14,
931 'unit' => 'px',
932 ],
933 ],
934 'font_weight' => [
935 'default' => '500',
936 ],
937 ],
938 ]
939 );
940
941 // Filter dropdown colors
942 $this->add_control(
943 'kng_dynamic_posts_filter_dropdown_color',
944 [
945 'label' => esc_html__('Text Color', 'king-addons'),
946 'type' => Controls_Manager::COLOR,
947 'default' => '#374151',
948 'selectors' => [
949 '{{WRAPPER}} .king-addons-dpg-posts-filter' => 'color: {{VALUE}};',
950 ],
951 ]
952 );
953
954 // Filter dropdown background
955 $this->add_control(
956 'kng_dynamic_posts_filter_dropdown_background',
957 [
958 'label' => esc_html__('Background Color', 'king-addons'),
959 'type' => Controls_Manager::COLOR,
960 'default' => '#ffffff',
961 'selectors' => [
962 '{{WRAPPER}} .king-addons-dpg-posts-filter' => 'background-color: {{VALUE}};',
963 ],
964 ]
965 );
966
967 // Filter dropdown border
968 $this->add_group_control(
969 Group_Control_Border::get_type(),
970 [
971 'name' => 'kng_dynamic_posts_filter_dropdown_border',
972 'label' => esc_html__('Border', 'king-addons'),
973 'selector' => '{{WRAPPER}} .king-addons-dpg-posts-filter',
974 'fields_options' => [
975 'border' => [
976 'default' => 'solid',
977 ],
978 'width' => [
979 'default' => [
980 'top' => 1,
981 'right' => 1,
982 'bottom' => 1,
983 'left' => 1,
984 'unit' => 'px',
985 ],
986 ],
987 'color' => [
988 'default' => '#E5E7EB',
989 ],
990 ],
991 ]
992 );
993
994 // Filter dropdown border radius
995 $this->add_responsive_control(
996 'kng_dynamic_posts_filter_dropdown_border_radius',
997 [
998 'label' => esc_html__('Border Radius', 'king-addons'),
999 'type' => Controls_Manager::DIMENSIONS,
1000 'size_units' => ['px', '%'],
1001 'default' => [
1002 'top' => 12,
1003 'right' => 12,
1004 'bottom' => 12,
1005 'left' => 12,
1006 'unit' => 'px',
1007 ],
1008 'selectors' => [
1009 '{{WRAPPER}} .king-addons-dpg-posts-filter' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1010 ],
1011 ]
1012 );
1013
1014 // Filter dropdown padding
1015 $this->add_responsive_control(
1016 'kng_dynamic_posts_filter_dropdown_padding',
1017 [
1018 'label' => esc_html__('Padding', 'king-addons'),
1019 'type' => Controls_Manager::DIMENSIONS,
1020 'size_units' => ['px', 'em', '%'],
1021 'default' => [
1022 'top' => 12,
1023 'right' => 40,
1024 'bottom' => 12,
1025 'left' => 16,
1026 'unit' => 'px',
1027 ],
1028 'selectors' => [
1029 '{{WRAPPER}} .king-addons-dpg-posts-filter' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1030 ],
1031 ]
1032 );
1033
1034 // Filter dropdown box shadow
1035 $this->add_group_control(
1036 Group_Control_Box_Shadow::get_type(),
1037 [
1038 'name' => 'kng_dynamic_posts_filter_dropdown_box_shadow',
1039 'label' => esc_html__('Box Shadow', 'king-addons'),
1040 'selector' => '{{WRAPPER}} .king-addons-dpg-posts-filter',
1041 'fields_options' => [
1042 'box_shadow_type' => [
1043 'default' => 'yes',
1044 ],
1045 'box_shadow' => [
1046 'default' => [
1047 'horizontal' => 0,
1048 'vertical' => 1,
1049 'blur' => 2,
1050 'spread' => 0,
1051 'color' => 'rgba(0, 0, 0, 0.05)',
1052 ],
1053 ],
1054 ],
1055 ]
1056 );
1057
1058 // Filter dropdown icon
1059 $this->add_control(
1060 'kng_dynamic_posts_filter_dropdown_icon_heading',
1061 [
1062 'label' => esc_html__('Dropdown Icon', 'king-addons'),
1063 'type' => Controls_Manager::HEADING,
1064 'separator' => 'before',
1065 ]
1066 );
1067
1068 // Use custom dropdown icon/image
1069 $this->add_control(
1070 'kng_dynamic_posts_filter_dropdown_use_custom',
1071 [
1072 'label' => esc_html__('Use Custom Icon/Image', 'king-addons'),
1073 'type' => Controls_Manager::SWITCHER,
1074 'label_on' => esc_html__('Yes', 'king-addons'),
1075 'label_off' => esc_html__('No', 'king-addons'),
1076 'return_value' => 'yes',
1077 'default' => 'no',
1078 'description' => esc_html__('Replace default dropdown arrow with custom icon or image', 'king-addons'),
1079 ]
1080 );
1081
1082 // Choose dropdown type (icon or image)
1083 $this->add_control(
1084 'kng_dynamic_posts_filter_dropdown_type',
1085 [
1086 'label' => esc_html__('Type', 'king-addons'),
1087 'type' => Controls_Manager::SELECT,
1088 'options' => [
1089 'icon' => esc_html__('Icon', 'king-addons'),
1090 'image' => esc_html__('Image', 'king-addons'),
1091 ],
1092 'default' => 'icon',
1093 'condition' => [
1094 'kng_dynamic_posts_filter_dropdown_use_custom' => 'yes',
1095 ],
1096 ]
1097 );
1098
1099 // Choose custom dropdown icon
1100 $this->add_control(
1101 'kng_dynamic_posts_filter_dropdown_custom_icon',
1102 [
1103 'label' => esc_html__('Choose Icon', 'king-addons'),
1104 'type' => Controls_Manager::ICONS,
1105 'default' => [
1106 'value' => 'fas fa-chevron-down',
1107 'library' => 'fa-solid',
1108 ],
1109 'condition' => [
1110 'kng_dynamic_posts_filter_dropdown_use_custom' => 'yes',
1111 'kng_dynamic_posts_filter_dropdown_type' => 'icon',
1112 ],
1113 ]
1114 );
1115
1116 // Choose custom dropdown image
1117 $this->add_control(
1118 'kng_dynamic_posts_filter_dropdown_custom_image',
1119 [
1120 'label' => esc_html__('Choose Image', 'king-addons'),
1121 'type' => Controls_Manager::MEDIA,
1122 'media_types' => ['image'],
1123 'default' => [
1124 'url' => '',
1125 ],
1126 'condition' => [
1127 'kng_dynamic_posts_filter_dropdown_use_custom' => 'yes',
1128 'kng_dynamic_posts_filter_dropdown_type' => 'image',
1129 ],
1130 ]
1131 );
1132
1133 // Dropdown icon size
1134 $this->add_control(
1135 'kng_dynamic_posts_filter_dropdown_icon_size',
1136 [
1137 'label' => esc_html__('Icon Size', 'king-addons'),
1138 'type' => Controls_Manager::SLIDER,
1139 'size_units' => ['px'],
1140 'range' => [
1141 'px' => [
1142 'min' => 8,
1143 'max' => 30,
1144 'step' => 1,
1145 ],
1146 ],
1147 'default' => [
1148 'size' => 14,
1149 'unit' => 'px',
1150 ],
1151 'selectors' => [
1152 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-icon' => 'font-size: {{SIZE}}{{UNIT}};',
1153 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-icon svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
1154 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-icon i' => 'font-size: {{SIZE}}{{UNIT}};',
1155 ],
1156 'condition' => [
1157 'kng_dynamic_posts_filter_dropdown_use_custom' => 'yes',
1158 'kng_dynamic_posts_filter_dropdown_type' => 'icon',
1159 ],
1160 ]
1161 );
1162
1163 // Dropdown image size
1164 $this->add_control(
1165 'kng_dynamic_posts_filter_dropdown_image_size',
1166 [
1167 'label' => esc_html__('Image Size', 'king-addons'),
1168 'type' => Controls_Manager::SLIDER,
1169 'size_units' => ['px', 'em', '%'],
1170 'range' => [
1171 'px' => [
1172 'min' => 8,
1173 'max' => 100,
1174 'step' => 1,
1175 ],
1176 'em' => [
1177 'min' => 0.5,
1178 'max' => 5,
1179 'step' => 0.1,
1180 ],
1181 '%' => [
1182 'min' => 50,
1183 'max' => 200,
1184 'step' => 5,
1185 ],
1186 ],
1187 'default' => [
1188 'size' => 16,
1189 'unit' => 'px',
1190 ],
1191 'selectors' => [
1192 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-image' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
1193 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-image img' => 'width: 100%; height: 100%; object-fit: contain;',
1194 ],
1195 'condition' => [
1196 'kng_dynamic_posts_filter_dropdown_use_custom' => 'yes',
1197 'kng_dynamic_posts_filter_dropdown_type' => 'image',
1198 ],
1199 ]
1200 );
1201
1202 // Dropdown icon color
1203 $this->add_control(
1204 'kng_dynamic_posts_filter_dropdown_icon_color',
1205 [
1206 'label' => esc_html__('Icon Color', 'king-addons'),
1207 'type' => Controls_Manager::COLOR,
1208 'default' => '#6B7280',
1209 'selectors' => [
1210 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-icon' => 'color: {{VALUE}};',
1211 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-icon svg' => 'fill: {{VALUE}};',
1212 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-icon i' => 'color: {{VALUE}};',
1213 ],
1214 'condition' => [
1215 'kng_dynamic_posts_filter_dropdown_use_custom' => 'yes',
1216 'kng_dynamic_posts_filter_dropdown_type' => 'icon',
1217 ],
1218 ]
1219 );
1220
1221 // Dropdown image opacity
1222 $this->add_control(
1223 'kng_dynamic_posts_filter_dropdown_image_opacity',
1224 [
1225 'label' => esc_html__('Image Opacity', 'king-addons'),
1226 'type' => Controls_Manager::SLIDER,
1227 'range' => [
1228 'px' => [
1229 'min' => 0.1,
1230 'max' => 1,
1231 'step' => 0.1,
1232 ],
1233 ],
1234 'default' => [
1235 'size' => 0.8,
1236 ],
1237 'selectors' => [
1238 '{{WRAPPER}} .king-addons-dpg-filter-dropdown .dropdown-image' => 'opacity: {{SIZE}};',
1239 ],
1240 'condition' => [
1241 'kng_dynamic_posts_filter_dropdown_use_custom' => 'yes',
1242 'kng_dynamic_posts_filter_dropdown_type' => 'image',
1243 ],
1244 ]
1245 );
1246
1247 // Search input styles
1248 $this->add_control(
1249 'kng_dynamic_posts_search_input_heading',
1250 [
1251 'label' => esc_html__('Search Input', 'king-addons'),
1252 'type' => Controls_Manager::HEADING,
1253 'separator' => 'before',
1254 'condition' => [
1255 'kng_dynamic_posts_enable_search' => 'yes',
1256 ],
1257 ]
1258 );
1259
1260 // Search input typography
1261 $this->add_group_control(
1262 Group_Control_Typography::get_type(),
1263 [
1264 'name' => 'kng_dynamic_posts_search_input_typography',
1265 'label' => esc_html__('Typography', 'king-addons'),
1266 'selector' => '{{WRAPPER}} .king-addons-dpg-posts-search',
1267 'condition' => [
1268 'kng_dynamic_posts_enable_search' => 'yes',
1269 ],
1270 'fields_options' => [
1271 'typography' => [
1272 'default' => 'yes',
1273 ],
1274 'font_size' => [
1275 'default' => [
1276 'size' => 14,
1277 'unit' => 'px',
1278 ],
1279 ],
1280 ],
1281 ]
1282 );
1283
1284 // Search input colors
1285 $this->add_control(
1286 'kng_dynamic_posts_search_input_color',
1287 [
1288 'label' => esc_html__('Text Color', 'king-addons'),
1289 'type' => Controls_Manager::COLOR,
1290 'default' => '#374151',
1291 'selectors' => [
1292 '{{WRAPPER}} .king-addons-dpg-posts-search' => 'color: {{VALUE}};',
1293 ],
1294 'condition' => [
1295 'kng_dynamic_posts_enable_search' => 'yes',
1296 ],
1297 ]
1298 );
1299
1300 // Search input placeholder color
1301 $this->add_control(
1302 'kng_dynamic_posts_search_placeholder_color',
1303 [
1304 'label' => esc_html__('Placeholder Color', 'king-addons'),
1305 'type' => Controls_Manager::COLOR,
1306 'default' => '#9CA3AF',
1307 'selectors' => [
1308 '{{WRAPPER}} .king-addons-dpg-posts-search::placeholder' => 'color: {{VALUE}};',
1309 ],
1310 'condition' => [
1311 'kng_dynamic_posts_enable_search' => 'yes',
1312 ],
1313 ]
1314 );
1315
1316 // Search input background
1317 $this->add_control(
1318 'kng_dynamic_posts_search_input_background',
1319 [
1320 'label' => esc_html__('Background Color', 'king-addons'),
1321 'type' => Controls_Manager::COLOR,
1322 'default' => '#ffffff',
1323 'selectors' => [
1324 '{{WRAPPER}} .king-addons-dpg-search-input' => 'background-color: {{VALUE}};',
1325 ],
1326 'condition' => [
1327 'kng_dynamic_posts_enable_search' => 'yes',
1328 ],
1329 ]
1330 );
1331
1332 // Search input border
1333 $this->add_group_control(
1334 Group_Control_Border::get_type(),
1335 [
1336 'name' => 'kng_dynamic_posts_search_input_border',
1337 'label' => esc_html__('Border', 'king-addons'),
1338 'selector' => '{{WRAPPER}} .king-addons-dpg-search-input',
1339 'condition' => [
1340 'kng_dynamic_posts_enable_search' => 'yes',
1341 ],
1342 'fields_options' => [
1343 'border' => [
1344 'default' => 'solid',
1345 ],
1346 'width' => [
1347 'default' => [
1348 'top' => 1,
1349 'right' => 1,
1350 'bottom' => 1,
1351 'left' => 1,
1352 'unit' => 'px',
1353 ],
1354 ],
1355 'color' => [
1356 'default' => '#E5E7EB',
1357 ],
1358 ],
1359 ]
1360 );
1361
1362 // Search input border radius
1363 $this->add_responsive_control(
1364 'kng_dynamic_posts_search_input_border_radius',
1365 [
1366 'label' => esc_html__('Border Radius', 'king-addons'),
1367 'type' => Controls_Manager::DIMENSIONS,
1368 'size_units' => ['px', '%'],
1369 'default' => [
1370 'top' => 12,
1371 'right' => 12,
1372 'bottom' => 12,
1373 'left' => 12,
1374 'unit' => 'px',
1375 ],
1376 'selectors' => [
1377 '{{WRAPPER}} .king-addons-dpg-search-input' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1378 ],
1379 'condition' => [
1380 'kng_dynamic_posts_enable_search' => 'yes',
1381 ],
1382 ]
1383 );
1384
1385 // Search input padding
1386 $this->add_responsive_control(
1387 'kng_dynamic_posts_search_input_padding',
1388 [
1389 'label' => esc_html__('Padding', 'king-addons'),
1390 'type' => Controls_Manager::DIMENSIONS,
1391 'size_units' => ['px', 'em', '%'],
1392 'default' => [
1393 'top' => 12,
1394 'right' => 16,
1395 'bottom' => 12,
1396 'left' => 16,
1397 'unit' => 'px',
1398 ],
1399 'selectors' => [
1400 '{{WRAPPER}} .king-addons-dpg-posts-search' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1401 ],
1402 'condition' => [
1403 'kng_dynamic_posts_enable_search' => 'yes',
1404 ],
1405 ]
1406 );
1407
1408 // Search input box shadow
1409 $this->add_group_control(
1410 Group_Control_Box_Shadow::get_type(),
1411 [
1412 'name' => 'kng_dynamic_posts_search_input_box_shadow',
1413 'label' => esc_html__('Box Shadow', 'king-addons'),
1414 'selector' => '{{WRAPPER}} .king-addons-dpg-search-input',
1415 'condition' => [
1416 'kng_dynamic_posts_enable_search' => 'yes',
1417 ],
1418 'fields_options' => [
1419 'box_shadow_type' => [
1420 'default' => 'yes',
1421 ],
1422 'box_shadow' => [
1423 'default' => [
1424 'horizontal' => 0,
1425 'vertical' => 1,
1426 'blur' => 2,
1427 'spread' => 0,
1428 'color' => 'rgba(0, 0, 0, 0.05)',
1429 ],
1430 ],
1431 ],
1432 ]
1433 );
1434
1435 // Search button heading
1436 $this->add_control(
1437 'kng_dynamic_posts_search_button_heading',
1438 [
1439 'label' => esc_html__('Search Button', 'king-addons'),
1440 'type' => Controls_Manager::HEADING,
1441 'separator' => 'before',
1442 'condition' => [
1443 'kng_dynamic_posts_enable_search' => 'yes',
1444 ],
1445 ]
1446 );
1447
1448 // Search button size
1449 $this->add_responsive_control(
1450 'kng_dynamic_posts_search_button_size',
1451 [
1452 'label' => esc_html__('Button Size', 'king-addons'),
1453 'type' => Controls_Manager::SLIDER,
1454 'size_units' => ['px'],
1455 'range' => [
1456 'px' => [
1457 'min' => 30,
1458 'max' => 80,
1459 ],
1460 ],
1461 'default' => [
1462 'size' => 44,
1463 'unit' => 'px',
1464 ],
1465 'selectors' => [
1466 '{{WRAPPER}} .king-addons-dpg-search-btn' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
1467 ],
1468 'condition' => [
1469 'kng_dynamic_posts_enable_search' => 'yes',
1470 ],
1471 ]
1472 );
1473
1474 // Search button color
1475 $this->add_control(
1476 'kng_dynamic_posts_search_button_color',
1477 [
1478 'label' => esc_html__('Button Color', 'king-addons'),
1479 'type' => Controls_Manager::COLOR,
1480 'default' => '#6B7280',
1481 'selectors' => [
1482 '{{WRAPPER}} .king-addons-dpg-search-btn' => 'color: {{VALUE}};',
1483 ],
1484 'condition' => [
1485 'kng_dynamic_posts_enable_search' => 'yes',
1486 ],
1487 ]
1488 );
1489
1490 // Search button background
1491 $this->add_control(
1492 'kng_dynamic_posts_search_button_background',
1493 [
1494 'label' => esc_html__('Button Background', 'king-addons'),
1495 'type' => Controls_Manager::COLOR,
1496 'default' => 'transparent',
1497 'selectors' => [
1498 '{{WRAPPER}} .king-addons-dpg-search-btn' => 'background-color: {{VALUE}};',
1499 ],
1500 'condition' => [
1501 'kng_dynamic_posts_enable_search' => 'yes',
1502 ],
1503 ]
1504 );
1505
1506 // Search button hover color
1507 $this->add_control(
1508 'kng_dynamic_posts_search_button_hover_color',
1509 [
1510 'label' => esc_html__('Button Hover Color', 'king-addons'),
1511 'type' => Controls_Manager::COLOR,
1512 'default' => '#374151',
1513 'selectors' => [
1514 '{{WRAPPER}} .king-addons-dpg-search-btn:hover' => 'color: {{VALUE}};',
1515 ],
1516 'condition' => [
1517 'kng_dynamic_posts_enable_search' => 'yes',
1518 ],
1519 ]
1520 );
1521
1522 // Search button hover background
1523 $this->add_control(
1524 'kng_dynamic_posts_search_button_hover_background',
1525 [
1526 'label' => esc_html__('Button Hover Background', 'king-addons'),
1527 'type' => Controls_Manager::COLOR,
1528 'default' => 'rgba(59, 130, 246, 0.05)',
1529 'selectors' => [
1530 '{{WRAPPER}} .king-addons-dpg-search-btn:hover' => 'background-color: {{VALUE}};',
1531 ],
1532 'condition' => [
1533 'kng_dynamic_posts_enable_search' => 'yes',
1534 ],
1535 ]
1536 );
1537
1538 // Search button border
1539 $this->add_group_control(
1540 Group_Control_Border::get_type(),
1541 [
1542 'name' => 'kng_dynamic_posts_search_button_border',
1543 'label' => esc_html__('Button Border', 'king-addons'),
1544 'selector' => '{{WRAPPER}} .king-addons-dpg-search-btn',
1545 'condition' => [
1546 'kng_dynamic_posts_enable_search' => 'yes',
1547 ],
1548 ]
1549 );
1550
1551 // Search button border radius
1552 $this->add_responsive_control(
1553 'kng_dynamic_posts_search_button_border_radius',
1554 [
1555 'label' => esc_html__('Button Border Radius', 'king-addons'),
1556 'type' => Controls_Manager::DIMENSIONS,
1557 'size_units' => ['px', '%'],
1558 'selectors' => [
1559 '{{WRAPPER}} .king-addons-dpg-search-btn' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1560 ],
1561 'condition' => [
1562 'kng_dynamic_posts_enable_search' => 'yes',
1563 ],
1564 ]
1565 );
1566
1567 // Search button padding
1568 $this->add_responsive_control(
1569 'kng_dynamic_posts_search_button_padding',
1570 [
1571 'label' => esc_html__('Button Padding', 'king-addons'),
1572 'type' => Controls_Manager::DIMENSIONS,
1573 'size_units' => ['px', 'em', '%'],
1574 'default' => [
1575 'top' => 8,
1576 'right' => 12,
1577 'bottom' => 8,
1578 'left' => 12,
1579 'unit' => 'px',
1580 ],
1581 'selectors' => [
1582 '{{WRAPPER}} .king-addons-dpg-search-btn' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1583 ],
1584 'condition' => [
1585 'kng_dynamic_posts_enable_search' => 'yes',
1586 ],
1587 ]
1588 );
1589
1590 // Search button transition duration
1591 $this->add_control(
1592 'kng_dynamic_posts_search_button_transition',
1593 [
1594 'label' => esc_html__('Transition Duration (ms)', 'king-addons'),
1595 'type' => Controls_Manager::SLIDER,
1596 'range' => [
1597 'px' => [
1598 'min' => 100,
1599 'max' => 1000,
1600 'step' => 50,
1601 ],
1602 ],
1603 'default' => [
1604 'size' => 300,
1605 ],
1606 'selectors' => [
1607 '{{WRAPPER}} .king-addons-dpg-search-btn' => 'transition: all {{SIZE}}ms ease;',
1608 ],
1609 'condition' => [
1610 'kng_dynamic_posts_enable_search' => 'yes',
1611 ],
1612 ]
1613 );
1614
1615 // Search button icon heading
1616 $this->add_control(
1617 'kng_dynamic_posts_search_button_icon_heading',
1618 [
1619 'label' => esc_html__('Search Button Icon', 'king-addons'),
1620 'type' => Controls_Manager::HEADING,
1621 'separator' => 'before',
1622 'condition' => [
1623 'kng_dynamic_posts_enable_search' => 'yes',
1624 ],
1625 ]
1626 );
1627
1628 // Use custom icon
1629 $this->add_control(
1630 'kng_dynamic_posts_search_use_custom_icon',
1631 [
1632 'label' => esc_html__('Use Custom Icon', 'king-addons'),
1633 'type' => Controls_Manager::SWITCHER,
1634 'label_on' => esc_html__('Yes', 'king-addons'),
1635 'label_off' => esc_html__('No', 'king-addons'),
1636 'return_value' => 'yes',
1637 'default' => '',
1638 'condition' => [
1639 'kng_dynamic_posts_enable_search' => 'yes',
1640 ],
1641 ]
1642 );
1643
1644 // Custom icon
1645 $this->add_control(
1646 'kng_dynamic_posts_search_custom_icon',
1647 [
1648 'label' => esc_html__('Choose Icon', 'king-addons'),
1649 'type' => Controls_Manager::ICONS,
1650 'default' => [
1651 'value' => 'fas fa-search',
1652 'library' => 'fa-solid',
1653 ],
1654 'condition' => [
1655 'kng_dynamic_posts_enable_search' => 'yes',
1656 'kng_dynamic_posts_search_use_custom_icon' => 'yes',
1657 ],
1658 ]
1659 );
1660
1661 // Icon size
1662 $this->add_responsive_control(
1663 'kng_dynamic_posts_search_icon_size',
1664 [
1665 'label' => esc_html__('Icon Size', 'king-addons'),
1666 'type' => Controls_Manager::SLIDER,
1667 'size_units' => ['px'],
1668 'range' => [
1669 'px' => [
1670 'min' => 10,
1671 'max' => 50,
1672 ],
1673 ],
1674 'default' => [
1675 'size' => 18,
1676 'unit' => 'px',
1677 ],
1678 'selectors' => [
1679 '{{WRAPPER}} .king-addons-dpg-search-btn svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
1680 '{{WRAPPER}} .king-addons-dpg-search-btn i' => 'font-size: {{SIZE}}{{UNIT}};',
1681 ],
1682 'condition' => [
1683 'kng_dynamic_posts_enable_search' => 'yes',
1684 ],
1685 ]
1686 );
1687
1688 // Icon color
1689 $this->add_control(
1690 'kng_dynamic_posts_search_icon_color',
1691 [
1692 'label' => esc_html__('Icon Color', 'king-addons'),
1693 'type' => Controls_Manager::COLOR,
1694 'default' => '',
1695 'selectors' => [
1696 '{{WRAPPER}} .king-addons-dpg-search-btn svg' => 'fill: {{VALUE}};',
1697 '{{WRAPPER}} .king-addons-dpg-search-btn i' => 'color: {{VALUE}};',
1698 ],
1699 'condition' => [
1700 'kng_dynamic_posts_enable_search' => 'yes',
1701 ],
1702 ]
1703 );
1704
1705 // Icon hover color
1706 $this->add_control(
1707 'kng_dynamic_posts_search_icon_hover_color',
1708 [
1709 'label' => esc_html__('Icon Hover Color', 'king-addons'),
1710 'type' => Controls_Manager::COLOR,
1711 'default' => '',
1712 'selectors' => [
1713 '{{WRAPPER}} .king-addons-dpg-search-btn:hover svg' => 'fill: {{VALUE}};',
1714 '{{WRAPPER}} .king-addons-dpg-search-btn:hover i' => 'color: {{VALUE}};',
1715 ],
1716 'condition' => [
1717 'kng_dynamic_posts_enable_search' => 'yes',
1718 ],
1719 ]
1720 );
1721
1722 $this->end_controls_section();
1723
1724 // Card Style
1725 $this->start_controls_section(
1726 'kng_dynamic_posts_card_style_section',
1727 [
1728 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Cards', 'king-addons'),
1729 'tab' => Controls_Manager::TAB_STYLE,
1730 ]
1731 );
1732
1733 // Icon Position
1734 $this->add_control(
1735 'kng_dynamic_posts_icon_position',
1736 [
1737 'label' => esc_html__('Icon Position', 'king-addons'),
1738 'type' => Controls_Manager::SELECT,
1739 'default' => 'left',
1740 'options' => [
1741 'left' => esc_html__('Left', 'king-addons'),
1742 'right' => esc_html__('Right', 'king-addons'),
1743 ],
1744 'prefix_class' => 'king-addons-icon-',
1745 ]
1746 );
1747
1748 // Card background color
1749 $this->add_control(
1750 'kng_dynamic_posts_card_background_color',
1751 [
1752 'label' => esc_html__('Background Color', 'king-addons'),
1753 'type' => Controls_Manager::COLOR,
1754 'default' => '#F8F9FA',
1755 'selectors' => [
1756 '{{WRAPPER}} .king-addons-dpg-card' => 'background-color: {{VALUE}};',
1757 ],
1758 ]
1759 );
1760
1761 // Card border
1762 $this->add_group_control(
1763 Group_Control_Border::get_type(),
1764 [
1765 'name' => 'kng_dynamic_posts_card_border',
1766 'label' => esc_html__('Border', 'king-addons'),
1767 'selector' => '{{WRAPPER}} .king-addons-dpg-card',
1768 'fields_options' => [
1769 'border' => [
1770 'default' => 'solid',
1771 ],
1772 'width' => [
1773 'default' => [
1774 'top' => 1,
1775 'right' => 1,
1776 'bottom' => 1,
1777 'left' => 1,
1778 'unit' => 'px',
1779 ],
1780 ],
1781 'color' => [
1782 'default' => 'rgba(0, 0, 0, 0.05)',
1783 ],
1784 ],
1785 ]
1786 );
1787
1788 // Card border radius
1789 $this->add_responsive_control(
1790 'kng_dynamic_posts_card_border_radius',
1791 [
1792 'label' => esc_html__('Border Radius', 'king-addons'),
1793 'type' => Controls_Manager::DIMENSIONS,
1794 'size_units' => ['px', '%'],
1795 'default' => [
1796 'top' => 20,
1797 'right' => 20,
1798 'bottom' => 20,
1799 'left' => 20,
1800 'unit' => 'px',
1801 ],
1802 'selectors' => [
1803 '{{WRAPPER}} .king-addons-dpg-card' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1804 ],
1805 ]
1806 );
1807
1808 // Card min height
1809 $this->add_responsive_control(
1810 'kng_dynamic_posts_card_min_height',
1811 [
1812 'label' => esc_html__('Min Height', 'king-addons'),
1813 'type' => Controls_Manager::SLIDER,
1814 'size_units' => ['px', 'vh'],
1815 'range' => [
1816 'px' => [
1817 'min' => 100,
1818 'max' => 800,
1819 'step' => 10,
1820 ],
1821 'vh' => [
1822 'min' => 10,
1823 'max' => 100,
1824 ],
1825 ],
1826 'default' => [
1827 'size' => 260,
1828 'unit' => 'px',
1829 ],
1830 'selectors' => [
1831 '{{WRAPPER}} .king-addons-dpg-card' => 'min-height: {{SIZE}}{{UNIT}};',
1832 ],
1833 ]
1834 );
1835
1836 // Card box shadow
1837 $this->add_group_control(
1838 Group_Control_Box_Shadow::get_type(),
1839 [
1840 'name' => 'kng_dynamic_posts_card_box_shadow',
1841 'label' => esc_html__('Box Shadow', 'king-addons'),
1842 'selector' => '{{WRAPPER}} .king-addons-dpg-card',
1843 'fields_options' => [
1844 'box_shadow_type' => [
1845 'default' => 'yes',
1846 ],
1847 'box_shadow' => [
1848 'default' => [
1849 'horizontal' => 0,
1850 'vertical' => 1,
1851 'blur' => 3,
1852 'spread' => 0,
1853 'color' => 'rgba(0, 0, 0, 0.1)',
1854 ],
1855 ],
1856 ],
1857 ]
1858 );
1859
1860 // Card typography
1861 $this->add_group_control(
1862 Group_Control_Typography::get_type(),
1863 [
1864 'name' => 'kng_dynamic_posts_card_typography',
1865 'label' => esc_html__('Typography', 'king-addons'),
1866 'selector' => '{{WRAPPER}} .king-addons-dpg-card',
1867 ]
1868 );
1869
1870 $this->end_controls_section();
1871
1872 // Card Hover Effects
1873 $this->start_controls_section(
1874 'kng_dynamic_posts_card_hover_style_section',
1875 [
1876 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Card Hover Effects', 'king-addons'),
1877 'tab' => Controls_Manager::TAB_STYLE,
1878 ]
1879 );
1880
1881 // Hover transform
1882 $this->add_control(
1883 'kng_dynamic_posts_card_hover_transform',
1884 [
1885 'label' => esc_html__('Hover Transform', 'king-addons'),
1886 'type' => Controls_Manager::SELECT,
1887 'default' => 'translateY(-4px)',
1888 'options' => [
1889 'none' => esc_html__('None', 'king-addons'),
1890 'translateY(-2px)' => esc_html__('Lift Small', 'king-addons'),
1891 'translateY(-4px)' => esc_html__('Lift Medium', 'king-addons'),
1892 'translateY(-6px)' => esc_html__('Lift Large', 'king-addons'),
1893 'scale(1.02)' => esc_html__('Scale Small', 'king-addons'),
1894 'scale(1.05)' => esc_html__('Scale Medium', 'king-addons'),
1895 ],
1896 'selectors' => [
1897 '{{WRAPPER}} .king-addons-dpg-card:hover' => 'transform: {{VALUE}};',
1898 ],
1899 ]
1900 );
1901
1902 // Hover box shadow
1903 $this->add_group_control(
1904 Group_Control_Box_Shadow::get_type(),
1905 [
1906 'name' => 'kng_dynamic_posts_card_hover_box_shadow',
1907 'label' => esc_html__('Hover Box Shadow', 'king-addons'),
1908 'selector' => '{{WRAPPER}} .king-addons-dpg-card:hover',
1909 'fields_options' => [
1910 'box_shadow_type' => [
1911 'default' => 'yes',
1912 ],
1913 'box_shadow' => [
1914 'default' => [
1915 'horizontal' => 0,
1916 'vertical' => 10,
1917 'blur' => 25,
1918 'spread' => 0,
1919 'color' => 'rgba(0, 0, 0, 0.15)',
1920 ],
1921 ],
1922 ],
1923 ]
1924 );
1925
1926 // Hover border color
1927 $this->add_control(
1928 'kng_dynamic_posts_card_hover_border_color',
1929 [
1930 'label' => esc_html__('Hover Border Color', 'king-addons'),
1931 'type' => Controls_Manager::COLOR,
1932 'default' => 'rgba(0, 0, 0, 0.1)',
1933 'selectors' => [
1934 '{{WRAPPER}} .king-addons-dpg-card:hover' => 'border-color: {{VALUE}};',
1935 ],
1936 ]
1937 );
1938
1939 // Transition duration
1940 $this->add_control(
1941 'kng_dynamic_posts_card_transition_duration',
1942 [
1943 'label' => esc_html__('Transition Duration (ms)', 'king-addons'),
1944 'type' => Controls_Manager::SLIDER,
1945 'range' => [
1946 'px' => [
1947 'min' => 100,
1948 'max' => 1000,
1949 'step' => 50,
1950 ],
1951 ],
1952 'default' => [
1953 'size' => 300,
1954 ],
1955 'selectors' => [
1956 '{{WRAPPER}} .king-addons-dpg-card' => 'transition: all {{SIZE}}ms cubic-bezier(0.4, 0, 0.2, 1);',
1957 ],
1958 ]
1959 );
1960
1961 // Card clickable
1962 $this->add_control(
1963 'kng_dynamic_posts_card_clickable',
1964 [
1965 'label' => esc_html__('Make Card Clickable', 'king-addons'),
1966 'type' => Controls_Manager::SWITCHER,
1967 'label_on' => esc_html__('Yes', 'king-addons'),
1968 'label_off' => esc_html__('No', 'king-addons'),
1969 'return_value' => 'yes',
1970 'default' => 'no',
1971 'description' => esc_html__('Makes the entire card clickable to navigate to the post. Note: This feature works only on the live site.', 'king-addons'),
1972 ]
1973 );
1974
1975 // Card clickable notice for editor
1976 $this->add_control(
1977 'kng_dynamic_posts_card_clickable_notice',
1978 [
1979 'type' => Controls_Manager::RAW_HTML,
1980 'raw' => '<div style="background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; padding: 12px; margin-top: 10px; color: #856404;">
1981 <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
1982 <i class="eicon-info-circle" style="color: #ffc107;"></i>
1983 <strong>' . esc_html__('Card Clickable Notice', 'king-addons') . '</strong>
1984 </div>
1985 <p style="margin: 0; font-size: 13px; line-height: 1.4;">' .
1986 esc_html__('Card clicking functionality is disabled in the Elementor editor to prevent interference with editing. It will work properly on the live site.', 'king-addons') .
1987 '</p>
1988 </div>',
1989 'condition' => [
1990 'kng_dynamic_posts_card_clickable' => 'yes',
1991 ],
1992 ]
1993 );
1994
1995 $this->end_controls_section();
1996
1997 // Card Header Style
1998 $this->start_controls_section(
1999 'kng_dynamic_posts_card_header_style_section',
2000 [
2001 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Card Header', 'king-addons'),
2002 'tab' => Controls_Manager::TAB_STYLE,
2003 ]
2004 );
2005
2006 // Header padding
2007 $this->add_responsive_control(
2008 'kng_dynamic_posts_header_padding',
2009 [
2010 'label' => esc_html__('Padding', 'king-addons'),
2011 'type' => Controls_Manager::DIMENSIONS,
2012 'size_units' => ['px', 'em', '%'],
2013 'default' => [
2014 'top' => 24,
2015 'right' => 24,
2016 'bottom' => 20,
2017 'left' => 24,
2018 'unit' => 'px',
2019 ],
2020 'selectors' => [
2021 '{{WRAPPER}} .king-addons-dpg-header' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2022 ],
2023 ]
2024 );
2025
2026 // Icon styles
2027 $this->add_control(
2028 'kng_dynamic_posts_icon_heading',
2029 [
2030 'label' => esc_html__('Icon', 'king-addons'),
2031 'type' => Controls_Manager::HEADING,
2032 'separator' => 'before',
2033 ]
2034 );
2035
2036 // Icon size
2037 $this->add_responsive_control(
2038 'kng_dynamic_posts_icon_size',
2039 [
2040 'label' => esc_html__('Icon Size', 'king-addons'),
2041 'type' => Controls_Manager::SLIDER,
2042 'size_units' => ['px'],
2043 'range' => [
2044 'px' => [
2045 'min' => 12,
2046 'max' => 50,
2047 ],
2048 ],
2049 'default' => [
2050 'size' => 20,
2051 'unit' => 'px',
2052 ],
2053 'selectors' => [
2054 '{{WRAPPER}} .king-addons-dpg-icon i' => 'font-size: {{SIZE}}{{UNIT}};',
2055 '{{WRAPPER}} .king-addons-dpg-icon svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
2056 '{{WRAPPER}} .king-addons-dpg-icon img' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
2057 ],
2058 ]
2059 );
2060
2061 // Icon color
2062 $this->add_control(
2063 'kng_dynamic_posts_icon_color',
2064 [
2065 'label' => esc_html__('Icon Color', 'king-addons'),
2066 'type' => Controls_Manager::COLOR,
2067 'default' => '#6B7280',
2068 'selectors' => [
2069 '{{WRAPPER}} .king-addons-dpg-icon i' => 'color: {{VALUE}};',
2070 '{{WRAPPER}} .king-addons-dpg-icon svg' => 'fill: {{VALUE}};',
2071 ],
2072 ]
2073 );
2074
2075 // Icon background
2076 $this->add_control(
2077 'kng_dynamic_posts_icon_background',
2078 [
2079 'label' => esc_html__('Icon Background', 'king-addons'),
2080 'type' => Controls_Manager::COLOR,
2081 'default' => 'rgba(255, 255, 255, 0.7)',
2082 'selectors' => [
2083 '{{WRAPPER}} .king-addons-dpg-icon' => 'background-color: {{VALUE}};',
2084 ],
2085 ]
2086 );
2087
2088 // Icon border radius
2089 $this->add_responsive_control(
2090 'kng_dynamic_posts_icon_border_radius',
2091 [
2092 'label' => esc_html__('Icon Border Radius', 'king-addons'),
2093 'type' => Controls_Manager::DIMENSIONS,
2094 'size_units' => ['px', '%'],
2095 'default' => [
2096 'top' => 12,
2097 'right' => 12,
2098 'bottom' => 12,
2099 'left' => 12,
2100 'unit' => 'px',
2101 ],
2102 'selectors' => [
2103 '{{WRAPPER}} .king-addons-dpg-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2104 ],
2105 ]
2106 );
2107
2108 // Icon container size
2109 $this->add_responsive_control(
2110 'kng_dynamic_posts_icon_container_size',
2111 [
2112 'label' => esc_html__('Icon Container Size', 'king-addons'),
2113 'type' => Controls_Manager::SLIDER,
2114 'size_units' => ['px'],
2115 'range' => [
2116 'px' => [
2117 'min' => 30,
2118 'max' => 80,
2119 ],
2120 ],
2121 'default' => [
2122 'size' => 44,
2123 'unit' => 'px',
2124 ],
2125 'selectors' => [
2126 '{{WRAPPER}} .king-addons-dpg-icon' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
2127 ],
2128 ]
2129 );
2130
2131 // Icon box shadow
2132 $this->add_group_control(
2133 Group_Control_Box_Shadow::get_type(),
2134 [
2135 'name' => 'kng_dynamic_posts_icon_box_shadow',
2136 'label' => esc_html__('Icon Box Shadow', 'king-addons'),
2137 'selector' => '{{WRAPPER}} .king-addons-dpg-icon',
2138 'fields_options' => [
2139 'box_shadow_type' => [
2140 'default' => 'yes',
2141 ],
2142 'box_shadow' => [
2143 'default' => [
2144 'horizontal' => 0,
2145 'vertical' => 2,
2146 'blur' => 4,
2147 'spread' => 0,
2148 'color' => 'rgba(0, 0, 0, 0.1)',
2149 ],
2150 ],
2151 ],
2152 ]
2153 );
2154
2155 // Label styles
2156 $this->add_control(
2157 'kng_dynamic_posts_label_heading',
2158 [
2159 'label' => esc_html__('Label', 'king-addons'),
2160 'type' => Controls_Manager::HEADING,
2161 'separator' => 'before',
2162 ]
2163 );
2164
2165 // Label typography
2166 $this->add_group_control(
2167 Group_Control_Typography::get_type(),
2168 [
2169 'name' => 'kng_dynamic_posts_label_typography',
2170 'label' => esc_html__('Label Typography', 'king-addons'),
2171 'selector' => '{{WRAPPER}} .king-addons-dpg-label',
2172 'fields_options' => [
2173 'typography' => [
2174 'default' => 'yes',
2175 ],
2176 'font_size' => [
2177 'default' => [
2178 'size' => 11,
2179 'unit' => 'px',
2180 ],
2181 ],
2182 'font_weight' => [
2183 'default' => '600',
2184 ],
2185 'text_transform' => [
2186 'default' => 'uppercase',
2187 ],
2188 'letter_spacing' => [
2189 'default' => [
2190 'size' => 1,
2191 'unit' => 'px',
2192 ],
2193 ],
2194 ],
2195 ]
2196 );
2197
2198 // Label color
2199 $this->add_control(
2200 'kng_dynamic_posts_label_color',
2201 [
2202 'label' => esc_html__('Label Color', 'king-addons'),
2203 'type' => Controls_Manager::COLOR,
2204 'default' => '#6B7280',
2205 'selectors' => [
2206 '{{WRAPPER}} .king-addons-dpg-label' => 'color: {{VALUE}};',
2207 ],
2208 ]
2209 );
2210
2211 // Label padding
2212 $this->add_responsive_control(
2213 'kng_dynamic_posts_label_padding',
2214 [
2215 'label' => esc_html__('Label Padding', 'king-addons'),
2216 'type' => Controls_Manager::DIMENSIONS,
2217 'size_units' => ['px', 'em', '%'],
2218 'default' => [
2219 'top' => 4,
2220 'right' => 8,
2221 'bottom' => 4,
2222 'left' => 8,
2223 'unit' => 'px',
2224 ],
2225 'selectors' => [
2226 '{{WRAPPER}} .king-addons-dpg-label' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2227 ],
2228 ]
2229 );
2230
2231 // Label border
2232 $this->add_group_control(
2233 Group_Control_Border::get_type(),
2234 [
2235 'name' => 'kng_dynamic_posts_label_border',
2236 'label' => esc_html__('Label Border', 'king-addons'),
2237 'selector' => '{{WRAPPER}} .king-addons-dpg-label',
2238 'fields_options' => [
2239 'border' => [
2240 'default' => 'solid',
2241 ],
2242 'width' => [
2243 'default' => [
2244 'top' => 1,
2245 'right' => 1,
2246 'bottom' => 1,
2247 'left' => 1,
2248 'unit' => 'px',
2249 ],
2250 ],
2251 'color' => [
2252 'default' => '#E5E7EB',
2253 ],
2254 ],
2255 ]
2256 );
2257
2258 // Label border radius
2259 $this->add_responsive_control(
2260 'kng_dynamic_posts_label_border_radius',
2261 [
2262 'label' => esc_html__('Label Border Radius', 'king-addons'),
2263 'type' => Controls_Manager::DIMENSIONS,
2264 'size_units' => ['px', 'em', '%'],
2265 'default' => [
2266 'top' => 4,
2267 'right' => 4,
2268 'bottom' => 4,
2269 'left' => 4,
2270 'unit' => 'px',
2271 ],
2272 'selectors' => [
2273 '{{WRAPPER}} .king-addons-dpg-label' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2274 ],
2275 ]
2276 );
2277
2278 // Label background
2279 $this->add_control(
2280 'kng_dynamic_posts_label_background',
2281 [
2282 'label' => esc_html__('Label Background', 'king-addons'),
2283 'type' => Controls_Manager::COLOR,
2284 'default' => 'transparent',
2285 'selectors' => [
2286 '{{WRAPPER}} .king-addons-dpg-label' => 'background-color: {{VALUE}};',
2287 ],
2288 ]
2289 );
2290
2291 $this->end_controls_section();
2292
2293 // Card Content Style
2294 $this->start_controls_section(
2295 'kng_dynamic_posts_card_content_style_section',
2296 [
2297 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Card Content', 'king-addons'),
2298 'tab' => Controls_Manager::TAB_STYLE,
2299 ]
2300 );
2301
2302 // Content padding
2303 $this->add_responsive_control(
2304 'kng_dynamic_posts_content_padding',
2305 [
2306 'label' => esc_html__('Content Padding', 'king-addons'),
2307 'type' => Controls_Manager::DIMENSIONS,
2308 'size_units' => ['px', 'em', '%'],
2309 'default' => [
2310 'top' => 0,
2311 'right' => 24,
2312 'bottom' => 20,
2313 'left' => 24,
2314 'unit' => 'px',
2315 ],
2316 'selectors' => [
2317 '{{WRAPPER}} .king-addons-dpg-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2318 ],
2319 ]
2320 );
2321
2322 // Content vertical alignment
2323 $this->add_responsive_control(
2324 'kng_dynamic_posts_content_vertical_alignment',
2325 [
2326 'label' => esc_html__('Content Vertical Alignment', 'king-addons'),
2327 'type' => Controls_Manager::SELECT,
2328 'default' => 'flex-start',
2329 'options' => [
2330 'flex-start' => esc_html__('Top', 'king-addons'),
2331 'center' => esc_html__('Center', 'king-addons'),
2332 'flex-end' => esc_html__('Bottom', 'king-addons'),
2333 'space-between' => esc_html__('Space Between', 'king-addons'),
2334 'space-around' => esc_html__('Space Around', 'king-addons'),
2335 ],
2336 'selectors' => [
2337 '{{WRAPPER}} .king-addons-dpg-content' => 'justify-content: {{VALUE}};',
2338 ],
2339 ]
2340 );
2341
2342 // Show excerpt
2343 $this->add_control(
2344 'kng_dynamic_posts_show_excerpt',
2345 [
2346 'label' => esc_html__('Show Excerpt', 'king-addons'),
2347 'type' => Controls_Manager::SWITCHER,
2348 'label_on' => esc_html__('Show', 'king-addons'),
2349 'label_off' => esc_html__('Hide', 'king-addons'),
2350 'return_value' => 'yes',
2351 'default' => 'yes',
2352 ]
2353 );
2354
2355 // Title typography
2356 $this->add_group_control(
2357 Group_Control_Typography::get_type(),
2358 [
2359 'name' => 'kng_dynamic_posts_title_typography',
2360 'label' => esc_html__('Title Typography', 'king-addons'),
2361 'selector' => '{{WRAPPER}} .king-addons-dpg-title',
2362 'fields_options' => [
2363 'typography' => [
2364 'default' => 'yes',
2365 ],
2366 'font_size' => [
2367 'default' => [
2368 'size' => 16,
2369 'unit' => 'px',
2370 ],
2371 ],
2372 'font_weight' => [
2373 'default' => '500',
2374 ],
2375 'line_height' => [
2376 'default' => [
2377 'size' => 1.5,
2378 'unit' => 'em',
2379 ],
2380 ],
2381 ],
2382 ]
2383 );
2384
2385 // Title color
2386 $this->add_control(
2387 'kng_dynamic_posts_title_color',
2388 [
2389 'label' => esc_html__('Title Color', 'king-addons'),
2390 'type' => Controls_Manager::COLOR,
2391 'default' => '#374151',
2392 'selectors' => [
2393 '{{WRAPPER}} .king-addons-dpg-title a' => 'color: {{VALUE}};',
2394 ],
2395 ]
2396 );
2397
2398 // Title hover color
2399 $this->add_control(
2400 'kng_dynamic_posts_title_hover_color',
2401 [
2402 'label' => esc_html__('Title Hover Color', 'king-addons'),
2403 'type' => Controls_Manager::COLOR,
2404 'default' => '#1F2937',
2405 'selectors' => [
2406 '{{WRAPPER}} .king-addons-dpg-title a:hover' => 'color: {{VALUE}};',
2407 ],
2408 ]
2409 );
2410
2411 // Excerpt heading
2412 $this->add_control(
2413 'kng_dynamic_posts_excerpt_heading',
2414 [
2415 'label' => esc_html__('Excerpt', 'king-addons'),
2416 'type' => Controls_Manager::HEADING,
2417 'separator' => 'before',
2418 'condition' => [
2419 'kng_dynamic_posts_show_excerpt' => 'yes',
2420 ],
2421 ]
2422 );
2423
2424 // Excerpt typography
2425 $this->add_group_control(
2426 Group_Control_Typography::get_type(),
2427 [
2428 'name' => 'kng_dynamic_posts_excerpt_typography',
2429 'label' => esc_html__('Excerpt Typography', 'king-addons'),
2430 'selector' => '{{WRAPPER}} .king-addons-dpg-excerpt',
2431 'condition' => [
2432 'kng_dynamic_posts_show_excerpt' => 'yes',
2433 ],
2434 'fields_options' => [
2435 'typography' => [
2436 'default' => 'yes',
2437 ],
2438 'font_size' => [
2439 'default' => [
2440 'size' => 14,
2441 'unit' => 'px',
2442 ],
2443 ],
2444 'line_height' => [
2445 'default' => [
2446 'size' => 1.5,
2447 'unit' => 'em',
2448 ],
2449 ],
2450 ],
2451 ]
2452 );
2453
2454 // Excerpt color
2455 $this->add_control(
2456 'kng_dynamic_posts_excerpt_color',
2457 [
2458 'label' => esc_html__('Excerpt Color', 'king-addons'),
2459 'type' => Controls_Manager::COLOR,
2460 'default' => '#6B7280',
2461 'selectors' => [
2462 '{{WRAPPER}} .king-addons-dpg-excerpt' => 'color: {{VALUE}};',
2463 ],
2464 'condition' => [
2465 'kng_dynamic_posts_show_excerpt' => 'yes',
2466 ],
2467 ]
2468 );
2469
2470 // Excerpt margin
2471 $this->add_responsive_control(
2472 'kng_dynamic_posts_excerpt_margin',
2473 [
2474 'label' => esc_html__('Excerpt Margin', 'king-addons'),
2475 'type' => Controls_Manager::DIMENSIONS,
2476 'size_units' => ['px', 'em', '%'],
2477 'default' => [
2478 'top' => 8,
2479 'right' => 0,
2480 'bottom' => 0,
2481 'left' => 0,
2482 'unit' => 'px',
2483 ],
2484 'selectors' => [
2485 '{{WRAPPER}} .king-addons-dpg-excerpt' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2486 ],
2487 'condition' => [
2488 'kng_dynamic_posts_show_excerpt' => 'yes',
2489 ],
2490 ]
2491 );
2492
2493 $this->end_controls_section();
2494
2495 // Card Button Style
2496 $this->start_controls_section(
2497 'kng_dynamic_posts_card_button_style_section',
2498 [
2499 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Card Button', 'king-addons'),
2500 'tab' => Controls_Manager::TAB_STYLE,
2501 ]
2502 );
2503
2504 // Button container padding
2505 $this->add_responsive_control(
2506 'kng_dynamic_posts_button_container_padding',
2507 [
2508 'label' => esc_html__('Container Padding', 'king-addons'),
2509 'type' => Controls_Manager::DIMENSIONS,
2510 'size_units' => ['px', 'em', '%'],
2511 'default' => [
2512 'top' => 0,
2513 'right' => 24,
2514 'bottom' => 24,
2515 'left' => 24,
2516 'unit' => 'px',
2517 ],
2518 'selectors' => [
2519 '{{WRAPPER}} .king-addons-dpg-cta' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2520 ],
2521 ]
2522 );
2523
2524 // Button typography
2525 $this->add_group_control(
2526 Group_Control_Typography::get_type(),
2527 [
2528 'name' => 'kng_dynamic_posts_button_typography',
2529 'label' => esc_html__('Button Typography', 'king-addons'),
2530 'selector' => '{{WRAPPER}} .king-addons-dpg-button',
2531 'fields_options' => [
2532 'typography' => [
2533 'default' => 'yes',
2534 ],
2535 'font_size' => [
2536 'default' => [
2537 'size' => 11,
2538 'unit' => 'px',
2539 ],
2540 ],
2541 'font_weight' => [
2542 'default' => '500',
2543 ],
2544 'text_transform' => [
2545 'default' => 'uppercase',
2546 ],
2547 'letter_spacing' => [
2548 'default' => [
2549 'size' => 0.5,
2550 'unit' => 'px',
2551 ],
2552 ],
2553 ],
2554 ]
2555 );
2556
2557 // Button border style
2558 $this->add_control(
2559 'kng_dynamic_posts_button_border_style',
2560 [
2561 'label' => esc_html__('Border Style', 'king-addons'),
2562 'type' => Controls_Manager::SELECT,
2563 'options' => [
2564 'none' => esc_html__('None', 'king-addons'),
2565 'solid' => esc_html__('Solid', 'king-addons'),
2566 'dashed' => esc_html__('Dashed', 'king-addons'),
2567 'dotted' => esc_html__('Dotted', 'king-addons'),
2568 ],
2569 'default' => 'solid',
2570 'selectors' => [
2571 '{{WRAPPER}} .king-addons-dpg-button' => 'border-style: {{VALUE}};',
2572 ],
2573 ]
2574 );
2575
2576 // Button border width
2577 $this->add_responsive_control(
2578 'kng_dynamic_posts_button_border_width',
2579 [
2580 'label' => esc_html__('Border Width', 'king-addons'),
2581 'type' => Controls_Manager::DIMENSIONS,
2582 'size_units' => ['px'],
2583 'default' => [
2584 'top' => 1,
2585 'right' => 1,
2586 'bottom' => 1,
2587 'left' => 1,
2588 'unit' => 'px',
2589 ],
2590 'selectors' => [
2591 '{{WRAPPER}} .king-addons-dpg-button' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2592 ],
2593 'condition' => [
2594 'kng_dynamic_posts_button_border_style!' => 'none',
2595 ],
2596 ]
2597 );
2598
2599 // Default button border color
2600 $this->add_control(
2601 'kng_dynamic_posts_default_button_border_color',
2602 [
2603 'label' => esc_html__('Default Border Color', 'king-addons'),
2604 'type' => Controls_Manager::COLOR,
2605 'default' => 'rgba(0, 0, 0, 0.1)',
2606 'selectors' => [
2607 '{{WRAPPER}} .king-addons-dpg-button' => 'border-color: {{VALUE}};',
2608 ],
2609 'condition' => [
2610 'kng_dynamic_posts_button_border_style!' => 'none',
2611 ],
2612 ]
2613 );
2614
2615 // Button border radius
2616 $this->add_responsive_control(
2617 'kng_dynamic_posts_button_border_radius',
2618 [
2619 'label' => esc_html__('Border Radius', 'king-addons'),
2620 'type' => Controls_Manager::DIMENSIONS,
2621 'size_units' => ['px', '%'],
2622 'default' => [
2623 'top' => 20,
2624 'right' => 20,
2625 'bottom' => 20,
2626 'left' => 20,
2627 'unit' => 'px',
2628 ],
2629 'selectors' => [
2630 '{{WRAPPER}} .king-addons-dpg-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2631 ],
2632 ]
2633 );
2634
2635 // Button padding
2636 $this->add_responsive_control(
2637 'kng_dynamic_posts_button_padding',
2638 [
2639 'label' => esc_html__('Button Padding', 'king-addons'),
2640 'type' => Controls_Manager::DIMENSIONS,
2641 'size_units' => ['px', 'em', '%'],
2642 'default' => [
2643 'top' => 10,
2644 'right' => 20,
2645 'bottom' => 10,
2646 'left' => 20,
2647 'unit' => 'px',
2648 ],
2649 'selectors' => [
2650 '{{WRAPPER}} .king-addons-dpg-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2651 ],
2652 ]
2653 );
2654
2655 // Button box shadow
2656 $this->add_group_control(
2657 Group_Control_Box_Shadow::get_type(),
2658 [
2659 'name' => 'kng_dynamic_posts_button_box_shadow',
2660 'label' => esc_html__('Box Shadow', 'king-addons'),
2661 'selector' => '{{WRAPPER}} .king-addons-dpg-button',
2662 'fields_options' => [
2663 'box_shadow_type' => [
2664 'default' => 'yes',
2665 ],
2666 'box_shadow' => [
2667 'default' => [
2668 'horizontal' => 0,
2669 'vertical' => 1,
2670 'blur' => 2,
2671 'spread' => 0,
2672 'color' => 'rgba(0, 0, 0, 0.05)',
2673 ],
2674 ],
2675 ],
2676 ]
2677 );
2678
2679 $this->end_controls_section();
2680
2681 // Load More Button Style
2682 $this->start_controls_section(
2683 'kng_dynamic_posts_load_more_style_section',
2684 [
2685 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Load More Button', 'king-addons'),
2686 'tab' => Controls_Manager::TAB_STYLE,
2687 ]
2688 );
2689
2690 // Button typography
2691 $this->add_group_control(
2692 Group_Control_Typography::get_type(),
2693 [
2694 'name' => 'kng_dynamic_posts_load_more_typography',
2695 'label' => esc_html__('Typography', 'king-addons'),
2696 'selector' => '{{WRAPPER}} .king-addons-dpg-load-more-btn',
2697 'fields_options' => [
2698 'typography' => [
2699 'default' => 'yes',
2700 ],
2701 'font_size' => [
2702 'default' => [
2703 'size' => 14,
2704 'unit' => 'px',
2705 ],
2706 ],
2707 'font_weight' => [
2708 'default' => '600',
2709 ],
2710 'text_transform' => [
2711 'default' => 'uppercase',
2712 ],
2713 'letter_spacing' => [
2714 'default' => [
2715 'size' => 0.5,
2716 'unit' => 'px',
2717 ],
2718 ],
2719 ],
2720 ]
2721 );
2722
2723 // Button text color
2724 $this->add_control(
2725 'kng_dynamic_posts_load_more_color',
2726 [
2727 'label' => esc_html__('Text Color', 'king-addons'),
2728 'type' => Controls_Manager::COLOR,
2729 'default' => '#1F2937',
2730 'selectors' => [
2731 '{{WRAPPER}} .king-addons-dpg-load-more-btn' => 'color: {{VALUE}};',
2732 ],
2733 ]
2734 );
2735
2736 // Button background
2737 $this->add_group_control(
2738 Group_Control_Background::get_type(),
2739 [
2740 'name' => 'kng_dynamic_posts_load_more_background',
2741 'label' => esc_html__('Background', 'king-addons'),
2742 'types' => ['classic', 'gradient'],
2743 'selector' => '{{WRAPPER}} .king-addons-dpg-load-more-btn',
2744 'fields_options' => [
2745 'background' => [
2746 'default' => 'classic',
2747 ],
2748 'color' => [
2749 'default' => '#FCD34D',
2750 ],
2751 ],
2752 ]
2753 );
2754
2755 // Button hover color
2756 $this->add_control(
2757 'kng_dynamic_posts_load_more_hover_color',
2758 [
2759 'label' => esc_html__('Hover Text Color', 'king-addons'),
2760 'type' => Controls_Manager::COLOR,
2761 'default' => '#1F2937',
2762 'selectors' => [
2763 '{{WRAPPER}} .king-addons-dpg-load-more-btn:hover' => 'color: {{VALUE}};',
2764 ],
2765 ]
2766 );
2767
2768 // Button hover background
2769 $this->add_control(
2770 'kng_dynamic_posts_load_more_hover_background',
2771 [
2772 'label' => esc_html__('Hover Background', 'king-addons'),
2773 'type' => Controls_Manager::COLOR,
2774 'default' => '#F59E0B',
2775 'selectors' => [
2776 '{{WRAPPER}} .king-addons-dpg-load-more-btn:hover' => 'background-color: {{VALUE}};',
2777 ],
2778 ]
2779 );
2780
2781 // Button border
2782 $this->add_group_control(
2783 Group_Control_Border::get_type(),
2784 [
2785 'name' => 'kng_dynamic_posts_load_more_border',
2786 'label' => esc_html__('Border', 'king-addons'),
2787 'selector' => '{{WRAPPER}} .king-addons-dpg-load-more-btn',
2788 ]
2789 );
2790
2791 // Button border radius
2792 $this->add_responsive_control(
2793 'kng_dynamic_posts_load_more_border_radius',
2794 [
2795 'label' => esc_html__('Border Radius', 'king-addons'),
2796 'type' => Controls_Manager::DIMENSIONS,
2797 'size_units' => ['px', '%'],
2798 'default' => [
2799 'top' => 24,
2800 'right' => 24,
2801 'bottom' => 24,
2802 'left' => 24,
2803 'unit' => 'px',
2804 ],
2805 'selectors' => [
2806 '{{WRAPPER}} .king-addons-dpg-load-more-btn' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2807 ],
2808 ]
2809 );
2810
2811 // Button padding
2812 $this->add_responsive_control(
2813 'kng_dynamic_posts_load_more_padding',
2814 [
2815 'label' => esc_html__('Padding', 'king-addons'),
2816 'type' => Controls_Manager::DIMENSIONS,
2817 'size_units' => ['px', 'em', '%'],
2818 'default' => [
2819 'top' => 16,
2820 'right' => 48,
2821 'bottom' => 16,
2822 'left' => 48,
2823 'unit' => 'px',
2824 ],
2825 'selectors' => [
2826 '{{WRAPPER}} .king-addons-dpg-load-more-btn' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
2827 ],
2828 ]
2829 );
2830
2831 // Button box shadow
2832 $this->add_group_control(
2833 Group_Control_Box_Shadow::get_type(),
2834 [
2835 'name' => 'kng_dynamic_posts_load_more_box_shadow',
2836 'label' => esc_html__('Box Shadow', 'king-addons'),
2837 'selector' => '{{WRAPPER}} .king-addons-dpg-load-more-btn',
2838 'fields_options' => [
2839 'box_shadow_type' => [
2840 'default' => 'yes',
2841 ],
2842 'box_shadow' => [
2843 'default' => [
2844 'horizontal' => 0,
2845 'vertical' => 2,
2846 'blur' => 4,
2847 'spread' => 0,
2848 'color' => 'rgba(252, 211, 77, 0.3)',
2849 ],
2850 ],
2851 ],
2852 ]
2853 );
2854
2855 $this->end_controls_section();
2856
2857 // Pagination Style
2858 $this->start_controls_section(
2859 'kng_dynamic_posts_pagination_style_section',
2860 [
2861 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Pagination', 'king-addons'),
2862 'tab' => Controls_Manager::TAB_STYLE,
2863 'condition' => [
2864 'kng_dynamic_posts_enable_load_more' => 'yes',
2865 ],
2866 ]
2867 );
2868
2869 // Pagination section margin top
2870 $this->add_responsive_control(
2871 'kng_dynamic_posts_pagination_margin_top',
2872 [
2873 'label' => esc_html__('Section Top Margin', 'king-addons'),
2874 'type' => Controls_Manager::SLIDER,
2875 'size_units' => ['px', 'em', 'rem'],
2876 'range' => [
2877 'px' => [
2878 'min' => 0,
2879 'max' => 100,
2880 ],
2881 ],
2882 'default' => [
2883 'size' => 40,
2884 'unit' => 'px',
2885 ],
2886 'selectors' => [
2887 '{{WRAPPER}} .king-addons-dpg-pagination' => 'margin-top: {{SIZE}}{{UNIT}};',
2888 ],
2889 ]
2890 );
2891
2892 // Pagination info typography
2893 $this->add_group_control(
2894 Group_Control_Typography::get_type(),
2895 [
2896 'name' => 'kng_dynamic_posts_pagination_info_typography',
2897 'label' => esc_html__('Info Typography', 'king-addons'),
2898 'selector' => '{{WRAPPER}} .king-addons-dpg-pagination-info',
2899 'fields_options' => [
2900 'typography' => [
2901 'default' => 'yes',
2902 ],
2903 'font_size' => [
2904 'default' => [
2905 'size' => 14,
2906 'unit' => 'px',
2907 ],
2908 ],
2909 ],
2910 ]
2911 );
2912
2913 // Pagination info color
2914 $this->add_control(
2915 'kng_dynamic_posts_pagination_info_color',
2916 [
2917 'label' => esc_html__('Info Text Color', 'king-addons'),
2918 'type' => Controls_Manager::COLOR,
2919 'default' => '#6B7280',
2920 'selectors' => [
2921 '{{WRAPPER}} .king-addons-dpg-pagination-info' => 'color: {{VALUE}};',
2922 ],
2923 ]
2924 );
2925
2926 // Count numbers color
2927 $this->add_control(
2928 'kng_dynamic_posts_pagination_count_color',
2929 [
2930 'label' => esc_html__('Count Numbers Color', 'king-addons'),
2931 'type' => Controls_Manager::COLOR,
2932 'default' => '#374151',
2933 'selectors' => [
2934 '{{WRAPPER}} .king-addons-dpg-current-count, {{WRAPPER}} .king-addons-dpg-total-count' => 'color: {{VALUE}};',
2935 ],
2936 ]
2937 );
2938
2939 // Pagination info margin
2940 $this->add_responsive_control(
2941 'kng_dynamic_posts_pagination_info_margin',
2942 [
2943 'label' => esc_html__('Info Bottom Margin', 'king-addons'),
2944 'type' => Controls_Manager::SLIDER,
2945 'size_units' => ['px', 'em', 'rem'],
2946 'range' => [
2947 'px' => [
2948 'min' => 0,
2949 'max' => 60,
2950 ],
2951 ],
2952 'default' => [
2953 'size' => 30,
2954 'unit' => 'px',
2955 ],
2956 'selectors' => [
2957 '{{WRAPPER}} .king-addons-dpg-pagination-info' => 'margin-bottom: {{SIZE}}{{UNIT}};',
2958 ],
2959 ]
2960 );
2961
2962 // Loading text styles
2963 $this->add_control(
2964 'kng_dynamic_posts_loading_heading',
2965 [
2966 'label' => esc_html__('Loading Text', 'king-addons'),
2967 'type' => Controls_Manager::HEADING,
2968 'separator' => 'before',
2969 ]
2970 );
2971
2972 // Loading text color
2973 $this->add_control(
2974 'kng_dynamic_posts_loading_color',
2975 [
2976 'label' => esc_html__('Loading Text Color', 'king-addons'),
2977 'type' => Controls_Manager::COLOR,
2978 'default' => '#666',
2979 'selectors' => [
2980 '{{WRAPPER}} .king-addons-dpg-pagination-loading' => 'color: {{VALUE}};',
2981 ],
2982 ]
2983 );
2984
2985 // Finish text styles
2986 $this->add_control(
2987 'kng_dynamic_posts_finish_heading',
2988 [
2989 'label' => esc_html__('Finish Text', 'king-addons'),
2990 'type' => Controls_Manager::HEADING,
2991 'separator' => 'before',
2992 ]
2993 );
2994
2995 // Finish text typography
2996 $this->add_group_control(
2997 Group_Control_Typography::get_type(),
2998 [
2999 'name' => 'kng_dynamic_posts_finish_typography',
3000 'label' => esc_html__('Finish Typography', 'king-addons'),
3001 'selector' => '{{WRAPPER}} .king-addons-dpg-pagination-finish',
3002 'fields_options' => [
3003 'typography' => [
3004 'default' => 'yes',
3005 ],
3006 'font_size' => [
3007 'default' => [
3008 'size' => 14,
3009 'unit' => 'px',
3010 ],
3011 ],
3012 ],
3013 ]
3014 );
3015
3016 // Finish text color
3017 $this->add_control(
3018 'kng_dynamic_posts_finish_color',
3019 [
3020 'label' => esc_html__('Finish Text Color', 'king-addons'),
3021 'type' => Controls_Manager::COLOR,
3022 'default' => '#6B7280',
3023 'selectors' => [
3024 '{{WRAPPER}} .king-addons-dpg-pagination-finish' => 'color: {{VALUE}};',
3025 ],
3026 ]
3027 );
3028
3029 // Finish text margin
3030 $this->add_responsive_control(
3031 'kng_dynamic_posts_finish_margin',
3032 [
3033 'label' => esc_html__('Finish Text Margin', 'king-addons'),
3034 'type' => Controls_Manager::DIMENSIONS,
3035 'size_units' => ['px', 'em', '%'],
3036 'default' => [
3037 'top' => 30,
3038 'right' => 0,
3039 'bottom' => 20,
3040 'left' => 0,
3041 'unit' => 'px',
3042 ],
3043 'selectors' => [
3044 '{{WRAPPER}} .king-addons-dpg-pagination-finish' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
3045 ],
3046 ]
3047 );
3048
3049 $this->end_controls_section();
3050
3051 // Messages Style
3052 $this->start_controls_section(
3053 'kng_dynamic_posts_messages_style_section',
3054 [
3055 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Messages', 'king-addons'),
3056 'tab' => Controls_Manager::TAB_STYLE,
3057 ]
3058 );
3059
3060 // No posts message
3061 $this->add_control(
3062 'kng_dynamic_posts_no_posts_heading',
3063 [
3064 'label' => esc_html__('No Posts Message', 'king-addons'),
3065 'type' => Controls_Manager::HEADING,
3066 ]
3067 );
3068
3069 // No posts typography
3070 $this->add_group_control(
3071 Group_Control_Typography::get_type(),
3072 [
3073 'name' => 'kng_dynamic_posts_no_posts_typography',
3074 'label' => esc_html__('Typography', 'king-addons'),
3075 'selector' => '{{WRAPPER}} .king-addons-dpg-no-posts',
3076 'fields_options' => [
3077 'typography' => [
3078 'default' => 'yes',
3079 ],
3080 'font_size' => [
3081 'default' => [
3082 'size' => 16,
3083 'unit' => 'px',
3084 ],
3085 ],
3086 ],
3087 ]
3088 );
3089
3090 // No posts color
3091 $this->add_control(
3092 'kng_dynamic_posts_no_posts_color',
3093 [
3094 'label' => esc_html__('Text Color', 'king-addons'),
3095 'type' => Controls_Manager::COLOR,
3096 'default' => '#666',
3097 'selectors' => [
3098 '{{WRAPPER}} .king-addons-dpg-no-posts' => 'color: {{VALUE}};',
3099 ],
3100 ]
3101 );
3102
3103 // No posts background
3104 $this->add_control(
3105 'kng_dynamic_posts_no_posts_background',
3106 [
3107 'label' => esc_html__('Background Color', 'king-addons'),
3108 'type' => Controls_Manager::COLOR,
3109 'default' => '#f8f9fa',
3110 'selectors' => [
3111 '{{WRAPPER}} .king-addons-dpg-no-posts' => 'background-color: {{VALUE}};',
3112 ],
3113 ]
3114 );
3115
3116 // No posts border
3117 $this->add_group_control(
3118 Group_Control_Border::get_type(),
3119 [
3120 'name' => 'kng_dynamic_posts_no_posts_border',
3121 'label' => esc_html__('Border', 'king-addons'),
3122 'selector' => '{{WRAPPER}} .king-addons-dpg-no-posts',
3123 'fields_options' => [
3124 'border' => [
3125 'default' => 'dashed',
3126 ],
3127 'width' => [
3128 'default' => [
3129 'top' => 2,
3130 'right' => 2,
3131 'bottom' => 2,
3132 'left' => 2,
3133 'unit' => 'px',
3134 ],
3135 ],
3136 'color' => [
3137 'default' => '#ddd',
3138 ],
3139 ],
3140 ]
3141 );
3142
3143 // No posts border radius
3144 $this->add_responsive_control(
3145 'kng_dynamic_posts_no_posts_border_radius',
3146 [
3147 'label' => esc_html__('Border Radius', 'king-addons'),
3148 'type' => Controls_Manager::DIMENSIONS,
3149 'size_units' => ['px', '%'],
3150 'default' => [
3151 'top' => 8,
3152 'right' => 8,
3153 'bottom' => 8,
3154 'left' => 8,
3155 'unit' => 'px',
3156 ],
3157 'selectors' => [
3158 '{{WRAPPER}} .king-addons-dpg-no-posts' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
3159 ],
3160 ]
3161 );
3162
3163 // No posts padding
3164 $this->add_responsive_control(
3165 'kng_dynamic_posts_no_posts_padding',
3166 [
3167 'label' => esc_html__('Padding', 'king-addons'),
3168 'type' => Controls_Manager::DIMENSIONS,
3169 'size_units' => ['px', 'em', '%'],
3170 'default' => [
3171 'top' => 60,
3172 'right' => 20,
3173 'bottom' => 60,
3174 'left' => 20,
3175 'unit' => 'px',
3176 ],
3177 'selectors' => [
3178 '{{WRAPPER}} .king-addons-dpg-no-posts' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
3179 ],
3180 ]
3181 );
3182
3183 // Error message
3184 $this->add_control(
3185 'kng_dynamic_posts_error_heading',
3186 [
3187 'label' => esc_html__('Error Message', 'king-addons'),
3188 'type' => Controls_Manager::HEADING,
3189 'separator' => 'before',
3190 ]
3191 );
3192
3193 // Error message typography
3194 $this->add_group_control(
3195 Group_Control_Typography::get_type(),
3196 [
3197 'name' => 'kng_dynamic_posts_error_typography',
3198 'label' => esc_html__('Typography', 'king-addons'),
3199 'selector' => '{{WRAPPER}} .king-addons-dpg-error-message',
3200 'fields_options' => [
3201 'typography' => [
3202 'default' => 'yes',
3203 ],
3204 'font_size' => [
3205 'default' => [
3206 'size' => 14,
3207 'unit' => 'px',
3208 ],
3209 ],
3210 ],
3211 ]
3212 );
3213
3214 // Error message colors
3215 $this->add_control(
3216 'kng_dynamic_posts_error_color',
3217 [
3218 'label' => esc_html__('Text Color', 'king-addons'),
3219 'type' => Controls_Manager::COLOR,
3220 'default' => '#721c24',
3221 'selectors' => [
3222 '{{WRAPPER}} .king-addons-dpg-error-message' => 'color: {{VALUE}};',
3223 ],
3224 ]
3225 );
3226
3227 // Error message background
3228 $this->add_control(
3229 'kng_dynamic_posts_error_background',
3230 [
3231 'label' => esc_html__('Background Color', 'king-addons'),
3232 'type' => Controls_Manager::COLOR,
3233 'default' => '#f8d7da',
3234 'selectors' => [
3235 '{{WRAPPER}} .king-addons-dpg-error-message' => 'background-color: {{VALUE}};',
3236 ],
3237 ]
3238 );
3239
3240 // Error message border
3241 $this->add_group_control(
3242 Group_Control_Border::get_type(),
3243 [
3244 'name' => 'kng_dynamic_posts_error_border',
3245 'label' => esc_html__('Border', 'king-addons'),
3246 'selector' => '{{WRAPPER}} .king-addons-dpg-error-message',
3247 'fields_options' => [
3248 'border' => [
3249 'default' => 'solid',
3250 ],
3251 'width' => [
3252 'default' => [
3253 'top' => 1,
3254 'right' => 1,
3255 'bottom' => 1,
3256 'left' => 1,
3257 'unit' => 'px',
3258 ],
3259 ],
3260 'color' => [
3261 'default' => '#f5c6cb',
3262 ],
3263 ],
3264 ]
3265 );
3266
3267 // Error message border radius
3268 $this->add_responsive_control(
3269 'kng_dynamic_posts_error_border_radius',
3270 [
3271 'label' => esc_html__('Border Radius', 'king-addons'),
3272 'type' => Controls_Manager::DIMENSIONS,
3273 'size_units' => ['px', '%'],
3274 'default' => [
3275 'top' => 8,
3276 'right' => 8,
3277 'bottom' => 8,
3278 'left' => 8,
3279 'unit' => 'px',
3280 ],
3281 'selectors' => [
3282 '{{WRAPPER}} .king-addons-dpg-error-message' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
3283 ],
3284 ]
3285 );
3286
3287 // Error message padding
3288 $this->add_responsive_control(
3289 'kng_dynamic_posts_error_padding',
3290 [
3291 'label' => esc_html__('Padding', 'king-addons'),
3292 'type' => Controls_Manager::DIMENSIONS,
3293 'size_units' => ['px', 'em', '%'],
3294 'default' => [
3295 'top' => 12,
3296 'right' => 16,
3297 'bottom' => 12,
3298 'left' => 16,
3299 'unit' => 'px',
3300 ],
3301 'selectors' => [
3302 '{{WRAPPER}} .king-addons-dpg-error-message' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
3303 ],
3304 ]
3305 );
3306
3307 // Error message margin
3308 $this->add_responsive_control(
3309 'kng_dynamic_posts_error_margin_bottom',
3310 [
3311 'label' => esc_html__('Bottom Margin', 'king-addons'),
3312 'type' => Controls_Manager::SLIDER,
3313 'size_units' => ['px', 'em', 'rem'],
3314 'range' => [
3315 'px' => [
3316 'min' => 0,
3317 'max' => 50,
3318 ],
3319 ],
3320 'default' => [
3321 'size' => 20,
3322 'unit' => 'px',
3323 ],
3324 'selectors' => [
3325 '{{WRAPPER}} .king-addons-dpg-error-message' => 'margin-bottom: {{SIZE}}{{UNIT}};',
3326 ],
3327 ]
3328 );
3329
3330 $this->end_controls_section();
3331 }
3332
3333 /**
3334 * Get available post types.
3335 *
3336 * @return array Post types array.
3337 */
3338 protected function get_post_types(): array
3339 {
3340 $post_types = get_post_types(['public' => true], 'objects');
3341 $options = [];
3342
3343 foreach ($post_types as $post_type) {
3344 $options[$post_type->name] = $post_type->label;
3345 }
3346
3347 return $options;
3348 }
3349
3350 /**
3351 * Get available taxonomies.
3352 *
3353 * @return array Taxonomies array.
3354 */
3355 protected function get_taxonomies(): array
3356 {
3357 $taxonomies = get_taxonomies(['public' => true], 'objects');
3358 $options = [];
3359
3360 foreach ($taxonomies as $taxonomy) {
3361 $options[$taxonomy->name] = $taxonomy->label;
3362 }
3363
3364 return $options;
3365 }
3366
3367 /**
3368 * Add dynamic category color controls.
3369 */
3370 protected function add_dynamic_category_colors(): void
3371 {
3372 // Get taxonomy from filter settings (default to category)
3373 $taxonomy = 'category';
3374
3375 // Get terms from the taxonomy
3376 $terms = get_terms([
3377 'taxonomy' => $taxonomy,
3378 'hide_empty' => false,
3379 'number' => 20, // Limit to prevent too many controls
3380 ]);
3381
3382 if (is_wp_error($terms) || empty($terms)) {
3383 // Fallback to default colors if no terms found
3384 $this->add_control(
3385 'kng_dynamic_posts_default_color',
3386 [
3387 'label' => esc_html__('Default Color', 'king-addons'),
3388 'type' => Controls_Manager::COLOR,
3389 'default' => '#F8F9FA',
3390 'description' => esc_html__('Default color for posts without categories', 'king-addons'),
3391 'selectors' => [
3392 '{{WRAPPER}} .king-addons-dpg-card' => 'background-color: {{VALUE}};',
3393 '{{WRAPPER}} .king-addons-dpg-card.king-addons-dpg-category-default' => 'background-color: {{VALUE}};',
3394 ],
3395 ]
3396 );
3397 return;
3398 }
3399
3400 // Add instruction
3401 $this->add_control(
3402 'kng_dynamic_posts_colors_info',
3403 [
3404 'type' => Controls_Manager::RAW_HTML,
3405 'raw' => esc_html__('Set custom colors for each category. These colors will be used as background colors for post cards.', 'king-addons'),
3406 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
3407 ]
3408 );
3409
3410 // Default color for uncategorized posts
3411 $this->add_control(
3412 'kng_dynamic_posts_default_color',
3413 [
3414 'label' => esc_html__('Default Color', 'king-addons'),
3415 'type' => Controls_Manager::COLOR,
3416 'default' => '#F8F9FA',
3417 'description' => esc_html__('Color for posts without categories', 'king-addons'),
3418 'selectors' => [
3419 '{{WRAPPER}} .king-addons-dpg-card' => 'background-color: {{VALUE}};',
3420 '{{WRAPPER}} .king-addons-dpg-card.king-addons-dpg-category-default' => 'background-color: {{VALUE}};',
3421 ],
3422 ]
3423 );
3424
3425 // Add color control for each term (matching original design)
3426 $default_colors = [
3427 '#FEF3C7', // Warm yellow/cream (like REPORT in design)
3428 '#DBEAFE', // Light blue (like PUBLICATION in design)
3429 '#FBCFE8', // Light pink (like VIDEO in design)
3430 '#F3F4F6', // Light gray (like WEBSITE in design)
3431 '#E0E7FF', // Light indigo
3432 '#FEE2E2', // Light red
3433 '#D1FAE5', // Light emerald
3434 '#FEF3C7', // Light amber
3435 ];
3436
3437 $color_index = 0;
3438 foreach ($terms as $term) {
3439 $default_color = isset($default_colors[$color_index]) ? $default_colors[$color_index] : '#F8F9FA';
3440
3441 $this->add_control(
3442 'kng_dynamic_posts_color_' . $term->slug,
3443 [
3444 'label' => sprintf(esc_html__('%s Color', 'king-addons'), $term->name),
3445 'type' => Controls_Manager::COLOR,
3446 'default' => $default_color,
3447 'selectors' => [
3448 '{{WRAPPER}} .king-addons-dpg-card.filter-' . $term->slug => 'background-color: {{VALUE}};',
3449 '{{WRAPPER}} .king-addons-dpg-card.king-addons-dpg-category-' . $term->slug => 'background-color: {{VALUE}};',
3450 ],
3451 ]
3452 );
3453
3454 $color_index++;
3455 if ($color_index >= count($default_colors)) {
3456 $color_index = 0; // Reset to cycle through colors
3457 }
3458 }
3459 }
3460
3461 /**
3462 * Add dynamic category icon controls.
3463 */
3464 protected function add_dynamic_category_icons(): void
3465 {
3466 // Get taxonomy from filter settings (default to category)
3467 $taxonomy = 'category';
3468
3469 // Get terms from the taxonomy
3470 $terms = get_terms([
3471 'taxonomy' => $taxonomy,
3472 'hide_empty' => false,
3473 'number' => 20, // Limit to prevent too many controls
3474 ]);
3475
3476 if (is_wp_error($terms) || empty($terms)) {
3477 // Fallback to default icon if no terms found
3478 $this->add_control(
3479 'kng_dynamic_posts_default_icon',
3480 [
3481 'label' => esc_html__('Default Icon', 'king-addons'),
3482 'type' => Controls_Manager::ICONS,
3483 'default' => [
3484 'value' => 'far fa-file-alt',
3485 'library' => 'fa-regular',
3486 ],
3487 'description' => esc_html__('Default icon for posts without categories', 'king-addons'),
3488 ]
3489 );
3490 return;
3491 }
3492
3493 // Add instruction
3494 $this->add_control(
3495 'kng_dynamic_posts_icons_info',
3496 [
3497 'type' => Controls_Manager::RAW_HTML,
3498 'raw' => esc_html__('Set custom icons for each category. These icons will be displayed in the header of post cards.', 'king-addons'),
3499 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
3500 ]
3501 );
3502
3503 // Default icon type
3504 $this->add_control(
3505 'kng_dynamic_posts_default_icon_type',
3506 [
3507 'label' => esc_html__('Default Type', 'king-addons'),
3508 'type' => Controls_Manager::SELECT,
3509 'options' => [
3510 'icon' => esc_html__('Icon', 'king-addons'),
3511 'image' => esc_html__('Image', 'king-addons'),
3512 ],
3513 'default' => 'icon',
3514 'description' => esc_html__('Choose type for posts without categories', 'king-addons'),
3515 ]
3516 );
3517
3518 // Default icon for uncategorized posts
3519 $this->add_control(
3520 'kng_dynamic_posts_default_icon',
3521 [
3522 'label' => esc_html__('Default Icon', 'king-addons'),
3523 'type' => Controls_Manager::ICONS,
3524 'default' => [
3525 'value' => 'far fa-file-alt',
3526 'library' => 'fa-regular',
3527 ],
3528 'condition' => [
3529 'kng_dynamic_posts_default_icon_type' => 'icon',
3530 ],
3531 ]
3532 );
3533
3534 // Default image for uncategorized posts
3535 $this->add_control(
3536 'kng_dynamic_posts_default_image',
3537 [
3538 'label' => esc_html__('Default Image', 'king-addons'),
3539 'type' => Controls_Manager::MEDIA,
3540 'media_types' => ['image'],
3541 'default' => [
3542 'url' => '',
3543 ],
3544 'condition' => [
3545 'kng_dynamic_posts_default_icon_type' => 'image',
3546 ],
3547 ]
3548 );
3549
3550 // Add icon control for each term
3551 $default_icons = [
3552 [
3553 'value' => 'far fa-file-alt',
3554 'library' => 'fa-regular',
3555 ], // Report
3556 [
3557 'value' => 'far fa-newspaper',
3558 'library' => 'fa-regular',
3559 ], // Publication
3560 [
3561 'value' => 'far fa-play-circle',
3562 'library' => 'fa-regular',
3563 ], // Video
3564 [
3565 'value' => 'fas fa-globe',
3566 'library' => 'fa-solid',
3567 ], // Website
3568 [
3569 'value' => 'far fa-star',
3570 'library' => 'fa-regular',
3571 ],
3572 [
3573 'value' => 'far fa-heart',
3574 'library' => 'fa-regular',
3575 ],
3576 [
3577 'value' => 'far fa-lightbulb',
3578 'library' => 'fa-regular',
3579 ],
3580 [
3581 'value' => 'far fa-bookmark',
3582 'library' => 'fa-regular',
3583 ],
3584 ];
3585
3586 $icon_index = 0;
3587 foreach ($terms as $term) {
3588 $default_icon = isset($default_icons[$icon_index]) ? $default_icons[$icon_index] : [
3589 'value' => 'fas fa-file',
3590 'library' => 'fa-solid',
3591 ];
3592
3593 // Category heading
3594 $this->add_control(
3595 'kng_dynamic_posts_' . $term->slug . '_heading',
3596 [
3597 'label' => sprintf(esc_html__('%s Settings', 'king-addons'), $term->name),
3598 'type' => Controls_Manager::HEADING,
3599 'separator' => 'before',
3600 ]
3601 );
3602
3603 // Icon type for this category
3604 $this->add_control(
3605 'kng_dynamic_posts_icon_type_' . $term->slug,
3606 [
3607 'label' => sprintf(esc_html__('%s Type', 'king-addons'), $term->name),
3608 'type' => Controls_Manager::SELECT,
3609 'options' => [
3610 'icon' => esc_html__('Icon', 'king-addons'),
3611 'image' => esc_html__('Image', 'king-addons'),
3612 ],
3613 'default' => 'icon',
3614 ]
3615 );
3616
3617 // Icon control
3618 $this->add_control(
3619 'kng_dynamic_posts_icon_' . $term->slug,
3620 [
3621 'label' => sprintf(esc_html__('%s Icon', 'king-addons'), $term->name),
3622 'type' => Controls_Manager::ICONS,
3623 'default' => $default_icon,
3624 'condition' => [
3625 'kng_dynamic_posts_icon_type_' . $term->slug => 'icon',
3626 ],
3627 ]
3628 );
3629
3630 // Image control
3631 $this->add_control(
3632 'kng_dynamic_posts_image_' . $term->slug,
3633 [
3634 'label' => sprintf(esc_html__('%s Image', 'king-addons'), $term->name),
3635 'type' => Controls_Manager::MEDIA,
3636 'media_types' => ['image'],
3637 'default' => [
3638 'url' => '',
3639 ],
3640 'condition' => [
3641 'kng_dynamic_posts_icon_type_' . $term->slug => 'image',
3642 ],
3643 ]
3644 );
3645
3646 $icon_index++;
3647 if ($icon_index >= count($default_icons)) {
3648 $icon_index = 0; // Reset to cycle through icons
3649 }
3650 }
3651 }
3652
3653 /**
3654 * Add dynamic category CTA controls.
3655 */
3656 protected function add_dynamic_category_ctas(): void
3657 {
3658 // Get taxonomy from filter settings (default to category)
3659 $taxonomy = 'category';
3660
3661 // Get terms from the taxonomy
3662 $terms = get_terms([
3663 'taxonomy' => $taxonomy,
3664 'hide_empty' => false,
3665 'number' => 20, // Limit to prevent too many controls
3666 ]);
3667
3668 if (is_wp_error($terms) || empty($terms)) {
3669 // Fallback to default CTA if no terms found
3670 $this->add_control(
3671 'kng_dynamic_posts_default_cta',
3672 [
3673 'label' => esc_html__('Default CTA Text', 'king-addons'),
3674 'type' => Controls_Manager::TEXT,
3675 'default' => 'READ MORE',
3676 'description' => esc_html__('Default CTA text for posts without categories', 'king-addons'),
3677 ]
3678 );
3679 return;
3680 }
3681
3682 // Add instruction
3683 $this->add_control(
3684 'kng_dynamic_posts_ctas_info',
3685 [
3686 'type' => Controls_Manager::RAW_HTML,
3687 'raw' => esc_html__('Set custom CTA button text for each category. Leave empty to use smart defaults.', 'king-addons'),
3688 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
3689 ]
3690 );
3691
3692 // Default CTA for uncategorized posts
3693 $this->add_control(
3694 'kng_dynamic_posts_default_cta',
3695 [
3696 'label' => esc_html__('Default CTA Text', 'king-addons'),
3697 'type' => Controls_Manager::TEXT,
3698 'default' => 'READ MORE',
3699 'description' => esc_html__('CTA text for posts without categories', 'king-addons'),
3700 ]
3701 );
3702
3703 // Add CTA control for each term
3704 $default_ctas = [
3705 'READ MORE',
3706 'LEARN MORE',
3707 'WATCH NOW',
3708 'DISCOVER',
3709 'EXPLORE',
3710 'VIEW MORE',
3711 'GET STARTED',
3712 'DOWNLOAD',
3713 ];
3714
3715 $cta_index = 0;
3716 foreach ($terms as $term) {
3717 $default_cta = isset($default_ctas[$cta_index]) ? $default_ctas[$cta_index] : 'READ MORE';
3718
3719 $this->add_control(
3720 'kng_dynamic_posts_cta_' . $term->slug,
3721 [
3722 'label' => sprintf(esc_html__('%s CTA Text', 'king-addons'), $term->name),
3723 'type' => Controls_Manager::TEXT,
3724 'default' => $default_cta,
3725 'placeholder' => 'READ MORE',
3726 'description' => sprintf(esc_html__('Custom CTA text for %s category', 'king-addons'), $term->name),
3727 ]
3728 );
3729
3730 $cta_index++;
3731 if ($cta_index >= count($default_ctas)) {
3732 $cta_index = 0; // Reset to cycle through CTAs
3733 }
3734 }
3735 }
3736
3737 /**
3738 * Add dynamic category button color controls.
3739 */
3740 protected function add_dynamic_category_button_colors(): void
3741 {
3742 // Get taxonomy from filter settings (default to category)
3743 $taxonomy = 'category';
3744
3745 // Get terms from the taxonomy
3746 $terms = get_terms([
3747 'taxonomy' => $taxonomy,
3748 'hide_empty' => false,
3749 'number' => 20, // Limit to prevent too many controls
3750 ]);
3751
3752 if (is_wp_error($terms) || empty($terms)) {
3753 // Fallback to default button colors if no terms found
3754 $this->add_control(
3755 'kng_dynamic_posts_button_color',
3756 [
3757 'label' => esc_html__('Button Color', 'king-addons'),
3758 'type' => Controls_Manager::COLOR,
3759 'default' => '#374151',
3760 'selectors' => [
3761 '{{WRAPPER}} .king-addons-dpg-button' => 'color: {{VALUE}};',
3762 ],
3763 ]
3764 );
3765
3766 $this->add_control(
3767 'kng_dynamic_posts_button_background',
3768 [
3769 'label' => esc_html__('Button Background', 'king-addons'),
3770 'type' => Controls_Manager::COLOR,
3771 'default' => 'rgba(255, 255, 255, 0.8)',
3772 'selectors' => [
3773 '{{WRAPPER}} .king-addons-dpg-button' => 'background-color: {{VALUE}};',
3774 ],
3775 ]
3776 );
3777
3778 $this->add_control(
3779 'kng_dynamic_posts_button_hover_color',
3780 [
3781 'label' => esc_html__('Button Hover Color', 'king-addons'),
3782 'type' => Controls_Manager::COLOR,
3783 'default' => '#1F2937',
3784 'selectors' => [
3785 '{{WRAPPER}} .king-addons-dpg-button:hover' => 'color: {{VALUE}};',
3786 ],
3787 ]
3788 );
3789
3790 $this->add_control(
3791 'kng_dynamic_posts_button_hover_background',
3792 [
3793 'label' => esc_html__('Button Hover Background', 'king-addons'),
3794 'type' => Controls_Manager::COLOR,
3795 'default' => 'rgba(255, 255, 255, 0.95)',
3796 'selectors' => [
3797 '{{WRAPPER}} .king-addons-dpg-button:hover' => 'background-color: {{VALUE}};',
3798 ],
3799 ]
3800 );
3801
3802 $this->add_control(
3803 'kng_dynamic_posts_button_border_color',
3804 [
3805 'label' => esc_html__('Button Border Color', 'king-addons'),
3806 'type' => Controls_Manager::COLOR,
3807 'default' => 'rgba(0, 0, 0, 0.1)',
3808 'selectors' => [
3809 '{{WRAPPER}} .king-addons-dpg-button' => 'border-color: {{VALUE}};',
3810 ],
3811 ]
3812 );
3813 return;
3814 }
3815
3816 // Add instruction
3817 $this->add_control(
3818 'kng_dynamic_posts_button_colors_info',
3819 [
3820 'type' => Controls_Manager::RAW_HTML,
3821 'raw' => esc_html__('Set custom button colors for each category. These colors will override the general button style.', 'king-addons'),
3822 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
3823 ]
3824 );
3825
3826 // Default colors for uncategorized posts
3827 $this->add_control(
3828 'kng_dynamic_posts_default_button_heading',
3829 [
3830 'label' => esc_html__('Default Button Colors', 'king-addons'),
3831 'type' => Controls_Manager::HEADING,
3832 'separator' => 'before',
3833 ]
3834 );
3835
3836 $this->add_control(
3837 'kng_dynamic_posts_default_button_color',
3838 [
3839 'label' => esc_html__('Default Button Color', 'king-addons'),
3840 'type' => Controls_Manager::COLOR,
3841 'default' => '#374151',
3842 'selectors' => [
3843 '{{WRAPPER}} .king-addons-dpg-button' => 'color: {{VALUE}};',
3844 ],
3845 ]
3846 );
3847
3848 $this->add_control(
3849 'kng_dynamic_posts_default_button_background',
3850 [
3851 'label' => esc_html__('Default Button Background', 'king-addons'),
3852 'type' => Controls_Manager::COLOR,
3853 'default' => 'rgba(255, 255, 255, 0.8)',
3854 'selectors' => [
3855 '{{WRAPPER}} .king-addons-dpg-button' => 'background-color: {{VALUE}};',
3856 ],
3857 ]
3858 );
3859
3860 $this->add_control(
3861 'kng_dynamic_posts_default_button_hover_color',
3862 [
3863 'label' => esc_html__('Default Button Hover Color', 'king-addons'),
3864 'type' => Controls_Manager::COLOR,
3865 'default' => '#1F2937',
3866 'selectors' => [
3867 '{{WRAPPER}} .king-addons-dpg-button:hover' => 'color: {{VALUE}};',
3868 ],
3869 ]
3870 );
3871
3872 $this->add_control(
3873 'kng_dynamic_posts_default_button_hover_background',
3874 [
3875 'label' => esc_html__('Default Button Hover Background', 'king-addons'),
3876 'type' => Controls_Manager::COLOR,
3877 'default' => 'rgba(255, 255, 255, 0.95)',
3878 'selectors' => [
3879 '{{WRAPPER}} .king-addons-dpg-button:hover' => 'background-color: {{VALUE}};',
3880 ],
3881 ]
3882 );
3883
3884 // Category-specific colors
3885 $default_colors = [
3886 ['color' => '#FFFFFF', 'bg' => '#EF4444', 'hover_color' => '#FFFFFF', 'hover_bg' => '#DC2626', 'border' => '#EF4444'], // Red
3887 ['color' => '#FFFFFF', 'bg' => '#3B82F6', 'hover_color' => '#FFFFFF', 'hover_bg' => '#2563EB', 'border' => '#3B82F6'], // Blue
3888 ['color' => '#FFFFFF', 'bg' => '#10B981', 'hover_color' => '#FFFFFF', 'hover_bg' => '#059669', 'border' => '#10B981'], // Green
3889 ['color' => '#FFFFFF', 'bg' => '#F59E0B', 'hover_color' => '#FFFFFF', 'hover_bg' => '#D97706', 'border' => '#F59E0B'], // Orange
3890 ['color' => '#FFFFFF', 'bg' => '#8B5CF6', 'hover_color' => '#FFFFFF', 'hover_bg' => '#7C3AED', 'border' => '#8B5CF6'], // Purple
3891 ['color' => '#FFFFFF', 'bg' => '#EC4899', 'hover_color' => '#FFFFFF', 'hover_bg' => '#DB2777', 'border' => '#EC4899'], // Pink
3892 ['color' => '#FFFFFF', 'bg' => '#06B6D4', 'hover_color' => '#FFFFFF', 'hover_bg' => '#0891B2', 'border' => '#06B6D4'], // Cyan
3893 ['color' => '#FFFFFF', 'bg' => '#84CC16', 'hover_color' => '#FFFFFF', 'hover_bg' => '#65A30D', 'border' => '#84CC16'], // Lime
3894 ];
3895
3896 $color_index = 0;
3897 foreach ($terms as $term) {
3898 $default_color_set = isset($default_colors[$color_index]) ? $default_colors[$color_index] : $default_colors[0];
3899
3900 // Category heading
3901 $this->add_control(
3902 'kng_dynamic_posts_' . $term->slug . '_button_heading',
3903 [
3904 'label' => sprintf(esc_html__('%s Button Colors', 'king-addons'), $term->name),
3905 'type' => Controls_Manager::HEADING,
3906 'separator' => 'before',
3907 ]
3908 );
3909
3910 // Button color
3911 $this->add_control(
3912 'kng_dynamic_posts_button_color_' . $term->slug,
3913 [
3914 'label' => sprintf(esc_html__('%s Button Text Color', 'king-addons'), $term->name),
3915 'type' => Controls_Manager::COLOR,
3916 'default' => $default_color_set['color'],
3917 'selectors' => [
3918 '{{WRAPPER}} .king-addons-dpg-card.king-addons-dpg-category-' . $term->slug . ' .king-addons-dpg-button' => 'color: {{VALUE}};',
3919 ],
3920 ]
3921 );
3922
3923 // Button background
3924 $this->add_control(
3925 'kng_dynamic_posts_button_background_' . $term->slug,
3926 [
3927 'label' => sprintf(esc_html__('%s Button Background', 'king-addons'), $term->name),
3928 'type' => Controls_Manager::COLOR,
3929 'default' => $default_color_set['bg'],
3930 'selectors' => [
3931 '{{WRAPPER}} .king-addons-dpg-card.king-addons-dpg-category-' . $term->slug . ' .king-addons-dpg-button' => 'background-color: {{VALUE}};',
3932 ],
3933 ]
3934 );
3935
3936 // Button hover color
3937 $this->add_control(
3938 'kng_dynamic_posts_button_hover_color_' . $term->slug,
3939 [
3940 'label' => sprintf(esc_html__('%s Button Hover Color', 'king-addons'), $term->name),
3941 'type' => Controls_Manager::COLOR,
3942 'default' => $default_color_set['hover_color'],
3943 'selectors' => [
3944 '{{WRAPPER}} .king-addons-dpg-card.king-addons-dpg-category-' . $term->slug . ' .king-addons-dpg-button:hover' => 'color: {{VALUE}};',
3945 ],
3946 ]
3947 );
3948
3949 // Button hover background
3950 $this->add_control(
3951 'kng_dynamic_posts_button_hover_background_' . $term->slug,
3952 [
3953 'label' => sprintf(esc_html__('%s Button Hover Background', 'king-addons'), $term->name),
3954 'type' => Controls_Manager::COLOR,
3955 'default' => $default_color_set['hover_bg'],
3956 'selectors' => [
3957 '{{WRAPPER}} .king-addons-dpg-card.king-addons-dpg-category-' . $term->slug . ' .king-addons-dpg-button:hover' => 'background-color: {{VALUE}};',
3958 ],
3959 ]
3960 );
3961
3962 // Button border color
3963 $this->add_control(
3964 'kng_dynamic_posts_button_border_color_' . $term->slug,
3965 [
3966 'label' => sprintf(esc_html__('%s Button Border Color', 'king-addons'), $term->name),
3967 'type' => Controls_Manager::COLOR,
3968 'default' => $default_color_set['border'],
3969 'selectors' => [
3970 '{{WRAPPER}} .king-addons-dpg-card.king-addons-dpg-category-' . $term->slug . ' .king-addons-dpg-button' => 'border-color: {{VALUE}};',
3971 ],
3972 ]
3973 );
3974
3975 $color_index++;
3976 if ($color_index >= count($default_colors)) {
3977 $color_index = 0; // Reset to cycle through colors
3978 }
3979 }
3980 }
3981
3982 /**
3983 * Get post category for display.
3984 *
3985 * @param object $post Post object.
3986 * @return string Post category display name.
3987 */
3988 private function get_post_type_display($post): string
3989 {
3990 // Get post categories
3991 $taxonomy = 'category';
3992 $terms = get_the_terms($post->ID, $taxonomy);
3993
3994 if ($terms && !is_wp_error($terms)) {
3995 // Use first category name
3996 $term = $terms[0];
3997 return strtoupper($term->name);
3998 }
3999
4000 // Fallback to post format/type based display
4001 $format = get_post_format($post->ID);
4002
4003 if ($format === 'video') {
4004 return 'VIDEO';
4005 } elseif ($format === 'audio') {
4006 return 'PUBLICATION';
4007 } elseif ($post->post_type === 'page') {
4008 return 'WEBSITE';
4009 } else {
4010 return 'POST';
4011 }
4012 }
4013
4014 /**
4015 * Get CTA button text based on category settings.
4016 *
4017 * @param object $post Post object.
4018 * @param array $settings Widget settings.
4019 * @return string CTA button text.
4020 */
4021 private function get_cta_text($post, $settings): string
4022 {
4023 // Get post categories for custom CTA text
4024 $taxonomy = 'category';
4025 $terms = get_the_terms($post->ID, $taxonomy);
4026
4027 if ($terms && !is_wp_error($terms)) {
4028 // Use first category's custom CTA
4029 $term = $terms[0];
4030 $cta_setting = $settings['kng_dynamic_posts_cta_' . $term->slug] ?? '';
4031
4032 if (!empty($cta_setting)) {
4033 return strtoupper(trim($cta_setting));
4034 }
4035 }
4036
4037 // Fallback to default CTA or smart detection
4038 $default_cta = $settings['kng_dynamic_posts_default_cta'] ?? '';
4039 if (!empty($default_cta)) {
4040 return strtoupper(trim($default_cta));
4041 }
4042
4043 // Final fallback - smart detection
4044 if ($terms && !is_wp_error($terms)) {
4045 $term = $terms[0];
4046 $slug = strtolower($term->slug);
4047
4048 $smart_cta_map = [
4049 'video' => 'WATCH NOW',
4050 'videos' => 'WATCH NOW',
4051 'website' => 'LEARN MORE',
4052 'websites' => 'LEARN MORE',
4053 ];
4054
4055 if (isset($smart_cta_map[$slug])) {
4056 return $smart_cta_map[$slug];
4057 }
4058 }
4059
4060 return 'READ MORE';
4061 }
4062
4063 /**
4064 * Get post category color classes.
4065 *
4066 * @param object $post Post object.
4067 * @param array $settings Widget settings.
4068 * @return string Color class names.
4069 */
4070 private function get_post_category_color_classes($post, $settings): string
4071 {
4072 $classes = [];
4073 $taxonomy = $settings['kng_dynamic_posts_filter_taxonomy'] ?? 'category';
4074
4075 // Get post categories/terms
4076 $terms = get_the_terms($post->ID, $taxonomy);
4077
4078 if ($terms && !is_wp_error($terms)) {
4079 foreach ($terms as $term) {
4080 $classes[] = 'filter-' . $term->slug;
4081 $classes[] = 'king-addons-dpg-category-' . $term->slug;
4082 }
4083 }
4084
4085 // Add default class if no terms
4086 if (empty($classes)) {
4087 $classes[] = 'king-addons-dpg-category-default';
4088 }
4089
4090 return implode(' ', $classes);
4091 }
4092
4093 /**
4094 * Get post type icon based on category settings.
4095 *
4096 * @param object $post Post object.
4097 * @param array $settings Widget settings.
4098 * @return string Icon HTML.
4099 */
4100 private function get_post_type_icon($post, $settings): string
4101 {
4102 // Get post categories/terms
4103 $taxonomy = 'category';
4104 $terms = get_the_terms($post->ID, $taxonomy);
4105
4106 if ($terms && !is_wp_error($terms)) {
4107 // Use first category's icon/image
4108 $term = $terms[0];
4109 $icon_type = $settings['kng_dynamic_posts_icon_type_' . $term->slug] ?? 'icon';
4110
4111 if ($icon_type === 'image') {
4112 // Use image
4113 $image_setting = $settings['kng_dynamic_posts_image_' . $term->slug] ?? null;
4114 if ($image_setting && !empty($image_setting['url'])) {
4115 return '<img src="' . esc_url($image_setting['url']) . '" alt="' . esc_attr($term->name) . '" class="category-image" />';
4116 }
4117 } else {
4118 // Use icon
4119 $icon_setting = $settings['kng_dynamic_posts_icon_' . $term->slug] ?? null;
4120 if ($icon_setting && !empty($icon_setting['value'])) {
4121 // Return FontAwesome icon or SVG
4122 if (isset($icon_setting['library']) && $icon_setting['library'] === 'svg') {
4123 return $icon_setting['value']['url'] ? '<img src="' . esc_url($icon_setting['value']['url']) . '" alt="" class="category-icon" />' : '';
4124 } else {
4125 return '<i class="' . esc_attr($icon_setting['value']) . ' category-icon"></i>';
4126 }
4127 }
4128 }
4129 }
4130
4131 // Fallback to default icon/image
4132 $default_type = $settings['kng_dynamic_posts_default_icon_type'] ?? 'icon';
4133
4134 if ($default_type === 'image') {
4135 // Use default image
4136 $default_image = $settings['kng_dynamic_posts_default_image'] ?? null;
4137 if ($default_image && !empty($default_image['url'])) {
4138 return '<img src="' . esc_url($default_image['url']) . '" alt="' . esc_attr__('Default', 'king-addons') . '" class="category-image" />';
4139 }
4140 }
4141
4142 // Use default icon
4143 $default_icon = $settings['kng_dynamic_posts_default_icon'] ?? [
4144 'value' => 'far fa-file-alt',
4145 'library' => 'fa-regular',
4146 ];
4147
4148 if (isset($default_icon['library']) && $default_icon['library'] === 'svg') {
4149 return $default_icon['value']['url'] ? '<img src="' . esc_url($default_icon['value']['url']) . '" alt="" class="category-icon" />' : '';
4150 } else {
4151 return '<i class="' . esc_attr($default_icon['value']) . ' category-icon"></i>';
4152 }
4153 }
4154
4155 /**
4156 * Render widget output on the frontend.
4157 */
4158 protected function render(): void
4159 {
4160 $settings = $this->get_settings_for_display();
4161 $widget_id = $this->get_id();
4162
4163 if ($this->maybe_render_pro($settings)) {
4164 return;
4165 }
4166
4167 // Query posts
4168 $query_args = [
4169 'post_type' => $settings['kng_dynamic_posts_post_types'],
4170 'posts_per_page' => $settings['kng_dynamic_posts_per_page'],
4171 'orderby' => $settings['kng_dynamic_posts_orderby'],
4172 'order' => $settings['kng_dynamic_posts_order'],
4173 'post_status' => 'publish',
4174 ];
4175
4176 $posts_query = new \WP_Query($query_args);
4177
4178 // Get filter terms if filtering is enabled
4179 $filter_terms = [];
4180 if ($settings['kng_dynamic_posts_enable_filters'] === 'yes') {
4181 $taxonomy = $settings['kng_dynamic_posts_filter_taxonomy'];
4182 $filter_terms = get_terms([
4183 'taxonomy' => $taxonomy,
4184 'hide_empty' => true,
4185 ]);
4186 }
4187
4188 // Wrapper attributes
4189 $this->add_render_attribute('wrapper', 'class', 'king-addons-dpg-wrapper');
4190 $this->add_render_attribute('wrapper', 'data-widget-id', $widget_id);
4191 $this->add_render_attribute('wrapper', 'data-widget-mode', 'default'); // Set default mode for Free version
4192 $this->add_render_attribute('wrapper', 'data-posts-per-page', $settings['kng_dynamic_posts_per_page']);
4193 $this->add_render_attribute('wrapper', 'data-post-types', wp_json_encode($settings['kng_dynamic_posts_post_types']));
4194 $this->add_render_attribute('wrapper', 'data-orderby', $settings['kng_dynamic_posts_orderby']);
4195 $this->add_render_attribute('wrapper', 'data-order', $settings['kng_dynamic_posts_order']);
4196 $this->add_render_attribute('wrapper', 'data-show-excerpt', ($settings['kng_dynamic_posts_show_excerpt'] ?? 'yes') === 'yes' ? '1' : '0');
4197 $this->add_render_attribute('wrapper', 'data-card-clickable', ($settings['kng_dynamic_posts_card_clickable'] ?? 'no') === 'yes' ? '1' : '0');
4198
4199 if ($settings['kng_dynamic_posts_enable_filters'] === 'yes') {
4200 $this->add_render_attribute('wrapper', 'data-filter-taxonomy', $settings['kng_dynamic_posts_filter_taxonomy']);
4201 }
4202
4203 // CPT-related attributes (empty for Free version, but needed for JS compatibility)
4204 $this->add_render_attribute('wrapper', 'data-cpt-actions', '');
4205 $this->add_render_attribute('wrapper', 'data-cpt-icons', '');
4206 ?>
4207
4208 <div <?php echo $this->get_render_attribute_string('wrapper'); ?>>
4209
4210 <?php if ($settings['kng_dynamic_posts_enable_filters'] === 'yes' || $settings['kng_dynamic_posts_enable_search'] === 'yes'): ?>
4211 <!-- Filter Bar -->
4212 <div class="king-addons-dpg-filter-bar">
4213
4214 <!-- Filter Header -->
4215 <div class="king-addons-dpg-filter-header">
4216 <h2 class="king-addons-dpg-filter-title"><?php echo esc_html($settings['kng_dynamic_posts_filter_title_text']); ?></h2>
4217 </div>
4218
4219 <!-- Filter Controls -->
4220 <div class="king-addons-dpg-filter-controls">
4221 <?php if ($settings['kng_dynamic_posts_enable_filters'] === 'yes' && !empty($filter_terms)): ?>
4222 <!-- Filter Dropdown -->
4223 <div class="king-addons-dpg-filter-dropdown<?php
4224 $has_custom = !empty($settings['kng_dynamic_posts_filter_dropdown_use_custom']) && $settings['kng_dynamic_posts_filter_dropdown_use_custom'] === 'yes';
4225 $has_icon = $has_custom && $settings['kng_dynamic_posts_filter_dropdown_type'] === 'icon' && !empty($settings['kng_dynamic_posts_filter_dropdown_custom_icon']['value']);
4226 $has_image = $has_custom && $settings['kng_dynamic_posts_filter_dropdown_type'] === 'image' && !empty($settings['kng_dynamic_posts_filter_dropdown_custom_image']['url']);
4227 echo ($has_custom && ($has_icon || $has_image)) ? ' has-custom-icon' : '';
4228 ?>">
4229 <select class="king-addons-dpg-posts-filter" data-taxonomy="<?php echo esc_attr($settings['kng_dynamic_posts_filter_taxonomy']); ?>">
4230 <option value="*"><?php echo esc_html__('All resources types', 'king-addons'); ?></option>
4231 <?php foreach ($filter_terms as $term): ?>
4232 <option value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></option>
4233 <?php endforeach; ?>
4234 </select>
4235 <?php if ($has_icon): ?>
4236 <span class="dropdown-icon">
4237 <?php \Elementor\Icons_Manager::render_icon($settings['kng_dynamic_posts_filter_dropdown_custom_icon'], ['class' => 'dropdown-custom-icon']); ?>
4238 </span>
4239 <?php elseif ($has_image): ?>
4240 <span class="dropdown-image">
4241 <img src="<?php echo esc_url($settings['kng_dynamic_posts_filter_dropdown_custom_image']['url']); ?>" alt="<?php echo esc_attr__('Dropdown icon', 'king-addons'); ?>" />
4242 </span>
4243 <?php endif; ?>
4244 </div>
4245 <?php endif; ?>
4246
4247 <?php if ($settings['kng_dynamic_posts_enable_search'] === 'yes'): ?>
4248 <!-- Search Input -->
4249 <div class="king-addons-dpg-search-input">
4250 <input type="text" class="king-addons-dpg-posts-search" placeholder="<?php echo esc_attr($settings['kng_dynamic_posts_search_placeholder']); ?>">
4251 <button class="king-addons-dpg-search-btn" type="button">
4252 <?php if (!empty($settings['kng_dynamic_posts_search_use_custom_icon']) && $settings['kng_dynamic_posts_search_use_custom_icon'] === 'yes' && !empty($settings['kng_dynamic_posts_search_custom_icon']['value'])): ?>
4253 <?php \Elementor\Icons_Manager::render_icon($settings['kng_dynamic_posts_search_custom_icon'], ['class' => 'king-addons-dpg-search-custom-icon']); ?>
4254 <?php else: ?>
4255 <svg width="20" height="20" viewBox="0 0 24 24">
4256 <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" />
4257 </svg>
4258 <?php endif; ?>
4259 </button>
4260 </div>
4261 <?php endif; ?>
4262 </div>
4263
4264 </div>
4265 <?php endif; ?>
4266
4267 <!-- Grid Container -->
4268 <div class="king-addons-dpg-grid" data-columns="<?php echo esc_attr($settings['kng_dynamic_posts_columns']); ?>">
4269 <?php $this->render_posts($posts_query, $settings); ?>
4270 </div>
4271
4272 <?php if ($settings['kng_dynamic_posts_enable_load_more'] === 'yes'): ?>
4273 <!-- Load More Section -->
4274 <div class="king-addons-dpg-pagination">
4275
4276 <!-- Posts Count Info -->
4277 <div class="king-addons-dpg-pagination-info">
4278 <?php echo esc_html__('Showing', 'king-addons'); ?> <span class="king-addons-dpg-current-count"><?php echo $posts_query->post_count; ?></span> <?php echo esc_html__('of', 'king-addons'); ?> <span class="king-addons-dpg-total-count"><?php echo $posts_query->found_posts; ?></span> <?php echo esc_html__('items', 'king-addons'); ?>
4279 </div>
4280
4281 <div class="king-addons-dpg-pagination-loading" style="display: none;">
4282 <?php echo esc_html($settings['kng_dynamic_posts_loading_text']); ?>
4283 </div>
4284
4285 <?php if ($posts_query->max_num_pages > 1): ?>
4286 <button class="king-addons-dpg-load-more-btn" data-page="1" data-max-pages="<?php echo esc_attr($posts_query->max_num_pages); ?>">
4287 <?php echo esc_html($settings['kng_dynamic_posts_load_more_text']); ?>
4288 </button>
4289 <?php endif; ?>
4290
4291 <div class="king-addons-dpg-pagination-finish" style="display: none;">
4292 <?php echo esc_html__('All items loaded', 'king-addons'); ?>
4293 </div>
4294 </div>
4295 <?php endif; ?>
4296
4297 </div>
4298
4299 <?php
4300 wp_reset_postdata();
4301 }
4302
4303 /**
4304 * Render posts grid.
4305 *
4306 * @param \WP_Query $posts_query Posts query object.
4307 * @param array $settings Widget settings.
4308 */
4309 private function render_posts($posts_query, $settings): void
4310 {
4311 if (!$posts_query->have_posts()) {
4312 echo '<div class="king-addons-dpg-no-posts">' . esc_html__('No posts found.', 'king-addons') . '</div>';
4313 return;
4314 }
4315
4316 while ($posts_query->have_posts()):
4317 $posts_query->the_post();
4318 $post = get_post();
4319 $post_type_display = $this->get_post_type_display($post);
4320 $category_classes = $this->get_post_category_color_classes($post, $settings);
4321 $cta_text = $this->get_cta_text($post, $settings);
4322 $post_icon = $this->get_post_type_icon($post, $settings);
4323 ?>
4324
4325 <div class="king-addons-dpg-card king-addons-dpg-item <?php echo esc_attr($category_classes); ?>" data-post-id="<?php echo esc_attr($post->ID); ?>">
4326
4327 <!-- Post Type Header -->
4328 <div class="king-addons-dpg-header">
4329 <div class="king-addons-dpg-icon">
4330 <?php echo $post_icon; ?>
4331 </div>
4332 <div class="king-addons-dpg-label">
4333 <?php echo esc_html($post_type_display); ?>
4334 </div>
4335 </div>
4336
4337 <!-- Post Content -->
4338 <div class="king-addons-dpg-content">
4339 <h3 class="king-addons-dpg-title">
4340 <a href="<?php echo esc_url(get_permalink()); ?>">
4341 <?php echo esc_html(get_the_title()); ?>
4342 </a>
4343 </h3>
4344
4345 <?php if (($settings['kng_dynamic_posts_show_excerpt'] ?? 'yes') === 'yes'): ?>
4346 <div class="king-addons-dpg-excerpt">
4347 <?php echo esc_html(wp_trim_words(get_the_excerpt(), 20, '...')); ?>
4348 </div>
4349 <?php endif; ?>
4350 </div>
4351
4352 <!-- CTA Button -->
4353 <div class="king-addons-dpg-cta">
4354 <?php echo $this->get_cta_button_html($post, $settings, $cta_text); ?>
4355 </div>
4356
4357 </div>
4358
4359 <?php
4360 endwhile;
4361 }
4362
4363 /**
4364 * Build WP_Query args. Pro overrides to support Custom CPT mode.
4365 *
4366 * @param array $settings Widget settings.
4367 * @return array
4368 */
4369 protected function build_query_args(array $settings): array
4370 {
4371 return [
4372 'post_type' => $settings['kng_dynamic_posts_post_types'],
4373 'posts_per_page' => $settings['kng_dynamic_posts_per_page'],
4374 'orderby' => $settings['kng_dynamic_posts_orderby'],
4375 'order' => $settings['kng_dynamic_posts_order'],
4376 'post_status' => 'publish',
4377 ];
4378 }
4379
4380 /**
4381 * Build filter terms data for filter bar. Pro overrides for CPT/tabs.
4382 *
4383 * @param array $settings Widget settings.
4384 * @return array
4385 */
4386 protected function get_filter_terms(array $settings): array
4387 {
4388 if (($settings['kng_dynamic_posts_enable_filters'] ?? '') !== 'yes') {
4389 return [];
4390 }
4391
4392 $taxonomy = $settings['kng_dynamic_posts_filter_taxonomy'] ?? 'category';
4393 $terms = get_terms([
4394 'taxonomy' => $taxonomy,
4395 'hide_empty' => true,
4396 ]);
4397
4398 return is_wp_error($terms) ? [] : $terms;
4399 }
4400
4401 /**
4402 * Render filter bar wrapper. Pro overrides for advanced UI.
4403 *
4404 * @param array $settings Widget settings.
4405 * @param array $filter_terms Terms list or structured data.
4406 */
4407 protected function render_filter_bar(array $settings, array $filter_terms): void
4408 {
4409 if (($settings['kng_dynamic_posts_enable_filters'] ?? '') !== 'yes' && ($settings['kng_dynamic_posts_enable_search'] ?? '') !== 'yes') {
4410 return;
4411 }
4412 ?>
4413 <div class="king-addons-dpg-filter-bar">
4414 <div class="king-addons-dpg-filter-header">
4415 <h2 class="king-addons-dpg-filter-title"><?php echo esc_html($settings['kng_dynamic_posts_filter_title_text'] ?? ''); ?></h2>
4416 </div>
4417
4418 <div class="king-addons-dpg-filter-controls">
4419 <?php if (($settings['kng_dynamic_posts_enable_filters'] ?? '') === 'yes' && !empty($filter_terms)): ?>
4420 <div class="king-addons-dpg-filter-dropdown<?php
4421 $has_custom = !empty($settings['kng_dynamic_posts_filter_dropdown_use_custom']) && $settings['kng_dynamic_posts_filter_dropdown_use_custom'] === 'yes';
4422 $has_icon = $has_custom && ($settings['kng_dynamic_posts_filter_dropdown_type'] ?? 'icon') === 'icon' && !empty($settings['kng_dynamic_posts_filter_dropdown_custom_icon']['value'] ?? '');
4423 $has_image = $has_custom && ($settings['kng_dynamic_posts_filter_dropdown_type'] ?? 'icon') === 'image' && !empty($settings['kng_dynamic_posts_filter_dropdown_custom_image']['url'] ?? '');
4424 echo ($has_custom && ($has_icon || $has_image)) ? ' has-custom-icon' : '';
4425 ?>">
4426 <select class="king-addons-dpg-posts-filter" data-taxonomy="<?php echo esc_attr($settings['kng_dynamic_posts_filter_taxonomy'] ?? 'category'); ?>">
4427 <option value="*">&nbsp;<?php echo esc_html__('All resources types', 'king-addons'); ?></option>
4428 <?php foreach ($filter_terms as $term): ?>
4429 <option value="<?php echo esc_attr($term->slug); ?>"><?php echo esc_html($term->name); ?></option>
4430 <?php endforeach; ?>
4431 </select>
4432 <?php if ($has_icon): ?>
4433 <span class="dropdown-icon">
4434 <?php \Elementor\Icons_Manager::render_icon($settings['kng_dynamic_posts_filter_dropdown_custom_icon'], ['class' => 'dropdown-custom-icon']); ?>
4435 </span>
4436 <?php elseif ($has_image): ?>
4437 <span class="dropdown-image">
4438 <img src="<?php echo esc_url($settings['kng_dynamic_posts_filter_dropdown_custom_image']['url']); ?>" alt="<?php echo esc_attr__('Dropdown icon', 'king-addons'); ?>" />
4439 </span>
4440 <?php endif; ?>
4441 </div>
4442 <?php endif; ?>
4443
4444 <?php if (($settings['kng_dynamic_posts_enable_search'] ?? '') === 'yes'): ?>
4445 <div class="king-addons-dpg-search-input">
4446 <input type="text" class="king-addons-dpg-posts-search" placeholder="<?php echo esc_attr($settings['kng_dynamic_posts_search_placeholder'] ?? ''); ?>">
4447 <button class="king-addons-dpg-search-btn" type="button">
4448 <?php if (!empty($settings['kng_dynamic_posts_search_use_custom_icon']) && $settings['kng_dynamic_posts_search_use_custom_icon'] === 'yes' && !empty($settings['kng_dynamic_posts_search_custom_icon']['value'] ?? '')): ?>
4449 <?php \Elementor\Icons_Manager::render_icon($settings['kng_dynamic_posts_search_custom_icon'], ['class' => 'king-addons-dpg-search-custom-icon']); ?>
4450 <?php else: ?>
4451 <svg width="20" height="20" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" /></svg>
4452 <?php endif; ?>
4453 </button>
4454 </div>
4455 <?php endif; ?>
4456 </div>
4457 </div>
4458 <?php
4459 }
4460
4461 /**
4462 * Render pagination wrapper. Pro overrides for advanced types.
4463 *
4464 * @param array $settings
4465 * @param \WP_Query $posts_query
4466 */
4467 protected function render_pagination(array $settings, \WP_Query $posts_query): void
4468 {
4469 if (($settings['kng_dynamic_posts_enable_load_more'] ?? '') !== 'yes') {
4470 return;
4471 }
4472 ?>
4473 <div class="king-addons-dpg-pagination">
4474 <div class="king-addons-dpg-pagination-info">
4475 <?php echo esc_html__('Showing', 'king-addons'); ?> <span class="king-addons-dpg-current-count"><?php echo (int) $posts_query->post_count; ?></span> <?php echo esc_html__('of', 'king-addons'); ?> <span class="king-addons-dpg-total-count"><?php echo (int) $posts_query->found_posts; ?></span> <?php echo esc_html__('items', 'king-addons'); ?>
4476 </div>
4477 <div class="king-addons-dpg-pagination-loading" style="display: none;">
4478 <?php echo esc_html($settings['kng_dynamic_posts_loading_text'] ?? 'Loading...'); ?>
4479 </div>
4480 <?php if ($posts_query->max_num_pages > 1): ?>
4481 <button class="king-addons-dpg-load-more-btn" data-page="1" data-max-pages="<?php echo esc_attr($posts_query->max_num_pages); ?>">
4482 <?php echo esc_html($settings['kng_dynamic_posts_load_more_text'] ?? 'LOAD MORE'); ?>
4483 </button>
4484 <?php endif; ?>
4485 <div class="king-addons-dpg-pagination-finish" style="display: none;">
4486 <?php echo esc_html__('All items loaded', 'king-addons'); ?>
4487 </div>
4488 </div>
4489 <?php
4490 }
4491
4492 /**
4493 * Render CTA button HTML. Pro overrides to inject action button behaviors.
4494 *
4495 * @param \WP_Post $post
4496 * @param array $settings
4497 * @param string $cta_text
4498 * @return string
4499 */
4500 protected function get_cta_button_html($post, array $settings, string $cta_text): string
4501 {
4502 return '<a href="' . esc_url(get_permalink($post)) . '" class="king-addons-dpg-button">' . esc_html($cta_text) . '</a>';
4503 }
4504
4505 /**
4506 * Extension points for Pro controls (content/style). Intentionally empty in Free.
4507 */
4508 // PRO Control Methods (empty in Free, overridden in Pro)
4509 public function add_control_widget_mode() {}
4510 public function add_control_custom_post_types() {}
4511 public function add_control_pagination_type() {}
4512 public function add_control_scroll_threshold() {}
4513 public function add_control_show_meta() {}
4514 public function add_control_meta_fields() {}
4515 public function add_control_cpt_actions() {}
4516 public function add_control_cpt_colors() {}
4517 public function add_control_cpt_button_colors() {}
4518 public function add_control_cpt_ctas() {}
4519 public function add_control_cpt_icons() {}
4520 }
4521