DoctrineParamConverter.php 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. namespace Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter;
  3. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface;
  4. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Bundle\DoctrineBundle\Registry;
  7. use Doctrine\ORM\NoResultException;
  8. use Doctrine\ORM\Mapping\MappingException;
  9. /*
  10. * This file is part of the Symfony framework.
  11. *
  12. * (c) Fabien Potencier <fabien@symfony.com>
  13. *
  14. * This source file is subject to the MIT license that is bundled
  15. * with this source code in the file LICENSE.
  16. */
  17. /**
  18. * DoctrineConverter.
  19. *
  20. * @author Fabien Potencier <fabien@symfony.com>
  21. */
  22. class DoctrineParamConverter implements ParamConverterInterface
  23. {
  24. protected $registry;
  25. public function __construct(Registry $registry = null)
  26. {
  27. $this->registry = $registry;
  28. }
  29. public function apply(Request $request, ConfigurationInterface $configuration)
  30. {
  31. $class = $configuration->getClass();
  32. $options = $this->getOptions($configuration);
  33. // find by identifier?
  34. if (false === $object = $this->find($class, $request, $options)) {
  35. // find by criteria
  36. if (false === $object = $this->findOneBy($class, $request, $options)) {
  37. throw new \LogicException('Unable to guess how to get a Doctrine instance from the request information.');
  38. }
  39. }
  40. if (null === $object && false === $configuration->isOptional()) {
  41. throw new NotFoundHttpException(sprintf('%s object not found.', $class));
  42. }
  43. $request->attributes->set($configuration->getName(), $object);
  44. }
  45. protected function find($class, Request $request, $options)
  46. {
  47. if (!$request->attributes->has('id')) {
  48. return false;
  49. }
  50. return $this->registry->getRepository($class, $options['entity_manager'])->find($request->attributes->get('id'));
  51. }
  52. protected function findOneBy($class, Request $request, $options)
  53. {
  54. $criteria = array();
  55. $metadata = $this->registry->getEntityManager($options['entity_manager'])->getClassMetadata($class);
  56. foreach ($request->attributes->all() as $key => $value) {
  57. if ($metadata->hasField($key)) {
  58. $criteria[$key] = $value;
  59. }
  60. }
  61. if (!$criteria) {
  62. return false;
  63. }
  64. return $this->registry->getRepository($class, $options['entity_manager'])->findOneBy($criteria);
  65. }
  66. public function supports(ConfigurationInterface $configuration)
  67. {
  68. if (null === $this->registry) {
  69. return false;
  70. }
  71. if (null === $configuration->getClass()) {
  72. return false;
  73. }
  74. $options = $this->getOptions($configuration);
  75. // Doctrine Entity?
  76. try {
  77. $this->registry->getEntityManager($options['entity_manager'])->getClassMetadata($configuration->getClass());
  78. return true;
  79. } catch (MappingException $e) {
  80. return false;
  81. }
  82. }
  83. protected function getOptions(ConfigurationInterface $configuration)
  84. {
  85. return array_replace(array(
  86. 'entity_manager' => null,
  87. ), $configuration->getOptions());
  88. }
  89. }