Skip to content
Snippets Groups Projects
BaseDto.php 3.27 KiB
Newer Older
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
<?php

namespace App\Service\Dto;

use App\Service\Response\ResponseServiceInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use Symfony\Component\HttpFoundation\Response;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use Symfony\Component\Serializer\Annotation\Ignore;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Validator\Validator\ValidatorInterface;

abstract class BaseDto implements DtoServiceInterface
{
    private ?Request $request = null;

    public function __construct(
        private ?ValidatorInterface $validator,
        ?RequestStack $requestStack = null,
    )
    {
        if ($requestStack) {
            $this->request = $requestStack->getCurrentRequest();
        }
    }


    /**
     * Получение класса Dto
     *
     * @return DtoServiceInterface|null
     */
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    #[Ignore]
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    public function getClass(): ?DtoServiceInterface
    {
        if ($this->request) {
            try {
                $normalizer = new ObjectNormalizer(
                    null,
                    new CamelCaseToSnakeCaseNameConverter(),
                    null,
                    new ReflectionExtractor()
                );
                $serializer = new Serializer(
                    [$normalizer, new DateTimeNormalizer()],
                    [new JsonEncoder()]
                );
                return $serializer->deserialize($this->request->getContent(), static::class, 'json');
            } catch (\Exception $exception) {
                return null;
            }
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        }

        return null;
    }

    public function toArray(): ?array
    {
        try {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
            $normalizer = new ObjectNormalizer(
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
                null,
                new CamelCaseToSnakeCaseNameConverter(),
                null,
                new ReflectionExtractor()
            );
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
            $serializer = new Serializer([$normalizer], [new JsonEncoder()]);
            $data = $serializer->serialize($this->getClass(), 'json');
            return json_decode($data, true, 512, JSON_THROW_ON_ERROR);
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        } catch (\Exception $oException) {
            return null;
        }
    }

    /**
     * Валидация Dto
     *
     * @param ResponseServiceInterface $response
     *
     * @return bool
     */
    public function validate(ResponseServiceInterface $response): bool
    {
        $bValid = true;
        if ($classObj = $this->getClass()) {
            $aErrors = $this->validator->validate($classObj);
            if (count($aErrors) > 0) {
                foreach ($aErrors as $error) {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
                    $response->addError($error->getMessage());
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
                    $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
                }
                $bValid = false;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
            }
        } else {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
            $response->addError("Данные не получены");
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
            $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
            $bValid = false;
        }
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        return $bValid;
    }
}