2021-05-14 20:06:58 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
2021-05-15 18:57:28 +03:00
|
|
|
* PHP 7.1
|
2021-05-14 20:06:58 +03:00
|
|
|
*
|
|
|
|
* @category PockResponseBuilder
|
|
|
|
* @package Pock
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Pock;
|
|
|
|
|
|
|
|
use InvalidArgumentException;
|
|
|
|
use JsonSerializable;
|
|
|
|
use Nyholm\Psr7\Factory\Psr17Factory;
|
2021-05-15 18:57:28 +03:00
|
|
|
use Pock\Traits\JsonSerializerAwareTrait;
|
|
|
|
use Pock\Traits\XmlSerializerAwareTrait;
|
2021-05-14 20:06:58 +03:00
|
|
|
use Psr\Http\Message\ResponseInterface;
|
2021-05-15 13:14:21 +03:00
|
|
|
use RuntimeException;
|
2021-05-14 20:06:58 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class PockResponseBuilder
|
|
|
|
*
|
|
|
|
* @category PockResponseBuilder
|
|
|
|
* @package Pock
|
|
|
|
*/
|
|
|
|
class PockResponseBuilder
|
|
|
|
{
|
2021-05-15 18:57:28 +03:00
|
|
|
use JsonSerializerAwareTrait;
|
|
|
|
use XmlSerializerAwareTrait;
|
|
|
|
|
2021-05-14 20:06:58 +03:00
|
|
|
/** @var \Psr\Http\Message\ResponseInterface */
|
2021-05-15 13:14:21 +03:00
|
|
|
protected $response;
|
2021-05-14 20:06:58 +03:00
|
|
|
|
|
|
|
/** @var Psr17Factory */
|
2021-05-15 13:14:21 +03:00
|
|
|
protected $factory;
|
2021-05-14 20:06:58 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* PockResponseBuilder constructor.
|
|
|
|
*
|
|
|
|
* @param int $statusCode
|
|
|
|
*/
|
|
|
|
public function __construct(int $statusCode = 200)
|
|
|
|
{
|
|
|
|
$this->factory = new Psr17Factory();
|
|
|
|
$this->response = $this->factory->createResponse($statusCode);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reply with specified status code.
|
|
|
|
*
|
|
|
|
* @param int $statusCode
|
|
|
|
*
|
2021-05-15 13:14:21 +03:00
|
|
|
* @return self
|
2021-05-14 20:06:58 +03:00
|
|
|
*/
|
2021-05-15 13:14:21 +03:00
|
|
|
public function withStatusCode(int $statusCode = 200): self
|
2021-05-14 20:06:58 +03:00
|
|
|
{
|
|
|
|
$this->response = $this->response->withStatus($statusCode);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2021-05-15 13:14:21 +03:00
|
|
|
/**
|
2021-05-15 18:57:28 +03:00
|
|
|
* Respond with specified header pattern.
|
2021-05-15 13:14:21 +03:00
|
|
|
* @see \Psr\Http\Message\MessageInterface::withHeader()
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
* @param string|string[] $value
|
|
|
|
*
|
|
|
|
* @return self
|
|
|
|
*/
|
|
|
|
public function withHeader(string $name, $value): self
|
|
|
|
{
|
|
|
|
$this->response = $this->response->withHeader($name, $value);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-05-15 18:57:28 +03:00
|
|
|
* Respond with specified header pattern appended to existing header.
|
2021-05-15 13:14:21 +03:00
|
|
|
* @see \Psr\Http\Message\MessageInterface::withAddedHeader()
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
* @param string|string[] $value
|
|
|
|
*
|
|
|
|
* @return self
|
|
|
|
*/
|
|
|
|
public function withAddedHeader(string $name, $value): self
|
|
|
|
{
|
|
|
|
$this->response = $this->response->withAddedHeader($name, $value);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Respond with specified headers. Works exactly like calling PockResponseBuilder::withHeader() would work.
|
|
|
|
*
|
|
|
|
* @param array<string, string|string[]> $headers
|
|
|
|
*
|
|
|
|
* @return self
|
|
|
|
*/
|
|
|
|
public function withHeaders(array $headers): self
|
|
|
|
{
|
|
|
|
foreach ($headers as $name => $value) {
|
|
|
|
$this->response = $this->response->withHeader($name, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Respond with specified headers. Works exactly like calling PockResponseBuilder::withAddedHeader() would work.
|
|
|
|
*
|
|
|
|
* @param array<string, string|string[]> $headers
|
|
|
|
*
|
|
|
|
* @return self
|
|
|
|
*/
|
|
|
|
public function withAddedHeaders(array $headers): self
|
|
|
|
{
|
|
|
|
foreach ($headers as $name => $value) {
|
|
|
|
$this->response = $this->response->withAddedHeader($name, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2021-05-14 20:06:58 +03:00
|
|
|
/**
|
|
|
|
* Reply with specified body. It can be:
|
|
|
|
* - PSR-7 StreamInterface - it will be used without any changes.
|
2021-05-15 18:57:28 +03:00
|
|
|
* - string - it will be used as contents contents.
|
|
|
|
* - resource - it's data will be used as contents contents.
|
2021-05-14 20:06:58 +03:00
|
|
|
*
|
|
|
|
* @param \Psr\Http\Message\StreamInterface|resource|string $stream
|
|
|
|
*
|
2021-05-15 13:14:21 +03:00
|
|
|
* @return self
|
2021-05-14 20:06:58 +03:00
|
|
|
*/
|
2021-05-15 13:14:21 +03:00
|
|
|
public function withBody($stream): self
|
2021-05-14 20:06:58 +03:00
|
|
|
{
|
|
|
|
if (is_string($stream)) {
|
|
|
|
$stream = $this->factory->createStream($stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_resource($stream)) {
|
|
|
|
$stream = $this->factory->createStreamFromResource($stream);
|
|
|
|
}
|
|
|
|
|
2021-05-15 13:14:21 +03:00
|
|
|
if ($stream->isSeekable()) {
|
|
|
|
$stream->seek(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->response = $this->response->withBody($stream);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reply with data from specified file.
|
|
|
|
* For available modes @see \fopen()
|
|
|
|
*
|
|
|
|
* @param string $path
|
|
|
|
* @param string $mode
|
|
|
|
*
|
|
|
|
* @return self
|
|
|
|
* @throws InvalidArgumentException|RuntimeException
|
|
|
|
*/
|
|
|
|
public function withFile(string $path, string $mode = 'r'): self
|
|
|
|
{
|
|
|
|
$stream = $this->factory->createStreamFromFile($path, $mode);
|
|
|
|
|
|
|
|
if ($stream->isSeekable()) {
|
|
|
|
$stream->seek(0);
|
|
|
|
}
|
|
|
|
|
2021-05-14 20:06:58 +03:00
|
|
|
$this->response = $this->response->withBody($stream);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param mixed $data
|
|
|
|
*
|
2021-05-15 13:14:21 +03:00
|
|
|
* @return self
|
2021-05-14 20:06:58 +03:00
|
|
|
* @throws \Pock\Exception\JsonException
|
|
|
|
*/
|
2021-05-15 13:14:21 +03:00
|
|
|
public function withJson($data): self
|
2021-05-14 20:06:58 +03:00
|
|
|
{
|
2021-05-15 18:57:28 +03:00
|
|
|
$result = static::serializeJson($data);
|
2021-05-14 20:06:58 +03:00
|
|
|
|
2021-05-15 18:57:28 +03:00
|
|
|
if (null !== $result) {
|
|
|
|
return $this->withBody($result);
|
2021-05-14 20:06:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
throw new InvalidArgumentException('Cannot serialize data with type ' . gettype($data));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param mixed $data
|
|
|
|
*
|
2021-05-15 13:14:21 +03:00
|
|
|
* @return self
|
|
|
|
* @throws \Pock\Exception\XmlException
|
2021-05-14 20:06:58 +03:00
|
|
|
*/
|
2021-05-15 13:14:21 +03:00
|
|
|
public function withXml($data): self
|
2021-05-14 20:06:58 +03:00
|
|
|
{
|
2021-05-15 18:57:28 +03:00
|
|
|
$result = static::serializeXml($data);
|
2021-05-14 20:06:58 +03:00
|
|
|
|
2021-05-15 18:57:28 +03:00
|
|
|
if (null !== $result) {
|
|
|
|
return $this->withBody($result);
|
2021-05-14 20:06:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
throw new InvalidArgumentException('Cannot serialize data with type ' . gettype($data));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return \Psr\Http\Message\ResponseInterface
|
|
|
|
*/
|
|
|
|
public function getResponse(): ResponseInterface
|
|
|
|
{
|
|
|
|
return $this->response;
|
|
|
|
}
|
|
|
|
}
|