PluginProbe
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News / 4.0.4
Smart Post – Post Grid, Post Carousel, Post Slider Gutenberg Blocks for Blog & News v4.0.4
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.4, at blocks/includes/class-template-part.php

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