<?php namespace App\Shared\Abstraction; use App\Shared\Dto\DtoCollection; use App\Shared\Dto\ValidateErrorDto; use App\Shared\DtoFactory\ValidateErrorDtoFactory; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Validator\Exception\ValidatorException; use Symfony\Component\Validator\Validator\ValidatorInterface; /** Абстракный реквест, необходим удобной валидации */ abstract class AbstractRequest { /** * активация автовалидации * перезаписать на false для отключение автовалидации */ protected const AUTO_VALIDATE = true; public function __construct(protected ValidatorInterface $validator) { $this->populate(); if (self::AUTO_VALIDATE) { $this->validate(); } } /** * Маппинг реквеста * @return void */ protected function populate(): void { foreach ($this->getRequest()->toArray() as $property => $value) { if (property_exists($this, $property)) { $this->{$property} = $value; } } } /** * Валидация и выброкса ошибки при валидации * @return void */ public function validate(): void { $errors = $this->validator->validate($this); $messages = new DtoCollection(ValidateErrorDto::class); foreach ($errors as $error) { $messages->add((new ValidateErrorDtoFactory($error))->create()); } if ($messages->count() > 0) { $response = new JsonResponse($messages, 422); $response->send(); throw new ValidatorException('Validation failed', $messages); } } /** * Возвращает HttpFoundation реквест * @return Request */ public function getRequest(): Request { return Request::createFromGlobals(); } }