ldc-bogt/app/Lib/CafelApi/Transport/ApiInterface.php

175 lines
4.8 KiB
PHP

<?php
namespace App\Lib\CafelApi\Transport;
use App\Enums\ApiStatus;
use App\Exceptions\CafelApiException;
use App\Lib\CafelApi\Models\CafelClientModel;
/**
* @ignore
*
* This class contains static api credentials
* It handles a request to get a response
*
* @package LDCCrmClient
* @subpackage transport
*/
class ApiInterface
{
/**
* The api endpoint url
*
* @var string
*/
protected static $endpoint;
/**
* The api user
*
* @var string
*/
protected static $user;
/**
* The api user password
*
* @var string
*/
protected static $password;
/**
* The api token
* ! For the service that should be stateless
*
* @var string
*/
protected static $token;
/**
* CafelApi
*
* @param string|null $endpoint The api endpoint url.
* @param string|null $user The api user.
* @param string|null $password The api password.
* @throws \App\Exceptions\CafelApiException If cafel.user, cafel.password or
* cafel.endpoint is missing on .env file or in laravel config. Or
* if authentification to the service failed.
*/
public function __construct(string $endpoint = null, string $user = null, string $password = null)
{
self::$endpoint = self::$endpoint ?: $endpoint;
self::$user = self::$user ?: $user;
self::$password = self::$password ?: $password;
static::$user = static::$user ?: config('cafel.user');
static::$password = static::$password ?: config('cafel.password');
static::$endpoint = static::$endpoint ?: config('cafel.endpoint');
if (!self::$user or !self::$password or !self::$endpoint) {
throw new CafelApiException(
'Either config or .env file need to have the token var set (cafel.user, cafel.password, cafel.endpoint)'
);
}
$this->authenticate();
}
/**
* Login to the api
* !That should be stateless !!!!!
*
* @return void
* @throws CafelApiException If Authentification failed.
*/
private function authenticate()
{
$request = CafelClientModel::getResquest(
'cafel.users.connect',
[],
[
'Login' => static::$user,
'Password' => static::$password
]
);
$response = $this->call($request);
if (!isset($response->body['token'])) {
throw new CafelApiException('Missing api token after authentification');
}
self::$token = $response->body['token'];
}
/**
* Make a crm http call to get a reponse
*
* @param \App\Lib\CafelApi\Transport\Request $request
* @return \App\Lib\CafelApi\Transport\Response
* @throws \App\Exceptions\CafelApiException If reponse status is KO or not Json.
*/
public function call(Request $request): Response
{
$response = $this->processRequest($request);
// * Handle response Status.
if ($response->status->equals(ApiStatus::KO())) {
throw new CafelApiException($response->message, $response->httpCode);
}
return $response;
}
/**
* Process request
*
* @param \App\Lib\CafelApi\Transport\Request $request
* @return \App\Lib\CafelApi\Transport\Response
* @throws \App\Exceptions\CafelApiException If HTTP response body in not JSON.
*/
private function processRequest(Request $request): Response
{
$this->setCredentials($request);
$this->setHeaders($request);
$request->setEndpoint(self::$endpoint);
/** @var \Psr\Http\Message\ResponseInterface $response */
$response = $request->call();
$status = in_array($response->getStatusCode(), [200, 201]) ?
ApiStatus::OK() : ApiStatus::KO();
return new Response($status, $response, $request);
}
/**
* Add spécific headers to the request
*
* @param \App\Lib\CafelApi\Transport\Request $request
* @return void
*/
private function setHeaders(Request &$request): void
{
$headers = [
'User-Agent' => sprintf('BOGT CAFEL API client version %s', config('cafel.client_version')),
'Accept' => 'application/json',
'Content-Type' => 'application/json'
];
$request->addHeaders($headers);
}
/**
* Inject bearer credentials into the request
*
* @param \LDC\LDCCRM\Transport\Request $request
* @return void
*/
protected function setCredentials(Request $request)
{
if (self::$token) {
$request->addHeaders([
'Authorization' => implode(',', [
sprintf('Bearer %s', self::$token)
])
]);
}
}
}