Actions!
This commit is contained in:
parent
e4ad33abec
commit
de3da89d9c
3 changed files with 216 additions and 0 deletions
src/Actions
92
src/Actions/Action.php
Normal file
92
src/Actions/Action.php
Normal 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());
|
||||
}
|
||||
}
|
61
src/Actions/ActionError.php
Normal file
61
src/Actions/ActionError.php
Normal 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,
|
||||
];
|
||||
}
|
||||
}
|
63
src/Actions/ActionPayload.php
Normal file
63
src/Actions/ActionPayload.php
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue