<?php
|
/**
|
* GMB Reviews Block - Render Template
|
*
|
* Displays recent Google My Business reviews with a link to leave a review
|
*/
|
function jvbRenderGMBReviewsBlock(array $attributes): string
|
{
|
$count = $attributes['count'] ?? 5;
|
$showRating = $attributes['showRating'] ?? true;
|
$showDate = $attributes['showDate'] ?? true;
|
$showReviewLink = $attributes['showReviewLink'] ?? true;
|
$showViewAllLink = $attributes['showViewAllLink'] ?? true;
|
$showStats = $attributes['showStats'] ?? true;
|
$minStars = $attributes['minStars'] ?? 4; // Only show 4+ star reviews
|
$inheritUser = $attributes['inheritUser']??null;
|
if ($inheritUser) {
|
global $post;
|
$inheritUser = $post->post_author;
|
}else {
|
$inheritUser = null;
|
}
|
try {
|
$gmb = JVB()->connect('gmb', $inheritUser);
|
if (!$gmb->isSetUp()) {
|
error_log('GMB Not set up for: '.(int)$inheritUser);
|
return '';
|
}
|
$gotReviews = $gmb->getReviews();
|
// Get all data
|
$allReviews = $gotReviews['reviews']??[];
|
$reviewUrl = $gmb->getReviewUrl();
|
$viewAllUrl = $gmb->getReviewsViewUrl();
|
|
$average = $gotReviews['averageRating']??null;
|
$total = $gotReviews['totalReviewCount']??null;
|
|
// Filter reviews by minimum stars
|
$reviews = [];
|
if (!empty($allReviews)) {
|
foreach ($allReviews as $review) {
|
$rating = $review['starRating'] ?? 0;
|
if ($rating >= $minStars) {
|
$reviews[] = $review;
|
if (count($reviews) >= $count) {
|
break; // Got enough reviews
|
}
|
}
|
}
|
}
|
|
if (empty($reviews) && empty($reviewUrl) && empty($stats)) {
|
error_log('No reviews to display...');
|
return '';
|
}
|
|
ob_start();
|
?>
|
<div class="gmb-reviews">
|
<div class="row center">
|
<?php
|
if ($showStats && !empty($average) && !empty($total)) {
|
?>
|
<p>
|
<span class="stars" title="<?= $average ?> out of 5 stars">
|
<?php
|
$fullStars = floor($average);
|
$hasHalfStar = ($average - $fullStars) >= 0.5;
|
|
for ($i = 1; $i <= 5; $i++) {
|
if ($i <= $fullStars) {
|
echo jvbIcon('star', ['style' => 'fill']);
|
} elseif ($i == $fullStars + 1 && $hasHalfStar) {
|
echo jvbIcon('star-half', ['style'=> 'fill']);
|
} else {
|
echo jvbIcon('star', ['style' => 'light']);
|
}
|
}
|
?>
|
</span>
|
<i>Average</i>
|
</p>
|
<?php
|
if ($total > 0) {
|
?>
|
<p><i>{ <?= number_format($total ) . ' ' . _n('Review', 'Reviews', $total, 'jvb')?> Total }</i></p>
|
<?php
|
}
|
?>
|
<?php
|
}
|
?>
|
|
|
</div>
|
<?php
|
if ($showReviewLink && !empty($reviewUrl)) {
|
?>
|
<a href="<?=esc_url($reviewUrl)?>"
|
class="button"
|
target="_blank"
|
rel="noopener noreferrer">
|
<?= jvbIcon('star', ['style' => 'fill']) ?>
|
Leave Your Review
|
</a>
|
<?php
|
}
|
?>
|
|
<ul>
|
<?php
|
foreach ($reviews as $review) {
|
$reviewer = $review['reviewer']['displayName'] ?? 'Anonymous';
|
$reviewer = strtok($reviewer, ' ');
|
$profilePhoto = $review['reviewer']['profilePhotoUrl'] ?? '';
|
$rating = $review['starRating'] ?? 0;
|
$rating = match($rating) {
|
'FIVE' => 5,
|
'FOUR' => 4,
|
'THREE' => 3,
|
'TWO' => 2,
|
'ONE' => 1,
|
default => $rating
|
};
|
$comment = $review['comment'] ?? '';
|
$date = $review['updateTime'] ?? '';
|
?>
|
<li>
|
<blockquote class="review">
|
<?php
|
// Review text
|
if (!empty($comment)) { ?>
|
<div class="content review">
|
<?= apply_filters('wpautop', $comment) ?>
|
</div>
|
<?php } ?>
|
<cite class="row start nowrap">
|
<?php if (!empty($profilePhoto)) { ?>
|
<img src="<?=esc_url($profilePhoto)?>"
|
alt="<?=esc_attr($reviewer)?>"
|
'loading="lazy">
|
<?php } else { ?>
|
<div class="avatar">
|
<?= jvbIcon('user-circle')?>
|
</div>
|
<?php } ?>
|
|
<div class="row start wrap">
|
<?php if ($showRating && $rating > 0) { ?>
|
<div class="stars" title="<?= $rating ?> out of 5 stars">
|
<?php
|
for ($i = 1; $i <= 5; $i++) {
|
echo ($i <= $rating) ? jvbIcon('star', ['style' => 'fill']) : jvbIcon('star', ['style' => 'light']);
|
} ?>
|
</div>
|
<?php } ?>
|
<p><?= esc_html($reviewer)?></p>
|
<?php
|
// Date
|
if ($showDate && !empty($date)) {
|
$formatted_date = human_time_diff(strtotime($date), current_time('timestamp')) . ' ago';
|
?>
|
<time datetime="<?=esc_attr($date)?>">
|
<?= esc_html($formatted_date) ?>
|
</time>
|
<?php } ?>
|
|
</div>
|
</cite>
|
</blockquote>
|
</li>
|
<?php
|
}
|
?>
|
</ul>
|
<?php
|
// Footer with "See All Reviews" button
|
if ($showViewAllLink && !empty($viewAllUrl)) {
|
?>
|
<div class="footer">
|
<a href=" <?= esc_url($viewAllUrl) ?>"
|
class="button"
|
target="_blank"
|
rel="noopener noreferrer">
|
|
<?php
|
if ($showStats ) {
|
echo 'See All ' . number_format($total) . ' Reviews';
|
} else {
|
echo ' See All Reviews';
|
}
|
?>
|
<?= jvbIcon('arrow-square-out') ?>
|
</a>
|
</div>
|
<?php
|
}
|
?>
|
</div>
|
<?php
|
return ob_get_clean();
|
|
} catch (\Exception $e) {
|
error_log('[GMB Reviews Block] Error: ' . $e->getMessage());
|
return '';
|
}
|
}
|