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