From e9967fa22781d922ba4eb8fb44fe72d200ac4b14 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Mon, 10 Nov 2025 21:04:10 +0000
Subject: [PATCH] =IconsManager.php update

---
 inc/integrations/GoogleMyBusiness.php |  152 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 145 insertions(+), 7 deletions(-)

diff --git a/inc/integrations/GoogleMyBusiness.php b/inc/integrations/GoogleMyBusiness.php
index 37a6821..3260b8c 100644
--- a/inc/integrations/GoogleMyBusiness.php
+++ b/inc/integrations/GoogleMyBusiness.php
@@ -10,9 +10,12 @@
 
 class GoogleMyBusiness extends Integrations
 {
-	private string $access_token;
+	private ?string $access_token = null;
 	protected string $readMask = 'name,title,storefrontAddress,metadata,openInfo,storeCode,categories,phoneNumbers,labels,specialHours';
 	private ?string $location = null;
+	private ?string $refresh_token = null;
+	private ?string $client_id = null;
+	private ?string $client_secret = null;
 	private ?string $account_id = null;
 
 	public function __construct(?int $userID = null)
@@ -35,6 +38,7 @@
 		];
 
 		$this->apiEndpoints = [
+			'/accounts/[^/]+/locations/[^/]+/reviews',
 			'/accounts/[^/]+/locations/[^/]+/foodMenus',
 			'/v4/accounts/[^/]+/locations/[^/]+/media',
 			'/v4/accounts/[^/]+/locations/[^/]+/localPosts',
@@ -124,6 +128,8 @@
 				'check_oauth_status' => 'Check OAuth Status'
 			]
 		);
+
+//		$this->cache->clear();
 	}
 
 	protected function initialize(): void
@@ -131,12 +137,12 @@
 		if (empty($this->credentials)) {
 			$this->loadCredentials();
 		}
-		$this->access_token = $this->credentials['access_token'] ?? '';
-		$this->refresh_token = $this->credentials['refresh_token'] ?? '';
-		$this->client_id = $this->credentials['client_id'] ?? '';
-		$this->client_secret = $this->credentials['client_secret'] ?? '';
-		$this->location = $this->credentials['location'] ?? null;
-		$this->account_id = $this->credentials['account'] ?? null;
+		$this->access_token = (array_key_exists('access_token', $this->credentials)) ? $this->credentials['access_token'] : null;
+		$this->refresh_token = (array_key_exists('refresh_token', $this->credentials)) ? $this->credentials['refresh_token'] : null;
+		$this->client_id = (array_key_exists('client_id', $this->credentials)) ? $this->credentials['client_id'] : null;
+		$this->client_secret = (array_key_exists('client_secret', $this->credentials)) ? $this->credentials['client_secret'] : null;
+		$this->location = (array_key_exists('location', $this->credentials)) ? $this->credentials['location'] : null;
+		$this->account_id = (array_key_exists('account', $this->credentials)) ? $this->credentials['account'] : null;
 
 		if ($this->account_id) {
 			$this->apiEndpoints[] = "/v1/{$this->account_id}/locations";
@@ -157,6 +163,16 @@
 		}
 	}
 
+	/**
+	 * Check if response contains an error - Google-specific
+	 */
+	protected function isErrorResponse(array $response): bool
+	{
+		// Google APIs return errors in this format:
+		// {"error": {"code": 401, "message": "...", "status": "UNAUTHENTICATED"}}
+		return isset($response['error']) && isset($response['error']['code']);
+	}
+
 	protected function getRequestHeaders(): array
 	{
 		return [
@@ -1431,6 +1447,128 @@
 	}
 
 	/**
+	 * Get reviews for the current location
+	 * @param int $page_size Number of reviews to fetch (max 50)
+	 * @return array|null
+	 */
+	public function getReviews(int $page_size = 5): ?array
+	{
+		$this->ensureInitialized();
+		if (!$this->location) {
+			throw new \Exception('No location selected');
+		}
+		if (!$this->account_id) {
+			throw new \Exception('No account configured');
+		}
+
+		$location = $this->getSelectedLocationResourceName();
+		$account = $this->account_id;
+
+
+		// Check cache first (weekly refresh = 604800 seconds)
+		$cache_key = ['reviews', $location, $page_size];
+		$cached = $this->cache->get($cache_key);
+		if ($cached !== false) {
+			return $cached;
+		}
+
+		try {
+			// Reviews endpoint from My Business Account Management API
+			$response = $this->getRequest(
+				"/{$account}/{$location}/reviews",
+				[
+					'orderBy' => 'updateTime desc'
+				],
+				'v4'
+			);
+
+			error_log('Review response: '.print_r($response, true));
+			$reviews = $response ?? [];
+
+			// Cache for 1 week (604800 seconds)
+			$this->cache->set($cache_key, $reviews, WEEK_IN_SECONDS);
+
+			return $reviews;
+
+		} catch (\Exception $e) {
+			$this->logError($e->getMessage(), [
+				'method' => 'getReviews'
+			]);
+			return null;
+		}
+	}
+
+	/**
+	 * Get the URL to view all Google reviews for the current location
+	 * @return string|null The reviews viewing URL or null if not available
+	 */
+	public function getReviewsViewUrl(): ?string
+	{
+		$this->ensureInitialized();
+		try {
+			$location = $this->getLocation();
+
+			if (empty($location)) {
+				return null;
+			}
+
+			// Prefer maps URL as it shows all reviews directly
+			if (!empty($location['metadata']['mapsUrl'])) {
+				return $location['metadata']['mapsUrl'];
+			}
+
+			// Fallback: construct from Place ID
+			if (!empty($location['metadata']['placeId'])) {
+				return 'https://search.google.com/local/reviews?placeid=' .
+					urlencode($location['metadata']['placeId']);
+			}
+
+			return null;
+
+		} catch (\Exception $e) {
+			$this->logError('Failed to get reviews view URL: ' . $e->getMessage(), [
+				'method' => 'getReviewsViewUrl'
+			]);
+			return null;
+		}
+	}
+
+	/**
+	 * Get the URL to leave a review for the current location
+	 * @return string|null The review URL or null if not available
+	 */
+	public function getReviewUrl(): ?string
+	{
+		$this->ensureInitialized();
+		try {
+			$location = $this->getLocation();
+
+			if (empty($location)) {
+				return null;
+			}
+
+			// Try to use Place ID for write review
+			if (!empty($location['metadata']['placeId'])) {
+				return 'https://search.google.com/local/writereview?placeid=' .
+					urlencode($location['metadata']['placeId']);
+			}
+
+			// Fallback to maps URL
+			if (!empty($location['metadata']['mapsUrl'])) {
+				return $location['metadata']['mapsUrl'] . '/reviews';
+			}
+
+			return null;
+
+		} catch (\Exception $e) {
+			$this->logError('Failed to get review URL: ' . $e->getMessage(), [
+				'method' => 'getReviewUrl'
+			]);
+			return null;
+		}
+	}
+
+	/**
 	 * Get locations for an account (with persistent storage)
 	 * Allowed Fields: https://developers.google.com/my-business/content/location-data#list_of_all_supported_filter_fields
 	 */

--
Gitblit v1.10.0