Skip to content
Snippets Groups Projects
BaseDto.php 2.73 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;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
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
     */
    public function getClass(): ?DtoServiceInterface
    {
        if ($this->request) {
            $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');
        }

        return null;
    }

    public function toArray(): ?array
    {
        try {
            $oNormalizer = new ObjectNormalizer(
                null,
                new CamelCaseToSnakeCaseNameConverter(),
                null,
                new ReflectionExtractor()
            );
            $oSerializer = new Serializer([$oNormalizer], [new JsonEncoder()]);
            $sData = $oSerializer->serialize($this->getClass(), 'json');
            return json_decode($sData, true, 512, JSON_THROW_ON_ERROR);
        } catch (\Exception $oException) {
            return null;
        }
    }

    /**
     * Валидация Dto
     *
     * @param ResponseServiceInterface $response
     *
     * @return bool
     */
    public function validate(ResponseServiceInterface $response): bool
    {
        $apiResponse = $response->getResponse();

        $bValid = true;
        $aErrors = $this->validator->validate($this->getClass());
        if (count($aErrors) > 0) {
            foreach ($aErrors as $error) {
                $apiResponse->addError($error->getMessage());
            }
            $bValid = false;
        }
        return $bValid;
    }
}