getRequest(); $controller = $request->get('_controller'); if (is_string($controller)) { $controller = explode('::', $controller); } if (is_callable($controller)){ if (is_object($controller[0])) { $controller[0] = get_class($controller[0]); } $methodExtractor = new MethodExtractor($controller[0], $controller[1]); } /** @var RequestDTO $requestDTO */ if ($requestDTO = $methodExtractor->fetch(RequestDTO::class)) { $requestDTOInstance = $this->grabRequestDTO($requestDTO->className, $request->getContent(), $request->query->all(), $request->request->all(), $request->headers->all()); $errorCollection = $this->validate($requestDTOInstance); if ($errorCollection->hasErrors()) { $event->setResponse(new JsonResponse(['errors' => $errorCollection->format()], Response::HTTP_BAD_REQUEST)); } else { $request->attributes->set(self::REQUEST_DATA, $requestDTOInstance); } } } protected function validate(object $data): ErrorCollection { $validator = Validation::createValidatorBuilder() ->enableAnnotationMapping(true) ->addDefaultDoctrineAnnotationReader() ->getValidator(); $violations = $validator->validate($data); $errorCollection = new ErrorCollection(); if ($violations->count()) { foreach ($violations as $violation) { $errorCollection->add(new Error($violation->getMessage(), $violation->getPropertyPath())); } } return $errorCollection; } /** * todo переделать на перебор филлеров * Сделать регистрацию филлеров * и выексти филеры заполнения entity и documents в отдельных бандлах */ protected function grabRequestDTO(string $requestClass, string $content, array $queryParameters = [], array $parameters = [], array $headers = []) { $serializer = SerializerBuilder::create()->build(); if ($content) { $object = $serializer->deserialize($content, $requestClass, 'json'); } else { $object = new $requestClass; } $this->fillFromData($object, $queryParameters); $this->fillFromData($object, $parameters); $this->fillFromData($object, $headers); return $object; } protected function fillFromData(object $object, array $data): object { $reflectionObject = new ReflectionObject($object); $properties = $reflectionObject->getProperties(); foreach ($properties as $property) { $attributes = $property->getAttributes(HeaderKey::class); $attribute = $attributes[0] ?? null; if ($attribute) { /** @var HeaderKey $headerKey */ $headerKey = $attribute->newInstance(); $value = $data[strtolower($headerKey->key)][0] ?? null; } else { $value = $data[$property->getName()] ?? null; } if ($value) { $property->setValue($object, $value); } } return $object; } }