166 lines
3.9 KiB
PHP
166 lines
3.9 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace Kreait\Firebase\Database;
|
||
|
|
|
||
|
|
use Beste\Json;
|
||
|
|
use GuzzleHttp\ClientInterface;
|
||
|
|
use GuzzleHttp\Psr7\Query;
|
||
|
|
use GuzzleHttp\Psr7\Request;
|
||
|
|
use GuzzleHttp\Psr7\Uri;
|
||
|
|
use Kreait\Firebase\Exception\DatabaseApiExceptionConverter;
|
||
|
|
use Kreait\Firebase\Exception\DatabaseException;
|
||
|
|
use Psr\Http\Message\ResponseInterface;
|
||
|
|
use Throwable;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @internal
|
||
|
|
*/
|
||
|
|
class ApiClient
|
||
|
|
{
|
||
|
|
public function __construct(
|
||
|
|
private readonly ClientInterface $client,
|
||
|
|
private readonly UrlBuilder $resourceUrlBuilder,
|
||
|
|
private readonly DatabaseApiExceptionConverter $errorHandler,
|
||
|
|
) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
public function get(string $path): mixed
|
||
|
|
{
|
||
|
|
$response = $this->requestApi('GET', $path);
|
||
|
|
|
||
|
|
return Json::decode((string) $response->getBody(), true);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws DatabaseException
|
||
|
|
*
|
||
|
|
* @return array<string, mixed>
|
||
|
|
*/
|
||
|
|
public function getWithETag(string $path): array
|
||
|
|
{
|
||
|
|
$response = $this->requestApi('GET', $path, [
|
||
|
|
'headers' => [
|
||
|
|
'X-Firebase-ETag' => 'true',
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$value = Json::decode((string) $response->getBody(), true);
|
||
|
|
$etag = $response->getHeaderLine('ETag');
|
||
|
|
|
||
|
|
return [
|
||
|
|
'value' => $value,
|
||
|
|
'etag' => $etag,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
public function set(string $path, mixed $value): mixed
|
||
|
|
{
|
||
|
|
$response = $this->requestApi('PUT', $path, ['json' => $value]);
|
||
|
|
|
||
|
|
return Json::decode((string) $response->getBody(), true);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
public function setWithEtag(string $path, mixed $value, string $etag): mixed
|
||
|
|
{
|
||
|
|
$response = $this->requestApi('PUT', $path, [
|
||
|
|
'headers' => [
|
||
|
|
'if-match' => $etag,
|
||
|
|
],
|
||
|
|
'json' => $value,
|
||
|
|
]);
|
||
|
|
|
||
|
|
return Json::decode((string) $response->getBody(), true);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
public function removeWithEtag(string $path, string $etag): void
|
||
|
|
{
|
||
|
|
$this->requestApi('DELETE', $path, [
|
||
|
|
'headers' => [
|
||
|
|
'if-match' => $etag,
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
public function updateRules(string $path, RuleSet $ruleSet): mixed
|
||
|
|
{
|
||
|
|
$rules = $ruleSet->getRules();
|
||
|
|
$encodedRules = Json::encode((object) $rules);
|
||
|
|
|
||
|
|
$response = $this->requestApi('PUT', $path, [
|
||
|
|
'body' => $encodedRules,
|
||
|
|
]);
|
||
|
|
|
||
|
|
return Json::decode((string) $response->getBody(), true);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
public function push(string $path, mixed $value): string
|
||
|
|
{
|
||
|
|
$response = $this->requestApi('POST', $path, ['json' => $value]);
|
||
|
|
|
||
|
|
return Json::decode((string) $response->getBody(), true)['name'];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
public function remove(string $path): void
|
||
|
|
{
|
||
|
|
$this->requestApi('DELETE', $path);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param array<array-key, mixed> $values
|
||
|
|
*
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
public function update(string $path, array $values): void
|
||
|
|
{
|
||
|
|
$this->requestApi('PATCH', $path, ['json' => $values]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param array<string, mixed>|null $options
|
||
|
|
*
|
||
|
|
* @throws DatabaseException
|
||
|
|
*/
|
||
|
|
private function requestApi(string $method, string $path, ?array $options = []): ResponseInterface
|
||
|
|
{
|
||
|
|
$options ??= [];
|
||
|
|
|
||
|
|
$uri = new Uri($path);
|
||
|
|
|
||
|
|
$url = $this->resourceUrlBuilder->getUrl(
|
||
|
|
$uri->getPath(),
|
||
|
|
Query::parse($uri->getQuery()),
|
||
|
|
);
|
||
|
|
|
||
|
|
$request = new Request($method, $url);
|
||
|
|
|
||
|
|
try {
|
||
|
|
return $this->client->send($request, $options);
|
||
|
|
} catch (Throwable $e) {
|
||
|
|
throw $this->errorHandler->convertException($e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|