Add PSR-7 requests to supported sources

This commit is contained in:
Andrea Marco Sartori
2023-01-12 21:13:00 +10:00
parent 114514291e
commit 6b0ea331fc
5 changed files with 128 additions and 24 deletions

View File

@ -0,0 +1,56 @@
<?php
namespace Cerbero\JsonParser\Concerns;
use Cerbero\JsonParser\Exceptions\SourceException;
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\UriInterface;
/**
* The Guzzle-aware trait.
*
*/
trait GuzzleAware
{
/**
* Abort if Guzzle is not loaded
*
* @return void
* @throws SourceException
*/
protected function requireGuzzle(): void
{
if (!class_exists(Client::class)) {
throw SourceException::requireGuzzle();
}
}
/**
* Retrieve the JSON response of the given URL
*
* @param UriInterface|string $url
* @return ResponseInterface
*/
protected function getJson(UriInterface|string $url): ResponseInterface
{
return (new Client())->get($url, [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
]);
}
/**
* Retrieve the JSON response of the given request
*
* @param RequestInterface $request
* @return ResponseInterface
*/
protected function sendRequest(RequestInterface $request): ResponseInterface
{
return (new Client())->sendRequest($request);
}
}

View File

@ -26,6 +26,7 @@ class AnySource extends Source
JsonResource::class, JsonResource::class,
LaravelClientResponse::class, LaravelClientResponse::class,
Psr7Message::class, Psr7Message::class,
Psr7Request::class,
Psr7Stream::class, Psr7Stream::class,
]; ];

View File

@ -3,19 +3,20 @@
namespace Cerbero\JsonParser\Sources; namespace Cerbero\JsonParser\Sources;
use Cerbero\JsonParser\Concerns\DetectsEndpoints; use Cerbero\JsonParser\Concerns\DetectsEndpoints;
use Cerbero\JsonParser\Exceptions\SourceException; use Cerbero\JsonParser\Concerns\GuzzleAware;
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
use Traversable; use Traversable;
/** /**
* The endpoint source. * The endpoint source.
* *
* @property-read string $source * @property-read UriInterface|string $source
*/ */
class Endpoint extends Source class Endpoint extends Source
{ {
use DetectsEndpoints; use DetectsEndpoints;
use GuzzleAware;
/** /**
* The endpoint response. * The endpoint response.
@ -28,33 +29,17 @@ class Endpoint extends Source
* Retrieve the JSON fragments * Retrieve the JSON fragments
* *
* @return Traversable<int, string> * @return Traversable<int, string>
* @throws \Cerbero\JsonParser\Exceptions\SourceException
*/ */
public function getIterator(): Traversable public function getIterator(): Traversable
{ {
if (!$this->guzzleIsLoaded()) { $this->requireGuzzle();
throw SourceException::requireGuzzle();
}
$this->response = (new Client())->get($this->source, [ $this->response = $this->getJson($this->source);
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
]);
return new Psr7Message($this->response, $this->config); return new Psr7Message($this->response, $this->config);
} }
/**
* Determine whether the Guzzle client is loaded
*
* @return bool
*/
protected function guzzleIsLoaded(): bool
{
return class_exists(Client::class);
}
/** /**
* Determine whether the JSON source can be handled * Determine whether the JSON source can be handled
* *
@ -62,7 +47,8 @@ class Endpoint extends Source
*/ */
public function matches(): bool public function matches(): bool
{ {
return is_string($this->source) && $this->isEndpoint($this->source); // @phpstan-ignore-next-line
return (is_string($this->source) || $this->source instanceof UriInterface) && $this->isEndpoint($this->source);
} }
/** /**

View File

@ -3,6 +3,7 @@
namespace Cerbero\JsonParser\Sources; namespace Cerbero\JsonParser\Sources;
use Psr\Http\Message\MessageInterface; use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Traversable; use Traversable;
/** /**
@ -29,7 +30,7 @@ class Psr7Message extends Source
*/ */
public function matches(): bool public function matches(): bool
{ {
return $this->source instanceof MessageInterface; return $this->source instanceof MessageInterface && !$this->source instanceof RequestInterface;
} }
/** /**

View File

@ -0,0 +1,60 @@
<?php
namespace Cerbero\JsonParser\Sources;
use Cerbero\JsonParser\Concerns\GuzzleAware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Traversable;
/**
* The PSR-7 request source.
*
* @property-read RequestInterface $source
*/
class Psr7Request extends Source
{
use GuzzleAware;
/**
* The endpoint response.
*
* @var ResponseInterface|null
*/
protected ?ResponseInterface $response;
/**
* Retrieve the JSON fragments
*
* @return Traversable<int, string>
* @throws \Cerbero\JsonParser\Exceptions\SourceException
*/
public function getIterator(): Traversable
{
$this->requireGuzzle();
$this->response = $this->sendRequest($this->source);
return new Psr7Message($this->response, $this->config);
}
/**
* Determine whether the JSON source can be handled
*
* @return bool
*/
public function matches(): bool
{
return $this->source instanceof RequestInterface;
}
/**
* Retrieve the calculated size of the JSON source
*
* @return int|null
*/
protected function calculateSize(): ?int
{
return $this->response?->getBody()->getSize();
}
}