Jake Vanderwerf
9 days ago 47e77f9fac1155c536b2b87fec552c7fcce66fa6
src/gmbreviews/render.php
@@ -1,203 +1 @@
<?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;
   }
   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 btw">
         <?php
         if ($showStats && !empty($average) && !empty($total)) {
            ?>
            <p>
               <span class="stars" aria-label="<?= $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
         }
         ?>
         <?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
         }
         ?>
      </div>
      <ul>
         <?php
         foreach ($reviews as $review) {
            $reviewer = $review['reviewer']['displayName'] ?? 'Anonymous';
            $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>
               <article class="review">
                  <header class="row btw">
                     <?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="col end">
                        <h4><?= esc_html($reviewer)?></h4>
                        <?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 } ?>
                        <?php if ($showRating && $rating > 0) { ?>
                           <div class="stars" aria-label="<?= $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 } ?>
                     </div>
                  </header>
                  <?php
                  // Review text
                  if (!empty($comment)) { ?>
                     <div class="review">
                        <?= apply_filters('the_content', $comment) ?>
                     </div>
                  <?php } ?>
               </article>
            </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 '';
   }
}