Jake Vanderwerf
5 days ago a9b3b28d001941921aa70d37fdc87c758a163a44
inc/integrations/GoogleMyBusiness.php
@@ -1,8 +1,7 @@
<?php
namespace JVBase\integrations;
use JVBase\meta\MetaManager;
use JVBase\managers\CacheManager;
use JVBase\meta\Meta;
use WP_Error;
if (!defined('ABSPATH')) {
   exit;
@@ -129,7 +128,9 @@
         ]
      );
//    $this->cache->clear();
      if (JVB_TESTING) {
         $this->cache->flush();
      }
   }
   protected function initialize(): void
@@ -203,7 +204,6 @@
      $type = $settings['content_type']??'post'; //can be 'post', 'offer', 'event', 'hours', 'info',
      $initial = $settings['initial']?? false;
      $syncOnUpdate = $settings['update']??false;
      error_log('Handling GMB Save Post with settings: '.print_r($settings, true));
      if ($update && !$syncOnUpdate) {
         return;
      }
@@ -211,7 +211,6 @@
         return;
      }
      error_log('Continuing on...');
      $options = $data = [];
      switch ($type) {
         case 'menu_item':
@@ -223,8 +222,7 @@
      }
      $data['post_id'] = $postID;
      $operation = ($update) ? 'update_' : 'create_';
      error_log('[GMB]Queuing sync to service:'.print_r($data, true));
      error_log('Options: '.print_r($options, true));
      $this->queueOperation(
         $operation.$type,
         $data,
@@ -284,7 +282,7 @@
      }
      $postID = $data['post_id'];
      $meta = new MetaManager($postID, 'post');
      $meta = Meta::forPost($postID);
      $fields = [
         'start_date',
         'end_date',
@@ -320,7 +318,7 @@
         $result =  $this->updatePost($fields["_{$this->service_name}_item_id"], $data);
      } else {
         $result = $this->createPost($data);
         $meta->updateValue("_{$this->service_name}_item_id", $result['name']);
         $meta->set("_{$this->service_name}_item_id", $result['name']);
      }
      return [
@@ -341,7 +339,7 @@
      }
      $postID = $data['post_id'];
      $meta = new MetaManager($postID, 'post');
      $meta = Meta::forPost($postID);
      $fields = [
         'post_excerpt',
         'post_title',
@@ -373,7 +371,7 @@
         $result =  $this->updatePost($fields["_{$this->service_name}_item_id"], $data);
      } else {
         $result = $this->createPost($data);
         $meta->updateValue("_{$this->service_name}_item_id", $result['name']);
         $meta->set("_{$this->service_name}_item_id", $result['name']);
      }
      return [
@@ -395,7 +393,7 @@
      }
      $postID = $data['post_id'];
      $meta = new MetaManager($postID, 'post');
      $meta = Meta::forPost($postID);
      $fields = [
         'post_excerpt',
         'post_title',
@@ -424,7 +422,7 @@
         $result =  $this->updatePost($fields["_{$this->service_name}_item_id"], $data);
      } else {
         $result = $this->createPost($data);
         $meta->updateValue("_{$this->service_name}_item_id", $result['name']);
         $meta->set("_{$this->service_name}_item_id", $result['name']);
      }
      return [
@@ -473,8 +471,6 @@
         // Build the complete menu structure
         $menu_data = $gmb->collectMenu($menu_items);
         error_log('Menu Data: '.print_r($menu_data, true));
         // Send to Google My Business API
         $result = $this->updateFoodMenus($menu_data);
         return [
@@ -512,7 +508,6 @@
            $locations = $this->getLocations($account['name']);
            foreach ($locations as $location) {
               error_log('Fetched Location: '.print_r($location, true));
               if ($location['storeCode'] === $this->credentials['location']) {
                  // Auto-migrate: update stored location to use full resource name
                  $this->setSelectedLocation($location['name']);
@@ -699,7 +694,6 @@
         // Filter to only allowed fields
         $patch_data = array_intersect_key($updates,$allowed_fields);
         error_log('Updates: '.print_r($updates, true));
         $location_name = $this->getSelectedLocationResourceName();
         if (empty($patch_data)) {
@@ -1044,7 +1038,6 @@
      if(!$this->isSetUp()) {
         return [];
      }
      error_log('[GMB] updateBusinessHours called with hours: ' . print_r($hours, true));
      $location_name = $this->credentials['location'];
      if (empty($location_name)) {
@@ -1067,11 +1060,7 @@
            ]
         ];
         error_log('[GMB] Complete update data: ' . print_r($update_data, true));
         $endpoint = "/v1/{$location_name}?updateMask=regularHours";
         error_log('[GMB] API endpoint: ' . $endpoint);
         error_log('[GMB] Using API base: ' . 'base');
         // Make the API request
         $response = $this->makeRequest(
@@ -1081,18 +1070,15 @@
            'base'
         );
         error_log('[GMB] API response: ' . print_r($response, true));
         $success = $response !== null;
         error_log('[GMB] updateBusinessHours result: ' . ($success ? 'SUCCESS' : 'FAILED'));
         // Additional validation - check if the response contains the updated hours
         if ($success && $response) {
            if (isset($response['regularHours'])) {
               error_log('[GMB] SUCCESS: Updated hours confirmed in response: ' . print_r($response['regularHours'], true));
//             error_log('[GMB] SUCCESS: Updated hours confirmed in response: ' . print_r($response['regularHours'], true));
            } else {
               error_log('[GMB] WARNING: No regularHours in response, but API call succeeded');
               error_log('[GMB] Full response keys: ' . implode(', ', array_keys($response)));
//             error_log('[GMB] WARNING: No regularHours in response, but API call succeeded');
//             error_log('[GMB] Full response keys: ' . implode(', ', array_keys($response)));
            }
         }
@@ -1102,9 +1088,6 @@
         ];
      } catch (\Exception $e) {
         error_log('[GMB] Exception in updateBusinessHours: ' . $e->getMessage());
         error_log('[GMB] Exception trace: ' . $e->getTraceAsString());
         $this->logError($e->getMessage(), [
            'method' => 'updateBusinessHours'
         ]);
@@ -1117,8 +1100,6 @@
   private function validateAndFormatHours(array $hours): array
   {
      error_log('[GMB] Validating hours format...');
      $valid_days = ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'];
      $periods = [];
@@ -1148,8 +1129,6 @@
            continue;
         }
         error_log('[GMB] Processing ' . $formatted_day . ' - times data: ' . print_r($times, true));
         // Check if day is open with flexible comparison
         $is_open = false;
         if (isset($times['open'])) {
@@ -1181,10 +1160,7 @@
         ];
         $periods[] = $period;
         error_log('[GMB] Valid period for ' . $formatted_day . ': ' . print_r($period, true));
      }
      error_log('[GMB] Total valid periods: ' . count($periods));
      return $periods;
   }
@@ -1263,8 +1239,6 @@
            ]
         ];
         error_log('[GMB] Updating special hours with corrected structure: ' . json_encode($update_data, JSON_PRETTY_PRINT));
         // Try the PATCH request
         $response = $this->makeRequest(
            'PATCH',
@@ -1279,8 +1253,6 @@
         ];
      } catch (\Exception $e) {
         error_log('[GMB] setSpecialHours Exception: ' . $e->getMessage());
         $this->logError($e->getMessage(), [
            'method' => 'setSpecialHours'
         ]);
@@ -1432,9 +1404,6 @@
      $ttl = 7 * 24 * 60 * 60; // week in seconds
      $response = $this->getRequest('/v1/accounts', [], 'accounts', $ttl, $force)??[];
      // Log the raw response for debugging
      error_log('[GMB] Raw accounts response: ' . print_r($response, true));
      if (isset($response['accounts']) && is_array($response['accounts'])) {
         return $response['accounts'];
      }
@@ -1482,7 +1451,6 @@
            'v4'
         );
         error_log('Review response: '.print_r($response, true));
         $reviews = $response ?? [];
         // Cache for 1 week (604800 seconds)
