This commit is contained in:
Greyscale 2024-05-22 04:54:23 +02:00
parent e4ad33abec
commit de3da89d9c
3 changed files with 216 additions and 0 deletions

92
src/Actions/Action.php Normal file
View file

@ -0,0 +1,92 @@
<?php
declare(strict_types=1);
namespace Benzine\Actions;
use App\Domain\DomainException\DomainRecordNotFoundException;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
use Slim\Exception\HttpBadRequestException;
use Slim\Exception\HttpNotFoundException;
abstract class Action
{
protected LoggerInterface $logger;
protected Request $request;
protected Response $response;
protected array $args;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* @throws HttpNotFoundException
* @throws HttpBadRequestException
*/
public function __invoke(Request $request, Response $response, array $args): Response
{
$this->request = $request;
$this->response = $response;
$this->args = $args;
try {
return $this->action();
} catch (DomainRecordNotFoundException $e) {
throw new HttpNotFoundException($this->request, $e->getMessage());
}
}
/**
* @throws DomainRecordNotFoundException
* @throws HttpBadRequestException
*/
abstract protected function action(): Response;
/**
* @return array|object
*/
protected function getFormData()
{
return $this->request->getParsedBody();
}
/**
* @return mixed
* @throws HttpBadRequestException
*/
protected function resolveArg(string $name)
{
if (!isset($this->args[$name])) {
throw new HttpBadRequestException($this->request, "Could not resolve argument `{$name}`.");
}
return $this->args[$name];
}
/**
* @param array|object|null $data
*/
protected function respondWithData($data = null, int $statusCode = 200): Response
{
$payload = new ActionPayload($statusCode, $data);
return $this->respond($payload);
}
protected function respond(ActionPayload $payload): Response
{
$json = json_encode($payload, JSON_PRETTY_PRINT);
$this->response->getBody()->write($json);
return $this->response
->withHeader('Content-Type', 'application/json')
->withStatus($payload->getStatusCode());
}
}

View file

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace Benzine\Actions;
use JsonSerializable;
class ActionError implements JsonSerializable
{
public const BAD_REQUEST = 'BAD_REQUEST';
public const INSUFFICIENT_PRIVILEGES = 'INSUFFICIENT_PRIVILEGES';
public const NOT_ALLOWED = 'NOT_ALLOWED';
public const NOT_IMPLEMENTED = 'NOT_IMPLEMENTED';
public const RESOURCE_NOT_FOUND = 'RESOURCE_NOT_FOUND';
public const SERVER_ERROR = 'SERVER_ERROR';
public const UNAUTHENTICATED = 'UNAUTHENTICATED';
public const VALIDATION_ERROR = 'VALIDATION_ERROR';
public const VERIFICATION_ERROR = 'VERIFICATION_ERROR';
private string $type;
private ?string $description;
public function __construct(string $type, ?string $description = null)
{
$this->type = $type;
$this->description = $description;
}
public function getType(): string
{
return $this->type;
}
public function setType(string $type): self
{
$this->type = $type;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description = null): self
{
$this->description = $description;
return $this;
}
#[\ReturnTypeWillChange]
public function jsonSerialize(): array
{
return [
'type' => $this->type,
'description' => $this->description,
];
}
}

View file

@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace Benzine\Actions;
use JsonSerializable;
class ActionPayload implements JsonSerializable
{
private int $statusCode;
/**
* @var array|object|null
*/
private $data;
private ?ActionError $error;
public function __construct(
int $statusCode = 200,
$data = null,
?ActionError $error = null
) {
$this->statusCode = $statusCode;
$this->data = $data;
$this->error = $error;
}
public function getStatusCode(): int
{
return $this->statusCode;
}
/**
* @return array|null|object
*/
public function getData()
{
return $this->data;
}
public function getError(): ?ActionError
{
return $this->error;
}
#[\ReturnTypeWillChange]
public function jsonSerialize(): array
{
$payload = [
'statusCode' => $this->statusCode,
];
if ($this->data !== null) {
$payload['data'] = $this->data;
} elseif ($this->error !== null) {
$payload['error'] = $this->error;
}
return $payload;
}
}