diff --git a/src/Actions/Action.php b/src/Actions/Action.php new file mode 100644 index 0000000..75b4c37 --- /dev/null +++ b/src/Actions/Action.php @@ -0,0 +1,92 @@ +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()); + } +} diff --git a/src/Actions/ActionError.php b/src/Actions/ActionError.php new file mode 100644 index 0000000..72dac2c --- /dev/null +++ b/src/Actions/ActionError.php @@ -0,0 +1,61 @@ +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, + ]; + } +} diff --git a/src/Actions/ActionPayload.php b/src/Actions/ActionPayload.php new file mode 100644 index 0000000..de60bb3 --- /dev/null +++ b/src/Actions/ActionPayload.php @@ -0,0 +1,63 @@ +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; + } +}