@@ -1583,7 +1551,6 @@
      if (empty($account_name) || !str_starts_with($account_name, 'accounts/')) {
         return [];
      }
      error_log('[GMB] getLocations() called for: ' . $account_name . ' (force: ' . ($force ? 'true' : 'false') . ')');
      $params = ['readMask' => $this->readMask];
      $ttl = 7 * 24 * 60 * 60; // Week in seconds
@@ -1613,8 +1580,6 @@
    */
   public function refreshStoredData(): array
   {
      error_log('[GMB] Manually refreshing accounts and locations data');
      try {
         // Fetch fresh accounts data from API
         $accounts = $this->getAccounts(true);
@@ -1674,7 +1639,6 @@
      ];
      $endpoint = "/v1/{$location_name}?".http_build_query($params);
      error_log('[GMB] Fetching location: ' . $location_name);
      $location = $this->getRequest($endpoint, [], 'base', 'moderate', $force);
      return $location??null;
@@ -1774,9 +1738,7 @@
      $text = preg_replace('/\s+/', ' ', $text);
      // Trim
      $text = trim($text);
      return $text;
      return trim($text);
   }
   /**
    * Format date for GMB API
@@ -1817,13 +1779,10 @@
         // Validate hour and minute ranges
         if ($hour >= 0 && $hour <= 23 && $minute >= 0 && $minute <= 59) {
            $result = [
            return [
               'hours' => $hour,
               'minutes' => $minute
            ];
            error_log('[GMB] Converted time "' . $time . '" to Google format: ' . print_r($result, true));
            return $result;
         }
      }
@@ -2113,9 +2072,7 @@
         [],
         'posts'
      );
      $result = $response['foodMenus'] ?? [];
      return $result;
      return $response['foodMenus'] ?? [];
   }
   /**
@@ -2237,8 +2194,6 @@
   public function handleGetAllLocations():WP_Error|array
   {
      try {
         error_log('[GMB] AJAX getAllLocations called');
         // Check if we should force refresh
         $force = isset($_POST['force']) && $_POST['force'] === 'true';
@@ -2252,7 +2207,6 @@
            $all_locations = array_merge($all_locations, $locations);
         }
         error_log('[GMB] AJAX returning ' . count($all_locations) . ' locations');
         return [
            'success'   => true,
            'locations' => $all_locations,
@@ -2260,7 +2214,6 @@
         ];
      } catch (\Exception $e) {
         error_log('[GMB] AJAX getAllLocations exception: ' . $e->getMessage());
         return new WP_Error('failure', 'Something went wrong: '.$e->getMessage());
      }
   }
@@ -2274,15 +2227,12 @@
         // Handle both AJAX and REST API calls
         $selected_account = null;
         error_log('handle Update Location: '.print_r($data, true));
         if (is_array($data)) {
            $selected_account = $data['account'] ?? $data['location'] ?? null;
         } elseif (isset($_POST['account'])) {
            $selected_account = sanitize_text_field($_POST['account']);
         }
         error_log('[GMB] updateLocation received: ' . print_r($selected_account, true));
         if (empty($selected_account)) {
            throw new \Exception('No account selected');
         }
@@ -2325,9 +2275,7 @@
   {
      try {
         // Use the static method to clear the entire cache group
         CacheManager::invalidateGroup('integrations_'.$this->cacheName);
         error_log('[GMB] Cleared all stored data for cache group: ' . $this->cacheName);
         $this->cache->flush();
         return true;
      } catch (\Exception $e) {
@@ -2399,12 +2347,11 @@
            'dailyRange.endDate.day' => date('j', strtotime($end_date))
         ];
         $response = $this->getRequest(
            "/v1/{$location_name}:fetchMultiDailyMetricsTimeSeries?" . http_build_query($params),
            $params,
            'performance'
         );
      return $response;
      return $this->getRequest(
         "/v1/{$location_name}:fetchMultiDailyMetricsTimeSeries?" . http_build_query($params),
         $params,
         'performance'
      );
   }
   /**
@@ -2523,7 +2470,7 @@
   protected function collectMenu(array $menu_items): array
   {
      $defaultMeta = new MetaManager($this->userID, 'integrations');
      $defaultMeta = Meta::forOptions($this->userID.'_integrations');
      $defaults = ['menu_name', 'menu_description', 'default_section', 'cuisines', 'source_url', 'language', 'default_currency'];
      $defaults = $defaultMeta->getAll($defaults);
@@ -2584,7 +2531,7 @@
   protected function buildMenuItem(\WP_Post $item, array $defaults):array
   {
      $meta = new MetaManager($item->ID, 'post');
      $meta = Meta::forPost($item->ID);
      $fields = $this->mappedMenuFields($item->post_type);
      $values = $meta->getAll(array_values($fields));
@@ -2713,8 +2660,8 @@
   protected function getMenuSectionsOrder(array $sections_map):array
   {
      $optionsMeta = new MetaManager(null, 'options');
      $sectionOrder = $optionsMeta->getValue('menu_section_order');
      $optionsMeta = Meta::forOptions('options');
      $sectionOrder = $optionsMeta->get('menu_section_order');
      // Build final GMB menu structure
      $ordered = [];
@@ -2750,8 +2697,8 @@
      // Collect cuisines from individual items if specified
      foreach ($menu_items as $item) {
         $meta = new MetaManager($item->ID, 'post');
         $item_cuisines = $meta->getValue('cuisines');
         $meta = Meta::forPost($item->ID);
         $item_cuisines = $meta->get('cuisines');
         if (!empty($item_cuisines)) {
            $item_cuisines = is_array($item_cuisines) ?
@@ -3022,4 +2969,6 @@
         ]
      ];
   }
}