Newer
Older
<?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;
#[Required]
public function initValidator(
?ValidatorInterface $validator
): void
{
$this->validator = $validator;
}
#[Required]
public function initRequest(
?RequestStack $requestStack = null
): void
{
if ($requestStack) {
$this->request = $requestStack->getCurrentRequest();
}
}
/**
* Получение класса Dto
*
* @return DtoServiceInterface|null
*/
public function getClass(): ?DtoServiceInterface
{
if ($this->request) {
return self::getClassByData($this->request->getContent());
}
return null;
}
public static function getClassByArray(?array $data = null): ?DtoServiceInterface
{
if (empty($data)) {
return null;
}
return self::getClassByData(json_encode($data, JSON_THROW_ON_ERROR) ?: '');
}
private static function getClassByData(string $data): ?DtoServiceInterface
{
if (!empty($data)) {
try {
$normalizer = new ObjectNormalizer(
null,
new CamelCaseToSnakeCaseNameConverter(),
null,
new ReflectionExtractor()
);
$serializer = new Serializer(
[$normalizer, new DateTimeNormalizer()],
[new JsonEncoder()]
);
return $serializer->deserialize($data, static::class, 'json');
} catch (\Exception $exception) {
return null;
}
}
return null;
}
public function toArray(): ?array
{
try {
null,
new CamelCaseToSnakeCaseNameConverter(),
null,
new ReflectionExtractor()
);
$serializer = new Serializer([$normalizer], [new JsonEncoder()]);
$data = $serializer->serialize($this->getClass(), 'json');
return json_decode($data, true, 512, JSON_THROW_ON_ERROR);
} 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) {
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);