| | |
| | | use JVBase\integrations\OAuthCredentials; |
| | | use JVBase\integrations\OAuthURLs; |
| | | use JVBase\integrations\Requests; |
| | | use JVBase\integrations\SyncTo; |
| | | use JVBase\integrations\SyncToPost; |
| | | use JVBase\integrations\UserConnection; |
| | | use WP_Error; |
| | |
| | | ); |
| | | $client_id->setRequired(); |
| | | $client_id->setHint('From your Google Cloud Console OAuth credentials.'); |
| | | $client_id->makeSetupField(); |
| | | $this->updateField('client_id', $client_id); |
| | | |
| | | $secret = $this->addField( |
| | | 'client_secret', |
| | |
| | | ); |
| | | $secret->setSubType('password'); |
| | | $secret->setRequired(); |
| | | $secret->makeSetupField(); |
| | | $this->updateField('client_secret', $client_id); |
| | | |
| | | if ($this->getAccessToken()) { |
| | | $accs = $this->addField('accounts', 'Accounts', 'select', [$this, 'testUserCanConnect']); |
| | |
| | | 'Add redirect URI: <code>'.esc_html($this->getRedirectUri()).'</code>', |
| | | 'Use the "Authorize" button below to complete OAuth flow' |
| | | ]; |
| | | |
| | | $this->instructions = [ |
| | | 'Go to <a href="https://console.cloud.google.com/apis/credentials" target="_blank">Google Cloud Console</a>', |
| | | 'Create OAuth 2.0 Client ID credentials', |
| | | 'Enable the following APIs in your project:', |
| | | [ |
| | | '<a href="https://console.cloud.google.com/apis/library/mybusinessaccountmanagement.googleapis.com" target="_blank">My Business Account Management API</a>', |
| | | '<a href="https://console.cloud.google.com/apis/library/mybusinessbusinessinformation.googleapis.com" target="_blank">My Business Business Information API</a>', |
| | | '<a href="https://console.cloud.google.com/apis/library/mybusiness.googleapis.com" target="_blank">Google My Business API</a> (legacy v4, required for reviews)', |
| | | ], |
| | | 'On the OAuth consent screen, add these scopes:', |
| | | [ |
| | | '<code>https://www.googleapis.com/auth/business.manage</code>', |
| | | '<code>https://www.googleapis.com/auth/userinfo.email</code>', |
| | | '<code>https://www.googleapis.com/auth/userinfo.profile</code>', |
| | | ], |
| | | 'Add redirect URI: <code>'.esc_html($this->getRedirectUri()).'</code>', |
| | | 'Use the "Authorize" button below to complete OAuth flow' |
| | | ]; |
| | | } |
| | | protected function defineOAuth():void |
| | | { |
| | |
| | | } |
| | | protected function defineActions():void |
| | | { |
| | | $this->addAction( |
| | | 'Update Location', |
| | | [$this, 'handleUpdateLocation'], |
| | | 'update_location', |
| | | ); |
| | | if ($this->hasOAuthCredentials($this->userID)) { |
| | | $this->addAction( |
| | | 'Update Location', |
| | | [$this, 'handleUpdateLocation'], |
| | | 'update_location', |
| | | ); |
| | | } |
| | | } |
| | | public function handleUpdateLocation(array $data):array |
| | | { |
| | |
| | | ]; |
| | | } |
| | | |
| | | protected function handleResponse(\WP_Error|array $response, string $method, string $endpoint): array |
| | | protected function handleResponse(WP_Error|array $response, string $method, string $endpoint): array |
| | | { |
| | | if (is_wp_error($response) && $response->get_error_message() === 'rate_limit_exceeded') { |
| | | return $this->response(false, 'Rate limit exceeded'); |
| | |
| | | |
| | | protected function refreshAccessToken(OAuthCredentials $credentials): array |
| | | { |
| | | if (empty($this->getClientID()) || empty($this->getClientSecret()) || empty($credentials->refresh_token)) { |
| | | $this->logError('refreshAccessToken', 'Missing refresh token'); |
| | | return $this->response(false, 'Missing client ID, client Secret, or refresh token'); |
| | | } |
| | | $response = wp_remote_post( |
| | | $this->oauth->getToken(), |
| | | [ |
| | | 'timeout' => 15, |
| | | 'body' => [ |
| | | 'grant_type' => 'refresh_token', |
| | | 'refresh_token' => $credentials->refresh_token, |
| | | 'client_id' =>$this->getClientID(), |
| | | 'client_secret' =>$this->getClientSecret() |
| | | ], |
| | | 'headers' => $this->getOAuthRequestHeaders() |
| | | ] |
| | | ); |
| | | if (is_wp_error($response)) { |
| | | $this->logError( |
| | | 'refreshAccessToken', |
| | | 'Failed to refresh GMB Token', |
| | | [ |
| | | 'error' => $response->get_error_message() |
| | | ] |
| | | ); |
| | | return $this->response(false, 'Failed to refresh GMB Token'); |
| | | } |
| | | |
| | | $data = json_decode(wp_remote_retrieve_body($response), true); |
| | | if (empty($data['access_token'])) { |
| | | $this->logError('refreshAccessToken', 'No access token in response'); |
| | | return $this->response(false, 'No access token in response'); |
| | | } |
| | | $credentials = [ |
| | | 'access_token' => $data['access_token'], |
| | | 'expires_at' => time() + (int)($data['expires_in']??3600), |
| | | // Google usually omits refresh_token on refresh — keep the old one |
| | | 'refresh_token' => $body['refresh_token'] ?? $credentials->refresh_token, |
| | | ]; |
| | | $this->saveCredentials($credentials); |
| | | |
| | | return $this->response(true, 'Successfully refreshed token'); |
| | | } |
| | | |
| | | /********************************************************* |
| | | * UTILITY |
| | | *********************************************************/ |
| | | protected function getClientID():string|false |
| | | { |
| | | $switch = false; |
| | | if ($this->userID !== null) { |
| | | $switch = $this->userID; |
| | | $this->switchUser(null); |
| | | } |
| | | |
| | | $ID = $this->loadCredentials()['client_id']??false; |
| | | if ($switch) { |
| | | $this->switchUser($switch); |
| | | } |
| | | return $ID; |
| | | } |
| | | protected function getClientSecret():string|false |
| | | { |
| | | $switch = false; |
| | | if ($this->userID !== null) { |
| | | $switch = $this->userID; |
| | | $this->switchUser(null); |
| | | } |
| | | |
| | | $ID = $this->loadCredentials()['client_secret']??false; |
| | | if ($switch) { |
| | | $this->switchUser($switch); |
| | | } |
| | | return $ID; |
| | | } |
| | | protected function getAccountID():string|false |
| | | { |
| | | return $this->loadCredentials()['account_id']??false; |