PluginProbe
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News / 4.0.2
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News v4.0.2
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 4.0.2 4.0.1 2.3.5 2.3.6 2.4.0 2.4.1 2.4.10 2.4.11 2.4.12 2.4.13 2.4.14 2.4.15 2.4.16 2.4.17 2.4.18 2.4.19 2.4.2 2.4.20 2.4.21 All 88 releases
post-carousel / blocks / includes / class-template-part.php

class-template-part.php in Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News 4.0.2, at blocks/includes/class-template-part.php

1,839 lines 76.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Blocks template parts.
4 *
5 * @package Smart_Post_Show
6 * @subpackage Smart_Post_Show/blocks/includes
7 * @author ShapedPlugin <support@shapedplugin.com>
8 */
9
10 namespace SmartPostShow\Blocks;
11
12 use SmartPostShow\Blocks\Helper;
13
14 if ( ! defined( 'ABSPATH' ) ) {
15 die;
16 }
17
18 /**
19 * Post Content render Class.
20 */
21 class Template_Part {
22 /**
23 * Preloader
24 *
25 * @param bool $preloader_enable enable preloader.
26 * @param url $preloader_svg svg img url.
27 * @return void
28 */
29 public static function preloader_front( $preloader_enable, $preloader_svg ) {
30 ob_start();
31 if ( $preloader_enable ) { ?>
32 <div class="sp-smart-post-preloader sp-d-block">
33 <img src="<?php echo esc_url( $preloader_svg ); ?>" alt="smart post preloader" />
34 </div>
35 <?php
36 }
37 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
38 echo ob_get_clean();
39 }
40 /**
41 * Render "No posts found" message.
42 *
43 * @param string $message The message to display when no posts are found.
44 * @param string $class_name Optional. Additional CSS classes for the wrapper.
45 *
46 * @return void The HTML output.
47 */
48 public static function no_posts_found_text( $message = '', $class_name = '' ) {
49 if ( empty( $message ) ) {
50 $message = __( 'No posts found.', 'post-carousel' );
51 }
52
53 // Merge default and custom classes.
54 $wrapper_class = trim( 'sp-smart-post-no-post ' . $class_name );
55
56 ob_start();
57 ?>
58 <div class="<?php echo esc_attr( $wrapper_class ); ?>">
59 <h4><?php echo esc_html( $message ); ?></h4>
60 </div>
61 <?php
62 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
63 echo ob_get_clean();
64 }
65
66 /**
67 * Generates a random color.
68 *
69 * @param string $color_type The type of color to generate.
70 * @return string|false The generated color string or false if type is not matched.
71 */
72 public static function random_color( $color_type ) {
73 $random_color = false;
74
75 if ( 'multi-solid' === $color_type ) {
76 $r = wp_rand( 0, 254 );
77 $g = wp_rand( 0, 254 );
78 $b = wp_rand( 0, 254 );
79 $a = 0.7;
80
81 $random_color = "rgba($r, $g, $b, $a)";
82 }
83
84 if ( 'multi-gradient' === $color_type ) {
85 $color_list = array(
86 'linear-gradient(293deg, rgba(251, 218, 97, .7) -0.37%, rgba(255, 90, 205, .7) 100%)',
87 'linear-gradient(90deg, rgba(203, 173, 109, .7) 0%, rgba(213, 51, 105, .7) 100%)',
88 'linear-gradient(90deg, rgba(36, 198, 220, .7) 0%, rgba(81, 74, 157, .7) 100%)',
89 'linear-gradient(90deg, rgba(255, 224, 0, .7) 0%, rgba(255, 75, 31, .7) 100%)',
90 'linear-gradient(90deg, rgba(28, 216, 210, .7) 0%, rgba(147, 237, 199, .7) 100%)',
91 'linear-gradient(90deg, rgba(255, 212, 82, .7) 0%, rgba(84, 74, 125, .7) 100%)',
92 'linear-gradient(90deg, rgba(91, 134, 229, .7) 0%, rgba(54, 209, 220, .7) 100%)',
93 'linear-gradient(90deg, rgba(253, 185, 155, .7) 0%, rgba(167, 112, 239, .7) 100%)',
94 );
95
96 $random_color = $color_list[ array_rand( $color_list ) ];
97 }
98
99 return $random_color;
100 }
101
102 /**
103 * Renders the featured image HTML for a post.
104 *
105 * @param array $attributes The block attributes.
106 * @param array $data The post data.
107 * @param bool $cat_hide Optional. Whether to hide the category meta on the image. Default true.
108 * @return void
109 */
110 public static function feature_image( $attributes, $data, $cat_hide = true ) {
111 $image_gallery_source = $attributes['imageGallerySource'] ?? 'post_gallery';
112
113 $enable_image = isset( $attributes['imageFeaturedImg'] ) ? $attributes['imageFeaturedImg'] : true;
114 $enable_image_srcset = isset( $attributes['imageSrcset'] ) ? $attributes['imageSrcset'] : true;
115 $enable_image_lazy = isset( $attributes['imageLazyLoad'] ) ? $attributes['imageLazyLoad'] : true;
116
117 $orientation = $attributes['contentOrientation'] ?? 'orientation_one';
118 $permalink = isset( $data['link'] ) ? $data['link'] : '';
119 $post_content = isset( $data['content'] ) ? $data['content'] : '';
120
121 $post_thumbnail_url = isset( $data['post_thumbnail_url'] ) ? $data['post_thumbnail_url'] : false;
122 $attachment_srcset = isset( $data['attachment_srcset'] ) ? $data['attachment_srcset'] : false;
123
124 $target = isset( $attributes['generalLinkOpen'] ) ? $attributes['generalLinkOpen'] : '';
125
126 $target_attr = ( 'new-tab' === $target ) ? 'target=_blank' : '';
127
128 $category_position = $attributes['catTabCategoryPosition'] ?? '';
129
130 $thumbnail_image = $data['thumbnail_image'] ?? '';
131 $attachment_url = $data['attachment_url'] ?? '';
132
133 $image_hover_effect = $attributes['imageHoverEffect'] ?? 'normal';
134
135 $color_type = $attributes['imageOverlayColor'] ?? 'none';
136 $image_replace_with = $attributes['imageReplaceWith'] ?? array();
137 $toggle_custom_fallback_bg = $attributes['toggleCustomFallbackBg'] ?? 'img';
138
139 $image_replace_with_image = $attributes['imageReplaceWithImage'] ?? '';
140 $image_replace_with_video = $attributes['imageReplaceWithVideo'] ?? '';
141
142 $image_fallback_replace = $attributes['imageFallbackReplace'] ?? 'source';
143 $img_fallback_url = $image_replace_with_image['url'] ?? $image_replace_with_image;
144
145 // Prepare upload directory and placeholder image URL.
146 $placeholder_img = SP_PC_URL . 'public/assets/img/placeholder.png';
147 $placeholder_img = apply_filters( 'pcp_no_thumb_placeholder', $placeholder_img );
148
149 $image_srcset = $enable_image_srcset && ! empty( $attachment_srcset ) ? 'srcset="' . esc_attr( $attachment_srcset ) . '"' : '';
150
151 $image_lazy = $enable_image_lazy ? 'loading="lazy"' : '';
152 $image_alt_text = 'alt="' . ( ! empty( $data['image_alt'] ) ? esc_attr( $data['image_alt'] ) : esc_attr( $data['title'] ) ) . '"';
153
154 $feature_image = $post_thumbnail_url ? '<img src="' . esc_url( $post_thumbnail_url ) . '" ' . $image_srcset . ' ' . $image_lazy . ' ' . $image_alt_text . ' />' : '';
155
156 // Feature image replace to post content image or video.
157 if ( 'source' === $image_fallback_replace && empty( $feature_image ) ) {
158 $feature_image = Helper::get_media_from_content( $attributes, $data );
159 }
160
161 // Feature image replace to custom image or video.
162 if ( 'custom' === $image_fallback_replace && empty( $feature_image ) ) {
163 if ( 'img' === $toggle_custom_fallback_bg ) {
164 $feature_image = '<img src="' . esc_url( $img_fallback_url ) . '" />';
165 }
166 if ( 'video' === $toggle_custom_fallback_bg ) {
167 $feature_image = '<video controls><source src=' . esc_url( $image_replace_with_video['url'] ) . ' type="video/mp4" /></video>';
168 }
169 }
170
171 if ( empty( $feature_image ) && $attachment_url ) {
172 $feature_image = '<img src="' . esc_url( $attachment_url ) . '" ' . $image_alt_text . ' />';
173 }
174
175 $feature_image = ! empty( $feature_image ) ? $feature_image : '<img src="' . $placeholder_img . '" ' . $image_alt_text . ' />';
176
177 preg_match( '/<img[^>]+src=["\']([^"\']+)["\']/', $feature_image, $video_feature_image );
178
179 $random_bg_color = self::random_color( $color_type );
180 $show_video_play_icon_class = '';
181
182 // Category hide in feature image area.
183 if ( $cat_hide ) {
184 $cat_hide = ! in_array( $category_position, array( '', 'beside-other-meta' ), true );
185
186 if ( $cat_hide && ( 'orientation_three' === $orientation || 'orientation_four' === $orientation ) ) {
187 $cat_hide = true;
188 }
189 }
190
191 if ( $enable_image ) {
192 ob_start()
193 ?>
194 <div class="sp-smart-post-card-image img-<?php echo esc_attr( $image_hover_effect ); ?> ">
195 <a href="<?php echo esc_attr( $permalink ); ?>" <?php echo esc_attr( $target_attr ); ?>>
196 <?php
197 if ( empty( $image_gallery ) ) {
198 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
199 echo $feature_image;
200 }
201 ?>
202 </a>
203
204 <div class="image-overlay overlay-<?php echo esc_attr( $color_type ); ?>" style="background: <?php echo esc_attr( $random_bg_color ); ?>"></div>
205
206 <?php 'orientation_two' === $orientation ? self::date_two( $data ) : null; ?>
207
208 <?php
209 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
210 echo $cat_hide ? self::category( $attributes, $data ) : null;
211 ?>
212 </div>
213 <?php
214 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
215 echo ob_get_clean();
216 }
217 }
218
219 /**
220 * Renders the date in the second style.
221 *
222 * @param array $data The post data.
223 * @return void
224 */
225 public static function date_two( $data ) {
226 $post_date = isset( $data['post_date'] ) ? $data['post_date'] : '';
227
228 ob_start()
229 ?>
230 <div class="sp-smart-post-meta sp-smart-post-date">
231 <div class="sp-smart-post-date-orientation-two">
232 <span class="sp-smart-post-day">
233 <?php echo esc_html( $post_date['day'] ); ?>
234 </span>
235 <span class="sp-smart-post-month-year">
236 <?php echo esc_html( $post_date['month'] ); ?><br>
237 <?php echo esc_html( $post_date['year'] ); ?>
238 </span>
239 </div>
240 </div>
241 <?php
242 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
243 echo ob_get_clean();
244 }
245
246 /**
247 * Renders the post title HTML.
248 *
249 * @param array $attributes The block attributes.
250 * @param array $data The post data.
251 * @param array $progress Progress bar.
252 * @return string The post title HTML.
253 */
254 public static function title( $attributes, $data, $progress = false ) {
255 $show_title = isset( $attributes['titleShow'] ) ? $attributes['titleShow'] : true;
256 $title_tag = isset( $attributes['titleHTMLTag'] ) ? $attributes['titleHTMLTag'] : 'h3';
257 $title_effect = isset( $attributes['titleEffect'] ) ? $attributes['titleEffect'] : 'none';
258
259 $title = isset( $data['title'] ) ? $data['title'] : '';
260 $link = isset( $data['link'] ) ? $data['link'] : '';
261 $target = isset( $attributes['generalLinkOpen'] ) ? $attributes['generalLinkOpen'] : '';
262 $layout = $attributes['layout'] ?? '';
263 $post_id = isset( $data['post_id'] ) ? $data['post_id'] : 0;
264
265 $title_icon = in_array( $layout, array( 'sp-smart-post-list-three-layout-two', 'sp-smart-post-list-three-layout-four' ), true ) ? true : false;
266
267 $title_length = isset( $attributes['titleLength'] ) ? $attributes['titleLength'] : '';
268 $title_length_type = isset( $title_length['unit'] ) ? $title_length['unit'] : 'words';
269 $title_length_num = isset( $title_length['value'] ) ? $title_length['value'] : 'words';
270
271 $title_content = 'chars' === $title_length_type ? substr( $title, 0, $title_length_num ) : implode( ' ', array_slice( explode( ' ', $title ), 0, $title_length_num ) );
272 $title_global_typo_class = isset( $attributes['titleGlobalTypography']['class'] ) ? $attributes['titleGlobalTypography']['class'] : '';
273
274 $target_attr = ( 'new-tab' === $target ) ? 'target=_blank' : '';
275 $thumb_index = ! empty( $attributes['thumbIndex'] ) ? $attributes['thumbIndex'] : null;
276
277 // Title Badges.
278 $post_badges_show = isset( $attributes['postBadgesShow'] ) ? $attributes['postBadgesShow'] : false;
279 $post_badges_position = isset( $attributes['postBadgesPosition'] ) ? $attributes['postBadgesPosition'] : 'before-title';
280 $badges_global_typo = isset( $attributes['postBadgesGlobalTypography']['class'] ) ? $attributes['postBadgesGlobalTypography']['class'] : '';
281 $badges_list = isset( $data['badges_list'] ) ? $data['badges_list'] : array();
282
283 // Title Wrapper class.
284 $title_wrapper_class = 'sp-smart-post-title-wrapper sp-text-d-none';
285 if ( 'none' !== $title_effect ) {
286 $title_wrapper_class .= ' sp-title-effect-' . esc_attr( $title_effect );
287 }
288
289 if ( ! empty( $title ) && $show_title ) {
290 ob_start()
291 ?>
292 <a href="<?php echo esc_attr( $link ); ?>" <?php echo esc_attr( $target_attr ); ?> class="<?php echo esc_attr( $title_wrapper_class ); ?>" data-post-id="<?php echo esc_attr( $post_id ); ?>">
293 <?php if ( $title_icon ) { ?>
294 <i class="sp-icon-right-dir sp-smart-post-title-icon"></i>
295 <?php } ?>
296 <<?php echo esc_html( $title_tag ); ?> class="sp-smart-post-title <?php echo esc_attr( $title_global_typo_class ); ?>">
297 <?php if ( $thumb_index ) : ?>
298 <span class="sp-thumb-item-page-id"> <?php echo esc_html( $thumb_index ); ?></span>
299 <?php endif; ?>
300 <span class="sp-smart-post-title-text"><?php echo wp_kses_post( $title_content ); ?></span>
301 </<?php echo esc_html( $title_tag ); ?>>
302 <?php if ( $progress ) : ?>
303 <span class="sp-thumbnail-progress-bar"></span>
304 <?php endif; ?>
305 </a>
306
307
308
309 <?php
310 return ob_get_clean();
311 }
312 }
313
314 /**
315 * Renders the post category HTML.
316 *
317 * @param array $attributes The block attributes.
318 * @param array $data The post data.
319 * @return string The post category HTML.
320 */
321 public static function category( $attributes, $data ) {
322 $show_category = isset( $attributes['catTabCategoryEnable'] ) ? $attributes['catTabCategoryEnable'] : true;
323 $category_type = isset( $attributes['catTabCategoryType'] ) ? $attributes['catTabCategoryType'] : 'category';
324
325 $category_list = isset( $data['category_list'] ) ? $data['category_list'] : '';
326 $cat_tab_category_type = isset( $attributes['catTabCategoryType'] ) ? $attributes['catTabCategoryType'] : '';
327 $tag_list = isset( $data['tag_list'] ) ? $data['tag_list'] : '';
328 $all_term_list = isset( $data['all_term_list'] ) ? $data['all_term_list'] : '';
329
330 $social_share_icon_position = isset( $attributes['socialShareIconPosition'] ) ? $attributes['socialShareIconPosition'] : '';
331
332 $social_icon_display_type = isset( $attributes['socialIconDisplayType'] ) ? $attributes['socialIconDisplayType'] : 'inline-icon';
333
334 $show_social_share = ( 'popup-share' === $social_icon_display_type && ( 'beside-taxonomy' === $social_share_icon_position || 'space-between-taxonomy' === $social_share_icon_position ) ) ? true : false;
335
336 $global_typo_class = isset( $attributes['catTabCategoryGlobalTypography']['class'] ) ? $attributes['catTabCategoryGlobalTypography']['class'] : '';
337
338 $taxonomy_list = array(
339 'category' => $category_list,
340 'post_tag' => $tag_list,
341 );
342 if ( '' === $cat_tab_category_type ) {
343 $taxonomy_list[ $cat_tab_category_type ] = $all_term_list;
344 }
345
346 if ( $show_category ) {
347 ob_start()
348 ?>
349 <div class="<?php echo esc_attr( $global_typo_class ); ?> sp-smart-post-category">
350 <span class="sp-taxonomy-type-<?php echo esc_attr( $cat_tab_category_type ); ?>">
351 <?php echo wp_kses_post( $taxonomy_list[ $cat_tab_category_type ] ); ?>
352 </span>
353 <?php
354 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
355 echo $show_social_share ? self::social_share( $attributes, $data ) : '';
356 ?>
357 </div>
358 <?php
359 return ob_get_clean();
360 }
361 }
362
363 /**
364 * Renders the post category HTML in the second style.
365 *
366 * @param array $attributes The block attributes.
367 * @param array $data The post data.
368 * @return string The post category HTML.
369 */
370 public static function category_two( $attributes, $data ) {
371 $show_category = isset( $attributes['catTabCategoryEnable'] ) ? $attributes['catTabCategoryEnable'] : true;
372
373 $category_type = isset( $attributes['catTabCategoryType'] ) ? $attributes['catTabCategoryType'] : 'category';
374
375 $category_list = isset( $data['category_list'] ) ? $data['category_list'] : '';
376 $tag_list = isset( $data['tag_list'] ) ? $data['tag_list'] : '';
377 $all_term_list = isset( $data['all_term_list'] ) ? $data['all_term_list'] : '';
378
379 $taxonomy_list = array(
380 'category' => $category_list,
381 'post_tag' => $tag_list,
382 );
383 if ( '' === $category_type ) {
384 $taxonomy_list[ $category_type ] = $all_term_list;
385 }
386
387 if ( $show_category ) {
388 ob_start()
389 ?>
390 <span class="sp-smart-post-meta sp-metadata-taxonomy">
391 <span class="sp-smart-post-meta-icon sp-metadata-taxonomy-icon">
392 <?php
393 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
394 echo Helper::get_svg_icon( 'taxonomy' );
395 ?>
396 </span>
397 <span class="sp-smart-post-meta-text">
398 <?php echo wp_kses_post( $taxonomy_list[ $category_type ] ); ?>
399 </span>
400 </span>
401 <?php
402
403 return ob_get_clean();
404 }
405 }
406
407
408 /**
409 * Renders the post author HTML.
410 *
411 * @param array $attributes The block attributes.
412 * @param array $data The post data.
413 * @return string The post author HTML.
414 */
415 public static function author( $attributes, $data ) {
416 $author = isset( $data['author'] ) ? $data['author'] : '';
417 $author_url = isset( $data['author_url'] ) ? $data['author_url'] : '';
418 $author_style = isset( $attributes['metaAuthorStyle'] ) ? $attributes['metaAuthorStyle'] : 'name_with_icon';
419
420 $avatar_url = isset( $data['author_avatar_url'] ) ? $data['author_avatar_url'] : '';
421
422 // Author .
423 $icon_type = isset( $attributes['metaUserIcon'] ) ? $attributes['metaUserIcon'] : 'outline';
424
425 $user_icon = Helper::get_author_icon( $icon_type );
426
427 ob_start()
428 ?>
429 <span class="sp-smart-post-meta sp-smart-post-author">
430 <a href="<?php echo esc_attr( $author_url ); ?>">
431 <?php if ( 'name_with_icon' === $author_style ) { ?>
432 <span class="sp-smart-post-meta-icon">
433 <?php
434 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
435 echo $user_icon;
436 ?>
437 </span>
438 <?php } ?>
439 <?php if ( 'show_gravatar' === $author_style || 'name_with_gravatar' === $author_style ) { ?>
440 <img src="<?php echo esc_attr( $avatar_url ); ?>" alt="<?php echo esc_attr( $author ); ?>" class="sp-smart-post-meta-icon"/>
441 <?php } ?>
442 <?php if ( 'show_gravatar' !== $author_style ) { ?>
443 <span class="sp-smart-post-meta-text">
444 <?php echo esc_html( $author ); ?>
445 </span>
446 <?php } ?>
447 </a>
448 </span>
449 <?php
450
451 return ob_get_clean();
452 }
453
454
455 /**
456 * Renders the post date HTML.
457 *
458 * @param array $attributes Block attributes.
459 * @param array $data The post data.
460 * @return string The post date HTML.
461 */
462 public static function date( $attributes, $data ) {
463 $post_date = $data['post_date'] ?? '';
464
465 $date_format = $attributes['metaDateFormat'] ?? 'default';
466
467 $display_date = $post_date['default'] ?? '';
468
469 if ( 'time_ago' === $date_format ) {
470 $time = get_the_date( 'Y-m-d', $data['post_id'] );
471 $display_date = Helper::simple_time_ago( $time );
472 }
473
474 ob_start()
475 ?>
476 <div class="sp-smart-post-meta sp-smart-post-date">
477 <div class="sp-smart-post-meta-icon">
478 <?php
479 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
480 echo Helper::get_svg_icon( 'meta-date' );
481 ?>
482 </div>
483 <span class="sp-smart-post-meta-text">
484 <?php echo esc_html( $display_date ); ?>
485 </span>
486 </div>
487 <?php
488
489 return ob_get_clean();
490 }
491
492
493 /**
494 * Renders the post comment count HTML.
495 *
496 * @param array $data The post data.
497 * @return string The post comment count HTML.
498 */
499 public static function comment( $data ) {
500 $post_id = $data['post_id'] ?? 0;
501 $comment_count = get_comment_count( $post_id );
502
503 ob_start()
504 ?>
505 <span class="sp-smart-post-meta sp-post-show-comment">
506 <span class="sp-smart-post-meta-icon">
507 <?php
508 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
509 echo Helper::get_svg_icon( 'comments-count' );
510 ?>
511 </span>
512 <span class="sp-smart-post-meta-text">
513 <?php echo esc_html( $comment_count['total_comments'] ); ?>
514 </span>
515 </span>
516 <?php
517 return ob_get_clean();
518 }
519
520
521 /**
522 * Renders the post view count HTML.
523 *
524 * @param array $data The post data.
525 * @return string The post view count HTML.
526 */
527 public static function views( $data ) {
528 $post_id = $data['post_id'] ?? 0;
529 $view_count = get_post_meta( $post_id, '_post_views_count', true );
530
531 ob_start()
532 ?>
533 <span class="sp-smart-post-meta sp-smart-post-view">
534 <span class="sp-smart-post-meta-icon">
535 <?php
536 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
537 echo Helper::get_svg_icon( 'view-count' );
538 ?>
539 </span>
540 <span class="sp-smart-post-meta-text">
541 <?php echo esc_html( ! empty( $view_count ) ? $view_count : 0 ); ?>
542 </span>
543 </span>
544 <?php
545 return ob_get_clean();
546 }
547
548 /**
549 * Calculates the estimated reading time for a given content.
550 *
551 * @param string $content The content to calculate reading time for.
552 * @param int $per_minutes Words per minute.
553 * @return int Estimated reading time in minutes.
554 */
555 public static function get_reading_time( $content, $per_minutes = 30 ) {
556 $words = explode( ' ', wp_strip_all_tags( $content ) );
557
558 $total_worlds = count( $words );
559 $per_minutes = max( 1, (int) $per_minutes );
560 $time = $total_worlds / $per_minutes;
561 return floor( $time );
562 }
563
564 /**
565 * Renders the estimated reading time HTML for a post.
566 *
567 * @param array $data The post data.
568 * @param array $attributes Block attributes.
569 * @return string The estimated reading time HTML.
570 */
571 public static function read_time( $data, $attributes ) {
572
573 $excerpt = isset( $data['excerpt'] ) ? $data['excerpt'] : '';
574 $all_content = isset( $data['content'] ) ? $data['content'] : '';
575 $per_minutes = isset( $attributes['metaPerMin']['value'] ) ? $attributes['metaPerMin']['value'] : '';
576
577 ob_start()
578 ?>
579 <span class="sp-smart-post-meta sp-smart-post-reading-time">
580 <span class="sp-smart-post-meta-icon">
581 <?php
582 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
583 echo Helper::get_svg_icon( 'read-time' );
584 ?>
585 </span>
586 <span class="sp-smart-post-meta-text">
587 <?php echo esc_html( self::get_reading_time( $all_content, $per_minutes ) ); ?> Min Read
588 </span>
589 </span>
590 <?php
591
592 return ob_get_clean();
593 }
594
595 /**
596 * Undocumented variable
597 *
598 * @var array
599 */
600 public static $separator = array(
601 'normal-space' => '<span>&nbsp;</span>',
602 'full-stop' => '<span>&#46;</span>',
603 'straight-line' => '<span>&#124;</span>',
604 'slash' => '<span>&#47;</span>',
605 'back-slash' => '<span>&#92;</span>',
606 );
607
608 /**
609 * Meta Separator Markup function
610 *
611 * @param string $attr meta separator type name.
612 *
613 * @return string html markup.
614 */
615 public static function meta_separator( $attr ) {
616 if ( empty( $attr ) || 'normal-space' === $attr ) {
617 return '';
618 }
619
620 ob_start();
621 ?>
622 <span class='sp-smart-post-meta-separator'>
623 <?php
624 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
625 echo self::$separator[ $attr ];
626 ?>
627 </span>
628 <?php
629 return ob_get_clean();
630 }
631
632 /**
633 * Renders the post meta data HTML.
634 *
635 * @param array $attributes The block attributes.
636 * @param array $data The post data.
637 * @return string The post meta data HTML.
638 */
639 public static function meta_data( $attributes, $data ) {
640 $show_meta_data = ! empty( $attributes['enableMetaData'] ) ? $attributes['enableMetaData'] : false;
641 $meta_data_attr = isset( $attributes['metaDataAllContentArray'] ) ? $attributes['metaDataAllContentArray'] : array();
642
643 $meta_data_separator = isset( $attributes['metaSeparator'] ) ? $attributes['metaSeparator'] : '';
644
645 $have_meta_item = false;
646 foreach ( $meta_data_attr as $item ) {
647 if ( $item['show'] ) {
648 $have_meta_item = true;
649 break;
650 }
651 }
652 if ( ! $show_meta_data || ! $have_meta_item ) {
653 return ''; // If metadata has no value to show or metadata show is false.
654 }
655
656 $orientation = $attributes['contentOrientation'] ?? 'orientation_one';
657
658 $category_position = $attributes['catTabCategoryPosition'] ?? '';
659
660 $social_share_icon_position = isset( $attributes['socialShareIconPosition'] ) ? $attributes['socialShareIconPosition'] : '';
661
662 $social_icon_display_type = isset( $attributes['socialIconDisplayType'] ) ? $attributes['socialIconDisplayType'] : 'inline-icon';
663 $meta_display_type = isset( $attributes['metaDisplayType'] ) ? $attributes['metaDisplayType'] : 'inline';
664
665 $show_social_share = ( 'popup-share' === $social_icon_display_type && ( 'beside-meta' === $social_share_icon_position || 'space-between-meta' === $social_share_icon_position ) ) ? true : false;
666
667 $meta_right_array = array( 'comments', 'views', 'likes', 'social-share' );
668
669 $meta_global_typo_class = isset( $attributes['metaGlobalTypography']['class'] ) ? $attributes['metaGlobalTypography']['class'] : '';
670
671 $meat_data = array(
672 'author' => self::author( $attributes, $data ),
673 'date' => 'orientation_two' !== $orientation ? self::date( $attributes, $data ) : null,
674 'comments' => self::comment( $data ),
675 'views' => self::views( $data ),
676 // 'likes' => self::like( $data ),
677 'reading-time' => self::read_time( $data, $attributes ),
678 'taxonomy' => 'beside-other-meta' === $category_position ? self::category_two( $attributes, $data ) : null,
679 );
680
681 // Social Share popup class.
682 $social_enable = ! empty( $attributes['socialShareEnableSocial'] ) ?? false;
683 $social_display_type = isset( $attributes['socialIconDisplayType'] ) ? $attributes['socialIconDisplayType'] : '';
684 $social_icon_position = isset( $attributes['socialShareIconPosition'] ) ? $attributes['socialShareIconPosition'] : '';
685
686 $social_condition = $social_enable && 'popup-share' === $social_display_type && 'space-between-meta' === $social_icon_position;
687
688 $social_share_classes = $social_condition ? ' sp-space-between' : '';
689
690 ob_start();
691 ?>
692 <div class="sp-meta-data sp-d-flex sp-smart-post-meta-details-<?php echo esc_attr( $meta_display_type ); ?><?php echo esc_attr( $social_share_classes ); ?>">
693 <?php if ( 'inline' === $meta_display_type ) : ?>
694 <span class="sp-smart-post-details <?php echo esc_attr( $meta_global_typo_class ); ?>">
695 <?php
696 foreach ( $meta_data_attr as $meta ) {
697 if ( $meta['show'] ) {
698 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
699 echo $meat_data[ $meta['value'] ];
700 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
701 echo self::meta_separator( $meta_data_separator );
702 }
703 }
704 ?>
705 </span>
706 <?php
707 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
708 echo ( $show_social_share ) ? self::social_share( $attributes, $data ) : '';
709 ?>
710 <?php endif; ?>
711 <?php if ( 'inline' !== $meta_display_type ) : ?>
712 <span class="sp-smart-post-details-left">
713 <span class="sp-smart-post-details <?php echo esc_attr( $meta_global_typo_class ); ?>">
714 <?php
715 foreach ( $meta_data_attr as $meta ) {
716 if ( $meta['show'] && ! in_array( $meta['value'], $meta_right_array ) ) {
717 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
718 echo $meat_data[ $meta['value'] ];
719 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
720 echo self::meta_separator( $meta_data_separator );
721 }
722 }
723 ?>
724 </span>
725 </span>
726 <span class="sp-smart-post-details-right">
727 <span class="sp-smart-post-details <?php echo esc_attr( $meta_global_typo_class ); ?>">
728 <?php
729 foreach ( $meta_data_attr as $meta ) {
730 if ( $meta['show'] && in_array( $meta['value'], $meta_right_array, true ) ) {
731 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
732 echo $meat_data[ $meta['value'] ];
733 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
734 echo self::meta_separator( $meta_data_separator );
735 }
736 }
737 ?>
738 </span>
739 <?php
740 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
741 echo ( $show_social_share ) ? self::social_share( $attributes, $data ) : '';
742 ?>
743 </span>
744 <?php endif; ?>
745 </div>
746 <?php
747
748 return ob_get_clean();
749 }
750
751 /**
752 * Outputs the post excerpt HTML.
753 *
754 * @param array $attributes Block attributes.
755 * @param array $data Post data.
756 * @return string Excerpt HTML.
757 */
758 public static function excerpt( $attributes, $data ) {
759 $show_excerpt = isset( $attributes['excerptShow'] ) ? $attributes['excerptShow'] : true;
760
761 $excerpt_type = isset( $attributes['excerptType'] ) ? $attributes['excerptType'] : 'limited';
762
763 $excerpt_ending_points = isset( $attributes['ellipsisPointsEndingExcerpt'] ) ? $attributes['ellipsisPointsEndingExcerpt'] : '';
764
765 $excerpt_ending_points = 'full' !== $excerpt_type ? $excerpt_ending_points : '';
766
767 $excerpt = isset( $data['excerpt'] )
768 ? $data['excerpt'] : '';
769 $excerpt_length = isset( $attributes['excerptLength'] )
770 ? $attributes['excerptLength'] : array();
771 $excerpt_length_type = isset( $excerpt_length['unit'] )
772 ? $excerpt_length['unit'] : '';
773 $excerpt_length_num = isset( $excerpt_length['value'] )
774 ? $excerpt_length['value'] : '';
775
776 $excerpt_content = 'chars' === $excerpt_length_type ? substr( $excerpt, 0, $excerpt_length_num ) : implode( ' ', array_slice( explode( ' ', $excerpt ), 0, $excerpt_length_num ) );
777 $excerpt_display = 'full' === $excerpt_type ? $excerpt : $excerpt_content;
778
779 $excerpt_global_typo_class = isset( $attributes['excerptGlobalTypography']['class'] ) ? $attributes['excerptGlobalTypography']['class'] : '';
780 $layout = $attributes['layout'] ?? '';
781
782 $excerpt_button = 'sp-smart-post-list-two-layout-seven' === $layout ? self::read_more_button_two( $attributes, $data ) : '';
783
784 if ( ! empty( $excerpt ) && $show_excerpt ) {
785 ob_start()
786 ?>
787 <div class="sp-smart-post-excerpt-wrapper">
788 <p class="sp-smart-post-excerpt <?php echo esc_attr( $excerpt_global_typo_class ); ?>">
789 <?php echo esc_html( $excerpt_display . $excerpt_ending_points ); ?>
790 <?php
791 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
792 echo $excerpt_button;
793 ?>
794 </p>
795 </div>
796 <?php
797 return ob_get_clean();
798 }
799 }
800
801 /**
802 * Renders the read more button HTML.
803 *
804 * @param array $attributes The block attributes.
805 * @param array $data The post data.
806 * @return string The read more button HTML.
807 */
808 public static function read_more_button( $attributes, $data ) {
809 $show_read_more_button = isset( $attributes['showReadMoreButton'] ) ? $attributes['showReadMoreButton'] : true;
810 $permalink = isset( $data['link'] ) ? $data['link'] : '';
811 $target = isset( $attributes['generalLinkOpen'] ) ? $attributes['generalLinkOpen'] : '';
812 $button_text = isset( $attributes['readMoreButtonLabel'] ) ? $attributes['readMoreButtonLabel'] : '';
813 $button_icon_style = isset( $attributes['readMoreIconStyle'] ) ? $attributes['readMoreIconStyle'] : '';
814
815 $target_attr = ( 'new-tab' === $target ) ? 'target=_blank' : '';
816
817 $icon_visibility = isset( $attributes['readMoreIocVisibility'] ) ? $attributes['readMoreIocVisibility'] : '';
818 $read_more_button_type = isset( $attributes['readMoreButtonType'] ) ? $attributes['readMoreButtonType'] : '';
819
820 $global_typo_class = isset( $attributes['readMoreButtonGlobalTypography']['class'] ) ? $attributes['readMoreButtonGlobalTypography']['class'] : '';
821
822 $icon_visibility_class = ' sp-read-more-icon-' . $icon_visibility;
823
824 if ( $show_read_more_button ) {
825 ob_start()
826 ?>
827 <div class="sp-smart-post-read-more-button">
828 <a href="<?php echo esc_attr( $permalink ); ?>"
829 class="sp-smart-post-read-more-btn-link type-<?php echo esc_attr( $read_more_button_type ); ?> <?php echo esc_attr( $global_typo_class ); ?>"
830 <?php
831 echo esc_attr( $target_attr );
832 ?>
833 role="button">
834 <?php echo esc_html( $button_text ); ?>
835 <i class="sp-icon-<?php echo esc_attr( $button_icon_style . $icon_visibility_class ); ?>"></i>
836 </a>
837 </div>
838 <?php
839 return ob_get_clean();
840 }
841 }
842
843 /**
844 * Renders the read more button HTML.
845 *
846 * @param array $attributes The block attributes.
847 * @param array $data The post data.
848 * @return string The read more button HTML.
849 */
850 public static function read_more_button_two( $attributes, $data ) {
851 $show_read_more_button = isset( $attributes['showReadMoreButton'] ) ? $attributes['showReadMoreButton'] : true;
852 $permalink = isset( $data['link'] ) ? $data['link'] : '';
853 $target = isset( $attributes['generalLinkOpen'] ) ? $attributes['generalLinkOpen'] : '';
854 $button_text = isset( $attributes['readMoreButtonLabel'] ) ? $attributes['readMoreButtonLabel'] : '';
855
856 $button_icon_style = isset( $attributes['readMoreIconStyle'] ) ? $attributes['readMoreIconStyle'] : '';
857
858 $target_attr = ( 'new-tab' === $target ) ? 'target=_blank' : '';
859
860 if ( $show_read_more_button ) {
861 ob_start()
862 ?>
863 <a href="<?php echo esc_attr( $permalink ); ?>" class="sp-smart-post-excerpt-read-more"
864 <?php
865 echo esc_attr(
866 $target_attr
867 );
868 ?>
869 role="button">
870 <?php echo esc_html( $button_text ); ?>
871 </a>
872 <?php
873 return ob_get_clean();
874 }
875 }
876 /**
877 * Renders the swiper navigation arrows HTML.
878 *
879 * @param mixed $nav_arrow_visibility_hover Whether the navigation arrow is visible on hover.
880 * @param mixed $style The style of the navigation arrow.
881 * @return void
882 */
883 public static function swiper_nav_arrow( $nav_arrow_visibility_hover, $style = 'open' ) {
884 ob_start();
885 ?>
886 <div class="sp-smart-post-swiper-nav-arrow <?php echo $nav_arrow_visibility_hover ? ' visible-on-hover' : ''; ?>">
887 <span class="sp-smart-post-swiper-nav-arrow-btn btn-prev"><i>
888 <?php
889 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
890 echo Helper::get_arrow_icon( $style );
891 ?>
892 </i></span>
893 <span class="sp-smart-post-swiper-nav-arrow-btn btn-next"> <i>
894 <?php
895 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
896 echo Helper::get_arrow_icon( $style );
897 ?>
898 </i></span>
899 </div>
900 <?php
901 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
902 echo ob_get_clean();
903 }
904
905 /**
906 * Pagination
907 *
908 * @param mixed $bullet_style The style of the pagination bullets.
909 * @param mixed $vertical Whether the pagination is vertical.
910 * @return void
911 */
912 public static function pagination( $bullet_style = 'bullets', $vertical = false ) {
913 ob_start();
914 ?>
915 <div class="swiper-pagination sp-smart-post-pagination-<?php echo esc_attr( $bullet_style ); ?>
916 <?php
917 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
918 echo $vertical ? 'sp-pagination-vertical' : 'sp-pagination-horizontal';
919 ?>
920 sp-mt-10">
921 </div>
922 <?php
923 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
924 echo ob_get_clean();
925 }
926
927 /**
928 * Renders the social sharing links HTML.
929 *
930 * @param array $attributes The block attributes.
931 * @param array $data The post data.
932 * @return void The social sharing links HTML.
933 */
934 public static function social_links( $attributes, $data ) {
935 $permalink = isset( $data['link'] ) ? $data['link'] : '';
936 $social_sharing_media = isset( $attributes['socialSharingMedia'] ) ? $attributes['socialSharingMedia'] : array();
937 $social_share_icon_type = isset( $attributes['socialShareIconType'] ) ? $attributes['socialShareIconType'] : 'original';
938 $social_icon_display_type = isset( $attributes['socialIconDisplayType'] ) ? $attributes['socialIconDisplayType'] : 'inline-icon';
939
940 $social_sharing_links = array(
941 'clone' => '',
942 'facebook' => 'https://www.facebook.com/sharer/sharer.php?u=' . $permalink,
943 'twitter' => 'https://twitter.com/intent/tweet?url=' . $permalink,
944 'x' => 'https://twitter.com/intent/tweet?url=' . $permalink,
945 'linkedin' => 'https://www.linkedin.com/sharing/share-offsite/?url=' . $permalink,
946 'pinterest' => 'https://pinterest.com/pin/create/button/?url=' . $permalink . '&media=' . $data['post_thumbnail_url'],
947 'instagram' => 'https://www.instagram.com/?url=' . $permalink,
948 'vkontakte' => 'https://vk.com/share.php?url=' . $permalink,
949 'digg' => 'http://digg.com/submit?url=' . $permalink,
950 'tumblr' => 'https://www.tumblr.com/widgets/share/tool?canonicalUrl=' . $permalink,
951 'reddit' => 'https://www.reddit.com/submit?url=' . $permalink,
952 'whatsapp' => 'https://api.whatsapp.com/send?text=' . $permalink,
953 'pocket' => 'https://getpocket.com/save?url=' . $permalink,
954 'xing' => 'https://www.xing.com/spi/shares/new?url=' . $permalink,
955 'mail' => 'mailto:?subject=&body=' . $permalink,
956 );
957 ob_start();
958 ?>
959 <ul class="sp-smart-post-social-share <?php echo esc_attr( $social_share_icon_type ); ?>-css">
960 <?php
961 foreach ( $social_sharing_media as $social ) {
962 ?>
963 <li class="sp-smart-post-social-share-icon sp-li-style-none" style="pointer-events: all;">
964 <?php
965 if ( 'clone' === $social['value'] ) {
966 ?>
967 <span class="sp-copy-url-area">
968 <a href="#" title="Copy post URL" class="sp-smart-post-social-share-link sp-smart-post-copy-btn"
969 data-url="<?php echo esc_attr( $permalink ); ?>" data-action="copy">
970 <i class='sp-icon-clone'></i>
971 <div class="sp-post-url-copy-popup sp-d-hidden">
972 Copied!
973 </div>
974 </a>
975 </span>
976 <?php
977 } else {
978 ?>
979 <a href="<?php echo esc_attr( $social_sharing_links[ $social['value'] ] ); ?>" target="_blank"
980 rel="noopener noreferrer" class="sp-smart-post-social-share-link"
981 title="<?php echo esc_attr( $social['label'] ); ?>" data-action="share">
982 <i class="sp-icon-<?php echo esc_attr( $social['value'] ); ?>"></i>
983 </a>
984 <?php
985 }
986 ?>
987 </li>
988 <?php
989 }
990 ?>
991 </ul>
992 <?php
993 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
994 echo ob_get_clean();
995 }
996
997 /**
998 * Outputs the taxonomy filter HTML for the block.
999 *
1000 * @param array $attributes Block attributes.
1001 * @return void
1002 */
1003 public static function taxonomy_filter( $attributes ) {
1004 $unique_id = $attributes['uniqueId'] ?? '';
1005 $post_type = $attributes['postType'] ?? 'post';
1006 $post_query = $attributes['postQuery'] ?? '';
1007 $filter_type = $attributes['filterType'] ?? 'dropdown';
1008 $taxonomy_type = $attributes['taxonomyType'] ?? 'category';
1009 $select_terms_type = $attributes['selectTermsType'] ?? 'all';
1010 $selected_terms = $attributes['selectedTerms'] ?? array();
1011 $exclude_terms = $attributes['excludeTerms'] ?? array();
1012 $hide_empty_term = $attributes['hideEmptyTerm'] ?? false;
1013 $category_label = $attributes['categoryLabel'] ?? true;
1014 $override_category_label = $attributes['overrideCategoryLabel'] ?? '';
1015 $override_category_text = $attributes['overrideCategoryText'] ?? '';
1016 $all_text_label = $attributes['allTextLabel'] ?? 'All';
1017 $show_post_counter = $attributes['showPostCount'] ?? false;
1018 $search_in_dropdown = $attributes['searchInDropdown'] ?? false;
1019 $additional_css_class = $attributes['additionalCssClass'] ?? '';
1020 $title_global_typo_class = isset( $attributes['titleGlobalTypography']['class'] ) ? $attributes['titleGlobalTypography']['class'] : '';
1021 $option_global_typo_class = isset( $attributes['optionGlobalTypography']['class'] ) ? $attributes['optionGlobalTypography']['class'] : '';
1022 $exclude_terms_ids = array();
1023 ?>
1024 <div class="sp-smart-post-taxonomy-filter <?php echo esc_attr( $additional_css_class ); ?>" data-show-count="<?php echo esc_attr( $show_post_counter ); ?>">
1025 <div id="<?php echo esc_html( $unique_id ); ?>" class="sp-smart-post-live-filter-wrapper">
1026 <select class='sp-d-hidden' id="filter-<?php echo esc_attr( $taxonomy_type ); ?>" name="tx_<?php echo esc_attr( $taxonomy_type ); ?>">
1027 <option value=""><?php echo esc_html( $all_text_label ); ?></option>
1028 <?php
1029 if ( 'specific' === $select_terms_type && ! empty( $selected_terms ) ) {
1030 foreach ( $selected_terms as $term ) {
1031 $term = get_term( $term['value'], $taxonomy_type );
1032 $slug = $term->slug ?? '';
1033 $post_count = $term->count ?? 0;
1034 $term_label = $term->name ?? '';
1035 ?>
1036 <option value="<?php echo esc_attr( $slug ); ?>" data-default-count="<?php echo intval( $post_count ); ?>" data-label="<?php echo esc_html( $term_label ); ?>"><?php echo esc_html( $term_label ); ?>
1037 <?php echo $show_post_counter ? intval( $post_count ) : ''; ?>
1038 </option>
1039 <?php
1040 }
1041 } else {
1042 $taxonomy_terms = get_terms(
1043 array(
1044 'taxonomy' => $taxonomy_type,
1045 'hide_empty' => $hide_empty_term,
1046 )
1047 );
1048 if ( 'exclude' === $select_terms_type ) {
1049 $exclude_terms_ids = array_column( $exclude_terms, 'slug' );
1050 }
1051
1052 foreach ( $taxonomy_terms as $term ) {
1053 if ( in_array( $term->slug, $exclude_terms_ids ) ) {
1054 continue;
1055 }
1056 $slug = $term->slug ?? '';
1057 $post_count = $term->count ?? 0;
1058 $term_label = $term->name ?? '';
1059
1060 ?>
1061 <option value="<?php echo esc_attr( $slug ); ?>" data-default-count="<?php echo intval( $post_count ); ?>" data-label="<?php echo esc_html( $term_label ); ?>">
1062 <?php echo esc_html( $term_label ); ?> <?php echo $show_post_counter ? intval( $post_count ) : ''; ?>
1063 </option>
1064 <?php
1065 }
1066 }
1067 ?>
1068 </select>
1069 <div class="sp-smart-post-taxonomy-filter sp-smart-post-live-filter" data-show-count="<?php echo esc_attr( $show_post_counter ); ?>">
1070 <?php if ( $category_label ) : ?>
1071 <span class="sp-smart-post-live-filter-label <?php echo esc_attr( $title_global_typo_class ); ?>">
1072 <?php echo esc_html( $override_category_label ? $override_category_label : str_replace( '_', ' ', $taxonomy_type ) ); ?>
1073 </span>
1074 <?php endif; ?>
1075 <?php if ( 'dropdown' === $filter_type ) { ?>
1076 <button class="sp-smart-post-live-filter-btn <?php echo esc_attr( $option_global_typo_class ); ?>">
1077 <span><?php echo esc_html( $all_text_label ); ?></span>
1078 <?php
1079 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1080 echo Helper::get_svg_icon( 'arrow-down' );
1081 ?>
1082 </button>
1083 <?php } ?>
1084 <ul class="sp-smart-post-live-filter-<?php echo esc_html( $filter_type ); ?>">
1085 </ul>
1086 </div>
1087 </div>
1088 </div>
1089 <?php
1090 }
1091
1092 /**
1093 * Renders the HTML for the author filter.
1094 *
1095 * @param array $attributes The block attributes.
1096 * @return void
1097 */
1098 public static function author_filter( $attributes ) {
1099 $unique_id = $attributes['uniqueId'] ?? '';
1100 $show_author_label = $attributes['showAuthorLabel'] ?? '';
1101 $author_label = $attributes['authorLabel'] ?? '';
1102 $filter_type = $attributes['filterType'] ?? '';
1103 $post_type = $attributes['postType'] ?? 'post';
1104 $taxonomy_type = $attributes['taxonomyType'] ?? '';
1105 $search_in_dropdown = $attributes['searchInDropdown'] ?? '';
1106 $exclude_author = $attributes['excludeAuthor'] ?? array();
1107 $author_type = $attributes['authorType'] ?? 'All';
1108 $specific_author = $attributes['specificAuthor'] ?? array();
1109 $all_text_label = $attributes['allTextLabel'] ?? 'All';
1110 $show_post_count = $attributes['showPostCount'] ?? false;
1111 $show_search_field_dropdown = $attributes['showSearchFieldInDropdown'] ?? false;
1112 $title_global_typo_class = isset( $attributes['titleGlobalTypography']['class'] ) ? $attributes['titleGlobalTypography']['class'] : '';
1113 $option_global_typo_class = isset( $attributes['optionGlobalTypography']['class'] ) ? $attributes['optionGlobalTypography']['class'] : '';
1114 $additional_css_class = $attributes['additionalCssClass'] ?? '';
1115 $exclude_author_ids = array();
1116 ?>
1117 <div class="sp-smart-post-taxonomy-filter <?php echo esc_attr( $additional_css_class ); ?>" data-show-count="<?php echo esc_attr( $show_post_count ); ?>">
1118 <div id="<?php echo esc_html( $unique_id ); ?>" class="sp-smart-post-live-filter-wrapper">
1119 <select class='sp-d-hidden' id="filter-author" name="sps_author">
1120 <option value=""><?php echo esc_html( $all_text_label ); ?></option>
1121 <?php
1122 if ( 'all' === $author_type || 'exclude' === $author_type ) {
1123 $authors = get_users(
1124 array(
1125 'orderby' => 'display_name',
1126 'order' => 'ASC',
1127 )
1128 );
1129 if ( 'exclude' === $author_type ) {
1130 $exclude_author_ids = array_column( $exclude_author, 'id' );
1131 }
1132 foreach ( $authors as $author ) {
1133 if ( in_array( $author->data->ID, $exclude_author_ids ) ) {
1134 continue;
1135 }
1136 $post_count = count_user_posts( $author->data->ID, $post_type );
1137 ?>
1138 <option value="<?php echo esc_attr( $author->data->ID ); ?>"
1139 data-default-count="<?php echo intval( $post_count ); ?>" data-label="<?php echo esc_html( $author->data->display_name ); ?>">
1140 <?php echo esc_html( $author->data->display_name ); ?>
1141 (<?php echo intval( $post_count ); ?>)
1142 </option>
1143 <?php
1144 }
1145 } else {
1146 foreach ( $specific_author as $author ) {
1147 $post_count = count_user_posts( $author['id'], $post_type );
1148 ?>
1149 <option value="<?php echo esc_attr( $author['id'] ); ?>"
1150 data-default-count="<?php echo intval( $post_count ); ?>" data-label="<?php echo esc_html( $author['label'] ); ?>">
1151 <?php echo esc_html( $author['label'] ); ?>
1152 (<?php echo intval( $post_count ); ?>)
1153 </option>
1154 <?php
1155 }
1156 }
1157 ?>
1158 </select>
1159
1160 <div class="sp-smart-post-taxonomy-filter sp-smart-post-live-filter" data-show-count="<?php echo esc_attr( $show_post_count ); ?>">
1161 <?php if ( $show_author_label ) : ?>
1162 <span class="sp-smart-post-live-filter-label <?php echo esc_attr( $title_global_typo_class ); ?>">
1163 <?php echo esc_html( $author_label ); ?>
1164 </span>
1165 <?php endif; ?>
1166 <?php if ( 'dropdown' === $filter_type ) { ?>
1167 <button class="sp-smart-post-live-filter-btn <?php echo esc_attr( $option_global_typo_class ); ?>">
1168 <span>All Author</span>
1169 <?php
1170 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1171 echo Helper::get_svg_icon( 'arrow-down' );
1172 ?>
1173 </button>
1174 <?php } ?>
1175 <ul class="sp-smart-post-live-filter-<?php echo esc_html( $filter_type ); ?>">
1176 </ul>
1177 </div>
1178 </div>
1179 </div>
1180 <?php
1181 }
1182
1183 /**
1184 * Live filter html.
1185 *
1186 * @return void
1187 */
1188 /**
1189 * Renders the HTML for the live filter.
1190 *
1191 * @param array $attributes The block attributes.
1192 * @return void
1193 */
1194 public static function live_filter_html( $attributes ) {
1195 $live_filter_parent = array();
1196 foreach ( $attributes as $key => $value ) {
1197 if ( strpos( $key, 'sp-smart-filter-' ) === 0 ) {
1198 $live_filter_parent[ $key ] = $value;
1199 }
1200 }
1201 $parent_id = $live_filter_parent['uniqueId'] ?? '';
1202 $field_alignment = $live_filter_parent['fieldAlignment'] ?? 'full';
1203 ?>
1204 <div id=<?php echo esc_attr( $parent_id ); ?> class="<?php echo 'full' === $field_alignment ? 'sp-smart-full' : ''; ?>">
1205 <div class="sp-smart-post-live-filter-parent">
1206 <?php
1207 foreach ( $attributes as $key => $attr ) {
1208 if ( strpos( $key, 'sp-smart-taxonomy-filter-' ) === 0 ) {
1209 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1210 echo self::taxonomy_filter( $attr );
1211 }
1212 if ( strpos( $key, 'sp-author-filter-' ) === 0 ) {
1213 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1214 echo self::author_filter( $attr );
1215 }
1216 }
1217 ?>
1218 </div>
1219 </div>
1220 <?php
1221 }
1222
1223 /**
1224 * Pagination HTML function.
1225 *
1226 * @param array $attributes attributes.
1227 * @param array $query_attr The query attributes.
1228 * @param int $total_pages The total number of pages.
1229 * @param string $parent_block_id The ID of the parent block.
1230 */
1231 public static function pagination_html( $attributes, $query_attr, $total_pages = 1, $parent_block_id = '' ) {
1232 $unique_id = $attributes['uniqueId'] ?? '';
1233 $pagination_type = isset( $attributes['paginationType'] ) ? $attributes['paginationType'] : '';
1234 $infinite_scroll = isset( $attributes['loadMoreInfiniteScroll'] ) ? $attributes['loadMoreInfiniteScroll'] : '';
1235 $load_more_btn_label = isset( $attributes['loadMoreBtnLabel'] ) ? $attributes['loadMoreBtnLabel'] : 'Load More';
1236 $pagination_shorten = isset( $attributes['paginationShorten'] ) ? $attributes['paginationShorten'] : false;
1237 $pagination_style = isset( $attributes['paginationStyle'] ) ? $attributes['paginationStyle'] : false;
1238 $navigation_arrow_style = isset( $attributes['navigationArrowStyle'] ) ? $attributes['navigationArrowStyle'] : 'open';
1239 $pagination_end_message = isset( $attributes['loadMoreEndMessage'] ) ? $attributes['loadMoreEndMessage'] : '';
1240 $pagination_align = isset( $attributes['paginationAlign'] ) ? $attributes['paginationAlign'] : 'center';
1241 $global_typo_class = isset( $attributes['paginationGlobalTypography']['class'] ) ? $attributes['paginationGlobalTypography']['class'] : '';
1242 $additional_css_class = $attributes['additionalCssClass'] ?? '';
1243 $pages = $total_pages;
1244 $page_current = 1;
1245 $big = 999999999; // An unlikely integer.
1246 ob_start();
1247 ?>
1248 <div id="<?php echo esc_attr( $unique_id ); ?>">
1249 <div class="sp-smart-post-pagination-section sp-justify-<?php echo esc_attr( $pagination_align ); ?> <?php echo esc_attr( $additional_css_class ); ?>" data-pages="<?php echo esc_attr( $pages ); ?>"
1250 data-current="<?php echo esc_attr( $page_current ); ?>"
1251 data-paginationtype="<?php echo esc_attr( $pagination_type ); ?>"
1252 data-endmessage="<?php echo esc_html( $pagination_end_message ); ?>"
1253 data-paginationstyle="<?php echo esc_attr( $pagination_style ); ?>">
1254 <?php if ( 'load-more' === $pagination_type ) { ?>
1255 <div class="sp-smart-post-load-more-button">
1256 <?php if ( $infinite_scroll ) { ?>
1257 <div class="sp-smart-post-show-preloading">
1258 <?php
1259 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1260 echo Helper::get_svg_icon( 'preloader' );
1261 ?>
1262 </div>
1263 <?php } else { ?>
1264 <div class="sp-smart-post-show-preloader sp-d-hidden">
1265 <?php
1266 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1267 echo Helper::get_svg_icon( 'preloader' );
1268 ?>
1269 </div>
1270 <a href="#" class="<?php echo esc_attr( $global_typo_class ); ?>"> <?php echo esc_html( $load_more_btn_label ); ?>
1271 </a>
1272 <?php } ?>
1273 </div>
1274 <?php } ?>
1275 <?php if ( 'navigation' === $pagination_type ) { ?>
1276 <div class="sp-smart-post-navigation-buttons">
1277 <div class="sp-smart-post-grid-nav-arrow sp-d-flex">
1278 <span class="sp-smart-post-grid-nav-arrow-btn sp-d-flex sp-align-i-center sp-justify-center sp-prev <?php echo esc_attr( $global_typo_class ); ?>"><i>
1279 <?php
1280 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1281 echo Helper::get_arrow_icon( $navigation_arrow_style );
1282 ?>
1283 </i></span>
1284 <span class="sp-smart-post-grid-nav-arrow-btn sp-d-flex sp-align-i-center sp-justify-center sp-next <?php echo esc_attr( $global_typo_class ); ?>"><i>
1285 <?php
1286 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1287 echo Helper::get_arrow_icon( $navigation_arrow_style );
1288 ?>
1289 </i></span>
1290 </div>
1291 </div>
1292 <?php } ?>
1293 <?php
1294 if ( 'pagination' === $pagination_type ) {
1295 if ( 'prev-next' === $pagination_style ) {
1296 ?>
1297 <div class="sp-smart-post-navigation-buttons sp-<?php echo esc_attr( $pagination_style ); ?>">
1298 <div class="sp-smart-post-grid-nav-arrow sp-d-flex">
1299 <span class="sp-smart-post-grid-nav-arrow-btn sp-d-flex sp-align-i-center sp-justify-center <?php echo esc_attr( $global_typo_class ); ?>"><i
1300 class="sp-icon-left-open"></i> Prev</span>
1301 <span class="sp-smart-post-grid-nav-arrow-btn sp-d-flex sp-align-i-center sp-justify-center <?php echo esc_attr( $global_typo_class ); ?>">Next <i
1302 class="sp-icon-right-open"></i></span>
1303 </div>
1304 </div>
1305 <?php
1306 } elseif ( 'number-arrow' == $pagination_style ) {
1307 ?>
1308 <div class="sp-smart-post-pagination-buttons">
1309 <a href="#" class="page-numbers prev number-arrow <?php echo $page_current <= 1 ? 'disabled' : ''; ?> <?php echo esc_attr( $global_typo_class ); ?>">
1310 <i class="sp-icon-left-open"></i>
1311 </a>
1312 <?php for ( $i = 1; $i <= $pages; $i++ ) : ?>
1313 <a href="#" class="page-numbers <?php echo $page_current == $i ? 'current' : ''; ?>"
1314 data-page="<?php echo esc_attr( $i ); ?>">
1315 <?php echo esc_html( $i ); ?>
1316 </a>
1317 <?php endfor; ?>
1318 <a href="#" class="page-numbers next number-arrow <?php echo $page_current >= $pages ? 'disabled' : ''; ?>">
1319 <i class="sp-icon-right-open"></i>
1320 </a>
1321 </div>
1322 <?php
1323 } elseif ( 'number-prev-next-arrow' == $pagination_style ) {
1324 ?>
1325 <div class="sp-smart-post-pagination-buttons">
1326 <a href="#" class="page-numbers prev <?php echo $page_current <= 1 ? 'disabled' : ''; ?> <?php echo esc_attr( $global_typo_class ); ?>">
1327 <i class="sp-icon-left-open"></i> Prev
1328 </a>
1329 <?php for ( $i = 1; $i <= $pages; $i++ ) : ?>
1330 <a href="#" class="page-numbers
1331 <?php
1332 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1333 echo $page_current == $i ? 'current' : '';
1334 ?>
1335 "
1336 data-page="<?php echo esc_attr( $i ); ?>">
1337 <?php echo esc_html( $i ); ?>
1338 </a>
1339 <?php endfor; ?>
1340 <a href="#" class="page-numbers next <?php echo $page_current >= $pages ? 'disabled' : ''; ?>">
1341 Next <i class="sp-icon-right-open"></i>
1342 </a>
1343 </div>
1344 <?php
1345 } elseif ( 'number' === $pagination_style ) {
1346 ?>
1347 <div class="sp-smart-post-pagination-buttons">
1348 <?php for ( $i = 1; $i <= $pages; $i++ ) : ?>
1349 <a href="#" class="page-numbers <?php echo $page_current == $i ? 'current' : ''; ?>" data-page="<?php echo esc_attr( $i ); ?> <?php echo esc_attr( $global_typo_class ); ?>">
1350 <?php echo esc_html( $i ); ?>
1351 </a>
1352 <?php endfor; ?>
1353 </div>
1354 <?php
1355 } else {
1356 $paged_var = 'paged_' . $parent_block_id;
1357 $page_current = ( ! empty( $_GET[ "$paged_var" ] ) ) ? sanitize_text_field( wp_unslash( $_GET[ "$paged_var" ] ) ) : 1;
1358 $page_links = paginate_links(
1359 array(
1360 'format' => '?' . $paged_var . '=%#%',
1361 'current' => $page_current,
1362 'total' => $pages,
1363 'show_all' => apply_filters( 'pcp_show_all_normal_pagination', true ),
1364 'prev_next' => true,
1365 'end_size' => 2,
1366 'mid_size' => 1,
1367 'type' => 'array',
1368 'prev_text' => '<i class="sp-icon-left-open"></i>Prev',
1369 'next_text' => 'Next<i class="sp-icon-right-open"></i></span>',
1370 )
1371 );
1372 ?>
1373 <div class="sp-smart-post-pagination-buttons ">
1374 <?php
1375 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1376 echo implode( $page_links );
1377 ?>
1378 </div>
1379 <?php
1380 }
1381 }
1382 ?>
1383 </div>
1384 </div>
1385 <?php
1386 return ob_get_clean();
1387 }
1388 /**
1389 * Pagination HTML function.
1390 *
1391 * @param array $attributes attributes.
1392 * @param array $total_pages Total page.
1393 * @param array $parent_block_id Parent block id.
1394 */
1395 public static function pagination_block_html( $attributes, $total_pages = 1, $parent_block_id = '' ) {
1396 $unique_id = $attributes['uniqueId'] ?? '';
1397 $pagination_type = isset( $attributes['paginationType'] ) ? $attributes['paginationType'] : '';
1398 $infinite_scroll = isset( $attributes['loadMoreInfiniteScroll'] ) ? $attributes['loadMoreInfiniteScroll'] : '';
1399 $load_more_btn_label = isset( $attributes['loadMoreBtnLabel'] ) ? $attributes['loadMoreBtnLabel'] : 'Load More';
1400 $pagination_shorten = isset( $attributes['paginationShorten'] ) ? $attributes['paginationShorten'] : false;
1401 $pagination_style = isset( $attributes['paginationStyle'] ) ? $attributes['paginationStyle'] : false;
1402 $navigation_arrow_style = isset( $attributes['navigationArrowStyle'] ) ? $attributes['navigationArrowStyle'] : 'open';
1403 $additional_css_class = $attributes['additionalCssClass'] ?? '';
1404 $global_typo_class = isset( $attributes['paginationGlobalTypography']['class'] ) ? $attributes['paginationGlobalTypography']['class'] : '';
1405 $pages = $total_pages;
1406 $page_current = 1;
1407 $big = 999999999; // An unlikely integer.
1408 ob_start();
1409 ?>
1410 <div id="<?php echo esc_attr( $unique_id ); ?>">
1411 <div class="sp-smart-post-pagination-section <?php echo esc_attr( $additional_css_class ); ?>" data-pages="<?php echo esc_attr( $pages ); ?>"
1412 data-current="<?php echo esc_attr( $page_current ); ?>"
1413 data-paginationtype="<?php echo esc_attr( $pagination_type ); ?>"
1414 data-paginationstyle="<?php echo esc_attr( $pagination_style ); ?>">
1415 <?php if ( 'load-more' === $pagination_type ) { ?>
1416 <div class="sp-smart-post-load-more-button">
1417 <?php if ( $infinite_scroll ) { ?>
1418 <div class="sp-smart-post-show-preloading">
1419 <?php
1420 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1421 echo Helper::get_svg_icon( 'preloader' );
1422 ?>
1423 </div>
1424 <?php } else { ?>
1425 <a href="#" class="<?php echo esc_attr( $global_typo_class ); ?>">
1426 <?php echo esc_html( $load_more_btn_label ); ?>
1427 </a>
1428 <?php } ?>
1429 </div>
1430 <?php } ?>
1431 <?php if ( 'navigation' === $pagination_type ) { ?>
1432 <div class="sp-smart-post-navigation-buttons">
1433 <div class="sp-smart-post-grid-nav-arrow sp-d-flex">
1434 <span class="sp-smart-post-grid-nav-arrow-btn sp-d-flex sp-align-i-center sp-justify-center <?php echo esc_attr( $global_typo_class ); ?>"><i
1435 class="sp-icon-left-<?php echo esc_attr( $navigation_arrow_style ); ?>"></i></span>
1436 <span class="sp-smart-post-grid-nav-arrow-btn sp-d-flex sp-align-i-center sp-justify-center <?php echo esc_attr( $global_typo_class ); ?>"><i
1437 class="sp-icon-right-<?php echo esc_attr( $navigation_arrow_style ); ?>"></i></span>
1438 </div>
1439 </div>
1440 <?php } ?>
1441 <?php
1442 if ( 'pagination' === $pagination_type ) {
1443 if ( 'prev-next' === $pagination_style ) {
1444 ?>
1445 <div class="sp-smart-post-navigation-buttons sp-<?php echo esc_attr( $pagination_style ); ?>">
1446 <div class="sp-smart-post-grid-nav-arrow sp-d-flex">
1447 <span class="sp-smart-post-grid-nav-arrow-btn sp-d-flex sp-align-i-center sp-justify-center <?php echo esc_attr( $global_typo_class ); ?>"><i class="sp-icon-left-open"></i> Prev</span>
1448 <span class="sp-smart-post-grid-nav-arrow-btn sp-d-flex sp-align-i-center sp-justify-center <?php echo esc_attr( $global_typo_class ); ?>">Next <i class="sp-icon-right-open"></i></span>
1449 </div>
1450 </div>
1451 <?php
1452 } elseif ( 'number-arrow' == $pagination_style ) {
1453 ?>
1454 <div class="sp-smart-post-pagination-buttons">
1455 <a href="#" class="page-numbers prev number-arrow <?php echo $page_current <= 1 ? 'disabled' : ''; ?>">
1456 <i class="sp-icon-left-open"></i>
1457 </a>
1458 <?php for ( $i = 1; $i <= $pages; $i++ ) : ?>
1459 <a href="#" class="page-numbers <?php echo $page_current == $i ? 'current' : ''; ?>"
1460 data-page="<?php echo esc_attr( $i ); ?>">
1461 <?php echo esc_html( $i ); ?>
1462 </a>
1463 <?php endfor; ?>
1464 <a href="#" class="page-numbers next number-arrow <?php echo $page_current >= $pages ? 'disabled' : ''; ?>">
1465 <i class="sp-icon-right-open"></i>
1466 </a>
1467 </div>
1468 <?php
1469 } elseif ( 'number-prev-next-arrow' == $pagination_style ) {
1470 ?>
1471 <div class="sp-smart-post-pagination-buttons">
1472 <a href="#" class="page-numbers prev <?php echo $page_current <= 1 ? 'disabled' : ''; ?>">
1473 <i class="sp-icon-left-open"></i> Prev
1474 </a>
1475 <?php for ( $i = 1; $i <= $pages; $i++ ) : ?>
1476 <a href="#" class="page-numbers <?php echo $page_current == $i ? 'current' : ''; ?>"
1477 data-page="<?php echo esc_attr( $i ); ?>">
1478 <?php echo esc_html( $i ); ?>
1479 </a>
1480 <?php endfor; ?>
1481 <a href="#" class="page-numbers next <?php echo $page_current >= $pages ? 'disabled' : ''; ?>">
1482 Next <i class="sp-icon-right-open"></i>
1483 </a>
1484 </div>
1485 <?php
1486 } elseif ( 'number' === $pagination_style ) {
1487 ?>
1488 <div class="sp-smart-post-pagination-buttons">
1489 <?php for ( $i = 1; $i <= $pages; $i++ ) : ?>
1490 <a href="#" class="page-numbers <?php echo $page_current == $i ? 'current' : ''; ?>" data-page="<?php echo esc_attr( $i ); ?> <?php echo esc_attr( $global_typo_class ); ?>">
1491 <?php echo esc_html( $i ); ?>
1492 </a>
1493 <?php endfor; ?>
1494 </div>
1495 <?php
1496 } else {
1497 $paged_var = 'paged_' . $parent_block_id;
1498 $page_current = ( ! empty( $_GET[ "$paged_var" ] ) ) ? sanitize_text_field( wp_unslash( $_GET[ "$paged_var" ] ) ) : 1;
1499 $page_links = paginate_links(
1500 array(
1501 'format' => '?' . $paged_var . '=%#%',
1502 'current' => $page_current,
1503 'total' => $pages,
1504 'show_all' => apply_filters( 'pcp_show_all_normal_pagination', true ),
1505 'prev_next' => true,
1506 'end_size' => 2,
1507 'mid_size' => 1,
1508 'type' => 'array',
1509 'prev_text' => '<i class="sp-icon-left-open"></i>Prev',
1510 'next_text' => 'Next<i class="sp-icon-right-open"></i></span>',
1511 )
1512 );
1513 ?>
1514 <div class="sp-smart-post-pagination-buttons <?php echo esc_attr( $global_typo_class ); ?>">
1515 <?php
1516 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1517 echo implode( $page_links );
1518 ?>
1519 </div>
1520 <?php
1521 }
1522 }
1523 ?>
1524 </div>
1525 </div>
1526 <?php
1527 return ob_get_clean();
1528 }
1529
1530 /**
1531 * Renders the social share HTML.
1532 *
1533 * @param array $attributes The block attributes.
1534 * @param array $data The post data.
1535 * @return string|null The social share HTML, or null if not enabled.
1536 */
1537 public static function social_share( $attributes, $data ) {
1538 $enable_social = isset( $attributes['socialShareEnableSocial'] ) ? $attributes['socialShareEnableSocial'] : false;
1539
1540 $social_icon_display_type = isset( $attributes['socialIconDisplayType'] ) ? $attributes['socialIconDisplayType'] : 'inline-icon';
1541
1542 $social_share_display_on_hover = isset( $attributes['socialShareDisplayOnHover'] ) ? $attributes['socialShareDisplayOnHover'] : false;
1543
1544 $social_share_icon_position = isset( $attributes['socialShareIconPosition'] ) ? $attributes['socialShareIconPosition'] : '';
1545
1546 $on_hover = $social_share_display_on_hover ? 'on-hover' : '';
1547
1548 if ( $enable_social ) {
1549 ob_start();
1550 if ( 'inline-icon' === $social_icon_display_type ) {
1551 self::social_links( $attributes, $data );
1552 }
1553 return ob_get_clean();
1554 }
1555 }
1556 /**
1557 * Renders the star rating HTML for a product.
1558 *
1559 * @param array $attributes The block attributes.
1560 * @param array $data The post data.
1561 * @return string The star rating HTML.
1562 */
1563 public static function star_rating( $attributes, $data ) {
1564 $show_review_count = isset( $attributes['showReviewCount'] ) ? $attributes['showReviewCount'] : '';
1565 $review_counter_color = isset( $attributes['reviewCounterColor']['color'] ) ? $attributes['reviewCounterColor']['color'] : '';
1566 $empty_star_color = isset( $attributes['emptyStarColor']['color'] ) ? $attributes['emptyStarColor']['color'] : '';
1567 $star_color = isset( $attributes['starColor']['color'] ) ? $attributes['starColor']['color'] : '';
1568 $average_rating = isset( $data['average_rating'] ) ? $data['average_rating'] : '';
1569 $star_data = (int) isset( $data['starRating'] ) ? $data['starRating'] : 0;
1570 $star_width = (int) $average_rating / 5 * 100;
1571
1572 ob_start();
1573 ?>
1574 <div class="sp-smart-post-product-rating-area">
1575 <div class="sp-smart-post-product-rating" title="Rated <?php echo esc_attr( $average_rating ); ?> out of 5">
1576 <div class="sp-smart-post-empty-stars" style="color: <?php echo esc_attr( $empty_star_color ); ?>">
1577 <i class="sp-icon-star"></i>
1578 <i class="sp-icon-star"></i>
1579 <i class="sp-icon-star"></i>
1580 <i class="sp-icon-star"></i>
1581 <i class="sp-icon-star"></i>
1582 </div>
1583 <div style="width: <?php echo esc_attr( $star_width ); ?>%; color: <?php echo esc_attr( $star_color ); ?>"
1584 class="sp-smart-post-filled-stars">
1585 <i class="sp-icon-star"></i>
1586 <i class="sp-icon-star"></i>
1587 <i class="sp-icon-star"></i>
1588 <i class="sp-icon-star"></i>
1589 <i class="sp-icon-star"></i>
1590 </div>
1591 </div>
1592 <?php if ( $show_review_count ) : ?>
1593 <span class="sp-smart-post-product-review-count" style="color: <?php echo esc_attr( $review_counter_color ); ?>"> (
1594 <?php echo esc_html( $star_data ); ?>)
1595 </span>
1596 <?php endif; ?>
1597 </div>
1598 <?php
1599 return ob_get_clean();
1600 }
1601 /**
1602 * Renders the price HTML for a product.
1603 *
1604 * @param array $attributes The block attributes.
1605 * @param array $data The post data.
1606 * @return string The price HTML.
1607 */
1608 public static function price( $attributes, $data ) {
1609 $show_price = isset( $attributes['showPrice'] ) ? $attributes['showPrice'] : '';
1610 $product_price = isset( $data['product_price'] ) ? $data['product_price'] : '';
1611
1612 ob_start();
1613 if ( $show_price ) :
1614 ?>
1615 <div class="sp-smart-post-product-price">
1616 <?php echo wp_kses_post( $product_price ); ?>
1617 </div>
1618 <?php
1619 endif;
1620 return ob_get_clean();
1621 }
1622 /**
1623 * Renders the add to cart HTML for a product.
1624 *
1625 * @param array $attributes The block attributes.
1626 * @param array $data The post data.
1627 * @return string The add to cart HTML.
1628 */
1629 public static function add_to_cart( $attributes, $data ) {
1630 $show_add_to_cart = isset( $attributes['showAddToCart'] ) ? $attributes['showAddToCart'] : '';
1631 $add_to_cart = isset( $data['add_to_cart'] ) ? $data['add_to_cart'] : '';
1632
1633 ob_start();
1634 if ( $show_add_to_cart ) :
1635 ?>
1636 <div class="sp-smart-post-product-add-to-cart">
1637 <?php echo wp_kses_post( $add_to_cart ); ?>
1638 </div>
1639 <?php
1640 endif;
1641 return ob_get_clean();
1642 }
1643
1644 /**
1645 * Renders the modal lightbox HTML.
1646 *
1647 * @param array $attributes The block attributes.
1648 * @param array $post_query The post query.
1649 * @return string|null The modal lightbox HTML, or null if not applicable.
1650 */
1651 public static function modal_lightbox( $attributes, $post_query ) {
1652 $unique_id = $attributes['uniqueId'] ?? '';
1653 $block_name = $attributes['blockName'] ?? '';
1654 $open_link_in = isset( $attributes['generalLinkOpen'] ) ? $attributes['generalLinkOpen'] : '';
1655 $close_btn_enable = isset( $attributes['popupCloseBtnEnable'] ) ? $attributes['popupCloseBtnEnable'] : true;
1656 $multi_popup = 'multi-popup' === $open_link_in ? true : false;
1657
1658 $image_size = isset( $attributes['popupImageSize'] ) ? $attributes['popupImageSize'] : '';
1659 // get all necessary attr and data.
1660 // Show meta data.
1661 $meta_data_attr = isset( $attributes['metaDataAllContentArray'] ) ? $attributes['metaDataAllContentArray'] : array();
1662 $flags = array(
1663 'author' => false,
1664 'date' => false,
1665 'comments' => false,
1666 'views' => false,
1667 'likes' => false,
1668 'reading-time' => false,
1669 );
1670 foreach ( $meta_data_attr as $item ) {
1671 if ( isset( $item['value'] ) && array_key_exists( $item['value'], $flags ) ) {
1672 $flags[ $item['value'] ] = ! empty( $item['show'] ) && 1 == $item['show'];
1673 }
1674 }
1675 // Reading time array.
1676 $reading_time = json_encode( $attributes['metaPerMin'] );
1677
1678 // Author.
1679 $icon_type = isset( $attributes['metaUserIcon'] ) ? $attributes['metaUserIcon'] : 'outline';
1680 $user_icon = Helper::get_author_icon( $icon_type );
1681
1682 $modal_popup = array( 'single-popup', 'multi-popup' );
1683
1684 // Post Badges.
1685 $post_badges_show = isset( $attributes['postBadgesShow'] ) ? $attributes['postBadgesShow'] : false;
1686 $post_badges_position = isset( $attributes['postBadgesPosition'] ) ? $attributes['postBadgesPosition'] : 'before-title';
1687 $badges_global_typo = isset( $attributes['postBadgesGlobalTypography']['class'] ) ? $attributes['postBadgesGlobalTypography']['class'] : '';
1688
1689 if ( ! in_array( $open_link_in, $modal_popup ) ) {
1690 return null;
1691 }
1692
1693 ob_start();
1694 ?>
1695 <div id="<?php echo esc_attr( $unique_id ); ?>-modal"
1696 class="sp-smart-post-<?php echo esc_attr( $block_name ); ?>-modal sp-smart-post-modal-container">
1697 <div class="sp-smart-post-modal-content-lightbox sp-smart-post-modal-content">
1698 <?php if ( $close_btn_enable ) : ?>
1699 <span class="sp-modal-close-btn cursor"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 98 98" fill="none">
1700 <path d="M49 0.5625C22.2422 0.5625 0.5625 22.2422 0.5625 49C0.5625 75.7578 22.2422 97.4375 49 97.4375C75.7578 97.4375 97.4375 75.7578 97.4375 49C97.4375 22.2422 75.7578 0.5625 49 0.5625ZM49 88.0625C27.418 88.0625 9.9375 70.582 9.9375 49C9.9375 27.418 27.418 9.9375 49 9.9375C70.582 9.9375 88.0625 27.418 88.0625 49C88.0625 70.582 70.582 88.0625 49 88.0625ZM68.8828 36.8516L56.7344 49L68.8828 61.1484C69.8008 62.0664 69.8008 63.5508 68.8828 64.4688L64.4688 68.8828C63.5508 69.8008 62.0664 69.8008 61.1484 68.8828L49 56.7344L36.8516 68.8828C35.9336 69.8008 34.4492 69.8008 33.5312 68.8828L29.1172 64.4688C28.1992 63.5508 28.1992 62.0664 29.1172 61.1484L41.2656 49L29.1172 36.8516C28.1992 35.9336 28.1992 34.4492 29.1172 33.5312L33.5312 29.1172C34.4492 28.1992 35.9336 28.1992 36.8516 29.1172L49 41.2656L61.1484 29.1172C62.0664 28.1992 63.5508 28.1992 64.4688 29.1172L68.8828 33.5312C69.8008 34.4492 69.8008 35.9336 68.8828 36.8516Z" fill="currentColor" />
1701 </svg></span>
1702 <?php endif; ?>
1703 <div class="sp-smart-post-modal-content-wrapper">
1704 <div class="sp-smart-post-card-modal sp-smart-post-modal-template">
1705 <div class="sp-smart-post-card-modal-image sp-d-flex sp-justify-center"
1706 data-image-size="<?php echo esc_attr( $image_size ); ?>"></div>
1707 <div class="sp-smart-post-template-one-content">
1708 <div class="sp-smart-post-card-content-modal">
1709 <div class="sp-post-modal-title-wrapper">
1710 <h1 class="sp-post-modal-title"></h1>
1711 </div>
1712 <div class="sp-smart-post-modal-meta-data sp-d-flex">
1713 <?php if ( $flags['author'] ) : ?>
1714 <!-- Author meta data -->
1715 <div class="sp-smart-post-meta sp-smart-post-author sp-d-flex sp-align-i-center">
1716 <div class="sp-smart-post-meta-icon">
1717 <?php
1718 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1719 echo $user_icon;
1720 ?>
1721 </div>
1722 <span class="sp-smart-post-meta-text sp-meta-author"></span>
1723 </div>
1724 <?php endif; ?>
1725 <?php if ( $flags['date'] ) : ?>
1726 <!-- Date meta data -->
1727 <div class="sp-smart-post-meta sp-align-i-center sp-smart-post-date sp-d-flex">
1728 <div class="sp-smart-post-meta-icon">
1729 <?php
1730 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1731 echo Helper::get_svg_icon( 'meta-date' );
1732 ?>
1733 </div>
1734 <span class="sp-smart-post-meta-text sp-meta-date"></span>
1735 </div>
1736 <?php endif; ?>
1737 <?php if ( $flags['comments'] ) : ?>
1738 <!-- Comments meta data -->
1739 <div class="sp-smart-post-meta sp-smart-post-comments sp-d-flex sp-align-i-center">
1740 <div class="sp-smart-post-meta-icon">
1741 <?php
1742 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1743 echo Helper::get_svg_icon( 'comments-count' );
1744 ?>
1745 </div>
1746 <span class="sp-smart-post-meta-text sp-meta-comments"></span>
1747 </div>
1748 <?php endif; ?>
1749 <?php if ( $flags['views'] ) : ?>
1750 <!-- Views meta data -->
1751 <div class="sp-smart-post-meta sp-smart-post-views sp-d-flex sp-align-i-center">
1752 <div class="sp-smart-post-meta-icon">
1753 <?php
1754 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1755 echo Helper::get_svg_icon( 'view-count' );
1756 ?>
1757 </div>
1758 <span class="sp-smart-post-meta-text sp-meta-views"></span>
1759 </div>
1760 <?php endif; ?>
1761 <?php if ( $flags['likes'] ) : ?>
1762 <!-- Likes meta data -->
1763 <div class="sp-smart-post-meta sp-smart-post-likes sp-d-flex sp-align-i-center">
1764 </div>
1765 <?php endif; ?>
1766 <?php if ( $flags['reading-time'] ) : ?>
1767 <!-- Reading Time meta data -->
1768 <div class="sp-smart-post-meta sp-smart-post-reading-time sp-d-flex sp-align-i-center"
1769 data-read-time="<?php echo esc_attr( $reading_time ); ?>">
1770 <div class="sp-smart-post-meta-icon">
1771 <?php
1772 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1773 echo Helper::get_svg_icon( 'read-time' );
1774 ?>
1775 </div>
1776 <span class="sp-smart-post-meta-text sp-meta-reading-time"></span>
1777 </div>
1778 <?php endif; ?>
1779 <!-- Taxonomy meta data -->
1780 <div class="sp-smart-post-meta sp-align-i-center sp-smart-post-taxonomy sp-d-flex">
1781 <span class="sp-smart-post-meta sp-metadata-taxonomy">
1782 <span class="sp-smart-post-meta-icon sp-metadata-taxonomy-icon">
1783 <?php
1784 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1785 echo Helper::get_svg_icon( 'taxonomy' );
1786 ?>
1787 </span>
1788 <span class="sp-smart-post-meta-text sp-meta-taxonomy-category">
1789 category
1790 </span>
1791 </span>
1792 </div>
1793 </div>
1794 <div class="sp-post-modal-excerpt"></div>
1795 </div>
1796 </div>
1797 </div>
1798 </div>
1799 <?php if ( $multi_popup ) : ?>
1800 <span class="sp-smart-modal-navigation sp-smart-modal-prev">&#10094;</span>
1801 <span class="sp-smart-modal-navigation sp-smart-modal-next">&#10095;</span>
1802 <?php endif; ?>
1803 </div>
1804 </div>
1805 <?php
1806 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
1807 echo ob_get_clean();
1808 }
1809
1810 /**
1811 * Renders the preloader HTML.
1812 *
1813 * @param array $attributes The block attributes.
1814 * @param array $data The post data.
1815 * @return string|null The preloader HTML, or null if not enabled.
1816 */
1817 public static function preloader( $attributes, $data ) {
1818 $show_preloader = isset( $attributes['preloaderEnable'] ) ? $attributes['preloaderEnable'] : '';
1819 if ( ! $show_preloader ) {
1820 return null;
1821 }
1822 $preloader_icon = SP_PC_URL . 'public/assets/img/preloader.svg';
1823 ob_start();
1824 ?>
1825 <div class="sp-smart-post-preloader">
1826 <div class="sp-smart-post-preloader-inner">
1827 <div class="sp-smart-post-preloader-spinner">
1828 <div class="sp-smart-post-preloader-spinner-inner">
1829 <img src="<?php echo esc_attr( $preloader_icon ); ?>" alt="Loading..." />
1830 </div>
1831 </div>
1832 </div>
1833 </div>
1834 <?php
1835 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The HTML output is already properly escaped at the time of generation, so additional escaping is not required here.
1836 echo ob_get_clean();
1837 }
1838 }
1839