koel/app/Services/ApiClient.php

134 lines
3.6 KiB
PHP
Raw Normal View History

<?php
namespace App\Services;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use InvalidArgumentException;
2018-08-24 15:27:19 +00:00
use SimpleXMLElement;
/**
* @method object get($uri, ...$args)
2017-06-03 23:21:50 +00:00
* @method object post($uri, ...$data)
* @method object put($uri, ...$data)
* @method object patch($uri, ...$data)
* @method object head($uri, ...$data)
* @method object delete($uri)
*/
abstract class ApiClient
{
protected $responseFormat = 'json';
/**
* The GuzzleHttp client to talk to the API.
*/
protected $client;
/**
* The query parameter name for the key.
* For example, Last.fm use api_key, like this:
* https://ws.audioscrobbler.com/2.0?method=artist.getInfo&artist=Kamelot&api_key=API_KEY.
*
* @var string
*/
protected $keyParam = 'key';
public function __construct(Client $client)
{
$this->client = $client;
}
/**
* Make a request to the API.
*
2018-08-24 15:27:19 +00:00
* @param string $method The HTTP method
* @param string $uri The API URI (segment)
* @param bool $appendKey Whether to automatically append the API key into the URI.
2018-08-29 07:07:44 +00:00
* While it's usually the case, some services (like Last.fm) requires
* an "API signature" of the request. Appending an API key will break the request.
2018-08-24 15:27:19 +00:00
* @param mixed[] $params An array of parameters
*
2018-08-24 15:27:19 +00:00
* @return mixed|SimpleXMLElement|null
*/
2018-08-24 15:27:19 +00:00
public function request(string $method, string $uri, bool $appendKey = true, array $params = [])
{
try {
2018-08-19 11:13:29 +00:00
$body = (string) $this->getClient()
2018-08-24 15:27:19 +00:00
->$method($this->buildUrl($uri, $appendKey), ['form_params' => $params])
->getBody();
if ($this->responseFormat === 'json') {
return json_decode($body);
}
if ($this->responseFormat === 'xml') {
return simplexml_load_string($body);
}
return $body;
} catch (ClientException $e) {
2018-08-29 07:07:44 +00:00
return;
}
}
/**
* Make an HTTP call to the external resource.
*
2018-08-24 15:27:19 +00:00
* @param string $method The HTTP method
* @param mixed[] $args An array of parameters
*
* @throws InvalidArgumentException
2016-08-03 10:42:39 +00:00
*
2018-08-29 07:07:44 +00:00
* @return mixed|null|SimpleXMLElement
*/
2018-08-24 15:27:19 +00:00
public function __call(string $method, array $args)
{
if (count($args) < 1) {
throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
}
$uri = $args[0];
$opts = isset($args[1]) ? $args[1] : [];
2015-12-20 12:17:35 +00:00
$appendKey = isset($args[2]) ? $args[2] : true;
2015-12-20 12:17:35 +00:00
return $this->request($method, $uri, $appendKey, $opts);
}
/**
* Turn a URI segment into a full API URL.
*
2018-08-29 07:07:44 +00:00
* @param bool $appendKey Whether to automatically append the API key into the URL.
*/
2018-08-24 15:27:19 +00:00
public function buildUrl(string $uri, bool $appendKey = true): string
{
if (!starts_with($uri, ['http://', 'https://'])) {
2016-08-16 15:12:11 +00:00
if ($uri[0] !== '/') {
$uri = "/$uri";
}
2018-08-19 11:13:29 +00:00
$uri = $this->getEndpoint().$uri;
}
2015-12-20 12:17:35 +00:00
if ($appendKey) {
if (parse_url($uri, PHP_URL_QUERY)) {
2018-08-19 11:13:29 +00:00
$uri .= "&{$this->keyParam}=".$this->getKey();
2015-12-20 12:17:35 +00:00
} else {
2018-08-19 11:13:29 +00:00
$uri .= "?{$this->keyParam}=".$this->getKey();
2015-12-20 12:17:35 +00:00
}
}
return $uri;
}
2018-08-24 15:27:19 +00:00
public function getClient(): Client
{
return $this->client;
}
2018-08-24 15:27:19 +00:00
abstract public function getKey(): ?string;
2018-08-24 15:27:19 +00:00
abstract public function getSecret(): ?string;
2018-08-24 15:27:19 +00:00
abstract public function getEndpoint(): string;
}