<?php
|
namespace JVBase\integrations\services;
|
use Exception;
|
use JVBase\integrations\Admin;
|
use JVBase\Instance;
|
use JVBase\integrations\Integrations;
|
use JVBase\integrations\OAuth;
|
use JVBase\integrations\OAuthCredentials;
|
use JVBase\integrations\OAuthURLs;
|
use JVBase\integrations\Requests;
|
use JVBase\integrations\SyncTo;
|
use JVBase\integrations\UserConnection;
|
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
|
class GoogleMyBusiness extends Integrations
|
{
|
use Admin, Instance, OAuth, Requests, UserConnection, SyncTo;
|
|
protected string $readMask = 'name,title,storefrontAddress,metadata,openInfo,storeCode,categories,phoneNumbers,labels,specialHours';
|
|
protected function __construct()
|
{
|
$this->service_name = 'gmb';
|
$this->title = 'Google My Business';
|
$this->icon = 'storefront';
|
|
$this->canSync = [
|
'initial' => true,
|
'update' => true,
|
'delete' => true,
|
];
|
$this->supportsWebp = false;
|
|
$this->defineFields();
|
$this->defineInstructions();
|
$this->defineOAuth();
|
$this->defineActions();
|
|
parent::__construct();
|
}
|
protected function defineFields():void
|
{
|
$client_id = $this->addField(
|
'client_id',
|
'OAuth Client ID',
|
'text',
|
'manage_options'
|
);
|
$client_id->setRequired();
|
$client_id->setHint('From your Google Cloud Console OAuth credentials.');
|
|
$secret = $this->addField(
|
'client_secret',
|
'OAuth Client Secret',
|
'text',
|
'manage_options',
|
);
|
$secret->setSubType('password');
|
$secret->setRequired();
|
|
if ($this->getAccessToken()) {
|
$accs = $this->addField('accounts', 'Accounts', 'select', [$this, 'testUserCanConnect']);
|
$accs->setHidden();
|
$accs->setOptions($this->getAccountOptions());
|
|
$acc = $this->addField('account_id', 'Set Account', 'select', [$this, 'testUserCanConnect']);
|
$acc->setOptions($this->loadCredentials()['accounts']??[]);
|
$acc->setHint('Select the account to connect to.');
|
|
if ($this->getAccountID()) {
|
$locs = $this->addField('locations', 'Locations', 'select', [$this, 'testUserCanConnect']);
|
$locs->setHidden();
|
$locs->setOptions($this->getLocationOptions());
|
|
$loc = $this->addField('location_id', 'Set Location', 'select', [$this, 'testUserCanConnect']);
|
$loc->setOptions($this->loadCredentials()['locations']??[]);
|
$loc->setHint('Select the location to connect to.');
|
}
|
}
|
|
}
|
public function testUserCanConnect():bool
|
{
|
$user = get_current_user_id();
|
return $this->userCanConnect($user);
|
}
|
protected function defineInstructions():void
|
{
|
$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 Google My Business API',
|
'Add redirect URI: <code>'.esc_html($this->getRedirectUri()).'</code>',
|
'Use the "Authorize" button below to complete OAuth flow'
|
];
|
}
|
protected function defineOAuth():void
|
{
|
$this->oauth = new OAuthURLs(
|
'https://accounts.google.com/o/oauth2/v2/auth',
|
'https://oauth2.googleapis.com/token',
|
'https://oauth2.googleapis.com/revoke'
|
);
|
|
$this->oathScopes = [
|
'https://www.googleapis.com/auth/business.manage',
|
'https://www.googleapis.com/auth/userinfo.email',
|
'https://www.googleapis.com/auth/userinfo.profile',
|
'https://www.googleapis.com/auth/plus.business.manage'
|
];
|
}
|
protected function defineActions():void
|
{
|
$this->addAction(
|
'Update Location',
|
[$this, 'handleUpdateLocation'],
|
'update_location',
|
);
|
}
|
public function handleUpdateLocation(array $data):array
|
{
|
if (empty($data['location_id']??'')) {
|
return $this->response(false, 'No location selected');
|
}
|
|
$credentials = [
|
'location_id' => sanitize_text_field($data['location_id'])
|
];
|
return $this->saveCredentials($credentials, false);
|
}
|
|
protected function initialize(): void
|
{
|
// TODO: Implement initialize() method.
|
}
|
|
protected function getRequestHeaders(): array
|
{
|
// TODO: Implement getRequestHeaders() method.
|
}
|
|
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');
|
}
|
|
return match($endpoint) {
|
'https://mybusinessaccountmanagement.googleapis.com/v1/accounts' => $this->handleGetAccountsResponse($response, $method),
|
sprintf('https://mybusinessbusinessinformation.googleapis.com/v1/%s/locations', $this->getAccountID()??'') => $this->handleGetLocationsResponse($response, $method),
|
default => $this->response(false, 'Unhandled response for '.$endpoint.' endpoint, with method: '.$method)
|
};
|
}
|
|
protected function refreshAccessToken(OAuthCredentials $credentials): array
|
{
|
// TODO: Implement refreshAccessToken() method.
|
}
|
|
/*********************************************************
|
* UTILITY
|
*********************************************************/
|
protected function getAccountID():string|false
|
{
|
return $this->loadCredentials()['account_id']??false;
|
}
|
protected function getAccountOptions(bool $force = false):array
|
{
|
$stored = $this->loadCredentials()['accounts']??[];
|
if ($force || empty($stored)) {
|
$stored = $this->getAccounts();
|
}
|
return $stored;
|
}
|
|
protected function getLocationID():string|false
|
{
|
return $this->loadCredentials()['location_id']??false;
|
}
|
protected function getLocationOptions(bool $force = false):array
|
{
|
$stored = $this->loadCredentials()['locations']??[];
|
if ($force || empty($stored)) {
|
$stored = $this->getLocations();
|
}
|
return $stored;
|
}
|
protected function getLocations():array|false
|
{
|
if (!$this->getAccessToken() || !$this->getAccountID()) {
|
return false;
|
}
|
try {
|
return $this->getRequest(
|
sprintf(
|
'/v1/%s/locations',
|
$this->getAccountID()
|
),
|
[
|
'readMask' => $this->readMask
|
]
|
);
|
} catch (Exception $e)
|
{
|
$this->logError('getLocations', 'Could not get locations: '.$e->getMessage());
|
return [];
|
}
|
}
|
protected function handleGetLocationsResponse(array $response, string $method):array
|
{
|
$locations = [];
|
if (isset($response['locations'])) {
|
foreach ($response['locations'] as $loc) {
|
if (isset($loc['name']) && isset($loc['title'])) {
|
$locations[$loc['name']] = $loc['title'];
|
}
|
}
|
}
|
return $locations;
|
}
|
|
protected function getAccounts(bool $force = false):array|false
|
{
|
if (!$this->getAccessToken()) {
|
return false;
|
}
|
|
return $this->getRequest(
|
'https://mybusinessaccountmanagement.googleapis.com/v1/accounts',
|
[],
|
$force
|
);
|
}
|
protected function handleGetAccountsResponse(array $response, string $method):array
|
{
|
$accounts = [];
|
if (isset($response['accounts']) && is_array($response['accounts'])) {
|
$accounts = $response['accounts'];
|
} elseif (is_array($response) && isset($response['name'])) {
|
$accounts = [$response];
|
}
|
$options = [];
|
foreach ($accounts as $account) {
|
if (isset($account['name']) && isset($account['accountName'])) {
|
$options[$account['name']] = $account['accountName'];
|
}
|
}
|
return $options;
|
}
|
|
protected function setContentTypes(): void
|
{
|
// TODO: Implement setContentTypes() method.
|
}
|
|
protected function formatForService(int $itemID, string $type = 'post'): array
|
{
|
// TODO: Implement formatForService() method.
|
}
|
}
|