PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.81
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.81
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 51.1.51 All 36 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.81, at includes/widgets/Dynamic_Posts_Grid/Dynamic_Posts_Grid.php

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