tagRepository = $tagRepository; } public function getAll(): array { $tags = $this->tagRepository->findBy([], ['id' => 'asc']); $result = []; foreach ($tags as $tag) { $result[] = $this->buildItem($tag); } return $result; } /** * @param int|string $tagIdOrName * @throws APIException */ public function getTag($tagIdOrName): array { $tag = $this->findTag($tagIdOrName); return $this->buildItem($tag); } public function addTag(array $data): array { $data = $this->sanitizeTagData($data); $this->validateTagName($data); try { $tag = new TagEntity($data['name'], $data['description']); $this->tagRepository->persist($tag); $this->tagRepository->flush(); } catch (\Exception $e) { throw new APIException( __('The tag couldn’t be created in the database', 'mailpoet'), APIException::FAILED_TO_SAVE_TAG ); } return $this->buildItem($tag); } public function updateTag(array $data): array { $this->validateTagId((string)($data['id'] ?? '')); $tag = $this->tagRepository->findOneById((int)$data['id']); if (!$tag instanceof TagEntity) { throw new APIException( __('The tag does not exist.', 'mailpoet'), APIException::TAG_NOT_EXISTS ); } $hasName = array_key_exists('name', $data); $hasDescription = array_key_exists('description', $data); $sanitizedName = $hasName && is_string($data['name']) ? sanitize_text_field($data['name']) : ''; $sanitizedDescription = $hasDescription && is_string($data['description']) ? sanitize_text_field($data['description']) : ''; if ($hasName) { if ($sanitizedName === '') { throw new APIException( __('Tag name is required.', 'mailpoet'), APIException::TAG_NAME_REQUIRED ); } $existing = $this->tagRepository->findOneBy(['name' => $sanitizedName]); if ($existing instanceof TagEntity && $existing->getId() !== (int)$data['id']) { throw new APIException( __('This tag already exists.', 'mailpoet'), APIException::TAG_EXISTS ); } } try { if ($hasName) { $tag->setName($sanitizedName); } if ($hasDescription) { $tag->setDescription($sanitizedDescription); } $this->tagRepository->flush(); } catch (\Exception $e) { throw new APIException( __('The tag couldn’t be updated in the database', 'mailpoet'), APIException::FAILED_TO_UPDATE_TAG ); } return $this->buildItem($tag); } public function deleteTag(string $tagId): bool { $this->validateTagId($tagId); $tag = $this->tagRepository->findOneById((int)$tagId); if (!$tag instanceof TagEntity) { throw new APIException( __('The tag does not exist.', 'mailpoet'), APIException::TAG_NOT_EXISTS ); } try { $this->tagRepository->deleteTag($tag); return true; } catch (\Exception $e) { throw new APIException( __('The tag couldn’t be deleted from the database', 'mailpoet'), APIException::FAILED_TO_DELETE_TAG ); } } /** * @param int|string $tagIdOrName * @throws APIException */ private function findTag($tagIdOrName): TagEntity { $tag = null; if (is_int($tagIdOrName) || (is_string($tagIdOrName) && (string)(int)$tagIdOrName === $tagIdOrName)) { $tag = $this->tagRepository->findOneById((int)$tagIdOrName); } if (!$tag && is_string($tagIdOrName) && strlen(trim($tagIdOrName)) > 0) { $tag = $this->tagRepository->findOneBy(['name' => $tagIdOrName]); } if (!$tag instanceof TagEntity) { throw new APIException( __('The tag does not exist.', 'mailpoet'), APIException::TAG_NOT_EXISTS ); } return $tag; } private function validateTagId(string $tagId): void { if ($tagId === '') { throw new APIException( __('Tag id is required.', 'mailpoet'), APIException::TAG_ID_REQUIRED ); } if (!$this->tagRepository->findOneById((int)$tagId)) { throw new APIException( __('The tag does not exist.', 'mailpoet'), APIException::TAG_NOT_EXISTS ); } } private function validateTagName(array $data): void { if (empty($data['name'])) { throw new APIException( __('Tag name is required.', 'mailpoet'), APIException::TAG_NAME_REQUIRED ); } $tagId = isset($data['id']) ? (int)$data['id'] : null; $existing = $this->tagRepository->findOneBy(['name' => $data['name']]); if ($existing instanceof TagEntity && $existing->getId() !== $tagId) { throw new APIException( __('This tag already exists.', 'mailpoet'), APIException::TAG_EXISTS ); } } private function sanitizeTagData(array $data): array { $data['name'] = isset($data['name']) && is_string($data['name']) ? sanitize_text_field($data['name']) : ''; $data['description'] = isset($data['description']) && is_string($data['description']) ? sanitize_text_field($data['description']) : ''; return $data; } private function buildItem(TagEntity $tag): array { return [ 'id' => (string)$tag->getId(), 'name' => $tag->getName(), 'description' => $tag->getDescription(), 'created_at' => ($createdAt = $tag->getCreatedAt()) ? $createdAt->format(self::DATE_FORMAT) : null, 'updated_at' => ($updatedAt = $tag->getUpdatedAt()) ? $updatedAt->format(self::DATE_FORMAT) : null, ]; } }