-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
688 additions
and
250 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Helloasso; | ||
|
||
use Helloasso\Http\ApiCaller; | ||
use Helloasso\Http\ResponseHandler; | ||
use Helloasso\Http\TokenManager; | ||
use Symfony\Component\HttpClient\HttpClient; | ||
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; | ||
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; | ||
use Symfony\Component\PropertyInfo\PropertyInfoExtractor; | ||
use Symfony\Component\Serializer\Encoder\JsonEncoder; | ||
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; | ||
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer; | ||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; | ||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; | ||
use Symfony\Component\Serializer\Serializer; | ||
|
||
class HelloassoClientFactory | ||
{ | ||
public static function create( | ||
string $clientId, | ||
string $clientSecret, | ||
string $organizationSlug, | ||
bool $sandbox = false, | ||
): HelloassoClient { | ||
$httpClient = HttpClient::createForBaseUri($sandbox ? 'https://api.helloasso-sandbox.com' : 'https://api.helloasso.com', [ | ||
'headers' => [ | ||
'accept' => 'application/json', | ||
'Content-type: application/json', | ||
], | ||
]); | ||
$serializer = self::createSerializer(); | ||
$responseHandler = new ResponseHandler($serializer); | ||
$tokenManager = new TokenManager($httpClient, $responseHandler, $clientId, $clientSecret); | ||
|
||
return new HelloassoClient( | ||
$serializer, | ||
new ApiCaller($httpClient, $tokenManager, $responseHandler, $serializer), | ||
$organizationSlug, | ||
); | ||
} | ||
|
||
private static function createSerializer(): Serializer | ||
{ | ||
$encoder = [new JsonEncoder()]; | ||
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); | ||
$normalizer = [ | ||
new DateTimeNormalizer(), | ||
new BackedEnumNormalizer(), | ||
new ArrayDenormalizer(), | ||
new ObjectNormalizer(null, null, null, $extractor), | ||
]; | ||
|
||
return new Serializer($normalizer, $encoder); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Helloasso\Http; | ||
|
||
use Helloasso\Models\HelloassoObject; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\Serializer\Serializer; | ||
use Symfony\Contracts\HttpClient\HttpClientInterface; | ||
|
||
class ApiCaller | ||
{ | ||
public function __construct( | ||
private readonly HttpClientInterface $httpClient, | ||
private readonly TokenManager $tokenManager, | ||
private readonly ResponseHandler $responseHandler, | ||
private readonly Serializer $serializer, | ||
) { | ||
} | ||
|
||
/** | ||
* @template T of HelloassoObject | ||
* | ||
* @param class-string<T> $responseClassType | ||
* | ||
* @return T | ||
*/ | ||
public function post(string $url, array|HelloassoObject|null $body, string $responseClassType): HelloassoObject | ||
{ | ||
$response = $this->httpClient->request(Request::METHOD_POST, $url, [ | ||
'auth_bearer' => $this->tokenManager->getAccessToken(), | ||
'body' => $this->serializer->serialize($body, 'json'), | ||
]); | ||
|
||
return $this->responseHandler->deserializeResponse($response, $responseClassType); | ||
} | ||
|
||
/** | ||
* @template T of HelloassoObject | ||
* | ||
* @param class-string<T> $responseClassType | ||
* | ||
* @return T | ||
*/ | ||
public function get(string $url, string $responseClassType): HelloassoObject | ||
{ | ||
$response = $this->httpClient->request(Request::METHOD_GET, $url, [ | ||
'auth_bearer' => $this->tokenManager->getAccessToken(), | ||
]); | ||
|
||
return $this->responseHandler->deserializeResponse($response, $responseClassType); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Helloasso\Http; | ||
|
||
use Helloasso\Exception\HelloassoApiException; | ||
use Helloasso\Models\HelloassoObject; | ||
use Symfony\Component\Serializer\Serializer; | ||
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface; | ||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; | ||
use Symfony\Contracts\HttpClient\ResponseInterface; | ||
|
||
class ResponseHandler | ||
{ | ||
public function __construct( | ||
private readonly Serializer $serializer, | ||
) { | ||
} | ||
|
||
/** | ||
* @template T of HelloassoObject | ||
* | ||
* @param class-string<T> $responseClassType | ||
* | ||
* @return T | ||
* | ||
* @throws HelloassoApiException | ||
*/ | ||
public function deserializeResponse(ResponseInterface $response, string $responseClassType): HelloassoObject | ||
{ | ||
try { | ||
$responseContent = $response->getContent(); | ||
} catch (HttpExceptionInterface|TransportExceptionInterface $e) { | ||
try { | ||
$content = $response->getContent(false); | ||
} catch (HttpExceptionInterface|TransportExceptionInterface $e) { | ||
$content = 'unknown error'; | ||
} | ||
|
||
throw new HelloassoApiException($e->getMessage().' : '.$content); | ||
} | ||
|
||
return $this->deserializeResponseContent($responseContent, $responseClassType); | ||
} | ||
|
||
/** | ||
* @template T of HelloassoObject | ||
* | ||
* @param class-string<T> $responseClassType | ||
* | ||
* @return T | ||
*/ | ||
public function deserializeResponseContent(string $content, string $responseClassType): HelloassoObject | ||
{ | ||
return $this->serializer->deserialize($content, $responseClassType, 'json'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Helloasso\Http; | ||
|
||
use Helloasso\Models\ClientCredentials; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Contracts\HttpClient\HttpClientInterface; | ||
|
||
class TokenManager | ||
{ | ||
private ?string $accessToken = null; | ||
|
||
public function __construct( | ||
private readonly HttpClientInterface $httpClient, | ||
private readonly ResponseHandler $responseHandler, | ||
private readonly string $clientId, | ||
private readonly string $clientSecret, | ||
) { | ||
} | ||
|
||
public function getAccessToken(): string | ||
{ | ||
if (null === $this->accessToken) { | ||
$this->retrieveAccessToken(); | ||
} | ||
|
||
return $this->accessToken; | ||
} | ||
|
||
private function retrieveAccessToken(): void | ||
{ | ||
$response = $this->httpClient->request(Request::METHOD_POST, '/oauth2/token', [ | ||
'body' => [ | ||
'grant_type' => 'client_credentials', | ||
'client_id' => $this->clientId, | ||
'client_secret' => $this->clientSecret, | ||
], | ||
'headers' => [ | ||
'Content-Type: application/x-www-form-urlencoded', | ||
], | ||
]); | ||
|
||
$credentials = $this->responseHandler->deserializeResponse($response, ClientCredentials::class); | ||
|
||
$this->accessToken = $credentials->getAccessToken(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.