Framework/src/Http/Responses/XmlResponseFactory.php

65 lines
1.9 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace Phred\Http\Responses;
use Nyholm\Psr7\Factory\Psr17Factory;
use Phred\Http\Contracts\ApiResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Serializer;
final class XmlResponseFactory implements ApiResponseFactoryInterface
{
private Serializer $serializer;
public function __construct(private Psr17Factory $psr17 = new Psr17Factory())
{
$this->serializer = new Serializer([new ArrayDenormalizer()], [new XmlEncoder()]);
}
public function ok(array $data = []): ResponseInterface
{
return $this->xml($data, 200);
}
public function created(array $data = [], ?string $location = null): ResponseInterface
{
$res = $this->xml($data, 201);
if ($location) {
$res = $res->withHeader('Location', $location);
}
return $res;
}
public function noContent(): ResponseInterface
{
return $this->psr17->createResponse(204);
}
public function error(int $status, string $title, ?string $detail = null, array $extra = []): ResponseInterface
{
$payload = array_merge([
'title' => $title,
'status' => $status,
], $detail !== null ? ['detail' => $detail] : [], $extra);
return $this->xml(['error' => $payload], $status);
}
public function fromArray(array $payload, int $status = 200): ResponseInterface
{
return $this->xml($payload, $status);
}
private function xml(array $data, int $status): ResponseInterface
{
$xml = $this->serializer->serialize($data, 'xml');
$res = $this->psr17->createResponse($status)
->withHeader('Content-Type', 'application/xml');
$res->getBody()->write($xml);
return $res;
}
}