EntityRouteEnhancer.php 4.85 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\Core\Entity\Enhancer;

5
use Drupal\Core\Routing\EnhancerInterface;
6
use Symfony\Component\HttpFoundation\Request;
7
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
8
use Symfony\Component\Routing\Route;
9 10 11 12

/**
 * Enhances an entity form route with the appropriate controller.
 */
13
class EntityRouteEnhancer implements EnhancerInterface {
14 15 16 17 18

  /**
   * {@inheritdoc}
   */
  public function enhance(array $defaults, Request $request) {
19 20 21 22 23
    $route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
    if (!$this->applies($route)) {
      return $defaults;
    }

24
    if (empty($defaults['_controller'])) {
25
      if (!empty($defaults['_entity_form'])) {
26
        $defaults = $this->enhanceEntityForm($defaults, $request);
27 28
      }
      elseif (!empty($defaults['_entity_list'])) {
29
        $defaults = $this->enhanceEntityList($defaults, $request);
30
      }
31
      elseif (!empty($defaults['_entity_view'])) {
32
        $defaults = $this->enhanceEntityView($defaults, $request);
33
      }
34 35 36 37
    }
    return $defaults;
  }

38
  /**
39 40 41 42 43 44
   * Returns whether the enhancer runs on the current route.
   *
   * @param \Symfony\Component\Routing\Route $route
   *   The current route.
   *
   * @return bool
45
   */
46
  protected function applies(Route $route) {
47 48 49 50 51 52 53
    return !$route->hasDefault('_controller') &&
      ($route->hasDefault('_entity_form')
        || $route->hasDefault('_entity_list')
        || $route->hasDefault('_entity_view')
      );
  }

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
  /**
   * Update defaults for entity forms.
   *
   * @param array $defaults
   *   The defaults to modify.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The Request instance.
   *
   * @return array
   *   The modified defaults.
   */
  protected function enhanceEntityForm(array $defaults, Request $request) {
    $defaults['_controller'] = 'controller.entity_form:getContentResult';

    return $defaults;
  }

  /**
   * Update defaults for an entity list.
   *
   * @param array $defaults
   *   The defaults to modify.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The Request instance.
   *
   * @return array
   *   The modified defaults.
   */
  protected function enhanceEntityList(array $defaults, Request $request) {
    $defaults['_controller'] = '\Drupal\Core\Entity\Controller\EntityListController::listing';
    $defaults['entity_type'] = $defaults['_entity_list'];
    unset($defaults['_entity_list']);

    return $defaults;
  }

  /**
   * Update defaults for an entity view.
   *
   * @param array $defaults
   *   The defaults to modify.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The Request instance.
   *
   * @return array
   *   The modified defaults.
100 101 102
   *
   * @throws \RuntimeException
   *   Thrown when an entity of a type cannot be found in a route.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
   */
  protected function enhanceEntityView(array $defaults, Request $request) {
    $defaults['_controller'] = '\Drupal\Core\Entity\Controller\EntityViewController::view';
    if (strpos($defaults['_entity_view'], '.') !== FALSE) {
      // The _entity_view entry is of the form entity_type.view_mode.
      list($entity_type, $view_mode) = explode('.', $defaults['_entity_view']);
      $defaults['view_mode'] = $view_mode;
    }
    else {
      // Only the entity type is nominated, the view mode will use the
      // default.
      $entity_type = $defaults['_entity_view'];
    }
    // Set by reference so that we get the upcast value.
    if (!empty($defaults[$entity_type])) {
      $defaults['_entity'] = &$defaults[$entity_type];
    }
    else {
      // The entity is not keyed by its entity_type. Attempt to find it
      // using a converter.
      $route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
      if ($route && is_object($route)) {
        $options = $route->getOptions();
        if (isset($options['parameters'])) {
          foreach ($options['parameters'] as $name => $details) {
            if (!empty($details['type'])) {
              $type = $details['type'];
              // Type is of the form entity:{entity_type}.
              $parameter_entity_type = substr($type, strlen('entity:'));
              if ($entity_type == $parameter_entity_type) {
                // We have the matching entity type. Set the '_entity' key
                // to point to this named placeholder. The entity in this
                // position is the one being rendered.
                $defaults['_entity'] = &$defaults[$name];
              }
            }
          }
        }
        else {
          throw new \RuntimeException(sprintf('Failed to find entity of type %s in route named %s', $entity_type, $defaults[RouteObjectInterface::ROUTE_NAME]));
        }
      }
      else {
        throw new \RuntimeException(sprintf('Failed to find entity of type %s in route named %s', $entity_type, $defaults[RouteObjectInterface::ROUTE_NAME]));
      }
    }
    unset($defaults['_entity_view']);

    return $defaults;
  }

154
}