PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.3.17
UiCore Elements – Free widgets and templates for Elementor v1.3.17
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 1.2.4 All 41 releases
uicore-elements / includes / utils / pagination-component.php

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

562 lines 19.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UiCoreElements\Utils;
4
5 use UicoreElements\Helper;
6
7 use \Elementor\Controls_Manager;
8 use \Elementor\Group_Control_Border;
9 use \Elementor\Group_Control_Box_Shadow;
10 use \Elementor\Group_Control_Typography;
11
12 defined('ABSPATH') || exit();
13
14 /**
15 * Paginations Trait Component
16 *
17 */
18
19 trait Pagination_Trait
20 {
21
22 function TRAIT_register_pagination_controls($section = true)
23 {
24 if ($section) {
25 $this->start_controls_section(
26 'section_pagination',
27 [
28 'label' => esc_html__('Pagination', 'uicore-elements'),
29 ]
30 );
31 }
32
33 $this->add_control(
34 'pagination',
35 [
36 'label' => __('Pagination', 'uicore-elements'),
37 'type' => Controls_Manager::SWITCHER,
38 'default' => 'no',
39 'render_type' => 'template',
40 ]
41 );
42 $this->add_control(
43 'pagination_type',
44 [
45 'label' => esc_html__('Pagination Type', 'uicore-elements'),
46 'type' => Controls_Manager::SELECT,
47 'default' => 'numbers',
48 'options' => [
49 'numbers' => esc_html__('Numbers', 'uicore-elements'),
50 'load_more' => esc_html__('Load More', 'uicore-elements'),
51 ],
52 'frontend_available' => true,
53 'condition' => [
54 'pagination' => 'yes',
55 ],
56 ]
57 );
58 $this->add_control(
59 'load_more_qty',
60 [
61 'label' => esc_html__('Posts per Load', 'uicore-elements'),
62 'type' => Controls_Manager::SLIDER,
63 'range' => [
64 'px' => [
65 'min' => -1,
66 'max' => 100,
67 ],
68 ],
69 'condition' => array(
70 'pagination_type' => 'load_more',
71 ),
72 ]
73 );
74
75 if ($section) {
76 $this->end_controls_section();
77 }
78 }
79 function TRAIT_register_pagination_style_controls($section = true)
80 {
81 if ($section) {
82 $this->start_controls_section(
83 'section_style_pagination',
84 [
85 'label' => __('Pagination Style', 'uicore-elements'),
86 'tab' => Controls_Manager::TAB_STYLE,
87 'condition' => [
88 'pagination' => 'yes',
89 ],
90 ]
91 );
92 }
93
94 $this->add_group_control(
95 Group_Control_Typography::get_type(),
96 [
97 'name' => 'pagination_typography',
98 'label' => esc_html__('Typography', 'uicore-elements'),
99 'selector' => '{{WRAPPER}} .uicore-page-item, {{WRAPPER}} .ui-e-load-more',
100 ]
101 );
102 $this->add_responsive_control(
103 'icon_size',
104 [
105 'label' => __('Previous/Next Icon Size', 'uicore-elements'),
106 'type' => Controls_Manager::SLIDER,
107 'size_units' => ['px'],
108 'range' => [
109 'px' => [
110 'min' => 0,
111 'max' => 30,
112 'step' => 1,
113 ],
114 ],
115 'default' => [
116 'unit' => 'px',
117 'size' => 16,
118 ],
119 'selectors' => [
120 '{{WRAPPER}} .uicore-pagination a.prev svg, {{WRAPPER}} .uicore-pagination a.next svg' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}}',
121 '{{WRAPPER}} .uicore-pagination a.prev i, {{WRAPPER}} .uicore-pagination a.next i' => 'font-size: {{SIZE}}{{UNIT}};',
122 ],
123 'condition' => [
124 'pagination_type' => 'numbers'
125 ]
126 ]
127 );
128 $this->add_responsive_control(
129 'pagination_top',
130 [
131 'label' => __('Pagination Top Space', 'uicore-elements'),
132 'type' => Controls_Manager::SLIDER,
133 'size_units' => ['px'],
134 'range' => [
135 'px' => [
136 'min' => 0,
137 'max' => 500,
138 'step' => 1,
139 ],
140 ],
141 'default' => [
142 'unit' => 'px',
143 'size' => 50,
144 ],
145 'selectors' => [
146 '{{WRAPPER}} .uicore-pagination' => 'margin-top: {{SIZE}}px;',
147 '{{WRAPPER}} .ui-e-load-more' => 'margin-top: {{SIZE}}px;',
148 ],
149 ]
150 );
151 $this->add_control(
152 'pagination_align',
153 [
154 'label' => esc_html__('Pagination Alignment', 'uicore-elements'),
155 'type' => Controls_Manager::CHOOSE,
156 'options' => [
157 'start' => [
158 'title' => esc_html__('Left', 'uicore-elements'),
159 'icon' => 'eicon-text-align-left',
160 ],
161 'center' => [
162 'title' => esc_html__('Center', 'uicore-elements'),
163 'icon' => 'eicon-text-align-center',
164 ],
165 ],
166 'selectors' => [
167 '{{WRAPPER}} .uicore-pagination ul' => 'justify-content: {{VALUE}};',
168 '{{WRAPPER}} .ui-e-pagination' => 'text-align: {{VALUE}};',
169 ],
170 ]
171 );
172 // Number Specific
173 $this->add_control(
174 'pagination_padding',
175 [
176 'label' => __('Items Padding', 'uicore-elements'),
177 'type' => Controls_Manager::SLIDER,
178 'size_units' => ['em'],
179 'range' => [
180 'em' => [
181 'min' => 0,
182 'max' => 3,
183 'step' => 0.1,
184 ],
185 ],
186 'default' => [
187 'unit' => 'em',
188 'size' => 0.4,
189 ],
190 'selectors' => [
191 '{{WRAPPER}} .uicore-pagination ul li > *' => ' width: calc(1em + {{SIZE}}em);line-height: calc(1em + {{SIZE}}em);',
192 ],
193 'condition' => array(
194 'pagination_type' => 'numbers',
195 ),
196 ]
197 );
198 $this->add_control(
199 'pagination_gap',
200 [
201 'label' => __('Items Gap', 'uicore-elements'),
202 'type' => Controls_Manager::SLIDER,
203 'size_units' => ['em'],
204 'range' => [
205 'em' => [
206 'min' => 0,
207 'max' => 3,
208 'step' => 0.1,
209 ],
210 ],
211 'default' => [
212 'unit' => 'em',
213 'size' => 0.4,
214 ],
215 'selectors' => [
216 '{{WRAPPER}} .uicore-pagination ul' => 'gap: {{SIZE}}em;',
217 ],
218 'condition' => array(
219 'pagination_type' => 'numbers',
220 ),
221 ]
222 );
223 $this->add_control(
224 'pagination_radius',
225 [
226 'label' => __('Items Border Radius', 'uicore-elements'),
227 'type' => Controls_Manager::SLIDER,
228 'size_units' => ['em'],
229 'range' => [
230 'em' => [
231 'min' => 0,
232 'max' => 3,
233 'step' => 0.1,
234 ],
235 ],
236 'default' => [
237 'unit' => 'em',
238 'size' => 0.2,
239 ],
240 'selectors' => [
241 '{{WRAPPER}} .uicore-pagination ul li' => 'border-radius: {{SIZE}}em;',
242 ],
243 'condition' => array(
244 'pagination_type' => 'numbers',
245 ),
246 ]
247 );
248 // Load More Specific
249 $this->add_control(
250 'load_more_padding',
251 [
252 'label' => esc_html__('Button Padding', 'uicore-elements'),
253 'type' => Controls_Manager::DIMENSIONS,
254 'size_units' => ['px', '%', 'em'],
255 'selectors' => [
256 '{{WRAPPER}} .ui-e-load-more' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
257 ],
258 'condition' => array(
259 'pagination_type' => 'load_more'
260 ),
261 ]
262 );
263 $this->add_control(
264 'load_more_radius',
265 [
266 'label' => esc_html__('Button Radius', 'uicore-elements'),
267 'type' => Controls_Manager::DIMENSIONS,
268 'size_units' => ['px', '%', 'em'],
269 'selectors' => [
270 '{{WRAPPER}} .ui-e-load-more' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
271 ],
272 'condition' => array(
273 'pagination_type' => 'load_more'
274 ),
275 ]
276 );
277 // General Again
278 $this->start_controls_tabs(
279 'pagination_item',
280 [
281 'condition' => [
282 'pagination' => 'yes',
283 ],
284 ]
285 );
286 $this->start_controls_tab(
287 'pagination_normal_tab',
288 [
289 'label' => esc_html__('Normal', 'uicore-elements'),
290 ]
291 );
292 $this->add_control(
293 'pagination_bg',
294 [
295 'label' => esc_html__('Background', 'uicore-elements'),
296 'type' => Controls_Manager::COLOR,
297 'default' => '',
298 'selectors' => [
299 '{{WRAPPER}} .uicore-pagination li' => 'background: {{VALUE}};',
300 '{{WRAPPER}} .ui-e-load-more' => 'background: {{VALUE}};',
301 ],
302 ]
303 );
304 $this->add_control(
305 'pagination_color',
306 [
307 'label' => esc_html__('Color', 'uicore-elements'),
308 'type' => Controls_Manager::COLOR,
309 'default' => '',
310 'selectors' => [
311 '{{WRAPPER}} .uicore-pagination li a' => 'color: {{VALUE}};',
312 '{{WRAPPER}} .uicore-pagination svg' => 'fill: {{VALUE}};',
313 '{{WRAPPER}} .ui-e-load-more' => 'color: {{VALUE}};',
314 ],
315 ]
316 );
317 $this->add_group_control(
318 Group_Control_Border::get_type(),
319 [
320 'name' => 'pagination_border',
321 'selector' => '{{WRAPPER}} .uicore-pagination ul li, {{WRAPPER}} .ui-e-load-more',
322 'separator' => 'before',
323 ]
324 );
325 $this->add_group_control(
326 Group_Control_Box_Shadow::get_type(),
327 [
328 'name' => 'pagination_shadow',
329 'selector' => '{{WRAPPER}} .uicore-pagination ul li, {{WRAPPER}} .ui-e-load-more',
330 ]
331 );
332 $this->end_controls_tab();
333
334 $this->start_controls_tab(
335 'pagination_hover_tab',
336 [
337 'label' => esc_html__('Hover', 'uicore-elements'),
338 ]
339 );
340 $this->add_control(
341 'pagination_hover_bg',
342 [
343 'label' => esc_html__('Background', 'uicore-elements'),
344 'type' => Controls_Manager::COLOR,
345 'default' => '',
346 'selectors' => [
347 '{{WRAPPER}} .uicore-pagination ul li:hover:not(.uicore-active)' => 'background: {{VALUE}};',
348 '{{WRAPPER}} .ui-e-load-more:hover' => 'background: {{VALUE}};',
349 ],
350 ]
351 );
352 $this->add_control(
353 'pagination_hover_color',
354 [
355 'label' => esc_html__('Color', 'uicore-elements'),
356 'type' => Controls_Manager::COLOR,
357 'default' => '',
358 'selectors' => [
359 '{{WRAPPER}} .uicore-pagination li:hover:not(.uicore-active) a' => 'color: {{VALUE}};',
360 '{{WRAPPER}} .uicore-pagination li:hover:not(.uicore-active) svg' => 'fill: {{VALUE}};',
361 '{{WRAPPER}} .ui-e-load-more:hover' => 'color: {{VALUE}};',
362 ],
363 ]
364 );
365 $this->add_group_control(
366 Group_Control_Border::get_type(),
367 [
368 'name' => 'pagination_border_hover',
369 'selector' => '{{WRAPPER}} .uicore-pagination ul li:hover:not(.uicore-active), {{WRAPPER}} .ui-e-load-more:hover',
370 'separator' => 'before',
371 ]
372 );
373 $this->add_group_control(
374 Group_Control_Box_Shadow::get_type(),
375 [
376 'name' => 'pagination_shadow_hover',
377 'selector' => '{{WRAPPER}} .uicore-pagination ul li:hover:not(.uicore-active), {{WRAPPER}} .ui-e-load-more:hover',
378 ]
379 );
380 $this->end_controls_tab();
381 // Number specific
382 $this->start_controls_tab(
383 'pagination_active_tab',
384 [
385 'label' => esc_html__('Active', 'uicore-elements'),
386 'condition' => [
387 'pagination_type' => 'numbers',
388 ]
389 ]
390 );
391 $this->add_control(
392 'pagination_active_bg',
393 [
394 'label' => esc_html__('Background', 'uicore-elements'),
395 'type' => Controls_Manager::COLOR,
396 'default' => '',
397 'selectors' => [
398 '{{WRAPPER}} .uicore-page-link.current' => 'background: {{VALUE}};',
399 ],
400 'condition' => [
401 'pagination_type' => 'numbers',
402 ]
403 ]
404 );
405 $this->add_control(
406 'pagination_active_color',
407 [
408 'label' => esc_html__('Color', 'uicore-elements'),
409 'type' => Controls_Manager::COLOR,
410 'default' => '',
411 'selectors' => [
412 '{{WRAPPER}} .uicore-page-link.current' => 'color: {{VALUE}};',
413 ],
414 'condition' => [
415 'pagination_type' => 'numbers',
416 ]
417 ]
418 );
419 $this->add_group_control(
420 Group_Control_Border::get_type(),
421 [
422 'name' => 'pagination_border_active',
423 'selector' => '{{WRAPPER}} .uicore-pagination li.uicore-active',
424 'separator' => 'before',
425 'condition' => [
426 'pagination_type' => 'numbers',
427 ]
428 ]
429 );
430 $this->add_group_control(
431 Group_Control_Box_Shadow::get_type(),
432 [
433 'name' => 'pagination_shadow_active',
434 'selector' => '{{WRAPPER}} .uicore-pagination li.uicore-active',
435 'condition' => [
436 'pagination_type' => 'numbers',
437 ]
438 ]
439 );
440 $this->end_controls_tab();
441
442 $this->end_controls_tabs();
443
444 if ($section) {
445 $this->end_controls_section();
446 }
447 }
448
449 /**
450 * Render pagination numbers.
451 *
452 * @param bool $is_product - If the pagination is for products
453 * @param array $args
454 * @author Andrei Voica <andrei@uicore.co>
455 * @since 1.0.0
456 */
457 function render_numbers($is_product, $args = [])
458 {
459
460 if ($is_product) {
461 $query = $this->get_query();
462
463 // Currently we alow users to use number pagination in contexts that shouldn't be used. E.g: in related posts on single product pages
464 if (!isset($query)) {
465 return;
466 }
467
468 $total_items = Helper::get_framework_visible_posts('product');
469 $total_count = wc_get_products(array_merge($query, ['limit' => -1, 'return' => 'ids'])); // Fetch all products - TODO: -1 is very bad for performance
470 $total = ceil(count($total_count) / $total_items);
471 $current_page = max(1, get_query_var('paged'));
472 } else {
473 global $query;
474 }
475
476 // Set pagination args
477 $args = wp_parse_args($args, [
478 'mid_size' => 2,
479 'prev_next' => true,
480 'prev_text' => null,
481 'next_text' => null,
482 'screen_reader_text' => _x('Posts navigation', 'Frontend - Pagination', 'uicore-elements'),
483 'type' => 'array',
484 'current' => max(1, get_query_var('paged')),
485 ]);
486
487
488 // Build woo pagination args
489 if ($is_product) {
490
491 if ($total && $total <= 1) {
492 return;
493 }
494
495 $args = apply_filters('woocommerce_pagination_args', [
496 // WPCS: XSS ok.
497 'current' => $current_page,
498 'total' => $total,
499 'prev_text' => '',
500 'next_text' => '',
501 'type' => 'array',
502 'base' => esc_url_raw(add_query_arg('product-page', '%#%', false)),
503 'screen_reader_text' => _x('Products navigation', 'Frontend - Pagination', 'uicore-elements'),
504 ]);
505
506 if (! wc_get_loop_prop('is_shortcode')) {
507 $args['format'] = '';
508 $args['base'] = esc_url_raw(str_replace(999999999, '%#%', remove_query_arg('add-to-cart', get_pagenum_link(999999999, false))));
509 }
510 }
511
512 $links = paginate_links($args);
513 $class = 'uicore-pagination';
514 $class .= !defined('UICORE_ASSETS') ? ' ui-e-pagination' : '';
515
516 if (is_array($links) || is_object($links)) { ?>
517 <nav aria-label="<?php echo esc_attr($args['screen_reader_text']); ?>" class="<?php echo esc_attr($class); ?>">
518 <ul>
519 <?php foreach ($links as $key => $link) :
520 // If next/prev buttons and Uicore Framework is not active, get arrow icon and append it
521 if ((strpos($link, 'prev') || strpos($link, 'next')) && !defined('UICORE_ASSETS')) {
522 $svg = \file_get_contents(UICORE_ELEMENTS_ASSETS . '/media/svg/pagination-icon.svg');
523 $link = str_replace('</a>', $svg . '</a>', $link);
524 }
525 ?>
526 <li class="uicore-page-item <?php echo strpos($link, 'current') ? 'uicore-active' : ''; ?>">
527 <?php echo wp_kses_post(str_replace('page-numbers', 'uicore-page-link', $link)); ?>
528 </li>
529 <?php endforeach; ?>
530 </ul>
531 </nav>
532 <?php }
533 }
534 function render_load_more($postID)
535 {
536 // Script may get the current page ID to set as exclusion list on related posts query
537 ?>
538 <nav data-ui-e-current-page="<?php echo esc_attr($postID); ?>" aria-label="Posts navigation" class="ui-e-pagination">
539 <button class="ui-e-load-more elementor-button">Load more</button>
540 </nav>
541 <?php
542 }
543
544 /**
545 * Render pagination for post/product widgets
546 *
547 * @param array $settings - The settings of the widget
548 * @param int $postID - The ID of the post or product
549 * @param bool $is_product - Whether the pagination is for products. Default is false.
550 */
551 function TRAIT_render_pagination($settings, $postID, $is_product = false)
552 {
553 if ($this->is_option('pagination', 'yes')) {
554 if ($this->is_option('pagination_type', 'load_more')) {
555 $this->render_load_more($postID);
556 } else {
557 $this->render_numbers($is_product);
558 }
559 }
560 }
561 }
562