EntityRouteEnhancer.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace Drupal\Core\Entity\Enhancer;
  3. use Drupal\Core\Routing\EnhancerInterface;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Cmf\Component\Routing\RouteObjectInterface;
  6. use Symfony\Component\Routing\Route;
  7. /**
  8. * Enhances an entity form route with the appropriate controller.
  9. */
  10. class EntityRouteEnhancer implements EnhancerInterface {
  11. /**
  12. * {@inheritdoc}
  13. */
  14. public function enhance(array $defaults, Request $request) {
  15. $route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
  16. if (!$this->applies($route)) {
  17. return $defaults;
  18. }
  19. if (empty($defaults['_controller'])) {
  20. if (!empty($defaults['_entity_form'])) {
  21. $defaults = $this->enhanceEntityForm($defaults, $request);
  22. }
  23. elseif (!empty($defaults['_entity_list'])) {
  24. $defaults = $this->enhanceEntityList($defaults, $request);
  25. }
  26. elseif (!empty($defaults['_entity_view'])) {
  27. $defaults = $this->enhanceEntityView($defaults, $request);
  28. }
  29. }
  30. return $defaults;
  31. }
  32. /**
  33. * Returns whether the enhancer runs on the current route.
  34. *
  35. * @param \Symfony\Component\Routing\Route $route
  36. * The current route.
  37. *
  38. * @return bool
  39. */
  40. protected function applies(Route $route) {
  41. return !$route->hasDefault('_controller') &&
  42. ($route->hasDefault('_entity_form')
  43. || $route->hasDefault('_entity_list')
  44. || $route->hasDefault('_entity_view')
  45. );
  46. }
  47. /**
  48. * Update defaults for entity forms.
  49. *
  50. * @param array $defaults
  51. * The defaults to modify.
  52. * @param \Symfony\Component\HttpFoundation\Request $request
  53. * The Request instance.
  54. *
  55. * @return array
  56. * The modified defaults.
  57. */
  58. protected function enhanceEntityForm(array $defaults, Request $request) {
  59. $defaults['_controller'] = 'controller.entity_form:getContentResult';
  60. return $defaults;
  61. }
  62. /**
  63. * Update defaults for an entity list.
  64. *
  65. * @param array $defaults
  66. * The defaults to modify.
  67. * @param \Symfony\Component\HttpFoundation\Request $request
  68. * The Request instance.
  69. *
  70. * @return array
  71. * The modified defaults.
  72. */
  73. protected function enhanceEntityList(array $defaults, Request $request) {
  74. $defaults['_controller'] = '\Drupal\Core\Entity\Controller\EntityListController::listing';
  75. $defaults['entity_type'] = $defaults['_entity_list'];
  76. unset($defaults['_entity_list']);
  77. return $defaults;
  78. }
  79. /**
  80. * Update defaults for an entity view.
  81. *
  82. * @param array $defaults
  83. * The defaults to modify.
  84. * @param \Symfony\Component\HttpFoundation\Request $request
  85. * The Request instance.
  86. *
  87. * @return array
  88. * The modified defaults.
  89. *
  90. * @throws \RuntimeException
  91. * Thrown when an entity of a type cannot be found in a route.
  92. */
  93. protected function enhanceEntityView(array $defaults, Request $request) {
  94. $defaults['_controller'] = '\Drupal\Core\Entity\Controller\EntityViewController::view';
  95. if (strpos($defaults['_entity_view'], '.') !== FALSE) {
  96. // The _entity_view entry is of the form entity_type.view_mode.
  97. list($entity_type, $view_mode) = explode('.', $defaults['_entity_view']);
  98. $defaults['view_mode'] = $view_mode;
  99. }
  100. else {
  101. // Only the entity type is nominated, the view mode will use the
  102. // default.
  103. $entity_type = $defaults['_entity_view'];
  104. }
  105. // Set by reference so that we get the upcast value.
  106. if (!empty($defaults[$entity_type])) {
  107. $defaults['_entity'] = &$defaults[$entity_type];
  108. }
  109. else {
  110. // The entity is not keyed by its entity_type. Attempt to find it
  111. // using a converter.
  112. $route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
  113. if ($route && is_object($route)) {
  114. $options = $route->getOptions();
  115. if (isset($options['parameters'])) {
  116. foreach ($options['parameters'] as $name => $details) {
  117. if (!empty($details['type'])) {
  118. $type = $details['type'];
  119. // Type is of the form entity:{entity_type}.
  120. $parameter_entity_type = substr($type, strlen('entity:'));
  121. if ($entity_type == $parameter_entity_type) {
  122. // We have the matching entity type. Set the '_entity' key
  123. // to point to this named placeholder. The entity in this
  124. // position is the one being rendered.
  125. $defaults['_entity'] = &$defaults[$name];
  126. }
  127. }
  128. }
  129. }
  130. else {
  131. throw new \RuntimeException(sprintf('Failed to find entity of type %s in route named %s', $entity_type, $defaults[RouteObjectInterface::ROUTE_NAME]));
  132. }
  133. }
  134. else {
  135. throw new \RuntimeException(sprintf('Failed to find entity of type %s in route named %s', $entity_type, $defaults[RouteObjectInterface::ROUTE_NAME]));
  136. }
  137. }
  138. unset($defaults['_entity_view']);
  139. return $defaults;
  140. }
  141. }