PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.0.11
UiCore Elements – Free widgets and templates for Elementor v1.0.11
1.3.18 1.3.17 1.3.16 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.2.0 1.2.1 1.2.2 1.2.3 All 42 releases
uicore-elements / includes / utils / post-component.php

post-component.php in UiCore Elements – Free widgets and templates for Elementor 1.0.11, at includes/utils/post-component.php

1,185 lines 45.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace UiCoreElements\Utils;
3 use Elementor\Controls_Manager;
4 use Elementor\Icons_Manager;
5 use Elementor\Plugin;
6
7 use UiCoreElements\Helper;
8 use UiCoreElements\Controls\Query;
9 use UiCoreElements\Controls\Post_Filter;
10
11 use Elementor\Group_Control_Background;
12 use Elementor\Group_Control_Border;
13 use Elementor\Group_Control_Box_Shadow;
14 use Elementor\Group_Control_Typography;
15 use Elementor\Includes\Widgets\Traits\Button_Trait;
16 use UiCoreElements\Utils\Meta_Trait;
17
18 defined('ABSPATH') || exit();
19
20 /**
21 * Post Component
22 *
23 * @since 1.0.4
24 */
25
26 trait Post_Trait {
27
28 use Button_Trait,
29 Meta_Trait;
30
31 // Control Register Content functions
32 function TRAIT_register_post_item_controls($section = true)
33 {
34 if($section) {
35 $this->start_controls_section(
36 'section_item_content',
37 [
38 'label' => esc_html__('Item', 'uicore-elements'),
39 ]
40 );
41 }
42 $this->add_control(
43 'box_style',
44 [
45 'label' => __('Item Style', 'uicore-elements'),
46 'type' => Controls_Manager::SELECT,
47 'default' => 'classic',
48 'options' => [
49 'classic' => __('Classic', 'uicore-elements'),
50 'split' => __('Split', 'uicore-elements'),
51 'overlay' => __('Overlay', 'uicore-elements'),
52 ],
53 'render_type' => 'template',
54 'prefix_class' => 'ui-e-apg-',
55 ]
56 );
57 $this->add_control(
58 'image',
59 [
60 'label' => __('Image', 'uicore-elements'),
61 'type' => Controls_Manager::SWITCHER,
62 'separator' => 'before',
63 'default' => 'yes'
64 ]
65 );
66 $this->add_control(
67 'image_size_select',
68 [
69 'label' => __('Image Size', 'uicore-elements'),
70 'type' => Controls_Manager::SELECT,
71 'default' => 'uicore-medium',
72 'options' => Helper::get_images_sizes(),
73 'separator' => 'after',
74 'condition' => [
75 'image' => 'yes',
76 ]
77 ]
78 );
79 $this->add_control(
80 'title',
81 [
82 'label' => __('Title', 'uicore-elements'),
83 'type' => Controls_Manager::SWITCHER,
84 'default' => 'yes'
85 ]
86 );
87 $this->add_control(
88 'excerpt',
89 [
90 'label' => __('Excerpt', 'uicore-elements'),
91 'type' => Controls_Manager::SWITCHER,
92 'default' => 'yes'
93 ]
94 );
95 $this->add_control(
96 'excerpt_trim',
97 [
98 'label' => __('Excerpt Length (words)', 'uicore-elements'),
99 'type' => Controls_Manager::NUMBER,
100 'min' => 5,
101 'max' => 100,
102 'step' => 1,
103 'default' => 55,
104 'separator' => 'after',
105 'condition' => array(
106 'excerpt' => 'yes',
107 ),
108 ]
109 );
110 $this->add_control(
111 'show_button',
112 [
113 'label' => __('Read More Button', 'uicore-elements'),
114 'type' => Controls_Manager::SWITCHER,
115 'default' => 'no'
116 ]
117 );
118
119 if($section) {
120 $this->end_controls_section();
121 }
122 }
123 function TRAIT_register_post_button_controls($section = true)
124 {
125 if($section){
126 $this->start_controls_section(
127 'section_button_content',
128 [
129 'label' => esc_html__('Button', 'uicore-elements'),
130 'condition' => array(
131 'show_button' => 'yes',
132 ),
133 ]
134 );
135 }
136
137 $this->register_button_content_controls(
138 [
139 'section_condition' => [
140 'show_button' => 'yes'
141 ],
142 'button_default_text' => 'Read More'
143 ]
144 );
145 $this->remove_control('button_type');
146 $this->remove_control('link');
147 $this->remove_control('button_css_id');
148 $this->remove_control('size');
149 $this->remove_control('align');
150
151 if($section){
152 $this->end_controls_section();
153 }
154 }
155 /**
156 * Register Post Meta Controls.
157 *
158 * @param bool $section. Print section or not.
159 * @param bool $product_metas. If true, will only print options that relates with products.
160 */
161 function TRAIT_register_post_meta_controls($section = true, $product_metas = false)
162 {
163 if($section){
164 $this->start_controls_section(
165 'section_extra_item_content',
166 [
167 'label' => esc_html__('Meta', 'uicore-elements'),
168 ]
169 );
170 }
171
172 $this->add_control(
173 'top_meta',
174 [
175 'label' => esc_html__('Top Meta', 'uicore-elements'),
176 'type' => \Elementor\Controls_Manager::REPEATER,
177 'fields' => $this->get_meta_content_controls($product_metas),
178 'default' => [
179 [
180 'type' => $product_metas ? 'product sale' : 'category'
181 ],
182 ],
183 'title_field' => '<span style="text-transform: capitalize">{{{ type }}}</span>',
184 'prevent_empty' => false,
185 'separator' => 'before'
186 ]
187 );
188 $this->add_control(
189 'before_title_meta',
190 [
191 'label' => esc_html__('Before Title Meta', 'uicore-elements'),
192 'type' => \Elementor\Controls_Manager::REPEATER,
193 'fields' => $this->get_meta_content_controls($product_metas),
194 'default' => [
195 [
196 'type' => $product_metas ? 'none' : 'author'
197 ],
198 ],
199 'title_field' => '<span style="text-transform: capitalize">{{{ type }}}</span>',
200 'prevent_empty' => false,
201 'separator' => 'before',
202 ]
203 );
204 $this->add_control(
205 'after_title_meta',
206 [
207 'label' => esc_html__('After Title Meta', 'uicore-elements'),
208 'type' => \Elementor\Controls_Manager::REPEATER,
209 'fields' => $this->get_meta_content_controls($product_metas),
210 'default' => [
211 [
212 'type' => $product_metas ? 'product price' : 'date'
213 ],
214 ],
215 'title_field' => '<span style="text-transform: capitalize">{{{ type }}}</span>',
216 'prevent_empty' => false,
217 'separator' => 'before',
218 ]
219 );
220 $this->add_control(
221 'bottom_meta',
222 [
223 'label' => esc_html__('Bottom Meta', 'uicore-elements'),
224 'type' => \Elementor\Controls_Manager::REPEATER,
225 'fields' => $this->get_meta_content_controls($product_metas),
226 'default' => [
227 [
228 'type' => $product_metas ? 'none' : 'none'
229 ],
230 ],
231 'title_field' => '<span style="text-transform: capitalize">{{{ type }}}</span>',
232 'prevent_empty' => false,
233 'separator' => 'before',
234 ]
235 );
236 if($section){
237 $this->end_controls_section();
238 }
239 }
240 function TRAIT_register_post_query_controls($section = true)
241 {
242 if($section){
243 $this->start_controls_section(
244 'section_post_grid_def',
245 [
246 'label' => esc_html__('Query', 'uicore-elements'),
247 ]
248 );
249 }
250
251 $this->add_group_control(
252 Post_Filter::get_type(),
253 [
254 'name' => 'posts-filter',
255 'label' => esc_html__('Posts', 'uicore-elements'),
256 'description' => esc_html__('Current Query Settings > Reading', 'uicore-elements'),
257 ]
258 );
259 $this->add_control(
260 'item_limit',
261 [
262 'label' => esc_html__('Item Limit', 'uicore-elements'),
263 'type' => Controls_Manager::SLIDER,
264 'reder_type' => 'template',
265 'range' => [
266 'px' => [
267 'min' => -1,
268 'max' => 100,
269 ],
270 ],
271 'default' => [
272 'size' => 3,
273 ],
274 'condition' => array(
275 'posts-filter_post_type!' => 'current',
276 ),
277 ]
278 );
279
280 $this->add_control(
281 'offset',
282 [
283 'label' => esc_html__('Query Offset', 'uicore-elements'),
284 'type' => Controls_Manager::SLIDER,
285 'render_type' => 'template',
286 'range' => [
287 'px' => [
288 'min' => -1,
289 'max' => 10,
290 ],
291 ],
292 'default' => [
293 'size' => 0,
294 ],
295 'condition' => [
296 'pagination_type' => 'numbers',
297 ]
298 ]
299 );
300
301 $this->add_control(
302 'offset_alert',
303 [
304 'type' => Controls_Manager::ALERT,
305 'alert_type' => 'info',
306 'content' => esc_html__('Offset is disabled with Load More pagination.', 'uicore-elements'),
307 'condition' => [
308 'pagination_type!' => 'numbers',
309 ]
310 ]
311 );
312
313 $this->add_control(
314 'sticky',
315 [
316 'label' => esc_html__('Sticky Posts', 'uicore-elements'),
317 'type' => Controls_Manager::SWITCHER,
318 'label_on' => esc_html__('Show', 'uicore-elements'),
319 'label_off' => esc_html__('Hide', 'uicore-elements'),
320 'description' => esc_html__('Sticky posts works only on the front-end.', 'uicore-elements'),
321 'return_value' => 1,
322 'default' => 0,
323 'condition' => [
324 'pagination!' => 'yes',
325 ],
326 ]
327 );
328
329 if($section){
330 $this->end_controls_section();
331 }
332 }
333
334 // Control Register Styles functions
335 function TRAIT_register_post_item_style_controls($section = true, $active_tab = false)
336 {
337 if($section){
338 $this->start_controls_section(
339 'section_style_item',
340 [
341 'label' => __('Item Style', 'uicore-elements'),
342 'tab' => Controls_Manager::TAB_STYLE,
343 ]
344 );
345 }
346
347 $this->start_controls_tabs(
348 'item_border_shadow'
349 );
350
351 $this->start_controls_tab(
352 'item_bs_normal_tab',
353 [
354 'label' => esc_html__('Normal', 'plugin-name'),
355 ]
356 );
357 $this->add_group_control(
358 Group_Control_Border::get_type(),
359 [
360 'name' => 'item_border',
361 'selector' => '{{WRAPPER}} .ui-e-item article',
362 ]
363 );
364 $this->add_group_control(
365 Group_Control_Box_Shadow::get_type(),
366 [
367 'name' => 'item_shadow',
368 'selector' => '{{WRAPPER}} .ui-e-item article',
369 ]
370 );
371 $this->end_controls_tab();
372
373 $this->start_controls_tab(
374 'item_bs_hover_tab',
375 [
376 'label' => esc_html__('Hover', 'plugin-name'),
377 ]
378 );
379 $this->add_group_control(
380 Group_Control_Border::get_type(),
381 [
382 'name' => 'item_border_hover',
383 'selector' => '{{WRAPPER}} .ui-e-item:hover article',
384 ]
385 );
386 $this->add_group_control(
387 Group_Control_Box_Shadow::get_type(),
388 [
389 'name' => 'item_shadow_hover',
390 'selector' => '{{WRAPPER}} .ui-e-item:hover article',
391 ]
392 );
393 $this->end_controls_tab();
394
395 if($active_tab){
396 $this->start_controls_tab(
397 'item_bs_active_tab',
398 [
399 'label' => esc_html__('Active', 'plugin-name'),
400 ]
401 );
402 $this->add_group_control(
403 Group_Control_Border::get_type(),
404 [
405 'name' => 'item_border_active',
406 'selector' => '{{WRAPPER}} .ui-e-item.ui-e-active article',
407 ]
408 );
409 $this->add_group_control(
410 Group_Control_Box_Shadow::get_type(),
411 [
412 'name' => 'item_shadow_active',
413 'selector' => '{{WRAPPER}} .ui-e-item.ui-e-active article',
414 ]
415 );
416 $this->end_controls_tab();
417 }
418
419 $this->end_controls_tabs();
420
421 $this->add_control(
422 'item_radius',
423 [
424 'label' => esc_html__('Border Radius', 'uicore-elements'),
425 'type' => Controls_Manager::DIMENSIONS,
426 'separator' => 'before',
427 'selectors' => [
428 '{{WRAPPER}} ' => '--ui-e-border-radius: {{TOP}}px {{RIGHT}}px {{BOTTOM}}px {{LEFT}}px;'
429 ],
430 ]
431 );
432
433 if($section){
434 $this->end_controls_section();
435 }
436 }
437 function TRAIT_register_post_content_style_controls($section = true)
438 {
439 if($section){
440 $this->start_controls_section(
441 'section_style_content',
442 [
443 'label' => __('Content Style', 'uicore-elements'),
444 'tab' => Controls_Manager::TAB_STYLE,
445 ]
446 );
447 }
448 $this->add_control(
449 'image_size',
450 [
451 'label' => __('Image Height (%)', 'uicore-elements'),
452 'type' => Controls_Manager::NUMBER,
453 'min' => 1,
454 'max' => 500,
455 'step' => 1,
456 'default' => 57,
457 'selectors' => [
458 '{{WRAPPER}} .ui-e-post-top' => '--ui-e-img-size: {{VALUE}}',
459 ],
460 'condition' => [
461 'masonry!' => 'ui-e-maso',
462 ],
463 ]
464 );
465 $this->add_control(
466 'image_overflow',
467 [
468 'label' => __('Independent Border Radius and Shadow', 'uicore-elements'),
469 'type' => Controls_Manager::SWITCHER,
470 'default' => 'no',
471 'prefix_class' => 'ui-e-post-ovf-',
472 'condition' => array(
473 'box_style!' => 'overlay',
474 ),
475 ]
476 );
477 $this->add_control(
478 'image_radius',
479 [
480 'label' => esc_html__('Border Radius', 'uicore-elements'),
481 'type' => Controls_Manager::DIMENSIONS,
482 'selectors' => [
483 '{{WRAPPER}} .ui-e-post-top' => 'border-radius: {{TOP}}px {{RIGHT}}px {{BOTTOM}}px {{LEFT}}px;'
484 ],
485 'condition' => array(
486 'image_overflow' => 'yes',
487 ),
488 ]
489 );
490 $this->add_group_control(
491 Group_Control_Box_Shadow::get_type(),
492 [
493 'name' => 'image_shadow',
494 'label' => esc_html__('Box Shadow', 'uicore-elements'),
495 'selector' => '{{WRAPPER}} .ui-e-post-top',
496 'condition' => array(
497 'image_overflow' => 'yes',
498 ),
499 ]
500 );
501 $this->add_responsive_control(
502 'content_alignment',
503 [
504 'label' => esc_html__('Content Alignment', 'uicore-elements'),
505 'type' => Controls_Manager::CHOOSE,
506 'options' => [
507 'left' => [
508 'title' => esc_html__('Left', 'uicore-elements'),
509 'icon' => 'eicon-text-align-left',
510 ],
511 'center' => [
512 'title' => esc_html__('Center', 'uicore-elements'),
513 'icon' => 'eicon-text-align-center',
514 ],
515 'stretch' => [
516 'title' => esc_html__('Justified', 'uicore-elements'),
517 'icon' => 'eicon-text-align-justify',
518 ],
519 ],
520 'selectors' => [
521 '{{WRAPPER}} .ui-e-post-content' => 'align-items: {{VALUE}}; text-align: {{VALUE}};',
522 ],
523 ]
524 );
525 $this->add_control(
526 'title_color',
527 [
528 'label' => esc_html__('Title Color', 'uicore-elements'),
529 'type' => Controls_Manager::COLOR,
530 'default' => '',
531 'separator' => 'before',
532 'selectors' => [
533 '{{WRAPPER}} .ui-e-post-title' => 'color: {{VALUE}};',
534 ],
535 ]
536 );
537 $this->add_control(
538 'title_hcolor',
539 [
540 'label' => esc_html__('Title Hover Color', 'uicore-elements'),
541 'type' => Controls_Manager::COLOR,
542 'default' => '',
543 'selectors' => [
544 '{{WRAPPER}} .ui-e-post-title:hover' => 'color: {{VALUE}};',
545 ],
546 ]
547 );
548 $this->add_group_control(
549 Group_Control_Typography::get_type(),
550 [
551 'name' => 'title_typography',
552 'label' => esc_html__('Title Typography', 'uicore-elements'),
553 'selector' => '{{WRAPPER}} .ui-e-post-title',
554 ]
555 );
556 $this->add_control(
557 'title_gap',
558 [
559 'label' => __('Title Top Space', 'uicore-elements'),
560 'type' => Controls_Manager::SLIDER,
561 'size_units' => ['em'],
562 'separator' => 'after',
563 'range' => [
564 'px' => [
565 'min' => 0,
566 'max' => 3,
567 'step' => 0.1,
568 ],
569 ],
570 'default' => [
571 'unit' => 'em',
572 'size' => 1.2,
573 ],
574 'selectors' => [
575 '{{WRAPPER}} .ui-e-post-title' => 'margin-top: {{SIZE}}em;',
576 ],
577 ]
578 );
579 $this->add_control(
580 'text_color',
581 [
582 'label' => esc_html__('Excerpt Color', 'uicore-elements'),
583 'type' => Controls_Manager::COLOR,
584 'default' => '',
585 'selectors' => [
586 '{{WRAPPER}} .ui-e-post-text' => 'color: {{VALUE}};',
587 ],
588 ]
589 );
590 $this->add_group_control(
591 Group_Control_Typography::get_type(),
592 [
593 'name' => 'text_typography',
594 'label' => esc_html__('Excerpt Typography', 'uicore-elements'),
595 'selector' => '{{WRAPPER}} .ui-e-post-text',
596 ]
597 );
598 $this->add_control(
599 'text_gap',
600 [
601 'label' => __('Excerpt Top Space', 'uicore-elements'),
602 'type' => Controls_Manager::SLIDER,
603 'size_units' => ['em'],
604 'separator' => 'after',
605 'range' => [
606 'px' => [
607 'min' => 0,
608 'max' => 3,
609 'step' => 0.1,
610 ],
611 ],
612 'default' => [
613 'unit' => 'em',
614 'size' => 0.8,
615 ],
616 'selectors' => [
617 '{{WRAPPER}} .ui-e-post-text' => 'margin-top: {{SIZE}}em;',
618 ],
619 ]
620 );
621 $this->add_responsive_control(
622 'content_padding',
623 [
624 'label' => esc_html__('Content Padding', 'uicore-elements'),
625 'type' => Controls_Manager::DIMENSIONS,
626 'size_units' => ['px', 'em', '%'],
627 'selectors' => [
628 '{{WRAPPER}} .ui-e-post-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};'
629 ]
630 ]
631 );
632 $this->add_control(
633 'content_gap',
634 [
635 'label' => __('Content Space', 'uicore-elements'),
636 'type' => Controls_Manager::SLIDER,
637 'size_units' => ['em'],
638 'separator' => 'after',
639 'range' => [
640 'px' => [
641 'min' => 0,
642 'max' => 3,
643 'step' => 0.1,
644 ],
645 ],
646 'default' => [
647 'unit' => 'em',
648 'size' => 0,
649 ],
650 'selectors' => [
651 '{{WRAPPER}} ' => '--ui-e-content-space: {{SIZE}}em;',
652 ],
653 ]
654 );
655 $this->add_group_control(
656 Group_Control_Background::get_type(),
657 [
658 'name' => 'content_bg',
659 'selector' => '{{WRAPPER}} .ui-e-post-content',
660 ]
661 );
662
663 if($section){
664 $this->end_controls_section();
665 }
666 }
667 function TRAIT_register_post_button_style_controls($section = true)
668 {
669 if($section){
670 $this->start_controls_section(
671 'section_button_style',
672 [
673 'label' => esc_html__('Button Style', 'uicore-elements'),
674 'tab' => Controls_Manager::TAB_STYLE,
675 'condition' => array(
676 'show_button' => 'yes',
677 ),
678 ]
679 );
680 }
681 $this->add_responsive_control(
682 'button_align',
683 [
684 'label' => esc_html__( 'Alignment', 'elementor' ),
685 'type' => Controls_Manager::CHOOSE,
686 'options' => [
687 'start' => [
688 'title' => esc_html__( 'Left', 'elementor' ),
689 'icon' => 'eicon-text-align-left',
690 ],
691 'center' => [
692 'title' => esc_html__( 'Center', 'elementor' ),
693 'icon' => 'eicon-text-align-center',
694 ],
695 'end' => [
696 'title' => esc_html__( 'Right', 'elementor' ),
697 'icon' => 'eicon-text-align-right',
698 ],
699 'normal' => [
700 'title' => esc_html__( 'Justified', 'elementor' ),
701 'icon' => 'eicon-text-align-justify',
702 ],
703 ],
704 'default' => 'start',
705 'selectors' => [
706 '{{WRAPPER}} .ui-e-readmore' => 'align-self: {{VALUE}};',
707 ],
708
709 ]
710 );
711 $this->register_button_style_controls(
712 [
713 'section_condition' => [
714 'show_button' => 'yes'
715 ]
716 ]
717 );
718 // Remove button alignment from Elementor button traits because (seens to be a bug), updating Selector CSS with update_control(), don't work as expected with responsiveness
719 $this->remove_responsive_control('align');
720
721 $this->TRAIT_register_post_specific_controls('button_gap');
722
723 if($section) {
724 $this->end_controls_section();
725 }
726 }
727 function TRAIT_register_post_meta_style_controls($section = true)
728 {
729 if($section) {
730 $this->start_controls_section(
731 'section_style_extra_content',
732 [
733 'label' => __('Meta Style', 'uicore-elements'),
734 'tab' => Controls_Manager::TAB_STYLE,
735 ]
736 );
737 }
738 $this->start_controls_tabs('style_extra_tabs');
739 $this->start_controls_tab(
740 'style_top_tab',
741 [
742 'label' => esc_html__('Top', 'uicore-elements'),
743 ]
744 );
745 $this->get_meta_style_controls('top');
746 $this->end_controls_tab();
747
748 $this->start_controls_tab(
749 'style_before_title_tab',
750 [
751 'label' => esc_html__('Before Title', 'uicore-elements'),
752 ]
753 );
754 $this->get_meta_style_controls('before_title');
755 $this->end_controls_tab();
756
757 $this->start_controls_tab(
758 'style_after_title_tab',
759 [
760 'label' => esc_html__('After Title', 'uicore-elements'),
761 ]
762 );
763 $this->get_meta_style_controls('after_title');
764 $this->end_controls_tab();
765
766 $this->start_controls_tab(
767 'style_bottom_tab',
768 [
769 'label' => esc_html__('Bottom', 'uicore-elements'),
770 ]
771 );
772 $this->get_meta_style_controls('bottom');
773 $this->end_controls_tab();
774 $this->end_controls_tabs();
775
776 if($section) {
777 $this->end_controls_section();
778 }
779 }
780 function TRAIT_register_post_animation_controls()
781 {
782 $this->add_control(
783 'anim_image',
784 [
785 'label' => __('Image Hover Animation', 'uicore-elements'),
786 'type' => Controls_Manager::SELECT,
787 'label_block' => true,
788 'default' => 'ui-e-img-anim-zoom',
789 'options' => [
790 '' => __('None', 'uicore-elements'),
791 'ui-e-img-anim-zoom' => __('Zoom', 'uicore-elements'),
792 ],
793 'prefix_class' => '',
794 ]
795 );
796 $this->add_control(
797 'anim_meta',
798 [
799 'label' => __('Meta Hover Animation', 'uicore-elements'),
800 'type' => Controls_Manager::SELECT,
801 'label_block' => true,
802 'default' => '',
803 'options' => [
804 '' => __('None', 'uicore-elements'),
805 'ui-e-meta-anim-show' => __('Show', 'uicore-elements'),
806 ],
807 'prefix_class' => '',
808 ]
809 );
810 $this->add_control(
811 'important_note',
812 [
813 'label' => esc_html__('Important Note', 'uicore-elements'),
814 'type' => \Elementor\Controls_Manager::RAW_HTML,
815 'raw' => '<div class="elementor-control-field-description" style="margin-top: -7px;">' . esc_html__('This works only for Below Title Meta.', 'uicore-elements') . '</div>',
816 'show_label' => false,
817 'condition' => array(
818 'box_style' => 'overlay',
819 ),
820 ]
821 );
822 $this->add_control(
823 'anim_title',
824 [
825 'label' => __('Title Hover Animation', 'uicore-elements'),
826 'type' => Controls_Manager::SELECT,
827 'label_block' => true,
828 'default' => '',
829 'options' => [
830 '' => __('None', 'uicore-elements'),
831 'ui-e-title-anim-underline' => __('Underline', 'uicore-elements'),
832 ],
833 'prefix_class' => '',
834 ]
835 );
836 $this->add_control(
837 'anim_content',
838 [
839 'label' => __('Content Hover Animation', 'uicore-elements'),
840 'type' => Controls_Manager::SELECT,
841 'label_block' => true,
842 'default' => '',
843 'options' => [
844 '' => __('None', 'uicore-elements'),
845 'ui-e-content-anim-show' => __('Show', 'uicore-elements'),
846 ],
847 'prefix_class' => '',
848 'condition' => array(
849 'box_style' => 'overlay',
850 ),
851 ]
852 );
853 $this->add_control(
854 'anim_btn',
855 [
856 'label' => __('Button Hover Animation', 'uicore-elements'),
857 'type' => Controls_Manager::SELECT,
858 'label_block' => true,
859 'default' => '',
860 'options' => [
861 '' => __('None', 'uicore-elements'),
862 'ui-e-btn-anim-show' => __('Show', 'uicore-elements'),
863 ],
864 'prefix_class' => '',
865 'condition' => [
866 'show_button' => 'yes',
867 ],
868 ]
869 );
870 }
871 /**
872 * Registers specific controls that can't be registered in blocks because of diferent use by different widgets or some other reason.
873 * TODO: update to the use injection control, a better approach.
874 *
875 * @param string $control The control to register.
876 * @return void
877 */
878 function TRAIT_register_post_specific_controls($control)
879 {
880 switch ($control) {
881 case 'button_gap':
882 $this->add_control(
883 'button_gap',
884 [
885 'label' => __('Button Top Space', 'uicore-elements'),
886 'type' => Controls_Manager::SLIDER,
887 'size_units' => ['em'],
888 'range' => [
889 'px' => [
890 'min' => 0,
891 'max' => 3,
892 'step' => 0.1,
893 ],
894 ],
895 'default' => [
896 'unit' => 'em',
897 'size' => 0.8,
898 ],
899 'selectors' => [
900 '{{WRAPPER}} .elementor-button' => 'margin-top: {{SIZE}}em;',
901 ],
902 ]
903 );
904 break;
905 }
906 }
907
908 /**
909 * Returns the proper query args for a given post type.
910 *
911 * @param array $settings Elementor controls settings.
912 * @param object $default_query The default query object. Used to tell if is a frontend or rest api request.
913 *
914 * @return void Don't return anything, but sets the query object to $_query variable that can be accessed by the widget.
915 */
916 function TRAIT_query_posts($settings, $default_query)
917 {
918 $post_type = $settings['posts-filter_post_type'];
919
920 if ( $post_type === 'related' ) {
921 $this->_query = Helper::get_related('random', $settings['item_limit']['size']);
922
923 } else {
924 $query_args = Query::get_query_args('posts-filter', $settings);
925
926 if ($post_type === 'current') {
927 $query_args = $default_query;
928
929 // Post type fallback for APG
930 if( isset($default_query['post_type']) || isset($default_query['query']['post_type']) ){
931 $post_type = $default_query['post_type'] ?? $default_query['query']['post_type'];
932 } else {
933 $post_type = 'post';
934 }
935
936 // Set pagination
937 $query_args['paged'] = Query::get_queried_page($settings);
938
939 // Set tax filters for filter component, if enabled
940 $queried_filters = Query::get_queried_filters($settings, get_post_type(), 'posts-filter');
941 $query_args['tax_query'] = empty($queried_filters['tax_query']) ? [] : $queried_filters['tax_query'];
942 }
943
944 if ($post_type === 'portfolio') {
945 $query_args['orderby'] = 'menu_order date';
946 }
947
948 $this->_query = new \WP_Query($query_args);
949 }
950 }
951
952
953 // Render functions
954 function get_post_image()
955 {
956 if ($this->get_settings_for_display('image') !== 'yes') {
957 return;
958 }
959
960 $pic_id = get_post_thumbnail_id();
961 if (!$pic_id)
962 return;
963 $size = $this->get_settings_for_display('image_size_select') ?? 'uicore-medium';
964 ?>
965 <a class="ui-e-post-img-wrapp"
966 href="<?php echo esc_url(get_permalink()); ?>"
967 title="<?php echo esc_attr__('View Post:', 'uicore-elements') . the_title_attribute(['echo' => false]); ?>">
968
969 <?php if ($this->get_settings_for_display('masonry') === 'ui-e-maso') { ?>
970 <?php the_post_thumbnail($size, ['class' => 'ui-e-post-img']); ?>
971 <?php } else { ?>
972 <div class="ui-e-post-img" style="background-image:url(<?php echo wp_get_attachment_image_url($pic_id, $size) ?>)"></div>
973 <?php } ?>
974 </a>
975 <?php
976
977 }
978 function get_post_title()
979 {
980 if ($this->get_settings_for_display('title') !== 'yes') {
981 return;
982 }
983 ?>
984 <a href="<?php echo esc_url( get_permalink() );?>" title="<?php echo esc_attr__('View Post:','uicore-elements') . esc_html(the_title_attribute(['echo'=>false])); ?>">
985 <h4 class="ui-e-post-title"><span><?php echo esc_html(get_the_title()); ?></span></h4>
986 </a>
987 <?php
988 }
989 function get_post_meta($position)
990 {
991 $meta_list = $this->get_settings_for_display($position . '_meta');
992 if (!isset($meta_list[0]) || $meta_list[0]['type'] == '') {
993 return;
994 }
995 echo ($position == 'top') ? '<div class="ui-e-post-top-meta">' : '';
996 echo ($position == 'after_title') ? '<div class="ui-e-meta-wrapp">' : '';
997 echo '<div class="ui-e-post-meta ui-e-'.esc_attr($position).'">';
998 foreach ($meta_list as $meta) {
999 if($meta['type'] != 'none'){
1000 $this->display_meta($meta);
1001
1002 if( next( $meta_list ) && $this->get_settings_for_display( $position.'_meta_separator' ) ) {
1003 echo '<span class="ui-e-separator">'.esc_html($this->get_settings_for_display( $position.'_meta_separator' )).'</span>';
1004 }
1005 }
1006 }
1007 echo '</div>';
1008 echo ($position == 'top' || $position == 'after_title') ? '</div>' : '';
1009 }
1010 /**
1011 * Render the post read more button.
1012 *
1013 * @param bool $is_product. If true, will render an add to cart button.
1014 *
1015 * @return void
1016 */
1017 function TRAIT_get_button($is_product = false)
1018 {
1019 $settings = $this->get_settings_for_display();
1020
1021 if( $is_product ){
1022 global $product;
1023
1024 // Get default add to cart text as fallback
1025 $settings['text'] = empty($settings['text']) ? $product->add_to_cart_text() : $settings['text'];
1026 }
1027
1028 $this->add_render_attribute('button', [
1029 'class' => ['elementor-button-link', 'elementor-button', 'ui-e-readmore'],
1030 'role' => 'button',
1031 ]);
1032 $this->add_render_attribute('content-wrapper', 'class', 'elementor-button-content-wrapper');
1033
1034 if (!empty($settings['button_css_id'])) {
1035 $this->add_render_attribute('button', 'id', $settings['button_css_id']);
1036 }
1037
1038 if (!empty($settings['size'])) {
1039 $this->add_render_attribute('button', 'class', 'elementor-size-' . $settings['size']);
1040 }
1041
1042 if (!empty($settings['hover_animation'])) {
1043 $this->add_render_attribute('button', 'class', 'elementor-animation-' . $settings['hover_animation']);
1044 }
1045 $this->add_render_attribute([
1046 'icon-align' => [
1047 'class' => [
1048 'elementor-button-icon',
1049 'elementor-align-icon-' . $settings['icon_align'],
1050 ],
1051 ],
1052 'text' => [
1053 'class' => 'elementor-button-text',
1054 ],
1055 ]);
1056
1057 $tbn_content = '<span ' . $this->get_render_attribute_string('content-wrapper') . '>';
1058
1059 if (!empty($settings['icon']) || !empty($settings['selected_icon']['value'])) {
1060 $tbn_content .= '<span ' . $this->get_render_attribute_string('icon-align') . '>';
1061 \ob_start();
1062 Icons_Manager::render_icon($settings['selected_icon'], ['aria-hidden' => 'true']);
1063 $tbn_content .= \ob_get_clean();
1064 $tbn_content .= '</span>';
1065 }
1066
1067 $tbn_content .= '<span ' . $this->get_render_attribute_string('text') . '>';
1068 $tbn_content .= $settings['text'];
1069 $tbn_content .= '</span> </span>';
1070
1071 // WooCommerce add to cart button
1072 if ($is_product) {
1073 if ($product) {
1074 echo Helper::esc_svg(apply_filters(
1075 'woocommerce_loop_add_to_cart_link', // WPCS: XSS ok.
1076 sprintf(
1077 '<a href="%s" data-quantity="%s" %s>%s</a>',
1078 esc_url($product->add_to_cart_url()),
1079 esc_attr(1),
1080 $this->get_render_attribute_string('button'),
1081 $tbn_content
1082 ),
1083 $product
1084 ));
1085 }
1086
1087 // Default button
1088 } else {
1089 ?>
1090 <a href="<?php echo esc_url(get_permalink()); ?>" <?php $this->print_render_attribute_string('button'); ?>>
1091 <?php echo Helper::esc_svg( $tbn_content ); ?>
1092 </a>
1093 <?php
1094 }
1095 }
1096 /**
1097 * Renders a post item with various settings and options.
1098 * Important: any changes here should also be considered to `TRAIT_render_product()` from Product Component.
1099 *
1100 * @param bool $carousel Indicates if the item needs carousel classnames.
1101 * @param bool $legacy Indicates if the item is using legacy classnames.
1102 *
1103 * @return void
1104 */
1105 function TRAIT_render_item($carousel = false, $legacy = false)
1106 {
1107 $settings = $this->get_settings_for_display();
1108 $excerpt_length = $settings['excerpt_trim'];
1109
1110 // Classnames but checking if we the widget is APG (legacy version)
1111 $item_classes = $legacy ? ['ui-e-post-item', 'ui-e-item'] : ['ui-e-item'] ; // Single item lower wrap class receptor
1112 $hover_item_class = $legacy ? 'anim_item' : 'item_hover_animation'; // item hover animation class
1113
1114 // If widget is not carousel type, we set animations classes directly on item selector
1115 if(!$carousel) {
1116 $item_classes[] = 'ui-e-animations-wrp';
1117 $item_classes[] = $settings['animate_items'] === 'ui-e-grid-animate' ? 'elementor-invisible' : '';
1118 $item_classes[] = $settings[$hover_item_class] !== '' ? $settings[$hover_item_class] : '';
1119
1120 } else {
1121 // Get entrance and item hover animation classes
1122 $entrance = (isset($settings['animate_items']) && $settings['animate_items'] == 'ui-e-grid-animate') ? 'elementor-invisible' : '';
1123 $hover = isset($settings[$hover_item_class]) ? $settings[$hover_item_class] : '';
1124 $animations = sprintf('%s %s', $entrance, $hover);
1125
1126 // Check if entrance or hover animation are set
1127 $has_animation = !empty($entrance) || !empty($hover)
1128
1129 // Prints extra wrappers required by the carousel script
1130 ?>
1131 <div class="ui-e-wrp swiper-slide">
1132 <?php if($has_animation) : ?>
1133 <div class="ui-e-animations-wrp <?php echo esc_attr($animations);?>">
1134 <?php endif; ?>
1135
1136 <?php } ?>
1137
1138 <div class="<?php echo esc_attr( implode(' ', $item_classes));?>">
1139 <article <?php post_class(); ?>>
1140 <div class="ui-e-post-top">
1141 <?php $this->get_post_image(); ?>
1142 <?php $this->get_post_meta('top'); ?>
1143 </div>
1144 <div class="ui-e-post-content">
1145 <?php $this->get_post_meta('before_title'); ?>
1146 <?php
1147 if ($this->get_settings_for_display('title') === 'yes')
1148 $this->get_post_title();
1149 ?>
1150 <?php $this->get_post_meta('after_title'); ?>
1151 <?php
1152 if ($this->get_settings_for_display('excerpt'))
1153 echo wp_kses_post('<div class="ui-e-post-text">' . wp_trim_words(get_the_excerpt(), $excerpt_length) . '</div>');
1154 ?>
1155 <?php $this->get_post_meta('bottom'); // button
1156 ?>
1157 <?php
1158 if ( $this->get_settings_for_display('show_button') === 'yes' ) {
1159 // Add match height spacing element if carousel. May look intrusive, but is the simplest method compared
1160 // to absolute positioning or catching last content element to apply margin.
1161 if($carousel && $settings['match_height'] === 'yes'){
1162 ?>
1163 <span class="ui-e-match-height"></span>
1164 <?php
1165 }
1166
1167 if( !isset($settings['button_position']) || empty($settings['button_position']) ) {
1168 $this->TRAIT_get_button();
1169 }
1170 }
1171 ?>
1172 </div>
1173 </article>
1174 </div>
1175
1176 <?php if($carousel) { ?>
1177 </div>
1178 <?php if($has_animation) : ?>
1179 </div>
1180 <?php endif; ?>
1181
1182 <?php }
1183 }
1184 }
1185