| @@ -10,8 +10,10 @@ | ||
| 10 | 10 | use Elementor\Group_Control_Text_Shadow; |
| 11 | 11 | use Elementor\Group_Control_Background; |
| 12 | 12 | use Elementor\Group_Control_Css_Filter; |
| 13 | 13 | |
| 14 | +use UltimatePostKit\Traits\Global_Widget_Controls; | |
| 15 | + | |
| 14 | 16 | if (!defined('ABSPATH')) { |
| 15 | 17 | exit; |
| 16 | 18 | } // Exit if accessed directly |
| 17 | 19 | |
| @@ -17,8 +19,10 @@ | ||
| 17 | 19 | |
| 18 | 20 | class Author extends Module_Base { |
| 19 | 21 | private $_query = null; |
| 20 | 22 | |
| 23 | + use Global_Widget_Controls; | |
| 24 | + | |
| 21 | 25 | public function get_name() { |
| 22 | 26 | return 'upk-author'; |
| 23 | 27 | } |
| 24 | 28 | |
| @@ -290,8 +294,17 @@ | ||
| 290 | 294 | ] |
| 291 | 295 | ] |
| 292 | 296 | ); |
| 293 | 297 | |
| 298 | + $this->add_control( | |
| 299 | + 'show_pagination', | |
| 300 | + [ | |
| 301 | + 'label' => esc_html__('Show Pagination', 'ultimate-post-kit') . BDTUPK_NC, | |
| 302 | + 'type' => Controls_Manager::SWITCHER, | |
| 303 | + 'separator' => 'before', | |
| 304 | + ] | |
| 305 | + ); | |
| 306 | + | |
| 294 | 307 | $this->end_controls_section(); |
| 295 | 308 | |
| 296 | 309 | $this->start_controls_section( |
| 297 | 310 | 'section_post_grid_query', |
| @@ -343,8 +356,30 @@ | ||
| 343 | 356 | ] |
| 344 | 357 | ); |
| 345 | 358 | |
| 346 | 359 | $this->add_control( |
| 360 | + 'min_published_posts', | |
| 361 | + [ | |
| 362 | + 'label' => esc_html__( 'Minimum Author Posts', 'ultimate-post-kit' ) . BDTUPK_NC, | |
| 363 | + 'type' => Controls_Manager::SLIDER, | |
| 364 | + 'range' => [ | |
| 365 | + 'px' => [ | |
| 366 | + 'min' => 0, | |
| 367 | + 'max' => 100, | |
| 368 | + 'step' => 1, | |
| 369 | + ], | |
| 370 | + ], | |
| 371 | + 'default' => [ | |
| 372 | + 'size' => 0, | |
| 373 | + ], | |
| 374 | + 'description' => esc_html__( | |
| 375 | + 'Only show authors who have at least this number of published posts. Set 0 to show all.', | |
| 376 | + 'ultimate-post-kit' | |
| 377 | + ), | |
| 378 | + ] | |
| 379 | + ); | |
| 380 | + | |
| 381 | + $this->add_control( | |
| 347 | 382 | 'orderby', |
| 348 | 383 | [ |
| 349 | 384 | 'label' => esc_html__('Order By', 'ultimate-post-kit'), |
| 350 | 385 | 'type' => Controls_Manager::SELECT, |
| @@ -408,9 +443,9 @@ | ||
| 408 | 443 | [ |
| 409 | 444 | 'label' => esc_html__('Glassmorphism', 'ultimate-post-kit'), |
| 410 | 445 | 'type' => Controls_Manager::SWITCHER, |
| 411 | 446 | // translators: %1s: Opening anchor tag with link to MDN backdrop-filter documentation, %2s: Closing anchor tag |
| 412 | - 'description' => sprintf(__('This feature will not work in the Firefox browser untill you enable browser compatibility so please %1s look here %2s', 'ultimate-post-kit'), '<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility" target="_blank">', '</a>'), | |
| 447 | + 'description' => sprintf(__('This feature will not work in the Firefox browser untill you enable browser compatibility so please %1$s look here %2$s', 'ultimate-post-kit'), '<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility" target="_blank">', '</a>'), | |
| 413 | 448 | |
| 414 | 449 | ] |
| 415 | 450 | ); |
| 416 | 451 | |
| @@ -1355,26 +1390,59 @@ | ||
| 1355 | 1390 | |
| 1356 | 1391 | $this->end_controls_tabs(); |
| 1357 | 1392 | |
| 1358 | 1393 | $this->end_controls_section(); |
| 1394 | + | |
| 1395 | + //Global Pagination Style Controls | |
| 1396 | + $this->register_pagination_controls(); | |
| 1359 | 1397 | } |
| 1360 | 1398 | |
| 1361 | 1399 | public function render() { |
| 1362 | 1400 | $settings = $this->get_settings_for_display(); |
| 1363 | 1401 | |
| 1402 | + $min_published_posts = isset($settings['min_published_posts']['size']) ? absint($settings['min_published_posts']['size']) : 0; | |
| 1403 | + $item_limit = (int) $settings['item_limit']['size']; | |
| 1404 | + $show_pagination = !empty($settings['show_pagination']); | |
| 1405 | + | |
| 1406 | + $number = ($min_published_posts > 0 || $show_pagination) ? -1 : $item_limit; | |
| 1407 | + | |
| 1364 | 1408 | $users = get_users([ |
| 1365 | 1409 | 'orderby' => $settings['orderby'], |
| 1366 | 1410 | 'order' => $settings['order'], |
| 1367 | 1411 | 'role__in' => (!empty($settings['role'])) ? $settings['role'] : null, |
| 1368 | - 'number' => $settings['item_limit']['size'], | |
| 1369 | - 'exclude' => explode(',', esc_attr($settings["exclude"])), | |
| 1412 | + 'number' => $number, | |
| 1413 | + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Elementor widget query built from user-configured controls; expected behaviour. | |
| 1414 | + 'exclude' => array_filter(array_map('absint', explode(',', esc_attr($settings['exclude'])))), | |
| 1370 | 1415 | ]); |
| 1371 | 1416 | |
| 1372 | - $social_links = $settings['social_links']; | |
| 1417 | + if ($min_published_posts > 0) { | |
| 1418 | + $users = array_filter($users, function ($user) use ($min_published_posts) { | |
| 1419 | + return count_user_posts($user->ID) >= $min_published_posts; | |
| 1420 | + }); | |
| 1421 | + $users = array_values($users); | |
| 1422 | + } | |
| 1373 | 1423 | |
| 1424 | + $total_users = count($users); | |
| 1425 | + $total_pages = $item_limit > 0 ? (int) ceil($total_users / $item_limit) : 1; | |
| 1426 | + $paged = max(1, (int) get_query_var('paged'), (int) get_query_var('page')); | |
| 1427 | + | |
| 1428 | + if ($show_pagination) { | |
| 1429 | + $offset = ($paged - 1) * $item_limit; | |
| 1430 | + $users = array_slice($users, $offset, $item_limit); | |
| 1431 | + } else { | |
| 1432 | + $users = array_slice($users, 0, $item_limit); | |
| 1433 | + } | |
| 1434 | + | |
| 1435 | + // Elementor stores control values verbatim, so the saved list must be checked | |
| 1436 | + // against the control's own options before any value is used as a user field name. | |
| 1437 | + $allowed_links = array_keys(ultimate_post_kit_user_contact_methods([], true)); | |
| 1438 | + $social_links = array_values(array_filter((array) $settings['social_links'], function ($link) use ($allowed_links) { | |
| 1439 | + return is_string($link) && in_array($link, $allowed_links, true); | |
| 1440 | + })); | |
| 1441 | + | |
| 1374 | 1442 | ?> |
| 1375 | 1443 | <div class="upk-author"> |
| 1376 | - <div class="upk-author-wrapper upk-<?php echo esc_html($settings['layout_style']) ?>"> | |
| 1444 | + <div class="upk-author-wrapper upk-<?php echo esc_attr($settings['layout_style']) ?>"> | |
| 1377 | 1445 | <?php |
| 1378 | 1446 | foreach ($users as $author) { |
| 1379 | 1447 | |
| 1380 | 1448 | ?> |
| @@ -1391,10 +1459,10 @@ | ||
| 1391 | 1459 | |
| 1392 | 1460 | <div class="upk-content"> |
| 1393 | 1461 | <?php if ($settings['show_author_name']) : ?> |
| 1394 | 1462 | <div class="upk-name"> |
| 1395 | - <a href="<?php echo get_bloginfo('url') . "/?author=" . esc_attr($author->ID); ?>"> | |
| 1396 | - <?php echo get_the_author_meta('display_name', $author->ID); ?> | |
| 1463 | + <a href="<?php echo esc_url(get_author_posts_url($author->ID)); ?>"> | |
| 1464 | + <?php echo esc_html(get_the_author_meta('display_name', $author->ID)); ?> | |
| 1397 | 1465 | </a> |
| 1398 | 1466 | </div> |
| 1399 | 1467 | <?php endif; ?> |
| 1400 | 1468 | |
| @@ -1399,15 +1467,15 @@ | ||
| 1399 | 1467 | <?php endif; ?> |
| 1400 | 1468 | |
| 1401 | 1469 | <?php if ($settings['show_author_role']) : ?> |
| 1402 | 1470 | <div class="upk-role"> |
| 1403 | - <?php echo ucwords(get_user_role($author->ID)); ?> | |
| 1471 | + <?php echo esc_html( get_user_role( $author->ID ) ); ?> | |
| 1404 | 1472 | </div> |
| 1405 | 1473 | <?php endif; ?> |
| 1406 | 1474 | |
| 1407 | 1475 | <?php if ($settings['show_author_description'] and get_the_author_meta('description', $author->ID)) : ?> |
| 1408 | 1476 | <div class="upk-description"> |
| 1409 | - <?php echo get_the_author_meta('description', $author->ID); ?> | |
| 1477 | + <?php echo wp_kses_post(get_the_author_meta('description', $author->ID)); ?> | |
| 1410 | 1478 | </div> |
| 1411 | 1479 | <?php endif; ?> |
| 1412 | 1480 | |
| 1413 | 1481 | <?php if ($settings['show_author_link'] and !empty($social_links)) : ?> |
| @@ -1429,9 +1497,9 @@ | ||
| 1429 | 1497 | } |
| 1430 | 1498 | |
| 1431 | 1499 | ?> |
| 1432 | 1500 | |
| 1433 | - <a href="<?php echo esc_url($final_url); ?>" title="<?php echo esc_html($alt_title); ?>"> | |
| 1501 | + <a href="<?php echo esc_url($final_url); ?>" title="<?php echo esc_attr($alt_title); ?>"> | |
| 1434 | 1502 | <i class="upk-icon-<?php echo esc_attr($link); ?>" aria-hidden="true"></i> |
| 1435 | 1503 | </a> |
| 1436 | 1504 | <?php endif; ?> |
| 1437 | 1505 | |
| @@ -1461,7 +1529,18 @@ | ||
| 1461 | 1529 | </div> |
| 1462 | 1530 | <?php } ?> |
| 1463 | 1531 | </div> |
| 1464 | 1532 | </div> |
| 1533 | + | |
| 1534 | + <?php if ($show_pagination && $total_pages > 1) : ?> | |
| 1535 | + <div class="ep-pagination"> | |
| 1536 | + <?php | |
| 1537 | + $author_pagination_query = new \stdClass(); | |
| 1538 | + $author_pagination_query->max_num_pages = $total_pages; | |
| 1539 | + $author_pagination_query->query_vars = ['paged' => $paged, 'page' => $paged]; | |
| 1540 | + ultimate_post_kit_post_pagination($author_pagination_query, $this->get_id()); | |
| 1541 | + ?> | |
| 1542 | + </div> | |
| 1543 | + <?php endif; ?> | |
| 1465 | 1544 | <?php |
| 1466 | 1545 | } |
| 1467 | 1546 | } |