review??null; } public function setReview(Review|array $review):void { if (is_array($review)) { $review = $this->classArray('review', $review, 'JVBase\managers\SEO\render\Thing\CreativeWork\Review'); } $this->review = $review; } public function getReviewFieldConfig():array { return [ 'type' => 'repeater', 'label' => 'Review(s)', 'hint' => 'Share some relevant reviews you\'d like to highlight', 'fields' => [ 'author' => [ 'type' => 'text', 'label' => 'Author', ], 'reviewRating' => [ 'type' => 'group', 'label' => 'Review Rating', 'fields'=> [ 'ratingValue' => [ 'type' => 'number', 'label' => 'Rating', ], 'bestRating' => [ 'type' => 'number', 'label' => 'Worst Value', 'default' => 5 ], 'worstRating' => [ 'type' => 'number', 'label' => 'Worst Value', 'default' => 1 ] ] ], 'reviewBody' => [ 'type' => 'textarea', 'label' => 'Review Text' ] ] ]; } public function setReviewField(Fields $fields):void { $fields->addField( 'enable_gmb_review_sync', [ 'type' => 'true_false', 'label' => 'Enable Google My Business Sync', 'hint' => 'Automagically fetch your latest positive reviews from your Google Business Listing. Note: you must enable your GMB integration in settings.', ] ); $fields->addField('gmb_min_rating', [ 'type' => 'number', 'default' => 4, 'min' => 1, 'max' => 5, 'label' => 'Minimum Rating to fetch', 'hint' => 'Defaults to 4 stars and above', 'condition' => [ 'field' => 'enable_gmb_review_sync', 'operator' => '==', 'value' => true, ] ] ); $fields->addField( 'reviews', [ 'type' => 'repeater', 'label' => 'Reviews', 'fields' => [ 'author' => [ 'type' => 'text', 'label' => 'Review Author', 'required' => true, ], 'reviewRating' => [ 'type' => 'number', 'min' => 1, 'max' => 5, 'label' => 'Review Rating', 'required' => true, ], 'reviewBody' => [ 'type' => 'textarea', 'label' => 'Review Text Content', ], 'url' => [ 'type' => 'url', 'label' => 'Link to actual review', 'hint' => 'Optional. Link directly to the review source for added authenticity.' ] ], 'condition' => [ 'field' => 'enable_gmb_review_sync', 'operator' => '!=', 'value' => true, ] ] ); } public function formatReviewField(Meta $meta):void { $gmb = $meta->get('enable_gmb_review_sync'); if (!empty($gmb) && $gmb === true) { $this->fetchGMBReviews($meta); return; } $reviews = $meta->get('reviews'); if (!empty($reviews)) { $theReviews = []; foreach ($reviews as $row) { $review = new Review(); $author = $row['author']; $reviewer = new Person(); $reviewer->setName($author); $review->setAuthor($reviewer); $rating = new Rating(); $rating->setRatingValue($row['reviewRating']); $review->setReviewRating($rating); if (!empty($row['reviewBody'])) { $review->setReviewBody($row['reviewBody']); } if (!empty($row['url'])){ $review->setUrl($row['url']); } $theReviews[] = $review; } if (!empty($theReviews)) { $this->setReview($theReviews); } } } protected function fetchGMBReviews(Meta $meta):void { $userID = (int) get_post_meta($meta->id(), BASE.'profile_link', true); if ($userID && $userID > 0) { $integration = JVB()->connect('gmb', $userID); if ($integration && $integration->isSetUp()){ $fetched = $integration->getReviews(20); if (!empty($fetched)) { $reviews = []; $minRating = $meta->get('gmb_min_rating'); foreach ($fetched as $review) { $rating = $review['starRating'] ?? 0; if ($rating >= $minRating) { $reviews[] = $review; if (count($reviews) >= 10) { break; } } } } if (!empty($reviews)) { $theReviews = []; foreach ($reviews as $r) { $review = new Review(); $author = $r['reviewer']['displayName'] ?? 'Anonymous'; $author = strtok($author, ' '); $reviewer = new Person(); $reviewer->setName($author); $review->setAuthor($reviewer); $rating = new Rating(); $rating->setRatingValue(match($r['starRating']) { 'FIVE' => 5, 'FOUR' => 4, 'THREE' => 3, 'TWO' => 2, 'ONE' => 1, default => 0 }); $review->setReviewRating($rating); if (!empty($r['comment'])) { $review->setReviewBody($r['comment']); } if (!empty($r['updateTime']??'')){ $review->setDateCreated($r['updateTime']); } $theReviews[] = $review; } if (!empty($theReviews)) { $this->setReview($theReviews); } } } } } }