DefaultRouteGenerator.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. /*
  3. * This file is part of the Sonata package.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. *
  10. */
  11. namespace Sonata\AdminBundle\Route;
  12. use Sonata\AdminBundle\Admin\AdminInterface;
  13. use Symfony\Component\Routing\RouterInterface;
  14. class DefaultRouteGenerator implements RouteGeneratorInterface
  15. {
  16. private $router;
  17. private $cache;
  18. private $caches = array();
  19. private $loaded = array();
  20. /**
  21. * @param RouterInterface $router
  22. * @param RoutesCache $cache
  23. */
  24. public function __construct(RouterInterface $router, RoutesCache $cache)
  25. {
  26. $this->router = $router;
  27. $this->cache = $cache;
  28. }
  29. /**
  30. * {@inheritdoc}
  31. */
  32. public function generate($name, array $parameters = array(), $absolute = false)
  33. {
  34. return $this->router->generate($name, $parameters, $absolute);
  35. }
  36. /**
  37. * {@inheritdoc}
  38. */
  39. public function generateUrl(AdminInterface $admin, $name, array $parameters = array(), $absolute = false)
  40. {
  41. $arrayRoute = $this->generateMenuUrl($admin, $name, $parameters, $absolute);
  42. return $this->router->generate($arrayRoute['route'], $arrayRoute['routeParameters'], $arrayRoute['routeAbsolute']);
  43. }
  44. /**
  45. * {@inheritdoc}
  46. */
  47. public function generateMenuUrl(AdminInterface $admin, $name, array $parameters = array(), $absolute = false)
  48. {
  49. // if the admin is a child we automatically append the parent's id
  50. if ($admin->isChild() && $admin->hasRequest() && $admin->getRequest()->attributes->has($admin->getParent()->getIdParameter())) {
  51. // twig template does not accept variable hash key ... so cannot use admin.idparameter ...
  52. // switch value
  53. if (isset($parameters['id'])) {
  54. $parameters[$admin->getIdParameter()] = $parameters['id'];
  55. unset($parameters['id']);
  56. }
  57. $parameters[$admin->getParent()->getIdParameter()] = $admin->getRequest()->attributes->get($admin->getParent()->getIdParameter());
  58. }
  59. // if the admin is linked to a parent FieldDescription (ie, embedded widget)
  60. if ($admin->hasParentFieldDescription()) {
  61. // merge link parameter if any provided by the parent field
  62. $parameters = array_merge($parameters, $admin->getParentFieldDescription()->getOption('link_parameters', array()));
  63. $parameters['uniqid'] = $admin->getUniqid();
  64. $parameters['code'] = $admin->getCode();
  65. $parameters['pcode'] = $admin->getParentFieldDescription()->getAdmin()->getCode();
  66. $parameters['puniqid'] = $admin->getParentFieldDescription()->getAdmin()->getUniqid();
  67. }
  68. if ($name == 'update' || substr($name, -7) == '|update') {
  69. $parameters['uniqid'] = $admin->getUniqid();
  70. $parameters['code'] = $admin->getCode();
  71. }
  72. // allows to define persistent parameters
  73. if ($admin->hasRequest()) {
  74. $parameters = array_merge($admin->getPersistentParameters(), $parameters);
  75. }
  76. $code = $this->getCode($admin, $name);
  77. if (!array_key_exists($code, $this->caches)) {
  78. throw new \RuntimeException(sprintf('unable to find the route `%s`', $code));
  79. }
  80. return array(
  81. 'route' => $this->caches[$code],
  82. 'routeParameters' => $parameters,
  83. 'routeAbsolute' => $absolute
  84. );
  85. }
  86. /**
  87. * {@inheritdoc}
  88. */
  89. public function hasAdminRoute(AdminInterface $admin, $name)
  90. {
  91. return array_key_exists($this->getCode($admin, $name), $this->caches);
  92. }
  93. /**
  94. * @param AdminInterface $admin
  95. * @param string $name
  96. *
  97. * @return string
  98. */
  99. private function getCode(AdminInterface $admin, $name)
  100. {
  101. $this->loadCache($admin);
  102. if ($admin->isChild()) {
  103. return $admin->getBaseCodeRoute().'.'.$name;
  104. }
  105. // someone provide the fullname
  106. if (array_key_exists($name, $this->caches)) {
  107. return $name;
  108. }
  109. // someone provide a code, so it is a child
  110. if (strpos($name, '.')) {
  111. return $admin->getCode().'|'.$name;
  112. }
  113. return $admin->getCode().'.'.$name;
  114. }
  115. /**
  116. * @param AdminInterface $admin
  117. */
  118. private function loadCache(AdminInterface $admin)
  119. {
  120. if ($admin->isChild()) {
  121. $this->loadCache($admin->getParent());
  122. } else {
  123. if (in_array($admin->getCode(), $this->loaded)) {
  124. return;
  125. }
  126. $this->caches = array_merge($this->cache->load($admin), $this->caches);
  127. $this->loaded[] = $admin->getCode();
  128. }
  129. }
  130. }