<?php namespace App\Service\Response\Classes; use App\Service\Response\ResponseServiceInterface; use Symfony\Component\DependencyInjection\Attribute\AsAlias; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\Ignore; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; #[AsAlias] class Response implements ResponseServiceInterface { /** * @var bool */ #[Groups(["message", "data"])] public bool $status = true; /** * @var string */ #[Groups(["message"])] public string $message = ''; #[Ignore] public int $statusCode = 200; #[Ignore] private array $messages = []; #[Ignore] private array $errors = []; #[Ignore] private JsonResponse $response; public function __construct() { $this->response = new JsonResponse(); } /** * Группы сериализации * * @return array */ #[Ignore] protected function getGroups(): array { return []; } /** * Добавление ошибки * * @param string $message * * @return $this * * @throws \JsonException */ #[Ignore] public function addError(string $message): self { $this->errors[] = $message; return $this; } /** * Добавление сообщения * * @param string $message * * @return $this * * @throws \JsonException */ #[Ignore] public function addMessage(string $message): self { $this->messages[] = $message; return $this; } #[Ignore] public function isSuccess(): bool { if (!empty($this->errors)) { $this->status = false; } else { $this->status = true; } return $this->status; } #[Ignore] public function getResponse(): JsonResponse { $this->refresh(); return $this->response; } #[Ignore] public function setStatusCode(int $code): self { $this->statusCode = $code; return $this; } #[Ignore] protected function refresh(): self { $groups = ['message']; if (!empty($this->errors)) { $this->status = false; if ($this->statusCode === 200) { $this->statusCode = \Symfony\Component\HttpFoundation\Response::HTTP_BAD_REQUEST; } } else { $this->status = true; } $this->message = implode(', ', array_merge($this->messages, $this->errors)); if (isset($this->data)) { $groups = ['data']; $groups = array_merge($groups, $this->getGroups()); } $normalizer = new ObjectNormalizer( new ClassMetadataFactory(new AttributeLoader()), new CamelCaseToSnakeCaseNameConverter(), null, new ReflectionExtractor() ); $serializer = new Serializer([new DateTimeNormalizer(), $normalizer], [new JsonEncoder()]); $dataStr = $serializer->serialize($this, 'json', ['groups' => $groups]); $dataArray = json_decode($dataStr, true, 512, JSON_THROW_ON_ERROR); $this->response->setData($dataArray); $this->response->setStatusCode($this->statusCode); return $this; } }