repository = $taskRepository; $this->builder = $builder; } // response is immutable. psr-7 impl makes copies of stuff. // TODO: There's a LOT of validation here. We need to build a validator, use a library, or refactor this method. public function addTask(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $params = $request->getParsedBody(); $requiredKeys = ['name', 'description', 'status', 'start', 'end']; if (!array_key_exists('tasks', $params)) { $this->builder->setError(); $this->builder->setErrorMessage('Malformed request payload. Please try again.'); $this->builder->setErrorCode(400); $errorResponse = $response->withStatus(400, 'Invalid payload'); $errorResponse->getBody()->write($this->builder->build()); return $errorResponse; } $missingKeys = []; foreach ($requiredKeys as $key) { if (!array_key_exists($key, $params['tasks'])) { $missingKeys[] = $key; } } if (!empty($missingKeys)) { $this->builder->setError(); $this->builder->setErrorMessage("The following parameters are missing: " . implode(', ', $missingKeys)); $this->builder->setErrorCode(400); $errorResponse = $response->withStatus('400', 'Missing arguments'); $errorResponse->getBody()->write($this->builder->build()); return $errorResponse; } try { $start = Carbon::parse($params['tasks']['start']); $end = Carbon::parse($params['tasks']['end']); if ($start->gt($end) || $end->lt($start)) { throw new \DomainException('Invalid task date. Start date must not be after end date.'); } } catch (InvalidFormatException | \DomainException $exception) { $this->builder->setError(); $this->builder->setErrorMessage($exception->getMessage()); $this->builder->setErrorCode(400); $errorResponse = $response->withStatus(400); $errorResponse->getBody()->write($this->builder->build()); return $errorResponse; } if (is_null(TaskStatus::tryFrom($params['tasks']['status']))) { $this->builder->setError(); $this->builder->setErrorCode(400); $this->builder->setErrorMessage('Invalid task status code. Status must range from 1-4 (started, in progress, blocked, completed).'); $errorResponse = $response->withStatus(400); $errorResponse->getBody()->write($this->builder->build()); return $errorResponse; } $task = new Task(); $task->setTitle($params['tasks']['name']) ->setStatus(TaskStatus::tryFrom((int) $params['tasks']['status'])) ->setDescription($params['tasks']['description']) ->setStartDt($params['tasks']['start']) ->setEndDt($params['tasks']['end']); if (!$this->repository->create($task)) { $this->builder->setError() ->setErrorMessage('An unexpected error has occurred whilst trying to perform this operation.') ->setErrorCode(500); $errorResponse = $response->withStatus(500); $errorResponse->getBody()->write($this->builder->build()); return $errorResponse; } $createdResponse = $response->withStatus(201); $this->builder->setOptionalMessage('Task created.') ->setPayload($task->persist()); $createdResponse->getBody()->write($this->builder->build()); return $createdResponse; } }