PluginProbe ʕ •ᴥ•ʔ
Royal Addons for Elementor – Addons and Templates Kit for Elementor / 1.7.1064
Royal Addons for Elementor – Addons and Templates Kit for Elementor v1.7.1064
1.7.1064 1.7.1063 1.7.1062 1.7.1061 1.7.1060 1.7.1059 1.7.1058 trunk 1.0.0 1.1.0 1.2 1.3 1.3.1 1.3.2 1.3.21 1.3.22 1.3.23 1.3.24 1.3.25 1.3.26 1.3.27 1.3.28 1.3.29 1.3.30 1.3.31 1.3.32 1.3.33 1.3.34 1.3.35 1.3.36 1.3.37 1.3.38 1.3.39 1.3.40 1.3.41 1.3.42 1.3.43 1.3.44 1.3.45 1.3.46 1.3.47 1.3.48 1.3.49 1.3.50 1.3.51 1.3.52 1.3.53 1.3.54 1.3.55 1.3.56 1.3.57 1.3.58 1.3.59 1.3.60 1.3.61 1.3.62 1.3.63 1.3.64 1.3.65 1.3.66 1.3.67 1.3.68 1.3.69 1.3.70 1.3.71 1.3.72 1.3.73 1.3.74 1.3.75 1.3.76 1.3.77 1.3.78 1.3.79 1.3.80 1.3.81 1.3.82 1.3.83 1.3.84 1.3.85 1.3.86 1.3.87 1.3.88 1.3.89 1.3.90 1.3.91 1.3.92 1.3.93 1.3.94 1.3.95 1.3.96 1.3.97 1.3.971 1.3.972 1.3.973 1.3.974 1.3.975 1.3.976 1.3.977 1.3.978 1.3.979 1.3.980 1.3.981 1.3.982 1.3.983 1.3.984 1.3.985 1.3.986 1.3.987 1.7.1 1.7.1001 1.7.1002 1.7.1003 1.7.1004 1.7.1005 1.7.1006 1.7.1007 1.7.1008 1.7.1009 1.7.1010 1.7.1011 1.7.1012 1.7.1013 1.7.1014 1.7.1015 1.7.1016 1.7.1017 1.7.1018 1.7.1019 1.7.1020 1.7.1021 1.7.1022 1.7.1023 1.7.1024 1.7.1025 1.7.1026 1.7.1027 1.7.1028 1.7.1029 1.7.1030 1.7.1031 1.7.1032 1.7.1033 1.7.1034 1.7.1035 1.7.1036 1.7.1037 1.7.1038 1.7.1039 1.7.1040 1.7.1041 1.7.1042 1.7.1043 1.7.1044 1.7.1045 1.7.1046 1.7.1047 1.7.1048 1.7.1049 1.7.1050 1.7.1051 1.7.1052 1.7.1053 1.7.1054 1.7.1055 1.7.1056 1.7.1057
royal-elementor-addons / classes / modules / wpr-grid-helpers.php
royal-elementor-addons / classes / modules Last commit date
forms 5 days ago wpr-ajax-search.php 5 days ago wpr-filter-grid-media.php 5 days ago wpr-form-handlers.php 5 days ago wpr-grid-helpers.php 5 days ago wpr-load-more-instagram-posts.php 5 days ago wpr-load-more-tweets.php 5 days ago wpr-post-likes.php 5 days ago wpr-woo-grid-helpers.php 5 days ago
wpr-grid-helpers.php
2189 lines
1 <?php
2 namespace WprAddons\Classes\Modules;
3
4 use Elementor\Utils;
5 use Elementor\Group_Control_Image_Size;
6 use WprAddons\Classes\Utilities;
7 use WprAddons\Classes\Modules\WPR_Post_Likes;
8
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit; // Exit if accessed directly.
12 }
13
14 /**
15 * WPR_Grid_Helpers setup
16 *
17 * @since 3.4.6
18 */
19
20 class WPR_Grid_Helpers {
21
22 public function __construct() {
23 add_action('wp_ajax_wpr_grid_filters_ajax', [$this, 'wpr_grid_filters_ajax']);
24 add_action('wp_ajax_nopriv_wpr_grid_filters_ajax', [$this, 'wpr_grid_filters_ajax']);
25 add_action('wp_ajax_wpr_get_filtered_count_posts', [$this, 'wpr_get_filtered_count_posts']);
26 add_action('wp_ajax_nopriv_wpr_get_filtered_count_posts', [$this, 'wpr_get_filtered_count_posts']);
27 add_action('wp_ajax_wpr_get_dependent_terms', [$this, 'get_dependent_terms']);
28 add_action('wp_ajax_nopriv_wpr_get_dependent_terms', [$this, 'get_dependent_terms']);
29 }
30
31 public function get_dependent_terms() {
32
33 if ( empty($_POST['taxonomy']) || empty($_POST['parent_term']) ) {
34 wp_send_json_error('Missing data');
35 }
36
37 $taxonomy = sanitize_text_field($_POST['taxonomy']);
38 $parent_raw = sanitize_text_field($_POST['parent_term']);
39
40 // Determine if parent_term is ID or slug
41 if ( is_numeric($parent_raw) ) {
42 $related_term = get_term(intval($parent_raw));
43 } else {
44 // Optional: detect the related taxonomy (requires an extra POST param or default)
45 $related_taxonomy = sanitize_text_field($_POST['related_taxonomy'] ?? '');
46 if ( empty($related_taxonomy) ) {
47 wp_send_json_error('Missing related taxonomy for slug');
48 }
49 $related_term = get_term_by('slug', $parent_raw, $related_taxonomy);
50 }
51
52 if ( ! $related_term || is_wp_error($related_term) ) {
53 wp_send_json_error('Invalid parent term');
54 }
55
56 $related_taxonomy = $related_term->taxonomy;
57 $tax_array = [];
58
59 if ( isset($_POST['tax_array']) ) {
60 $related_taxonomies = $_POST['tax_array'];
61 $related_terms = $_POST['parent_terms'];
62
63 // Add relation AND
64 $tax_array['relation'] = 'AND';
65
66 foreach ( $related_taxonomies as $index => $tax ) {
67 if ( isset($related_terms[$index]) && $related_terms[$index] !== '' ) {
68 $tax_array[] = [
69 'taxonomy' => sanitize_text_field($tax),
70 'field' => 'term_id',
71 'terms' => intval($related_terms[$index]),
72 ];
73 }
74 }
75 } else {
76 $tax_array[] = [
77 'taxonomy' => $related_taxonomy,
78 'field' => 'term_id',
79 'terms' => $related_term->term_id,
80 ];
81 }
82
83 // Get all posts with the related term
84 $posts = get_posts([
85 'post_type' => 'any',
86 'posts_per_page' => -1,
87 'tax_query' => $tax_array,
88 'fields' => 'ids',
89 ]);
90
91 if ( empty($posts) ) {
92 wp_send_json_success([]);
93 }
94
95 // Get all terms from the target taxonomy used in these posts
96 $terms = wp_get_object_terms($posts, $taxonomy, [
97 'hide_empty' => true,
98 ]);
99
100 $options = [];
101 foreach ( $terms as $term ) {
102 $options[] = [
103 'id' => $term->term_id,
104 'name' => $term->name,
105 // 'posts' => $posts,
106 // 'related_tax' => $related_taxonomy,
107 // 'related_term' => $related_term->slug,
108 // 'taxonomy' => $taxonomy,
109 ];
110 }
111
112 wp_send_json_success($options);
113 }
114
115 // Get Taxonomies Related to Post Type
116 public static function get_related_taxonomies() {
117 $relations = [];
118 $post_types = Utilities::get_custom_types_of( 'post', false );
119
120 foreach ( $post_types as $slug => $title ) {
121 $relations[$slug] = [];
122
123 foreach ( get_object_taxonomies( $slug ) as $tax ) {
124 array_push( $relations[$slug], $tax );
125 }
126 }
127
128 return json_encode( $relations );
129 }
130
131 // Get Max Pages
132 public static function get_max_num_pages( $settings ) {
133 if ( isset($_POST['wpr_url_params']) ) {
134 $query = new \WP_Query( WPR_Grid_Helpers::get_main_query_args($settings, []) );
135 $max_num_pages = intval( ceil( $query->max_num_pages ) );
136
137 // Reset
138 wp_reset_postdata();
139
140 // $max_num_pages
141 return $max_num_pages;
142 } else if ( isset($_POST['grid_settings']) ) {
143 $query = new \WP_Query(WPR_Grid_Helpers::get_main_query_args($settings, []) );
144 $max_num_pages = intval( ceil( $query->max_num_pages ) );
145
146 $adjustedTotalPosts = max(0, $query->found_posts - $query->query_vars['offset']); // Ensuring it doesn't go below 0
147 $numberOfPages = ceil($adjustedTotalPosts / $query->query_vars['posts_per_page']);
148
149 wp_send_json_success([
150 'page_count' => $numberOfPages,
151 'max_num_pages' => $max_num_pages,
152 'query_found' => $query->found_posts,
153 'post_count' => $query->post_count,
154 'query_offset' => $query->query_vars['offset'],
155 'query_num' => $query->query_vars['posts_per_page']
156 ]);
157
158 // Reset
159 wp_reset_postdata();
160
161 // $max_num_pages
162 return $max_num_pages;
163 } else {
164 $query = new \WP_Query( WPR_Grid_Helpers::get_main_query_args($settings, []) );
165 $max_num_pages = intval( ceil( $query->max_num_pages ) );
166
167 // Reset
168 wp_reset_postdata();
169
170 // $max_num_pages
171 return $max_num_pages;
172 }
173 }
174
175 /**
176 * Check if the current user is allowed to query the post type(s) in grid settings.
177 * Prevents unauthenticated disclosure of non-public post types (e.g. flamingo_inbound, shop_coupon).
178 *
179 * @param array $settings Grid settings (e.g. $_POST['grid_settings']).
180 * @return bool True if allowed, false otherwise.
181 */
182 public static function is_allowed_grid_query_post_type( $settings ) {
183 if ( empty( $settings ) || ! is_array( $settings ) ) {
184 return false;
185 }
186
187 $query_source = isset( $settings['query_source'] ) ? $settings['query_source'] : '';
188
189 // Resolve effective post type(s) to validate
190 if ( 'current' === $query_source && ! empty( $settings['current_query_source'] ) ) {
191 $post_types = (array) $settings['current_query_source'];
192 } elseif ( 'related' !== $query_source && '' !== $query_source ) {
193 $post_types = (array) $query_source;
194 } else {
195 // 'related' uses get_post_type(get_the_ID()) in get_main_query_args; no user-controlled type
196 return true;
197 }
198
199 $is_logged_in = is_user_logged_in();
200
201 // For unauthenticated requests, only allow post types that are publicly queryable
202 if ( ! $is_logged_in ) {
203 $allowed_types = get_post_types( array( 'publicly_queryable' => true ), 'names' );
204 foreach ( $post_types as $post_type ) {
205 $post_type = sanitize_key( $post_type );
206 if ( '' === $post_type ) {
207 continue;
208 }
209 if ( ! in_array( $post_type, $allowed_types, true ) ) {
210 return false;
211 }
212 }
213 return true;
214 }
215
216 // Logged-in: allow if publicly_queryable OR user has capability to read that post type
217 foreach ( $post_types as $post_type ) {
218 $post_type = sanitize_key( $post_type );
219 if ( '' === $post_type ) {
220 continue;
221 }
222 $obj = get_post_type_object( $post_type );
223 if ( ! $obj ) {
224 return false;
225 }
226 if ( $obj->publicly_queryable ) {
227 continue;
228 }
229 $cap = isset( $obj->cap->read_private_posts ) ? $obj->cap->read_private_posts : 'read';
230 if ( ! current_user_can( $cap ) ) {
231 return false;
232 }
233 }
234 return true;
235 }
236
237 // Main Query Args
238 public static function get_main_query_args($settings, $params) {
239 $author = ! empty( $settings[ 'query_author' ] ) ? implode( ',', $settings[ 'query_author' ] ) : '';
240
241 // if ( is_user_logged_in() ){
242 // $logged_in_user = wp_get_current_user();
243 // $author = '1' . ',' . $logged_in_user->ID;
244 // }
245
246 // Get Paged
247 if ( get_query_var( 'paged' ) ) {
248 $paged = get_query_var( 'paged' );
249 } elseif ( get_query_var( 'page' ) ) {
250 $paged = get_query_var( 'page' );
251 } else {
252 $paged = 1;
253 }
254
255 // Change Posts Per Page for Slider Layout
256 if ( 'slider' === $settings['layout_select'] && Utilities::is_new_free_user() ) {
257 $settings['query_posts_per_page'] = $settings['query_slides_to_show'] ? $settings['query_slides_to_show'] : -1;
258 $settings['query_posts_per_page'] = $settings['query_posts_per_page'] > 4 ? 4 : $settings['query_posts_per_page'];
259 }
260
261 if ( 'slider' === $settings['layout_select'] ) {
262 $paged = 1;
263 }
264
265 if ( empty($settings['query_offset']) ) {
266 $settings[ 'query_offset' ] = 0;
267 }
268
269 $offset = ( $paged - 1 ) * intval($settings['query_posts_per_page']) + intval($settings[ 'query_offset' ]);
270
271 if ( empty($settings['query_posts_per_page']) ) {
272 if ( !('slider' === $settings['layout_select'] && Utilities::is_new_free_user()) ) {
273 $settings['query_posts_per_page'] = 999;
274 }
275 }
276
277 if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
278 $settings[ 'query_randomize' ] = '';
279 $settings['order_posts'] = 'date';
280 }
281
282 $query_order_by = '' != $settings['query_randomize'] ? $settings['query_randomize'] : $settings['order_posts'];
283 $post__not_in = isset($settings[ 'query_exclude_'. $settings[ 'query_source' ] ]) && !empty($settings[ 'query_exclude_'. $settings[ 'query_source' ] ]) ? $settings[ 'query_exclude_'. $settings[ 'query_source' ] ] : [];
284
285 // Dynamic
286 $args = [
287 'post_type' => $settings[ 'query_source' ],
288 'tax_query' => WPR_Grid_Helpers::get_tax_query_args($settings),
289 'post__not_in' => $post__not_in,
290 'posts_per_page' => $settings['query_posts_per_page'],
291 'orderby' => $query_order_by,
292 'author' => $author,
293 'paged' => $paged,
294 'offset' => $offset
295 ];
296
297 // if ( isset($_POST['wpr_item_length']) ) {
298 // $args['posts_per_page'] == $_POST['wpr_item_length'];
299 // } check before uncomenting (may conflict)
300
301 if ( $query_order_by == 'meta_value' ) {
302 $args['meta_key'] = $settings['order_posts_by_acf'];
303 }
304
305 // Display Scheduled Posts
306 if ( 'yes' === $settings['display_scheduled_posts'] && (defined('WPR_ADDONS_PRO_VERSION') && wpr_fs()->can_use_premium_code()) ) {
307 $args['post_status'] = 'future';
308 } else {
309 $args['post_status'] = 'publish';
310 }
311
312 // Exclude Items without F/Image
313 if ( 'yes' === $settings['query_exclude_no_images'] ) {
314 $args['meta_key'] = '_thumbnail_id';
315 }
316
317 // Manual
318 if ( 'manual' === $settings[ 'query_selection' ] ) {
319 $post_ids = [''];
320
321 if ( ! empty($settings[ 'query_manual_'. $settings[ 'query_source' ] ]) ) {
322 $post_ids = $settings[ 'query_manual_'. $settings[ 'query_source' ] ];
323 }
324
325 $args = [
326 'post_type' => $settings[ 'query_source' ],
327 'post__in' => $post_ids,
328 'ignore_sticky_posts' => 1,
329 'posts_per_page' => $settings['query_posts_per_page'],
330 'orderby' => $query_order_by,
331 'paged' => $paged,
332 ];
333 }
334
335 // Current
336 if ( 'current' === $settings[ 'query_source' ] ) {
337 global $wp_query;
338
339 $tax_query = [];
340
341 $args = $wp_query->query_vars;
342
343 if ( is_post_type_archive() ) {
344 $posts_per_page = intval(get_option('wpr_cpt_ppp_'. $args['post_type']), 10);
345 } else {
346 $posts_per_page = intval(get_option('posts_per_page'));
347 }
348
349 if ( isset($settings['current_query_source']) ) {
350 $args['post_type'] = $settings['current_query_source'];
351 if ( $args['post_type'] != 'post' ) {
352 $posts_per_page = intval(get_option('wpr_cpt_ppp_'. $args['post_type']), 10);
353 $args['posts_per_page'] = $posts_per_page;
354 }
355 }
356
357 $args['orderby'] = $query_order_by;
358
359 $args['offset'] = ( $paged - 1 ) * $posts_per_page + intval($settings[ 'query_offset' ]);
360
361 if ( isset($_GET['category']) ) {
362
363 if ( $_GET['category'] != '0' ) {
364 // Get category from URL
365 $category = sanitize_text_field($_GET['category']);
366
367 array_push( $tax_query, [
368 'taxonomy' => 'category',
369 'field' => 'id',
370 'terms' => $category
371 ] );
372 }
373 }
374
375 if ( isset($_GET['wpr_select_category']) ) {
376
377 if ( $_GET['wpr_select_category'] != '0' ) {
378 // Get category from URL
379 $category = sanitize_text_field($_GET['wpr_select_category']);
380 $taxonomy_name = 'category';
381
382 $term = get_term($category);
383
384 // Check if the term is valid
385 if (!is_wp_error($term)) {
386 // Get the taxonomy name
387 $taxonomy_name = $term->taxonomy;
388 }
389
390 array_push( $tax_query, [
391 'taxonomy' => $taxonomy_name,
392 'field' => 'id',
393 'terms' => $category
394 ] );
395 }
396 }
397 // Get category from URL (CHECK BELOW FOR FILTERS)
398
399 if ( !empty($tax_query) ) {
400 $args['tax_query'] = $tax_query;
401 }
402 }
403
404 // Related
405 if ( 'related' === $settings[ 'query_source' ] ) {
406 $args = [
407 'post_type' => get_post_type( get_the_ID() ),
408 'tax_query' => WPR_Grid_Helpers::get_tax_query_args($settings),
409 'post__not_in' => [ get_the_ID() ],
410 'ignore_sticky_posts' => 1,
411 'posts_per_page' => $settings['query_posts_per_page'],
412 'orderby' => $query_order_by,
413 'offset' => $offset,
414 ];
415 }
416
417 if ( 'rand' !== $query_order_by ) {
418 $args['order'] = $settings['order_direction'];
419 }
420
421 if ( isset($_POST['wpr_offset']) ) { // Check if causes issues with grid itself
422 $args['offset'] = $_POST['wpr_offset'];
423 }
424
425 if ( !isset($args['tax_query']) ) {
426 $args['tax_query'] = [];
427 }
428
429 if ( isset($_POST['wpr_taxonomy'] ) ) {
430 $settings = $_POST['grid_settings'];
431 $taxonomy = $_POST['wpr_taxonomy'];
432 $term = $_POST['wpr_filter'];
433 $tax_query = [];
434
435 if ( $term != '*' ) {
436 if ( 'tag' === $taxonomy ) {
437 $taxonomy = 'post_' . $_POST['wpr_taxonomy'];
438 }
439 array_push( $tax_query, [
440 'taxonomy' => $taxonomy,
441 'field' => 'slug',
442 'terms' => $term
443 ] );
444 }
445
446 if ( !empty($tax_query) ) {
447 $args['tax_query'] = $tax_query;
448 }
449
450 if ( isset($_POST['wpr_offset']) ) {
451 $args['offset'] = $_POST['wpr_offset'];
452 }
453
454 return $args;
455 }
456
457 if ( isset($args['tax_query']) ) {
458
459 $tax_query = ['relation' => 'AND'];
460 $meta_query = ['relation' => 'AND'];
461
462 $prev_cleaned_key = '';
463
464 $wpr_url_params = isset($params) && !empty($params) ? $params : (isset($_POST['wpr_url_params']) ? $_POST['wpr_url_params'] : []);
465
466 if ( empty($wpr_url_params) && isset($_GET) && !empty($_GET) ) {
467 $wpr_url_params = $_GET;
468 }
469
470 if ( isset($wpr_url_params) && !empty($wpr_url_params) ) {
471 // Iterate through the POST array
472 foreach ( $wpr_url_params as $key => $value ) {
473
474 // Check if the variable name contains "wpr_af_"
475 if (strpos($key, 'wpr_af_') !== false) {
476
477 // Need to setup logic to get relation from filters separately
478 $cleanedKey = str_replace('wpr_af_', '', $key);
479 $prev_cleaned_key = $cleanedKey;
480
481 if ( isset($wpr_url_params[$key]) ) {
482 if ( $cleanedKey == 'date_range' ) {
483 $date = $wpr_url_params[$key];
484
485 $args['date_query'] = [];
486
487 if ( str_contains($date, ',') ) {
488 $date = explode(',', $date);
489
490 if (false) {
491 $args['date_query'] = ['relation' => 'or'];
492
493 list($year1, $month1, $day1) = explode("-", $date[0]);
494 list($year2, $month2, $day2) = explode("-", $date[1]);
495
496 array_push( $args['date_query'], [
497 'year' => $year1,
498 'month' => $month1,
499 'day' => $day1,
500 ] );
501
502 array_push( $args['date_query'], [
503 'year' => $year2,
504 'month' => $month2,
505 'day' => $day2,
506 ] );
507
508 } else {
509 array_push( $args['date_query'], [
510 'after' => $date[0],
511 'before' => $date[1],
512 'inclusive' => true
513 ] );
514 }
515 }
516 } elseif ( $cleanedKey == 'date' ) {
517
518 $date = $wpr_url_params[$key];
519
520 $args['date_query'] = [];
521
522 if ( str_contains($date, '-') && explode("-", $date) ) {
523 list($year, $month, $day) = explode("-", $date);
524
525 array_push( $args['date_query'], [
526 'year' => $year,
527 'month' => $month,
528 'day' => $day,
529 ]);
530 }
531 } else {
532 if ( $wpr_url_params[$key] != '0' ) {
533 // Get category from URL
534 if ( str_contains($wpr_url_params[$key], ',') ) {
535
536 // Example usage
537 $key_type = WPR_Grid_Helpers::identify_key_type($cleanedKey);
538 $filtervalues = explode(',', $wpr_url_params[$key]);
539
540 if ( ('meta_field' == $key_type || 'custom_field' == $key_type) ) {
541 if ( is_numeric($filtervalues[0]) && isset($wpr_url_params['wpr_aft_' . $cleanedKey]) && $wpr_url_params['wpr_aft_' . $cleanedKey] == 'range' ) {
542 $minValue = min(array_values($filtervalues));
543 $maxValue = max(array_values($filtervalues));
544
545 if ( isset($meta_query) ) {
546 array_push($meta_query, [
547 [
548 'key' => $cleanedKey,
549 'value' => [$minValue, $maxValue],
550 'type' => 'NUMERIC',
551 'compare' => 'BETWEEN',
552 ],
553 ]);
554 } else {
555 $meta_query = [
556 [
557 'key' => $cleanedKey,
558 'value' => [$minValue, $maxValue],
559 'type' => 'NUMERIC',
560 'compare' => 'BETWEEN',
561 ],
562 ];
563 }
564 } else {
565 if ( isset($meta_query) ) {
566 if ( isset($_POST['wpr_afr_' . $cleanedKey]) && !empty(explode(',', $_POST['wpr_afr_'. $cleanedKey])[0]) ) {
567 $meta_relation = explode(',', $_POST['wpr_afr_'. $cleanedKey])[0];
568 } else if ( isset($wpr_url_params['wpr_afr_'. $cleanedKey]) && !empty(explode(',', $wpr_url_params['wpr_afr_'. $cleanedKey])[0]) ) {
569 $meta_relation = explode(',', $wpr_url_params['wpr_afr_'. $cleanedKey])[0];
570 } else {
571 $meta_relation = '';
572 }
573
574 $for_meta_query = [ // needs check if overrides somethings
575 'relation' => $meta_relation,
576 ];
577
578 foreach ($filtervalues as $filtervalue) {
579 $filtervalue = sanitize_text_field($filtervalue);
580
581 array_push($for_meta_query, [
582 [
583 'key' => $cleanedKey,
584 'value' => $filtervalue
585 ],
586 ]);
587 }
588
589 array_push( $meta_query, $for_meta_query );
590 } else {
591 $meta_query = [ // needs check if overrides something
592 'relation' => explode(',', $_POST['wpr_afr_'. $cleanedKey])[0] ? explode(',', $_POST['wpr_afr_'. $cleanedKey])[0] : explode(',', $wpr_url_params['wpr_afr_'. $cleanedKey])[0],
593 ];
594
595 if (is_array($filtervalues)) {
596 foreach ($filtervalues as $filtervalue) {
597 $meta_query[] = [
598 'key' => $cleanedKey,
599 'value' => $filtervalue,
600 'compare' => '=',
601 ];
602 }
603 }
604 }
605 }
606 } else { // if != 'meta_field'
607 // if ( isset($_POST['wpr_afr_'. $cleanedKey]) ) {
608 $for_tax_query = [ // needs check if overrides something
609 // 'relation' => isset($_POST['wpr_afr_' . $cleanedKey]) && !empty(explode(',', $_POST['wpr_afr_' . $cleanedKey])[0]) ? explode(',', $_POST['wpr_afr_' . $cleanedKey])[0] : '',
610 'relation' => isset($wpr_url_params['wpr_afr_' . $cleanedKey]) && !empty(explode(',', $wpr_url_params['wpr_afr_' . $cleanedKey])[0]) ? explode(',', $wpr_url_params['wpr_afr_' . $cleanedKey])[0] : '',
611 ];
612 // } else {
613 // $for_tax_query = [];
614 // }
615
616 foreach ($filtervalues as $filtervalue) {
617 $filtervalue = sanitize_text_field($filtervalue);
618
619 array_push( $for_tax_query, [
620 'taxonomy' => $cleanedKey,
621 'field' => 'id',
622 'terms' => $filtervalue
623 ] );
624 }
625
626 array_push($tax_query, $for_tax_query);
627 }
628 } else { // not str_contains($wpr_url_params[$key], ',')
629 $key_type = WPR_Grid_Helpers::identify_key_type($cleanedKey);
630 $filtervalues = sanitize_text_field($wpr_url_params[$key]);
631
632 if ( $key_type == 'meta_field' || $key_type == 'custom_field' ) {
633 if ( isset($meta_query) ) {
634 array_push($meta_query, [
635 [
636 'key' => $cleanedKey,
637 'value' => [$filtervalues],
638 // 'type' => 'NUMERIC',
639 // 'compare' => 'BETWEEN',
640 ],
641 ]);
642 } else {
643 $meta_query = [
644 [
645 'key' => $cleanedKey,
646 'value' => [$filtervalues],
647 // 'type' => 'NUMERIC',
648 // 'compare' => 'BETWEEN',
649 ],
650 ];
651 }
652 } else {
653 if (isset($wpr_url_params[$key])) {
654
655 array_push( $tax_query, [
656 'taxonomy' => $cleanedKey,
657 'field' => 'id',
658 'terms' => $filtervalues
659 ] );
660 }
661 }
662 }
663 }
664 }
665 }
666 }
667 }
668
669 if ( !empty($tax_query) ) {
670 if ( !empty($args['tax_query']) ) {
671 $args['tax_query'] = array_merge( $args['tax_query'], $tax_query );
672 } else {
673 $args['tax_query'] = $tax_query;
674 }
675 }
676
677 if ( !empty($meta_query) ) {
678 if ( !empty($args['meta_query']) ) {
679 $args['tax_query'] = array_merge( $args['tax_query'], $tax_query );
680 } else {
681 $args['meta_query'] = $meta_query;
682 }
683 }
684 }
685 }
686
687 return $args;
688 }
689
690 public static function identify_key_type($key) {
691 // Check if it's a built-in taxonomy
692 $builtin_taxonomies = array('category', 'post_tag'); // Add more if needed
693 if (in_array($key, $builtin_taxonomies)) {
694 return 'taxonomy';
695 }
696
697 // Check if it's a custom taxonomy
698 $custom_taxonomies = get_taxonomies(['_builtin' => false]);
699 if (in_array($key, $custom_taxonomies)) {
700 return 'taxonomy';
701 }
702
703 // Check if it's a custom field key - WHY?
704 $custom_field_keys = get_post_custom_keys();
705 if ( is_array($custom_field_keys) && in_array($key, $custom_field_keys) ) {
706 return 'custom_field';
707 }
708
709 // Add more checks if needed...
710
711 // If none of the checks match, assume it's a meta field
712 return 'meta_field';
713 }
714
715 // Taxonomy Query Args
716 public static function get_tax_query_args($settings) {
717 $settings = $settings;
718 $tax_query = [];
719
720 if ( isset($_POST['wpr_taxonomy']) ) {
721 $taxonomy = $_POST['wpr_taxonomy'];
722 $term = $_POST['wpr_filter'];
723
724 if ( $term != '*' ) {
725 if ( 'tag' === $taxonomy ) {
726 $taxonomy = 'post_' . $_POST['wpr_taxonomy'];
727 }
728 array_push( $tax_query, [
729 'taxonomy' => $taxonomy,
730 'field' => 'slug',
731 'terms' => $term
732 ] );
733 }
734 }
735
736 if ( 'related' === $settings[ 'query_source' ] ) {
737 $tax_query = [
738 [
739 'taxonomy' => $settings['query_tax_selection'],
740 'field' => 'term_id',
741 'terms' => wp_get_object_terms( get_the_ID(), $settings['query_tax_selection'], array( 'fields' => 'ids' ) ),
742 ]
743 ];
744 } else {
745 foreach ( get_object_taxonomies($settings[ 'query_source' ]) as $tax ) {
746 if ( ! empty($settings[ 'query_taxonomy_'. $tax ]) ) {
747 array_push( $tax_query, [
748 'taxonomy' => $tax,
749 'field' => 'id',
750 'terms' => $settings[ 'query_taxonomy_'. $tax ]
751 ] );
752 }
753 }
754 }
755
756 return $tax_query;
757 }
758
759 // Get Animation Class
760 public static function get_animation_class( $data, $object ) {
761 $class = '';
762
763 // Disable Animation on Mobile
764 if ( 'overlay' !== $object ) {
765 if ( 'yes' === $data[$object .'_animation_disable_mobile'] && wp_is_mobile() ) {
766 return $class;
767 }
768 }
769
770 // Animation Class
771 if ( 'none' !== $data[ $object .'_animation'] ) {
772 $class .= ' wpr-'. $object .'-'. $data[ $object .'_animation'];
773 $class .= ' wpr-anim-size-'. $data[ $object .'_animation_size'];
774 $class .= ' wpr-anim-timing-'. $data[ $object .'_animation_timing'];
775
776 if ( 'yes' === $data[ $object .'_animation_tr'] ) {
777 $class .= ' wpr-anim-transparency';
778 }
779 }
780
781 return $class;
782 }
783
784 // Get Image Effect Class
785 public static function get_image_effect_class( $settings ) {
786 $class = '';
787
788 if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
789 if ( 'pro-zi' == $settings['image_effects'] || 'pro-zo' == $settings['image_effects'] || 'pro-go' == $settings['image_effects'] || 'pro-bo' == $settings['image_effects'] ) {
790 $settings['image_effects'] = 'none';
791 }
792 }
793
794 // Animation Class
795 if ( 'none' !== $settings['image_effects'] ) {
796 $class .= ' wpr-'. $settings['image_effects'];
797 }
798
799 // Slide Effect
800 if ( 'slide' !== $settings['image_effects'] ) {
801 $class .= ' wpr-effect-size-'. $settings['image_effects_size'];
802 } else {
803 $class .= ' wpr-effect-dir-'. $settings['image_effects_direction'];
804 }
805
806 return $class;
807 }
808
809 /**
810 * URL used for grid featured image overlay and title links (and any other post-level links using this helper).
811 *
812 * @param array $settings Widget settings.
813 * @param int|null $post_id Post ID; defaults to the current post in the loop.
814 * @return string Unescaped URL string suitable for esc_url() / esc_attr() when outputting.
815 */
816 public static function get_grid_item_link_url( $settings, $post_id = null ) {
817 if ( null === $post_id ) {
818 $post_id = get_the_ID();
819 }
820
821 if ( ! is_array( $settings ) ) {
822 $settings = [];
823 }
824
825 $permalink = get_permalink( $post_id );
826
827 if ( empty( $settings['post_link_source'] ) || 'post' === $settings['post_link_source'] ) {
828 return $permalink;
829 }
830
831 if ( 'custom_field' !== $settings['post_link_source'] ) {
832 return $permalink;
833 }
834
835 $key = isset( $settings['post_link_custom_field_key'] ) ? trim( (string) $settings['post_link_custom_field_key'] ) : '';
836 if ( '' === $key ) {
837 return $permalink;
838 }
839
840 $raw_value = '';
841
842 if ( function_exists( 'get_field' ) ) {
843 $acf_val = get_field( $key, $post_id, false );
844 if ( null !== $acf_val && '' !== $acf_val && false !== $acf_val ) {
845 if ( is_array( $acf_val ) && isset( $acf_val['url'] ) ) {
846 $raw_value = $acf_val['url'];
847 } elseif ( is_string( $acf_val ) ) {
848 $raw_value = $acf_val;
849 }
850 }
851 }
852
853 if ( '' === $raw_value ) {
854 $meta = get_post_meta( $post_id, $key, true );
855 if ( is_array( $meta ) && isset( $meta['url'] ) ) {
856 $raw_value = $meta['url'];
857 } elseif ( is_string( $meta ) ) {
858 $raw_value = $meta;
859 }
860 }
861
862 $raw_value = trim( (string) $raw_value );
863
864 if ( '' === $raw_value ) {
865 return $permalink;
866 }
867
868 if ( preg_match( '#^/#', $raw_value ) && ! preg_match( '#^//#', $raw_value ) ) {
869 $raw_value = home_url( $raw_value );
870 }
871
872 $url = esc_url_raw( $raw_value );
873
874 if ( '' === $url ) {
875 return $permalink;
876 }
877
878 return $url;
879 }
880
881 // Render Password Protected Input
882 public static function render_password_protected_input( $settings ) {
883 if ( ! post_password_required() ) {
884 return;
885 }
886
887 add_filter( 'the_password_form', function () {
888 $output = '<form action="'. esc_url(home_url( 'wp-login.php?action=postpass' )) .'" method="post">';
889 $output .= '<i class="fas fa-lock"></i>';
890 $output .= '<p>'. esc_html(get_the_title()) .'</p>';
891 $output .= '<input type="password" name="post_password" id="post-'. esc_attr(get_the_id()) .'" placeholder="'. esc_html__( 'Type and hit Enter...', 'wpr-addons' ) .'">';
892 $output .= '</form>';
893
894 return $output;
895 } );
896
897 echo '<div class="wpr-grid-item-protected wpr-cv-container">';
898
899 echo '<div class="wpr-cv-outer">';
900 echo '<div class="wpr-cv-inner">';
901 echo get_the_password_form(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
902 echo '</div>';
903 echo '</div>';
904 echo '</div>';
905 }
906
907 // Render Post Thumbnail
908 public static function render_post_thumbnail( $settings ) {
909 $id = get_post_thumbnail_id();
910
911 if ( isset($settings['check_ajax_filter']) && $settings['check_ajax_filter'] == 'yes' ) {
912 $src = Group_Control_Image_Size::get_attachment_image_src( $id, 'layout_image_crop', $settings['layout_image_crop'] );
913 } else {
914 $src = Group_Control_Image_Size::get_attachment_image_src( $id, 'layout_image_crop', $settings );
915 }
916
917 if ( get_post_meta(get_the_ID(), 'wpr_secondary_image_id') && !empty(get_post_meta(get_the_ID(), 'wpr_secondary_image_id')) ) {
918 if ( isset($settings['check_ajax_filter']) && $settings['check_ajax_filter'] == 'yes' ) {
919 $src2 = Group_Control_Image_Size::get_attachment_image_src( get_post_meta(get_the_ID(), 'wpr_secondary_image_id')[0], 'layout_image_crop', $settings['layout_image_crop'] );
920 } else {
921 $src2 = Group_Control_Image_Size::get_attachment_image_src( get_post_meta(get_the_ID(), 'wpr_secondary_image_id')[0], 'layout_image_crop', $settings );
922 }
923 } else {
924 $src2 = '';
925 }
926
927 if ( !empty( get_post_meta( $id, '_wp_attachment_image_alt', true ) ) ) {
928 $alt = get_post_meta( $id, '_wp_attachment_image_alt', true );
929 } else {
930 $alt = '' === wp_get_attachment_caption( $id ) ? get_the_title() : wp_get_attachment_caption( $id );
931 }
932
933 if ( has_post_thumbnail() ) {
934 echo '<div class="wpr-grid-image-wrap" data-src="'. esc_url( $src ) .'" data-img-on-hover="'. esc_attr( $settings['secondary_img_on_hover'] ) .'" data-src-secondary="'. esc_url( $src2 ) .'">';
935 if ( 'yes' == $settings['grid_lazy_loading'] ) {
936 echo '<img data-no-lazy="1" src="'. WPR_ADDONS_ASSETS_URL . 'img/icon-256x256.png" alt="'. esc_attr( $alt ) .'" class="wpr-hidden-image wpr-anim-timing-'. esc_attr($settings[ 'image_effects_animation_timing']) .'">';
937 if ( 'yes' == $settings['secondary_img_on_hover'] ) {
938 echo '<img data-no-lazy="1" src="'. esc_url( $src2 ) . '" alt="'. esc_attr( $alt ) .'" class="wpr-hidden-img wpr-anim-timing-'. esc_attr($settings[ 'image_effects_animation_timing']) .'">';
939 }
940 } else {
941 echo '<img data-no-lazy="1" src="'. esc_url( $src ) . '" alt="'. esc_attr( $alt ) .'" class="wpr-anim-timing-'. esc_attr($settings[ 'image_effects_animation_timing']) .'">';
942 if ( 'yes' == $settings['secondary_img_on_hover'] ) {
943 echo '<img data-no-lazy="1" src="'. esc_url( $src2 ) . '" alt="'. esc_attr( $alt ) .'" class="wpr-hidden-img wpr-anim-timing-'. esc_attr($settings[ 'image_effects_animation_timing']) .'">';
944 }
945 }
946 echo '</div>';
947 }
948 }
949
950 // Render Media Overlay
951 public static function render_media_overlay( $settings ) {
952 $item_url = self::get_grid_item_link_url( $settings );
953 echo '<div class="wpr-grid-media-hover-bg '. esc_attr(WPR_Grid_Helpers::get_animation_class( $settings, 'overlay' )) .'" data-url="'. esc_attr( $item_url ) .'">'; // changed esc_url to esc_attr (why?)
954
955 if ( defined('WPR_ADDONS_PRO_VERSION') && wpr_fs()->can_use_premium_code() ) {
956 if ( '' !== $settings['overlay_image']['url'] ) {
957 echo '<img data-no-lazy="1" src="'. esc_url( $settings['overlay_image']['url'] ) .'">';
958 }
959 }
960
961 echo '</div>';
962 }
963
964 // Render Post Title
965 public static function render_post_title( $settings, $class, $general_settings = '' ) {
966 $title_pointer = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'none' : $general_settings['title_pointer'];
967 $title_pointer_animation = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'fade' : $general_settings['title_pointer_animation'];
968 $pointer_item_class = (isset($general_settings['title_pointer']) && 'none' !==$general_settings['title_pointer']) ? 'class="wpr-pointer-item"' : '';
969 $open_links_in_new_tab = 'yes' === $general_settings['open_links_in_new_tab'] ? '_blank' : '_self';
970
971 $class .= ' wpr-pointer-'. $title_pointer;
972 $class .= ' wpr-pointer-line-fx wpr-pointer-fx-'. $title_pointer_animation;
973
974 $tags_whitelist = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p'];
975 $element_title_tag = Utilities::validate_html_tags_wl( $settings['element_title_tag'], 'h2', $tags_whitelist );
976
977 echo '<'. esc_attr($element_title_tag) .' class="'. esc_attr($class) .'">';
978 echo '<div class="inner-block">';
979 $title_link_url = is_array( $general_settings ) ? self::get_grid_item_link_url( $general_settings ) : get_the_permalink();
980 echo '<a target="'. $open_links_in_new_tab .'" '. $pointer_item_class .' href="'. esc_url( $title_link_url ) .'">';
981 if ( 'word_count' === $settings['element_trim_text_by'] ) {
982 echo esc_html(wp_trim_words( get_the_title(), $settings['element_word_count'] ));
983 } else {
984 $letter_count = isset( $settings['element_letter_count'] ) ? absint( $settings['element_letter_count'] ) : 0;
985 echo esc_html( substr( html_entity_decode( get_the_title(), ENT_QUOTES, 'UTF-8' ), 0, $letter_count ) ) . '...';
986 }
987 echo '</a>';
988 echo '</div>';
989 echo '</'. esc_attr($element_title_tag) .'>';
990 }
991
992 // Render Post Content
993 public static function render_post_content( $settings, $class ) {
994 $dropcap_class = 'yes' === $settings['element_dropcap'] ? ' wpr-enable-dropcap' : '';
995 $class .= $dropcap_class;
996
997 if ( '' === get_the_content() ) {
998 return;
999 }
1000
1001 echo '<div class="'. esc_attr($class) .'">';
1002 echo '<div class="inner-block">';
1003 echo wp_kses_post(get_the_content());
1004 echo '</div>';
1005 echo '</div>';
1006 }
1007
1008 // Render Post Excerpt
1009 public static function render_post_excerpt( $settings, $class ) {
1010 $dropcap_class = 'yes' === $settings['element_dropcap'] ? ' wpr-enable-dropcap' : '';
1011 $class .= $dropcap_class;
1012
1013 if ( '' === get_the_excerpt() ) {
1014 return;
1015 }
1016
1017 $excerpt = get_the_excerpt();
1018
1019 // Convert HTML entities to their respective characters
1020 $decoded_excerpt = html_entity_decode($excerpt, ENT_QUOTES | ENT_HTML5, 'UTF-8');
1021
1022 // Trim the string to the desired length
1023 $trimmed_excerpt = mb_substr($decoded_excerpt, 0, $settings['element_letter_count'], 'UTF-8');
1024
1025 echo '<div class="'. esc_attr($class) .'">';
1026 echo '<div class="inner-block">';
1027 if ( 'word_count' === $settings['element_trim_text_by'] ) {
1028 $show_dots = $settings['element_show_dots'] === 'yes' ? '...' : '';
1029 $the_excerpt = str_replace('Edit Template', '', get_the_excerpt());
1030 echo '<p>'. esc_html(wp_trim_words( $the_excerpt, $settings['element_word_count'], $show_dots )) .'</p>';
1031 } else {
1032 // echo '<p>'. substr(html_entity_decode(get_the_title()), 0, $settings['element_letter_count']) .'...' . '</p>';
1033 // echo '<p>'. esc_html(implode('', array_slice( str_split(get_the_excerpt()), 0, $settings['element_letter_count'] ))) .'...' .'</p>';
1034 echo '<p>' . esc_html($trimmed_excerpt) . '...' . '</p>';
1035 }
1036 echo '</div>';
1037 echo '</div>';
1038 }
1039
1040 // Render Post Date
1041 public static function render_post_date( $settings, $class ) {
1042 echo '<div class="'. esc_attr($class) .'">';
1043 echo '<div class="inner-block">';
1044 echo '<span>';
1045 // Text: Before
1046 if ( 'before' === $settings['element_extra_text_pos'] ) {
1047 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1048 }
1049 // Icon: Before
1050 if ( 'before' === $settings['element_extra_icon_pos'] ) {
1051 ob_start();
1052 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1053 $extra_icon = ob_get_clean();
1054
1055 echo '<span class="wpr-grid-extra-icon-left">';
1056 echo $extra_icon;
1057 echo '</span>';
1058 }
1059
1060 // Date
1061 if ( 'yes' === $settings['show_last_update_date'] ) {
1062 echo esc_html(get_the_modified_time(get_option( 'date_format' )));
1063 } else {
1064 echo esc_html(apply_filters( 'the_date', get_the_date( '' ), get_option( 'date_format' ), '', '' ));
1065 }
1066
1067 // Icon: After
1068 if ( 'after' === $settings['element_extra_icon_pos'] ) {
1069 ob_start();
1070 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1071 $extra_icon = ob_get_clean();
1072
1073 echo '<span class="wpr-grid-extra-icon-right">';
1074 echo $extra_icon;
1075 echo '</span>';
1076 }
1077 // Text: After
1078 if ( 'after' === $settings['element_extra_text_pos'] ) {
1079 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1080 }
1081 echo '</span>';
1082 echo '</div>';
1083 echo '</div>';
1084 }
1085
1086 // Render Post Time
1087 public static function render_post_time( $settings, $class ) {
1088 echo '<div class="'. esc_attr($class) .'">';
1089 echo '<div class="inner-block">';
1090 echo '<span>';
1091 // Text: Before
1092 if ( 'before' === $settings['element_extra_text_pos'] ) {
1093 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1094 }
1095 // Icon: Before
1096 if ( 'before' === $settings['element_extra_icon_pos'] ) {
1097 ob_start();
1098 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1099 $extra_icon = ob_get_clean();
1100
1101 echo '<span class="wpr-grid-extra-icon-left">';
1102 echo $extra_icon;
1103 echo '</span>';
1104 }
1105
1106 // Time
1107 echo esc_html(get_the_time(''));
1108
1109 // Icon: After
1110 if ( 'after' === $settings['element_extra_icon_pos'] ) {
1111 ob_start();
1112 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1113 $extra_icon = ob_get_clean();
1114
1115 echo '<span class="wpr-grid-extra-icon-right">';
1116 echo $extra_icon;
1117 echo '</span>';
1118 }
1119 // Text: After
1120 if ( 'after' === $settings['element_extra_text_pos'] ) {
1121 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1122 }
1123 echo '</span>';
1124 echo '</div>';
1125 echo '</div>';
1126 }
1127
1128 // Render Post Author
1129 public static function render_post_author( $settings, $class ) {
1130 $author_id = get_post_field( 'post_author' );
1131
1132 echo '<div class="'. esc_attr($class) .'">';
1133 echo '<div class="inner-block">';
1134 // Text: Before
1135 if ( 'before' === $settings['element_extra_text_pos'] ) {
1136 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1137 }
1138
1139 // Author
1140 echo '<a href="'. esc_url( get_author_posts_url( $author_id ) ) .'">';
1141
1142 // Icon: Before
1143 if ( 'before' === $settings['element_extra_icon_pos'] ) {
1144 ob_start();
1145 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1146 $extra_icon = ob_get_clean();
1147
1148 echo '<span class="wpr-grid-extra-icon-left">';
1149 echo $extra_icon;
1150 echo '</span>';
1151 }
1152 if ( 'yes' === $settings['element_show_avatar'] ) {
1153 echo get_avatar( $author_id, $settings['element_avatar_size'] );
1154 }
1155
1156 echo '<span>'. esc_html(get_the_author_meta( 'display_name', $author_id )) .'</span>';
1157
1158 // Icon: After
1159 if ( 'after' === $settings['element_extra_icon_pos'] ) {
1160 ob_start();
1161 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1162 $extra_icon = ob_get_clean();
1163
1164 echo '<span class="wpr-grid-extra-icon-right">';
1165 echo $extra_icon;
1166 echo '</span>';
1167 }
1168 echo '</a>';
1169
1170 // Text: After
1171 if ( 'after' === $settings['element_extra_text_pos'] ) {
1172 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1173 }
1174 echo '</div>';
1175 echo '</div>';
1176 }
1177
1178 // Render Post Comments
1179 public static function render_post_comments( $settings, $class ) {
1180 $count = get_comments_number();
1181
1182 if ( comments_open() ) {
1183 if ( $count == 1 ) {
1184 $text = $count .'&nbsp;'. $settings['element_comments_text_2'];
1185 } elseif ( $count > 1 ) {
1186 $text = $count .'&nbsp;'. $settings['element_comments_text_3'];
1187 } else {
1188 $text = $settings['element_comments_text_1'];
1189 }
1190
1191 echo '<div class="'. esc_attr($class) .'">';
1192 echo '<div class="inner-block">';
1193 // Text: Before
1194 if ( 'before' === $settings['element_extra_text_pos'] ) {
1195 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1196 }
1197
1198 // Comments
1199 echo '<a href="'. esc_url( get_comments_link() ) .'">';
1200
1201 // Icon: Before
1202 if ( 'before' === $settings['element_extra_icon_pos'] ) {
1203 ob_start();
1204 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1205 $extra_icon = ob_get_clean();
1206
1207 echo '<span class="wpr-grid-extra-icon-left">';
1208 echo $extra_icon;
1209 echo '</span>';
1210 }
1211
1212 echo '<span>'. esc_html($text) .'</span>';
1213
1214 // Icon: After
1215 if ( 'after' === $settings['element_extra_icon_pos'] ) {
1216 ob_start();
1217 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1218 $extra_icon = ob_get_clean();
1219
1220 echo '<span class="wpr-grid-extra-icon-right">';
1221 echo $extra_icon;
1222 echo '</span>';
1223 }
1224
1225 echo '</a>';
1226
1227 // Text: After
1228 if ( 'after' === $settings['element_extra_text_pos'] ) {
1229 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1230 }
1231 echo '</div>';
1232 echo '</div>';
1233 }
1234 }
1235
1236 // Render Post Read More
1237 public static function render_post_read_more( $settings, $class, $general_settings ) {
1238 $read_more_animation = !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ? 'wpr-button-none' : $general_settings['read_more_animation'];
1239 $open_links_in_new_tab = 'yes' === $general_settings['open_links_in_new_tab'] ? '_blank' : '_self';
1240
1241 echo '<div class="'. esc_attr($class) .'">';
1242 echo '<div class="inner-block">';
1243 echo '<a target="'. $open_links_in_new_tab .'" href="'. esc_url( get_the_permalink() ) .'" class="wpr-button-effect '. esc_attr($read_more_animation) .'">';
1244
1245 // Icon: Before
1246 if ( 'before' === $settings['element_extra_icon_pos'] ) {
1247 ob_start();
1248 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1249 $extra_icon = ob_get_clean();
1250
1251 echo '<span class="wpr-grid-extra-icon-left">';
1252 echo $extra_icon;
1253 echo '</span>';
1254 }
1255
1256 // Read More Text
1257 echo '<span>'. esc_html( $settings['element_read_more_text'] ) .'</span>';
1258
1259 // Icon: After
1260 if ( 'after' === $settings['element_extra_icon_pos'] ) {
1261 ob_start();
1262 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1263 $extra_icon = ob_get_clean();
1264
1265 echo '<span class="wpr-grid-extra-icon-right">';
1266 echo $extra_icon;
1267 echo '</span>';
1268 }
1269
1270 echo '</a>';
1271 echo '</div>';
1272 echo '</div>';
1273 }
1274
1275 // Render Post Likes (Pro)
1276 public static function render_post_likes( $settings, $class, $post_id ) {
1277
1278 if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
1279 return;
1280 }
1281
1282 $post_likes = new WPR_Post_Likes();
1283
1284 echo '<div class="'. esc_attr($class) .'">';
1285 echo '<div class="inner-block">';
1286 // Text: Before
1287 if ( 'before' === $settings['element_extra_text_pos'] ) {
1288 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1289 }
1290
1291 echo $post_likes->get_button( $post_id, $settings );
1292
1293 // Text: After
1294 if ( 'after' === $settings['element_extra_text_pos'] ) {
1295 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1296 }
1297 echo '</div>';
1298 echo '</div>';
1299 }
1300
1301 // Render Post Sharing Icons (Pro)
1302 public static function render_post_sharing_icons( $settings, $class ) {
1303
1304 if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
1305 return;
1306 }
1307
1308 $args = [
1309 'icons' => 'yes',
1310 'tooltip' => $settings['element_sharing_tooltip'],
1311 'url' => esc_url( get_the_permalink() ),
1312 'title' => esc_html( get_the_title() ),
1313 'text' => esc_html( get_the_excerpt() ),
1314 'image' => esc_url( get_the_post_thumbnail_url() ),
1315 ];
1316
1317 $hidden_class = '';
1318
1319 echo '<div class="'. esc_attr($class) .'">';
1320 echo '<div class="inner-block">';
1321 // Text: Before
1322 if ( 'before' === $settings['element_extra_text_pos'] ) {
1323 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1324 }
1325
1326 echo '<span class="wpr-post-sharing">';
1327
1328 if ( 'yes' === $settings['element_sharing_trigger'] ) {
1329 $hidden_class = ' wpr-sharing-hidden';
1330 $attributes = ' data-action="'. esc_attr( $settings['element_sharing_trigger_action'] ) .'"';
1331 $attributes .= ' data-direction="'. esc_attr( $settings['element_sharing_trigger_direction'] ) .'"';
1332
1333 echo '<a class="wpr-sharing-trigger wpr-sharing-icon"'. $attributes .'>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1334 if ( 'yes' === $settings['element_sharing_tooltip'] ) {
1335 echo '<span class="wpr-sharing-tooltip wpr-tooltip">'. esc_html__( 'Share', 'wpr-addons' ) .'</span>';
1336 }
1337
1338 echo Utilities::get_wpr_icon( $settings['element_sharing_trigger_icon'], '' );
1339 echo '</a>';
1340 }
1341
1342
1343 echo '<span class="wpr-post-sharing-inner'. $hidden_class .'">';
1344
1345 for ( $i = 1; $i < 7; $i++ ) {
1346 $args['network'] = $settings['element_sharing_icon_'. $i];
1347
1348 echo Utilities::get_post_sharing_icon( $args );
1349 }
1350
1351 echo '</span>';
1352
1353 echo '</span>';
1354
1355 // Text: After
1356 if ( 'after' === $settings['element_extra_text_pos'] ) {
1357 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1358 }
1359 echo '</div>';
1360 echo '</div>';
1361 }
1362
1363 // Render Post Lightbox
1364 public static function render_post_lightbox( $settings, $class, $post_id ) {
1365 echo '<div class="'. esc_attr($class) .'">';
1366 echo '<div class="inner-block">';
1367 $lightbox_source = get_the_post_thumbnail_url( $post_id );
1368
1369 // Audio Post Type
1370 if ( 'audio' === get_post_format() ) {
1371 // Load Meta Value
1372 if ( 'meta' === $settings['element_lightbox_pfa_select'] ) {
1373 $utilities = new Utilities();
1374 $meta_value = get_post_meta( $post_id, $settings['element_lightbox_pfa_meta'], true );
1375
1376 // URL
1377 if ( false === strpos( $meta_value, '<iframe ' ) ) {
1378 add_filter( 'oembed_result', [ $utilities, 'filter_oembed_results' ], 50, 3 );
1379 $track_url = wp_oembed_get( $meta_value );
1380 remove_filter( 'oembed_result', [ $utilities, 'filter_oembed_results' ], 50 );
1381
1382 // Iframe
1383 } else {
1384 $track_url = Utilities::filter_oembed_results( $meta_value );
1385 }
1386
1387 $lightbox_source = $track_url;
1388 }
1389
1390 // Video Post Type
1391 } elseif ( 'video' === get_post_format() ) {
1392 // Load Meta Value
1393 if ( 'meta' === $settings['element_lightbox_pfv_select'] ) {
1394 $meta_value = get_post_meta( $post_id, $settings['element_lightbox_pfv_meta'], true );
1395
1396 // URL
1397 if ( false === strpos( $meta_value, '<iframe ' ) ) {
1398 $video = \Elementor\Embed::get_video_properties( $meta_value );
1399
1400 // Iframe
1401 } else {
1402 $video = \Elementor\Embed::get_video_properties( Utilities::filter_oembed_results($meta_value) );
1403 }
1404
1405 // Provider URL
1406 if ( 'youtube' === $video['provider'] ) {
1407 $video_url = '//www.youtube.com/embed/'. $video['video_id'] .'?feature=oembed&autoplay=1&controls=1';
1408 } elseif ( 'vimeo' === $video['provider'] ) {
1409 $video_url = 'https://player.vimeo.com/video/'. $video['video_id'] .'?autoplay=1#t=0';
1410 }
1411
1412 // Add Lightbox Attributes
1413 if ( isset( $video_url ) ) {
1414 $lightbox_source = $video_url;
1415 }
1416 }
1417 }
1418
1419 // Lightbox Button
1420 echo '<span data-src="'. esc_url( $lightbox_source ) .'">';
1421
1422 // Text: Before
1423 if ( 'before' === $settings['element_extra_text_pos'] ) {
1424 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1425 }
1426
1427 // Lightbox Icon
1428 echo '<i class="'. esc_attr( $settings['element_extra_icon']['value'] ) .'"></i>';
1429
1430 // Text: After
1431 if ( 'after' === $settings['element_extra_text_pos'] ) {
1432 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1433 }
1434
1435 echo '</span>';
1436
1437 // Media Overlay
1438 if ( 'yes' === $settings['element_lightbox_overlay'] ) {
1439 echo '<div class="wpr-grid-lightbox-overlay"></div>';
1440 }
1441 echo '</div>';
1442 echo '</div>';
1443 }
1444
1445 public static function render_post_custom_field( $settings, $class, $post_id ) {
1446
1447 if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
1448 return;
1449 }
1450
1451 $custom_field_value = get_post_meta( $post_id, $settings['element_custom_field'], true );
1452 $custom_field_html = $settings['element_custom_field_wrapper_html'];
1453
1454 // Check if the custom field is a date and format it
1455 if ( !is_array($custom_field_value) && strtotime( $custom_field_value ) !== false ) {
1456 if ( function_exists('get_field_object') && get_field_object($settings['element_custom_field'], $post_id) && isset(get_field_object($settings['element_custom_field'], $post_id)['display_format']) ) {
1457 $date_format = get_field_object($settings['element_custom_field'], $post_id)['display_format'];
1458 } else {
1459 $date_format = get_option('date_format');
1460 }
1461
1462 if ( \DateTime::createFromFormat($date_format, $custom_field_value) !== false ) {
1463 $custom_field_value = date_i18n( $date_format, strtotime( $custom_field_value ) );
1464 }
1465 }
1466
1467 if ( has_filter('wpr_update_custom_field_value') ) {
1468 ob_start();
1469 apply_filters('wpr_update_custom_field_value', $custom_field_value, $post_id, $settings['element_custom_field']);
1470 $custom_field_value = ob_get_clean();
1471 }
1472
1473 // Get First Value if Array (works only for single value checkboxes)
1474 if ( is_array($custom_field_value) && 1 === count($custom_field_value) ) {
1475 $custom_field_value = $custom_field_value[0];
1476 }
1477
1478 // Erase if Array or Object
1479 if ( ! is_string( $custom_field_value ) && ! is_numeric( $custom_field_value ) ) {
1480 $custom_field_value = '';
1481 }
1482
1483 // Return if Empty
1484 if ( '' === $custom_field_value ) {
1485 return;
1486 }
1487
1488 echo '<div class="'. esc_attr($class) .' '. $settings['element_custom_field_style'] .'">';
1489 echo '<div class="inner-block">';
1490 if ( 'yes' === $settings['element_custom_field_btn_link'] ) {
1491 $target = 'yes' === $settings['element_custom_field_new_tab'] ? '_blank' : '_self';
1492 echo '<a href="'. esc_url($custom_field_value) .'" target="'. esc_attr($target) .'">';
1493 } else {
1494 echo '<span>';
1495 }
1496
1497 // Text: Before
1498 if ( 'before' === $settings['element_extra_text_pos'] ) {
1499 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1500 }
1501 // Icon: Before
1502 if ( 'before' === $settings['element_extra_icon_pos'] ) {
1503 ob_start();
1504 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1505 $extra_icon = ob_get_clean();
1506
1507 echo '<span class="wpr-grid-extra-icon-left">';
1508 echo $extra_icon;
1509 echo '</span>';
1510 }
1511
1512 // Custom Field
1513 if ( 'yes' === $settings['element_custom_field_img_ID'] ) {
1514 $cf_img = wp_get_attachment_image_src( $custom_field_value, 'full' );
1515 if ( isset($cf_img) && is_array($cf_img) ) {
1516 echo '<img src="'. esc_url($cf_img[0]) .'" alt="" width="'. esc_attr($cf_img[1]) .'" height="'. esc_attr($cf_img[2]) .'">';
1517 }
1518 } else {
1519 if ( 'yes' !== $settings['element_custom_field_btn_link'] ) {
1520 $tags_whitelist = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p'];
1521 $element_cf_tag = Utilities::validate_html_tags_wl( $settings['element_cf_tag'], 'span', $tags_whitelist );
1522
1523 echo '<'. esc_attr($element_cf_tag) .'>';
1524 if ( 'yes' === $settings['element_custom_field_wrapper'] ) {
1525 echo str_replace( '*cf_value*', $custom_field_value, $custom_field_html );
1526 } else {
1527 echo $custom_field_value;
1528 }
1529 echo '</'. esc_attr($element_cf_tag) .'>';
1530 }
1531 }
1532
1533 // Icon: After
1534 if ( 'after' === $settings['element_extra_icon_pos'] ) {
1535 ob_start();
1536 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1537 $extra_icon = ob_get_clean();
1538
1539 echo '<span class="wpr-grid-extra-icon-right">';
1540 echo $extra_icon;
1541 echo '</span>';
1542 }
1543 // Text: After
1544 if ( 'after' === $settings['element_extra_text_pos'] ) {
1545 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1546 }
1547
1548 if ( 'yes' === $settings['element_custom_field_btn_link'] ) {
1549 echo '</a>';
1550 } else {
1551 echo '</span>';
1552 }
1553 echo '</div>';
1554 echo '</div>';
1555 }
1556
1557 // Render Post Element Separator
1558 public static function render_post_element_separator( $settings, $class ) {
1559 echo '<div class="'. esc_attr($class .' '. $settings['element_separator_style']) .'">';
1560 echo '<div class="inner-block"><span></span></div>';
1561 echo '</div>';
1562 }
1563
1564 // Render Post Taxonomies
1565 public static function render_post_taxonomies( $settings, $class, $post_id, $general_settings ) {
1566 $terms = wp_get_post_terms( $post_id, $settings['element_select'] );
1567 $count = 0;
1568
1569 $tax1_pointer = ! wpr_fs()->can_use_premium_code() ? 'none' : $general_settings['tax1_pointer'];
1570 $tax1_pointer_animation = ! wpr_fs()->can_use_premium_code() ? 'fade' : $general_settings['tax1_pointer_animation'];
1571 $tax2_pointer = ! wpr_fs()->can_use_premium_code() ? 'none' : $general_settings['tax2_pointer'];
1572 $tax2_pointer_animation = ! wpr_fs()->can_use_premium_code() ? 'fade' : $general_settings['tax2_pointer_animation'];
1573 $pointer_item_class = (isset($general_settings['tax1_pointer']) && 'none' !== $general_settings['tax1_pointer']) || (isset($general_settings['tax2_pointer']) && 'none' !== $general_settings['tax2_pointer']) ? 'wpr-pointer-item' : '';
1574
1575 // Pointer Class
1576 if ( 'wpr-grid-tax-style-1' === $settings['element_tax_style'] ) {
1577 $class .= ' wpr-pointer-'. $tax1_pointer;
1578 $class .= ' wpr-pointer-line-fx wpr-pointer-fx-'. $tax1_pointer_animation;
1579 } else {
1580 $class .= ' wpr-pointer-'. $tax2_pointer;
1581 $class .= ' wpr-pointer-line-fx wpr-pointer-fx-'. $tax2_pointer_animation;
1582 }
1583
1584 echo '<div class="'. esc_attr($class .' '. $settings['element_tax_style']) .'">';
1585 echo '<div class="inner-block">';
1586 // Text: Before
1587 if ( 'before' === $settings['element_extra_text_pos'] ) {
1588 echo '<span class="wpr-grid-extra-text-left">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1589 }
1590 // Icon: Before
1591 if ( 'before' === $settings['element_extra_icon_pos'] ) {
1592 ob_start();
1593 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1594 $extra_icon = ob_get_clean();
1595
1596 echo '<span class="wpr-grid-extra-icon-left">';
1597 echo $extra_icon;
1598 echo '</span>';
1599 }
1600
1601 // Taxonomies
1602 foreach ( $terms as $term ) {
1603 if ( ! $term || ! isset( $term->term_id, $term->name ) ) {
1604 continue;
1605 }
1606 $term_link = get_term_link( $term->term_id );
1607 if ( is_wp_error( $term_link ) ) {
1608 continue;
1609 }
1610
1611 // Custom Colors
1612 $enable_custom_colors = ! wpr_fs()->can_use_premium_code() ? '' : $general_settings['tax1_custom_color_switcher'];
1613
1614 if ( 'yes' === $enable_custom_colors ) {
1615 $custom_tax_styles = '';
1616 $cfc_text = get_term_meta($term->term_id, $general_settings['tax1_custom_color_field_text'], true);
1617 $cfc_bg = get_term_meta($term->term_id, $general_settings['tax1_custom_color_field_bg'], true);
1618 $color_styles = 'color:'. $cfc_text .'; background-color:'. $cfc_bg .'; border-color:'. $cfc_bg .';';
1619 // $css_selector = '.elementor-element'. $this->get_unique_selector() .' .wpr-grid-tax-style-1 .inner-block a.wpr-tax-id-'. esc_attr($term->term_id);
1620 $css_selector = '.elementor-element .wpr-grid-tax-style-1 .inner-block a.wpr-tax-id-'. esc_attr($term->term_id); // TODO: get_unique_selector()
1621 $custom_tax_styles .= $css_selector .'{'. $color_styles .'}';
1622 echo '<style>'. esc_html($custom_tax_styles) .'</style>'; // TODO: take out of loop if possible
1623 }
1624
1625 echo '<a class="'. $pointer_item_class .' wpr-tax-id-'. esc_attr($term->term_id) .'" href="'. esc_url( $term_link ) .'">'. esc_html( $term->name );
1626 if ( ++$count !== count( $terms ) ) {
1627 echo '<span class="tax-sep">'. esc_html($settings['element_tax_sep']) .'</span>';
1628 }
1629 echo '</a>';
1630 }
1631
1632 // Icon: After
1633 if ( 'after' === $settings['element_extra_icon_pos'] ) {
1634 ob_start();
1635 \Elementor\Icons_Manager::render_icon($settings['element_extra_icon'], ['aria-hidden' => 'true']);
1636 $extra_icon = ob_get_clean();
1637
1638 echo '<span class="wpr-grid-extra-icon-right">';
1639 echo $extra_icon;
1640 echo '</span>';
1641 }
1642 // Text: After
1643 if ( 'after' === $settings['element_extra_text_pos'] ) {
1644 echo '<span class="wpr-grid-extra-text-right">'. esc_html( $settings['element_extra_text'] ) .'</span>';
1645 }
1646 echo '</div>';
1647 echo '</div>';
1648 }
1649
1650 // Get Elements
1651 public static function get_elements( $type, $settings, $class, $post_id, $general_settings ) {
1652 if ( 'pro-lk' == $type || 'pro-shr' == $type || 'pro-cf' == $type ) {
1653 $type = 'title';
1654 }
1655
1656 switch ( $type ) {
1657 case 'title':
1658 WPR_Grid_Helpers::render_post_title( $settings, $class, $general_settings );
1659 break;
1660
1661 case 'content':
1662 WPR_Grid_Helpers::render_post_content( $settings, $class );
1663 break;
1664
1665 case 'excerpt':
1666 WPR_Grid_Helpers::render_post_excerpt( $settings, $class, $general_settings );
1667 break;
1668
1669 case 'date':
1670 WPR_Grid_Helpers::render_post_date( $settings, $class );
1671 break;
1672
1673 case 'time':
1674 WPR_Grid_Helpers::render_post_time( $settings, $class );
1675 break;
1676
1677 case 'author':
1678 WPR_Grid_Helpers::render_post_author( $settings, $class );
1679 break;
1680
1681 case 'comments':
1682 WPR_Grid_Helpers::render_post_comments( $settings, $class );
1683 break;
1684
1685 case 'read-more':
1686 WPR_Grid_Helpers::render_post_read_more( $settings, $class, $general_settings );
1687 break;
1688
1689 case 'likes':
1690 WPR_Grid_Helpers::render_post_likes( $settings, $class, $post_id );
1691 break;
1692
1693 case 'sharing':
1694 WPR_Grid_Helpers::render_post_sharing_icons( $settings, $class );
1695 break;
1696
1697 case 'lightbox':
1698 WPR_Grid_Helpers::render_post_lightbox( $settings, $class, $post_id );
1699 break;
1700
1701 case 'custom-field':
1702 WPR_Grid_Helpers::render_post_custom_field( $settings, $class, $post_id );
1703 break;
1704
1705 case 'separator':
1706 WPR_Grid_Helpers::render_post_element_separator( $settings, $class );
1707 break;
1708
1709 default:
1710 WPR_Grid_Helpers::render_post_taxonomies( $settings, $class, $post_id, $general_settings );
1711 break;
1712 }
1713
1714 }
1715
1716 // Get Elements by Location
1717 public static function get_elements_by_location( $location, $settings, $post_id ) {
1718 $locations = [];
1719
1720 foreach ( $settings['grid_elements'] as $data ) {
1721 $place = $data['element_location'];
1722 $align_vr = $data['element_align_vr'];
1723
1724 if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
1725 $align_vr = 'middle';
1726 }
1727
1728 if ( ! isset($locations[$place]) ) {
1729 $locations[$place] = [];
1730 }
1731
1732 if ( 'over' === $place ) {
1733 if ( ! isset($locations[$place][$align_vr]) ) {
1734 $locations[$place][$align_vr] = [];
1735 }
1736
1737 array_push( $locations[$place][$align_vr], $data );
1738 } else {
1739 array_push( $locations[$place], $data );
1740 }
1741 }
1742
1743 if ( ! empty( $locations[$location] ) ) {
1744
1745 if ( 'over' === $location ) {
1746 foreach ( $locations[$location] as $align => $elements ) {
1747
1748 if ( 'middle' === $align ) {
1749 echo '<div class="wpr-cv-container"><div class="wpr-cv-outer"><div class="wpr-cv-inner">';
1750 }
1751
1752 echo '<div class="wpr-grid-media-hover-'. esc_attr($align) .' elementor-clearfix">';
1753 foreach ( $elements as $data ) {
1754
1755 // Get Class
1756 $class = 'wpr-grid-item-'. $data['element_select'];
1757 $class .= ' elementor-repeater-item-'. $data['_id'];
1758 $class .= ' wpr-grid-item-display-'. $data['element_display'];
1759 $class .= ' wpr-grid-item-align-'. $data['element_align_hr'];
1760 $class .= WPR_Grid_Helpers::get_animation_class( $data, 'element' );
1761
1762 // Element
1763 WPR_Grid_Helpers::get_elements( $data['element_select'], $data, $class, $post_id, $settings );
1764 }
1765 echo '</div>';
1766
1767 if ( 'middle' === $align ) {
1768 echo '</div></div></div>';
1769 }
1770 }
1771 } else {
1772 echo '<div class="wpr-grid-item-'. esc_attr($location) .'-content elementor-clearfix">';
1773 foreach ( $locations[$location] as $data ) {
1774
1775 // Get Class
1776 $class = 'wpr-grid-item-'. $data['element_select'];
1777 $class .= ' elementor-repeater-item-'. $data['_id'];
1778 $class .= ' wpr-grid-item-display-'. $data['element_display'];
1779 $class .= ' wpr-grid-item-align-'. $data['element_align_hr'];
1780
1781 // Element
1782 WPR_Grid_Helpers::get_elements( $data['element_select'], $data, $class, $post_id, $settings );
1783 }
1784 echo '</div>';
1785 }
1786
1787 }
1788 }
1789
1790 public static function get_hidden_filter_class($slug, $settings) {
1791 $posts = new \WP_Query( WPR_Grid_Helpers::get_main_query_args($settings, []) );
1792 $visible_categories = [];
1793
1794 if ( $posts->have_posts() ) {
1795 while ( $posts->have_posts() ) {
1796 $posts->the_post();
1797 $categories = get_the_category();
1798
1799 foreach ($categories as $key => $category) {
1800 array_push($visible_categories, $category->slug);
1801 }
1802 }
1803
1804 $visible_categories = array_unique($visible_categories);
1805
1806 wp_reset_postdata();
1807 }
1808
1809 return ( ! in_array($slug, $visible_categories) && 'yes' == $settings['filters_hide_empty'] ) ? ' wpr-hidden-element' : '';
1810 }
1811
1812 // Render Grid Pagination
1813 public static function render_grid_pagination( $settings ) {
1814 // Return if Disabled
1815 if ( 'yes' !== $settings['layout_pagination'] || 'slider' === $settings['layout_select'] ) {
1816 return;
1817 }
1818
1819 if ( 'yes' !== $settings['advanced_filters'] && 1 === WPR_Grid_Helpers::get_max_num_pages( $settings ) ) {
1820 return;
1821 }
1822
1823 global $paged;
1824 $pages = WPR_Grid_Helpers::get_max_num_pages( $settings );
1825
1826 // $paged = empty( $paged ) ? 1 : $paged;
1827 if ( get_query_var('paged') ) {
1828 $paged = get_query_var('paged');
1829 } elseif ( get_query_var('page') ) {
1830 $paged = get_query_var('page');
1831 } else {
1832 $paged = 1;
1833 }
1834
1835 if ( !defined('WPR_ADDONS_PRO_VERSION') || !wpr_fs()->can_use_premium_code() ) {
1836 $settings['pagination_type'] = 'pro-is' == $settings['pagination_type'] ? 'default' : $settings['pagination_type'];
1837 }
1838
1839 echo '<div class="wpr-grid-pagination elementor-clearfix wpr-grid-pagination-'. esc_attr($settings['pagination_type']) .'" data-pages="'. esc_attr($pages) .'">';
1840
1841 // Default
1842 if ( 'default' === $settings['pagination_type'] ) {
1843 if ( $paged < $pages ) {
1844 echo '<a href="'. esc_url(get_pagenum_link( $paged + 1, true )) .'" class="wpr-prev-post-link">';
1845 echo Utilities::get_wpr_icon( $settings['pagination_on_icon'], 'left' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1846 echo esc_html($settings['pagination_older_text']);
1847 echo '</a>';
1848 } elseif ( 'yes' === $settings['pagination_disabled_arrows'] ) {
1849 echo '<span class="wpr-prev-post-link wpr-disabled-arrow">';
1850 echo Utilities::get_wpr_icon( $settings['pagination_on_icon'], 'left' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1851 echo esc_html($settings['pagination_older_text']);
1852 echo '</span>';
1853 }
1854
1855 if ( $paged > 1 ) {
1856 echo '<a href="'. esc_url(get_pagenum_link( $paged - 1, true )) .'" class="wpr-next-post-link">';
1857 echo esc_html($settings['pagination_newer_text']);
1858 echo Utilities::get_wpr_icon( $settings['pagination_on_icon'], 'right' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1859 echo '</a>';
1860 } elseif ( 'yes' === $settings['pagination_disabled_arrows'] ) {
1861 echo '<span class="wpr-next-post-link wpr-disabled-arrow">';
1862 echo esc_html($settings['pagination_newer_text']);
1863 echo Utilities::get_wpr_icon( $settings['pagination_on_icon'], 'right' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1864 echo '</span>';
1865 }
1866
1867 // Numbered
1868 } elseif ( 'numbered' === $settings['pagination_type'] ) {
1869 $range = $settings['pagination_range'];
1870 $showitems = ( $range * 2 ) + 1;
1871
1872 if ( 1 !== $pages ) {
1873
1874 if ( 'yes' === $settings['pagination_prev_next'] || 'yes' === $settings['pagination_first_last'] ) {
1875 echo '<div class="wpr-grid-pagi-left-arrows">';
1876
1877 if ( 'yes' === $settings['pagination_first_last'] ) {
1878 if ( $paged >= 2 ) {
1879 echo '<a href="'. esc_url(get_pagenum_link( 1, true )) .'" class="wpr-first-page">';
1880 echo Utilities::get_wpr_icon( $settings['pagination_fl_icon'], 'left' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1881 echo '<span>'. esc_html($settings['pagination_first_text']) .'</span>';
1882 echo '</a>';
1883 } elseif ( 'yes' === $settings['pagination_disabled_arrows'] ) {
1884 echo '<span class="wpr-first-page wpr-disabled-arrow">';
1885 echo Utilities::get_wpr_icon( $settings['pagination_fl_icon'], 'left' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1886 echo '<span>'. esc_html($settings['pagination_first_text']) .'</span>';
1887 echo '</span>';
1888 }
1889 }
1890
1891 if ( 'yes' === $settings['pagination_prev_next'] ) {
1892 if ( $paged > 1 ) {
1893 echo '<a href="'. esc_url(get_pagenum_link( $paged - 1, true )) .'" class="wpr-prev-page">';
1894 echo Utilities::get_wpr_icon( $settings['pagination_pn_icon'], 'left' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1895 echo '<span>'. esc_html($settings['pagination_prev_text']) .'</span>';
1896 echo '</a>';
1897 } elseif ( 'yes' === $settings['pagination_disabled_arrows'] ) {
1898 echo '<span class="wpr-prev-page wpr-disabled-arrow">';
1899 echo Utilities::get_wpr_icon( $settings['pagination_pn_icon'], 'left' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1900 echo '<span>'. esc_html($settings['pagination_prev_text']) .'</span>';
1901 echo '</span>';
1902 }
1903 }
1904
1905 echo '</div>';
1906 }
1907
1908 for ( $i = 1; $i <= $pages; $i++ ) {
1909 if ( 1 !== $pages && ( ! ( $i >= $paged + $range + 1 || $i <= $paged - $range - 1 ) || $pages <= $showitems ) ) {
1910 if ( $paged === $i ) {
1911 echo '<span class="wpr-grid-current-page">'. esc_html($i) .'</span>';
1912 } else {
1913 echo '<a href="'. esc_url(get_pagenum_link( $i, true )) .'">'. esc_html($i) .'</a>';
1914 }
1915 }
1916 }
1917
1918 if ( 'yes' === $settings['pagination_prev_next'] || 'yes' === $settings['pagination_first_last'] ) {
1919 echo '<div class="wpr-grid-pagi-right-arrows">';
1920
1921 if ( 'yes' === $settings['pagination_prev_next'] ) {
1922 if ( $paged < $pages ) {
1923 echo '<a href="'. esc_url(get_pagenum_link( $paged + 1, true )) .'" class="wpr-next-page">';
1924 echo '<span>'. esc_html($settings['pagination_next_text']) .'</span>';
1925 echo Utilities::get_wpr_icon( $settings['pagination_pn_icon'], 'right' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1926 echo '</a>';
1927 } elseif ( 'yes' === $settings['pagination_disabled_arrows'] ) {
1928 echo '<span class="wpr-next-page wpr-disabled-arrow">';
1929 echo '<span>'. esc_html($settings['pagination_next_text']) .'</span>';
1930 echo Utilities::get_wpr_icon( $settings['pagination_pn_icon'], 'right' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1931 echo '</span>';
1932 }
1933 }
1934
1935 if ( 'yes' === $settings['pagination_first_last'] ) {
1936 if ( $paged <= $pages - 1 ) {
1937 echo '<a href="'. esc_url(get_pagenum_link( $pages, true )) .'" class="wpr-last-page">';
1938 echo '<span>'. esc_html($settings['pagination_last_text']) .'</span>';
1939 echo Utilities::get_wpr_icon( $settings['pagination_fl_icon'], 'right' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1940 echo '</a>';
1941 } elseif ( 'yes' === $settings['pagination_disabled_arrows'] ) {
1942 echo '<span class="wpr-last-page wpr-disabled-arrow">';
1943 echo '<span>'. esc_html($settings['pagination_last_text']) .'</span>';
1944 echo Utilities::get_wpr_icon( $settings['pagination_fl_icon'], 'right' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1945 echo '</span>';
1946 }
1947 }
1948
1949 echo '</div>';
1950 }
1951 }
1952
1953 // Load More / Infinite Scroll
1954 } else {
1955 echo '<a href="'. esc_url(get_pagenum_link( $paged + 1, true )) .'" class="wpr-load-more-btn" data-e-disable-page-transition >';
1956 echo esc_html($settings['pagination_load_more_text']);
1957 echo '</a>';
1958
1959 echo '<div class="wpr-pagination-loading">';
1960 switch ( $settings['pagination_animation'] ) {
1961 case 'loader-1':
1962 echo '<div class="wpr-double-bounce">';
1963 echo '<div class="wpr-child wpr-double-bounce1"></div>';
1964 echo '<div class="wpr-child wpr-double-bounce2"></div>';
1965 echo '</div>';
1966 break;
1967 case 'loader-2':
1968 echo '<div class="wpr-wave">';
1969 echo '<div class="wpr-rect wpr-rect1"></div>';
1970 echo '<div class="wpr-rect wpr-rect2"></div>';
1971 echo '<div class="wpr-rect wpr-rect3"></div>';
1972 echo '<div class="wpr-rect wpr-rect4"></div>';
1973 echo '<div class="wpr-rect wpr-rect5"></div>';
1974 echo '</div>';
1975 break;
1976 case 'loader-3':
1977 echo '<div class="wpr-spinner wpr-spinner-pulse"></div>';
1978 break;
1979 case 'loader-4':
1980 echo '<div class="wpr-chasing-dots">';
1981 echo '<div class="wpr-child wpr-dot1"></div>';
1982 echo '<div class="wpr-child wpr-dot2"></div>';
1983 echo '</div>';
1984 break;
1985 case 'loader-5':
1986 echo '<div class="wpr-three-bounce">';
1987 echo '<div class="wpr-child wpr-bounce1"></div>';
1988 echo '<div class="wpr-child wpr-bounce2"></div>';
1989 echo '<div class="wpr-child wpr-bounce3"></div>';
1990 echo '</div>';
1991 break;
1992 case 'loader-6':
1993 echo '<div class="wpr-fading-circle">';
1994 echo '<div class="wpr-circle wpr-circle1"></div>';
1995 echo '<div class="wpr-circle wpr-circle2"></div>';
1996 echo '<div class="wpr-circle wpr-circle3"></div>';
1997 echo '<div class="wpr-circle wpr-circle4"></div>';
1998 echo '<div class="wpr-circle wpr-circle5"></div>';
1999 echo '<div class="wpr-circle wpr-circle6"></div>';
2000 echo '<div class="wpr-circle wpr-circle7"></div>';
2001 echo '<div class="wpr-circle wpr-circle8"></div>';
2002 echo '<div class="wpr-circle wpr-circle9"></div>';
2003 echo '<div class="wpr-circle wpr-circle10"></div>';
2004 echo '<div class="wpr-circle wpr-circle11"></div>';
2005 echo '<div class="wpr-circle wpr-circle12"></div>';
2006 echo '</div>';
2007 break;
2008
2009 default:
2010 break;
2011 }
2012 echo '</div>';
2013
2014 echo '<p class="wpr-pagination-finish">'. esc_html($settings['pagination_finish_text']) .'</p>';
2015 }
2016
2017 echo '</div>';
2018 }
2019
2020 public function wpr_get_filtered_count_posts() {
2021 $nonce = $_POST['nonce'];
2022
2023 if (!isset($nonce) || !wp_verify_nonce($nonce, 'wpr-addons-js')) {
2024 wp_send_json_error(array(
2025 'message' => esc_html__('Security check failed.', 'wpr-addons'),
2026 ));
2027 }
2028
2029 if ( ! empty( $_POST['grid_settings'] ) && ! WPR_Grid_Helpers::is_allowed_grid_query_post_type( $_POST['grid_settings'] ) ) {
2030 wp_send_json_error(array(
2031 'message' => esc_html__('Security check failed.', 'wpr-addons'),
2032 ));
2033 }
2034
2035 if ( isset($_POST['wpr_url_params']) ) {
2036 $results = [];
2037
2038 // Loop through each set of parameters
2039 foreach ($_POST['wpr_url_params'] as $params) {
2040 $query_args = WPR_Grid_Helpers::get_main_query_args($_POST['grid_settings'], $params);
2041 $query = new \WP_Query($query_args);
2042
2043 // Add the count of found posts to the results array
2044 $results[] = [
2045 'found_posts' => $query->found_posts,
2046 'post_count' => $query->post_count,
2047 ];
2048
2049 wp_reset_postdata();
2050 }
2051
2052 // Send the array of results
2053 wp_send_json_success($results);
2054 } else if ( isset($_POST['grid_settings']) ) {
2055 $settings = $_POST['grid_settings'];
2056 $page_count = WPR_Grid_Helpers::get_max_num_pages( $settings );
2057
2058 wp_send_json_success([
2059 'page_count' => $page_count,
2060 ]);
2061 }
2062
2063 wp_die();
2064 }
2065
2066 public function wpr_grid_filters_ajax() {
2067 $nonce = $_POST['nonce'];
2068
2069 if (!isset($nonce) || !wp_verify_nonce($nonce, 'wpr-addons-js')) {
2070 wp_send_json_error(array(
2071 'message' => esc_html__('Security check failed.', 'wpr-addons'),
2072 ));
2073 }
2074
2075 $settings = isset( $_POST['grid_settings'] ) && is_array( $_POST['grid_settings'] ) ? $_POST['grid_settings'] : array();
2076 if ( ! WPR_Grid_Helpers::is_allowed_grid_query_post_type( $settings ) ) {
2077 wp_send_json_error(array(
2078 'message' => esc_html__('Security check failed.', 'wpr-addons'),
2079 ));
2080 }
2081
2082 $start = microtime(true);
2083 // Get Settings
2084
2085 // Create a unique cache key based on the settings
2086 $cache_key = 'wpr_grid_filters_' . md5(serialize(WPR_Grid_Helpers::get_main_query_args($settings, [])));
2087 // wp_send_json_success($cache_key);
2088 // wp_die();
2089
2090 // Try to get cached data
2091 // $cached_data = get_transient($cache_key);
2092
2093 // if ($cached_data !== false) {
2094 // $end = microtime(true);
2095 // $duration = round(($end - $start) * 1000, 2); // in ms
2096 // wp_send_json_success([
2097 // 'output' => $cached_data,
2098 // 'duration' => $duration
2099 // ]);
2100 // wp_die();
2101 // }
2102
2103 // Start output buffering to capture the HTML output
2104 ob_start();
2105
2106 // Get Posts
2107 $posts = new \WP_Query(WPR_Grid_Helpers::get_main_query_args($settings, []));
2108
2109 // Loop: Start
2110 if ($posts->have_posts()) :
2111
2112 while ($posts->have_posts()) : $posts->the_post();
2113
2114 // Post Class
2115 $post_class = implode(' ', get_post_class('wpr-grid-item elementor-clearfix', get_the_ID()));
2116
2117 // Grid Item
2118 echo '<article class="' . esc_attr($post_class) . '">';
2119
2120 // Password Protected Form
2121 WPR_Grid_Helpers::render_password_protected_input($settings);
2122
2123 // Inner Wrapper
2124 echo '<div class="wpr-grid-item-inner">';
2125
2126 // Content: Above Media
2127 WPR_Grid_Helpers::get_elements_by_location('above', $settings, get_the_ID());
2128
2129 // Media
2130 if (has_post_thumbnail()) {
2131 echo '<div class="wpr-grid-media-wrap' . esc_attr(WPR_Grid_Helpers::get_image_effect_class($settings)) . '" data-overlay-link="' . esc_attr($settings['overlay_post_link']) . '">';
2132 // Post Thumbnail
2133 WPR_Grid_Helpers::render_post_thumbnail($settings, get_the_ID());
2134
2135 // Media Hover
2136 echo '<div class="wpr-grid-media-hover wpr-animation-wrap">';
2137 // Media Overlay
2138 WPR_Grid_Helpers::render_media_overlay($settings);
2139
2140 // Content: Over Media
2141 WPR_Grid_Helpers::get_elements_by_location('over', $settings, get_the_ID());
2142
2143 echo '</div>';
2144 echo '</div>';
2145 }
2146
2147 // Content: Below Media
2148 WPR_Grid_Helpers::get_elements_by_location('below', $settings, get_the_ID());
2149
2150 echo '</div>'; // End .wpr-grid-item-inner
2151
2152 echo '</article>'; // End .wpr-grid-item
2153
2154 endwhile;
2155
2156 // reset
2157 wp_reset_postdata();
2158
2159 // Loop: End
2160 else :
2161
2162 if ( 'dynamic' === $settings['query_selection'] || 'current' === $settings['query_selection'] ) {
2163 echo '<h2>'. esc_html($settings['query_not_found_text']) .'</h2>';
2164 }
2165
2166 endif;
2167
2168 // Get the buffered content
2169 $output = ob_get_clean();
2170
2171 // Cache the output
2172 // set_transient($cache_key, $output, HOUR_IN_SECONDS);
2173
2174 // Return the output
2175 $end = microtime(true);
2176 $duration = round(($end - $start) * 1000, 2); // in ms
2177 wp_send_json_success([
2178 'output' => $output,
2179 'duration' => $duration,
2180 'found_posts' => $posts->found_posts,
2181 'post_count' => $posts->post_count,
2182 ]);
2183
2184 wp_die();
2185 }
2186
2187 }
2188
2189 new WPR_Grid_Helpers();