Viewing file: APIResource.php (12.91 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
declare(strict_types=1);
namespace Vonage\Client;
use Laminas\Diactoros\Request; use Psr\Log\LogLevel; use Vonage\Client\Credentials\Handler\BasicHandler; use Vonage\Entity\Filter\EmptyFilter; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Vonage\Entity\IterableAPICollection; use Vonage\Entity\Filter\FilterInterface; use Psr\Http\Client\ClientExceptionInterface; use Vonage\Client\Credentials\Handler\HandlerInterface; use Vonage\Logger\LoggerTrait;
use function is_null; use function json_decode; use function json_encode; use function http_build_query;
class APIResource implements ClientAwareInterface { use ClientAwareTrait; use LoggerTrait;
/** * @var HandlerInterface[] */ protected array $authHandlers = [];
/** * Base URL that we will hit. This can be overridden from the underlying * client or directly on this class. */ protected string $baseUrl = '';
protected string $baseUri = '';
protected string $collectionName = '';
protected ?IterableAPICollection $collectionPrototype = null;
/** * Sets flag that says to check for errors even on 200 Success */ protected bool $errorsOn200 = false;
/** * Error handler to use when reviewing API responses * * @var callable */ protected $exceptionErrorHandler;
protected bool $isHAL = true;
protected ?RequestInterface $lastRequest = null;
protected ?ResponseInterface $lastResponse = null;
/** * Adds authentication to a request * */ public function addAuth(RequestInterface $request): RequestInterface { $credentials = $this->getClient()->getCredentials();
if (is_array($this->getAuthHandlers())) { foreach ($this->getAuthHandlers() as $handler) { try { $request = $handler($request, $credentials); break; } catch (\RuntimeException) { continue; // We are OK if multiple are sent but only one match // This has a really nasty side effect for complex handlers where we never see the error } throw new \RuntimeException( 'Unable to set credentials, please check configuration and supplied authentication' ); } return $request; }
return $this->getAuthHandlers()($request, $credentials); }
/** * @throws ClientExceptionInterface * @throws Exception\Exception */ public function create(array $body, string $uri = '', array $headers = []): ?array { if (empty($headers)) { $headers = ['content-type' => 'application/json']; }
$request = new Request( $this->getBaseUrl() . $this->getBaseUri() . $uri, 'POST', 'php://temp', $headers );
$request->getBody()->write(json_encode($body));
if ($this->getAuthHandlers()) { $request = $this->addAuth($request); }
$this->lastRequest = $request;
$response = $this->getClient()->send($request); $status = (int)$response->getStatusCode();
$this->setLastResponse($response);
if (($status < 200 || $status > 299) || $this->errorsOn200()) { $e = $this->getException($response, $request);
if ($e) { $e->setEntity($body);
throw $e; } }
$response->getBody()->rewind();
return json_decode($response->getBody()->getContents(), true); }
/** * @throws ClientExceptionInterface * @throws Exception\Exception */ public function delete(string $id, array $headers = []): ?array { $uri = $this->getBaseUrl() . $this->baseUri . '/' . $id;
if (empty($headers)) { $headers = [ 'accept' => 'application/json', 'content-type' => 'application/json' ]; }
$request = new Request( $uri, 'DELETE', 'php://temp', $headers );
if ($this->getAuthHandlers()) { $request = $this->addAuth($request); }
$response = $this->getClient()->send($request); $status = (int)$response->getStatusCode();
$this->lastRequest = $request; $this->setLastResponse($response);
if ($status < 200 || $status > 299) { $e = $this->getException($response, $request); $e->setEntity($id);
throw $e; }
$response->getBody()->rewind();
return json_decode($response->getBody()->getContents(), true); }
/** * @throws ClientExceptionInterface * @throws Exception\Exception */ public function get( $id, array $query = [], array $headers = [], bool $jsonResponse = true, bool $uriOverride = false ) { $uri = $this->getBaseUrl() . $this->baseUri . '/' . $id;
// This is a necessary hack if you want to fetch a totally different URL but use Vonage Auth if ($uriOverride) { $uri = $id; }
if (!empty($query)) { $uri .= '?' . http_build_query($query); }
if (empty($headers)) { $headers = [ 'accept' => 'application/json', 'content-type' => 'application/json' ]; }
$request = new Request( $uri, 'GET', 'php://temp', $headers );
if ($this->getAuthHandlers()) { $request = $this->addAuth($request); }
$response = $this->getClient()->send($request); $status = (int)$response->getStatusCode();
$this->lastRequest = $request; $this->setLastResponse($response);
if ($status < 200 || $status > 299) { $e = $this->getException($response, $request); $e->setEntity($id);
throw $e; }
if (!$jsonResponse) { return $response->getBody(); }
return json_decode($response->getBody()->getContents(), true); }
public function getAuthHandlers() { // If we have not set a handler, default to Basic and issue warning. if (!$this->authHandlers) { $this->log( LogLevel::WARNING, 'Warning: no authorisation handler set for this Client. Defaulting to Basic which might not be the correct authorisation for this API call' );
return new BasicHandler(); }
return $this->authHandlers; }
public function getBaseUrl(): ?string { if (!$this->baseUrl && $this->client) { $this->baseUrl = $this->client->getApiUrl(); }
return $this->baseUrl; }
public function getBaseUri(): ?string { return $this->baseUri; }
public function getCollectionName(): string { return $this->collectionName; }
public function getCollectionPrototype(): IterableAPICollection { if (is_null($this->collectionPrototype)) { $this->collectionPrototype = new IterableAPICollection(); }
return clone $this->collectionPrototype; }
public function getExceptionErrorHandler(): callable { if (is_null($this->exceptionErrorHandler)) { return new APIExceptionHandler(); }
return $this->exceptionErrorHandler; }
/** * Sets the error handler to use when reviewing API responses. */ public function setExceptionErrorHandler(callable $handler): self { $this->exceptionErrorHandler = $handler;
return $this; }
protected function getException(ResponseInterface $response, RequestInterface $request) { return $this->getExceptionErrorHandler()($response, $request); }
public function getLastRequest(): ?RequestInterface { $this->lastRequest->getBody()->rewind();
return $this->lastRequest; }
public function getLastResponse(): ?ResponseInterface { $this->lastResponse->getBody()->rewind();
return $this->lastResponse; }
public function isHAL(): bool { return $this->isHAL; }
public function partiallyUpdate(string $id, array $body, array $headers = []): ?array { return $this->updateEntity('PATCH', $id, $body, $headers); }
public function search(?FilterInterface $filter = null, string $uri = ''): IterableAPICollection { if (is_null($filter)) { $filter = new EmptyFilter(); }
$api = clone $this;
if ($uri) { $api->setBaseUri($uri); }
$collection = $this->getCollectionPrototype(); $collection ->setApiResource($api) ->setFilter($filter); $collection->setClient($this->client);
return $collection; }
/** * Set the auth handler(s). This can be a handler that extends off AbstractHandler, * or an array of handlers that will attempt to resolve at runtime * * @param HandlerInterface|array $handler * * @return $this */ public function setAuthHandlers($handler): self { if (!is_array($handler)) { $handler = [$handler]; } $this->authHandlers = $handler;
return $this; }
public function setBaseUrl(string $url): self { $this->baseUrl = $url;
return $this; }
public function setBaseUri(string $uri): self { $this->baseUri = $uri;
return $this; }
public function setCollectionName(string $name): self { $this->collectionName = $name;
return $this; }
public function setCollectionPrototype(IterableAPICollection $prototype): self { $this->collectionPrototype = $prototype;
return $this; }
public function setIsHAL(bool $state): self { $this->isHAL = $state;
return $this; }
public function setLastResponse(ResponseInterface $response): self { $this->lastResponse = $response;
return $this; }
public function setLastRequest(RequestInterface $request): self { $this->lastRequest = $request;
return $this; }
/** * Allows form URL-encoded POST requests. * * @throws ClientExceptionInterface * @throws Exception\Exception */ public function submit(array $formData = [], string $uri = '', array $headers = []): string { if (empty($headers)) { $headers = ['content-type' => 'application/x-www-form-urlencoded']; }
$request = new Request( $this->baseUrl . $this->baseUri . $uri, 'POST', 'php://temp', $headers );
if ($this->getAuthHandlers()) { $request = $this->addAuth($request); }
$request->getBody()->write(http_build_query($formData)); $response = $this->getClient()->send($request); $status = $response->getStatusCode();
$this->lastRequest = $request; $this->setLastResponse($response);
if ($status < 200 || $status > 299) { $e = $this->getException($response, $request); $e->setEntity($formData);
throw $e; }
return $response->getBody()->getContents(); }
public function update(string $id, array $body, array $headers = []): ?array { return $this->updateEntity('PUT', $id, $body, $headers); }
/** * @throws ClientExceptionInterface * @throws Exception\Exception */ protected function updateEntity(string $method, string $id, array $body, array $headers = []): ?array { if (empty($headers)) { $headers = ['content-type' => 'application/json']; }
$request = new Request( $this->getBaseUrl() . $this->baseUri . '/' . $id, $method, 'php://temp', $headers );
if ($this->getAuthHandlers()) { $request = $this->addAuth($request); }
$request->getBody()->write(json_encode($body)); $response = $this->getClient()->send($request);
$this->lastRequest = $request; $this->setLastResponse($response); $status = $response->getStatusCode();
if (($status < 200 || $status > 299) || $this->errorsOn200()) { $e = $this->getException($response, $request); $e->setEntity(['id' => $id, 'body' => $body]);
throw $e; }
return json_decode($response->getBody()->getContents(), true); }
public function errorsOn200(): bool { return $this->errorsOn200; }
public function setErrorsOn200(bool $value): self { $this->errorsOn200 = $value;
return $this; } }
|