From 9bbeea742424837fb58207d88e10dbca0b2cae04 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 03 May 2026 22:04:17 +0000
Subject: [PATCH] =SEO Field registration and formatting

---
 inc/managers/SEO/render/Traits/_Properties/reviewTrait.php |  156 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 156 insertions(+), 0 deletions(-)

diff --git a/inc/managers/SEO/render/Traits/_Properties/reviewTrait.php b/inc/managers/SEO/render/Traits/_Properties/reviewTrait.php
index 2f5a238..db6bcf1 100644
--- a/inc/managers/SEO/render/Traits/_Properties/reviewTrait.php
+++ b/inc/managers/SEO/render/Traits/_Properties/reviewTrait.php
@@ -2,7 +2,11 @@
 namespace JVBase\managers\SEO\render\Traits\_Properties;
 
 use JVBase\managers\SEO\render\Thing\CreativeWork\Review;
+use JVBase\managers\SEO\render\Thing\Intangible\Rating\Rating;
+use JVBase\managers\SEO\render\Thing\Person\Person;
 use JVBase\managers\SEO\render\Traits\_Helpers\arrayHelper;
+use JVBase\meta\Meta;
+use JVBase\registrar\Fields;
 
 if (!defined('ABSPATH')) {
 	exit;
@@ -64,4 +68,156 @@
 			]
 		];
 	}
+	public function setReviewField(Fields $fields):void
+	{
+		$fields->addField(
+			'enable_gmb_review_sync',
+			[
+				'type'	=> 'true_false',
+				'label'	=> __('Enable Google My Business Sync', 'jvb'),
+				'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', 'jvb'),
+				'fields'	=> [
+					'author'	=> [
+						'type'	=> 'text',
+						'label'	=> __('Review Author', 'jvb'),
+						'required'	=> true,
+					],
+					'reviewRating'	=> [
+						'type'	=> 'number',
+						'min'	=> 1,
+						'max'	=> 5,
+						'label'	=> __('Review Rating', 'jvb'),
+						'required'	=> true,
+					],
+					'reviewBody'	=> [
+						'type'	=> 'textarea',
+						'label'	=> __('Review Text Content', 'jvb'),
+					],
+					'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);
+					}
+				}
+			}
+		}
+	}
 }

--
Gitblit v1.10.0