Last active
December 17, 2015 13:19
-
-
Save tystr/5616563 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace MyNamespace\Controller; | |
| use JMS\DiExtraBundle\Annotation\Inject; | |
| class PostsController | |
| { | |
| /** | |
| * @Inject("my_namespace.post_repository") | |
| * @var \MyNamespace\Repository\PostRepository | |
| */ | |
| protected $repository; | |
| /** | |
| * @Put("/posts/{id}") | |
| * | |
| * @param Request $request | |
| * @param Post $post | |
| * @param string $id | |
| * @param ValidationErrors $errors | |
| * | |
| * @return Post|ValidationErrors | |
| */ | |
| public function putPostAction(Request $request, Post $post, $id, ValidationErrors $errors = null) | |
| { | |
| if (null !== $errors) { | |
| return $errors; | |
| } | |
| $this->repository->replacePost($id, $post); | |
| return $post; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace MyNamespace\Request\ParamConverter; | |
| use Doctrine\Common\Persistence\Mapping\MappingException; | |
| use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
| use Symfony\Component\Validator\ValidatorInterface; | |
| use Symfony\Component\HttpFoundation\Request; | |
| use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface; | |
| use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface; | |
| use Doctrine\Common\Persistence\ObjectManager; | |
| use Doctrine\Common\Persistence\ObjectRepository; | |
| use JMS\Serializer\SerializerInterface; | |
| use JMS\Serializer\Naming\PropertyNamingStrategyInterface; | |
| use Metadata\Driver\AdvancedDriverInterface; | |
| use MyNamespace\Model\ValidationErrors; | |
| class RequestBodyParamConverter implements ParamConverterInterface | |
| { | |
| /** | |
| * @var SerializerInterface | |
| */ | |
| protected $serializer; | |
| /** | |
| * @var ValidatorInterface | |
| */ | |
| protected $validator; | |
| /** | |
| * @var ObjectManager | |
| */ | |
| protected $om; | |
| /** | |
| * @var AdvancedDriverInterface | |
| */ | |
| protected $metadataDriver; | |
| /** | |
| * @var PropertyNamingStrategyInterface | |
| */ | |
| protected $namingStrategy; | |
| /** | |
| * @var ObjectRepository | |
| */ | |
| protected $repository; | |
| /** | |
| * @param SerializerInterface $serializer | |
| * @param ValidatorInterface $validator | |
| * @param ObjectManager $om | |
| * @param AdvancedDriverInterface $metadataDriver | |
| * @param PropertyNamingStrategyInterface $namingStrategy | |
| */ | |
| public function __construct( | |
| SerializerInterface $serializer, | |
| ValidatorInterface $validator, | |
| ObjectManager $om, | |
| AdvancedDriverInterface $metadataDriver, | |
| PropertyNamingStrategyInterface $namingStrategy | |
| ) { | |
| $this->serializer = $serializer; | |
| $this->validator = $validator; | |
| $this->om = $om; | |
| $this->metadataDriver = $metadataDriver; | |
| $this->namingStrategy = $namingStrategy; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| public function apply(Request $request, ConfigurationInterface $configuration) | |
| { | |
| $name = $configuration->getName(); | |
| $class = $configuration->getClass(); | |
| if (null === $name || 'MyNamespace\Model\ValidationErrors' === $class) { | |
| return false; | |
| } | |
| $object = $this->serializer->deserialize( | |
| $request->getContent(), | |
| $configuration->getClass(), | |
| $request->getRequestFormat() | |
| ); | |
| if ($request->getMethod() == 'PUT' || $request->getMethod() == 'PATCH') { | |
| $id = $request->attributes->get('_route_params[id]', null, true); | |
| if (null === $id || null === $this->repository->find($id)) { | |
| throw new NotFoundHttpException(); | |
| } | |
| } | |
| $errors = new ValidationErrors($this->validator->validate($object)); | |
| // Add errors for extra fields | |
| $translatedNames = []; | |
| $metadata = $this->metadataDriver->loadMetadataForClass(new \ReflectionClass($class)); | |
| foreach ($metadata->propertyMetadata as $propertyMetadata) { | |
| $translatedNames[] = $this->namingStrategy->translateName($propertyMetadata); | |
| } | |
| foreach ($request->request->all() as $key => $value) { | |
| if (!in_array($key, $translatedNames)) { | |
| $errors->addError($key, 'Invalid field name.'); | |
| } | |
| } | |
| if (count($errors->getErrors()) > 0) { | |
| $request->attributes->set('errors', $errors); | |
| } | |
| $request->attributes->set($name, $object); | |
| return true; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| public function supports(ConfigurationInterface $configuration) | |
| { | |
| try { | |
| return $this->repository = $this->om->getRepository($configuration->getClass()); | |
| } catch (MappingException $e) { | |
| return false; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace MyNamespace\Model\ValidationErrors; | |
| use Symfony\Component\Validator\ConstraintViolationListInterface; | |
| class ValidationErrors | |
| { | |
| /** | |
| * @var int | |
| */ | |
| protected $statusCode = 400; | |
| /** | |
| * @var array | |
| */ | |
| protected $errors = []; | |
| /** | |
| * @param ConstraintViolationListInterface $constraintViolationList | |
| */ | |
| public function __construct(ConstraintViolationListInterface $constraintViolationList) | |
| { | |
| foreach ($constraintViolationList as $violation) { | |
| $this->errors[][$violation->getPropertyPath()] = $violation->getMessage(); | |
| } | |
| } | |
| /** | |
| * @return array | |
| */ | |
| public function getErrors() | |
| { | |
| return $this->errors; | |
| } | |
| /** | |
| * @param string $property | |
| * @param string $message | |
| */ | |
| public function addError($property, $message) | |
| { | |
| $this->errors[][$property] = $message; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment