Skip to content

Commit bfb4f86

Browse files
committed
feat(zohoCliq): add DataCenter class for Zoho Cliq API integration
- Introduced a new DataCenter class to manage data center URLs for Zoho Cliq. - Implemented methods to retrieve base URLs for both API and OAuth based on the specified data center. - Utilized PHP 8.0 match expression for cleaner URL resolution. - Added exception handling for invalid data center inputs. Signed-off-by: guanguans <[email protected]>
1 parent 0836713 commit bfb4f86

File tree

5 files changed

+107
-39
lines changed

5 files changed

+107
-39
lines changed

ide.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2334,7 +2334,6 @@
23342334
"client_id",
23352335
"client_secret",
23362336
"code",
2337-
"data_center",
23382337
"grant_type",
23392338
"redirect_uri",
23402339
"refresh_token",

src/ZohoCliq/Authenticator.php

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
*/
4949
class Authenticator extends NullAuthenticator implements \Stringable
5050
{
51+
private DataCenter $dataCenter;
5152
private CacheInterface $cache;
5253
private string $cacheKey;
5354
private Client $client;
@@ -56,12 +57,14 @@ public function __construct(
5657
private string $clientId,
5758
#[\SensitiveParameter]
5859
private string $clientSecret,
60+
?string $dataCenter = null,
5961
?CacheInterface $cache = null,
6062
?string $cacheKey = null,
6163
?Client $client = null,
6264
) {
65+
$this->dataCenter = new DataCenter($dataCenter);
6366
$this->cache = $cache ?? new FileCache;
64-
$this->cacheKey = $cacheKey ?? "zoho_cliq.access_token.$clientId.$clientSecret";
67+
$this->cacheKey = $cacheKey ?? "zoho_cliq.$this->dataCenter.access_token.$clientId.$clientSecret";
6568
$this->client = $client ?? new Client;
6669
}
6770

@@ -80,35 +83,20 @@ public function applyToMiddleware(callable $handler): callable
8083
{
8184
return array_reduce(
8285
[
83-
[$this, 'dataCenter'],
84-
[$this, 'retry'],
85-
[$this, 'authenticate'],
86+
$this->retryMiddleware(),
87+
$this->authMiddleware(),
88+
$this->baseUriMiddleware($this->dataCenter->toBaseUri()),
8689
],
8790
static fn (callable $handler, callable $next): callable => $next($handler),
8891
$handler,
8992
);
9093
}
9194

92-
/**
93-
* @todo
94-
*/
95-
private function dataCenter(callable $handler): callable
96-
{
97-
return $handler;
98-
}
99-
100-
private function authenticate(callable $handler): callable
101-
{
102-
return Middleware::mapRequest(
103-
fn (RequestInterface $request): RequestInterface => $request->withHeader('Authorization', "Bearer $this"),
104-
)($handler);
105-
}
106-
10795
/**
10896
* @see \GuzzleHttp\RetryMiddleware::onFulfilled()
10997
* @see \GuzzleHttp\RetryMiddleware::onRejected()
11098
*/
111-
private function retry(callable $handler): callable
99+
private function retryMiddleware(): callable
112100
{
113101
return Middleware::retry(
114102
function (int $retries, RequestInterface &$request, ?ResponseInterface $response = null): bool {
@@ -124,7 +112,28 @@ function (int $retries, RequestInterface &$request, ?ResponseInterface $response
124112

125113
return false;
126114
}
127-
)($handler);
115+
);
116+
}
117+
118+
private function authMiddleware(): callable
119+
{
120+
return Middleware::mapRequest(
121+
fn (RequestInterface $request): RequestInterface => $request->withHeader('Authorization', "Bearer $this"),
122+
);
123+
}
124+
125+
/**
126+
* @see \GuzzleHttp\Client::buildUri()
127+
*/
128+
private function baseUriMiddleware(string $baseUri): callable
129+
{
130+
$parsedBaseUri = parse_url($baseUri);
131+
132+
return Middleware::mapRequest(
133+
static fn (RequestInterface $request): RequestInterface => $request->withUri(
134+
$request->getUri()->withScheme($parsedBaseUri['scheme'])->withHost($parsedBaseUri['host'])
135+
),
136+
);
128137
}
129138

130139
/**
@@ -157,13 +166,20 @@ private function getToken(): string
157166
* "expires_in": 3600
158167
* }
159168
* ```
169+
*
170+
* ```json
171+
* {"error":"invalid_client_secret"}
172+
* ```
160173
*/
161174
private function refreshToken(): string
162175
{
163-
$response = $this->client->send(AccessTokenMessage::make([
164-
'client_id' => $this->clientId,
165-
'client_secret' => $this->clientSecret,
166-
]));
176+
$response = $this
177+
->client
178+
->push($this->baseUriMiddleware($this->dataCenter->toOauthBaseUri()))
179+
->send(AccessTokenMessage::make([
180+
'client_id' => $this->clientId,
181+
'client_secret' => $this->clientSecret,
182+
]));
167183

168184
if (!$token = $response->json('access_token')) {
169185
throw RequestException::create($response->request(), $response);

src/ZohoCliq/Client.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,5 @@ class Client extends \Guanguans\Notify\Foundation\Client
2626
public function __construct(Authenticator $authenticator)
2727
{
2828
parent::__construct($authenticator);
29-
$this->baseUri('https://cliq.zoho.com/');
3029
}
3130
}

src/ZohoCliq/DataCenter.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* Copyright (c) 2021-2025 guanguans<[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*
11+
* @see https://github.com/guanguans/notify
12+
*/
13+
14+
namespace Guanguans\Notify\ZohoCliq;
15+
16+
use Guanguans\Notify\Foundation\Exceptions\InvalidArgumentException;
17+
18+
/**
19+
* @see https://www.zoho.com/cliq/help/restapi/v2/#cliq_rest_api
20+
* @see https://github.com/MarJose123/laravel-zoho-cliq-alert/blob/main/src/ZohoDataCenter.php
21+
*/
22+
class DataCenter
23+
{
24+
public const AU = 'au';
25+
public const CA = 'ca';
26+
public const CN = 'cn';
27+
public const EU = 'eu';
28+
public const IN = 'in';
29+
public const JP = 'jp';
30+
public const SA = 'sa';
31+
public const UK = 'uk';
32+
public const US = 'us';
33+
private string $value;
34+
35+
public function __construct(?string $value = null)
36+
{
37+
$this->value = $value ?? self::US;
38+
}
39+
40+
public function __toString(): string
41+
{
42+
return $this->value;
43+
}
44+
45+
public function toOauthBaseUri(): string
46+
{
47+
return str_replace('https://cliq.', 'https://accounts.', $this->toBaseUri());
48+
}
49+
50+
public function toBaseUri(): string
51+
{
52+
return match ($this->value) {
53+
self::AU => 'https://cliq.zoho.com.au/',
54+
self::CA => 'https://cliq.zohocloud.ca/',
55+
self::CN => 'https://cliq.zoho.com.cn/',
56+
self::EU => 'https://cliq.zoho.eu/',
57+
self::IN => 'https://cliq.zoho.in/',
58+
self::JP => 'https://cliq.zoho.jp/',
59+
self::SA => 'https://cliq.zoho.sa/',
60+
self::UK => 'https://cliq.zoho.uk/',
61+
self::US => 'https://cliq.zoho.com/',
62+
default => throw new InvalidArgumentException("Invalid data center [$this->value]."),
63+
};
64+
}
65+
}

src/ZohoCliq/Messages/AccessTokenMessage.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@
1515

1616
use Guanguans\Notify\Foundation\Concerns\AsFormParams;
1717
use Guanguans\Notify\Foundation\Message;
18-
use Guanguans\Notify\Foundation\Support\Arr;
1918

2019
/**
2120
* @method self clientId(mixed $clientId)
2221
* @method self clientSecret(mixed $clientSecret)
2322
* @method self code(mixed $code)
24-
* @method self dataCenter(mixed $dataCenter)
2523
* @method self grantType(mixed $grantType)
2624
* @method self redirectUri(mixed $redirectUri)
2725
* @method self refreshToken(mixed $refreshToken)
@@ -31,8 +29,6 @@ final class AccessTokenMessage extends Message // @internal
3129
{
3230
use AsFormParams;
3331
protected array $defined = [
34-
'data_center',
35-
3632
'client_id',
3733
'client_secret',
3834
'grant_type',
@@ -49,13 +45,6 @@ final class AccessTokenMessage extends Message // @internal
4945

5046
public function toHttpUri(): string
5147
{
52-
return 'https://accounts.zoho.com/oauth/v2/token';
53-
}
54-
55-
protected function toPayload(): array
56-
{
57-
return Arr::except(parent::toPayload(), [
58-
'data_center',
59-
]);
48+
return 'oauth/v2/token';
6049
}
6150
}

0 commit comments

Comments
 (0)