LegacyUrlMatcher.php 4.83 KB
Newer Older
neclimdul's avatar
neclimdul committed
1 2
<?php

Crell's avatar
Crell committed
3 4
/**
 * @file
Crell's avatar
Crell committed
5
 * Definition of Drupal\Core\LegacyUrlMatcher.
Crell's avatar
Crell committed
6 7
 */

neclimdul's avatar
neclimdul committed
8 9
namespace Drupal\Core;

10
use Symfony\Component\HttpFoundation\Request;
neclimdul's avatar
neclimdul committed
11
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
12 13
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\RequestContextAwareInterface;
neclimdul's avatar
neclimdul committed
14 15 16 17 18
use Symfony\Component\Routing\RequestContext;

/**
 * UrlMatcher matches URL based on a set of routes.
 */
19
class LegacyUrlMatcher implements RequestMatcherInterface, RequestContextAwareInterface {
neclimdul's avatar
neclimdul committed
20

Crell's avatar
Crell committed
21 22 23
  /**
   * The request context for this matcher.
   *
24
   * @var Symfony\Component\Routing\RequestContext
Crell's avatar
Crell committed
25
   */
neclimdul's avatar
neclimdul committed
26 27 28
  protected $context;

  /**
29
   * The request object for this matcher.
neclimdul's avatar
neclimdul committed
30
   *
31
   * @var Symfony\Component\HttpFoundation\Request
neclimdul's avatar
neclimdul committed
32
   */
33 34
  protected $request;

Niklas Fiekas's avatar
Niklas Fiekas committed
35 36 37
  /**
   * Constructor.
   */
38 39 40 41 42 43 44 45 46 47 48 49 50
  public function __construct() {
    // We will not actually use this object, but it's needed to conform to
    // the interface.
    $this->context = new RequestContext();
  }

  /**
   * Sets the request context.
   *
   * This method is just to satisfy the interface, and is largely vestigial.
   * The request context object does not contain the information we need, so
   * we will use the original request object.
   *
51 52
   * @param Symfony\Component\Routing\RequestContext $context
   *   The context.
53 54 55 56
   *
   * @api
   */
  public function setContext(RequestContext $context) {
neclimdul's avatar
neclimdul committed
57 58 59
    $this->context = $context;
  }

60 61 62 63 64 65 66
  /**
   * Gets the request context.
   *
   * This method is just to satisfy the interface, and is largely vestigial.
   * The request context object does not contain the information we need, so
   * we will use the original request object.
   *
67 68
   * @return Symfony\Component\Routing\RequestContext
   *   The context.
69 70 71 72 73
   */
  public function getContext() {
    return $this->context;
  }

Niklas Fiekas's avatar
Niklas Fiekas committed
74 75 76 77 78 79 80 81 82
  /**
   * Sets the request object to use.
   *
   * This is used by the RouterListener to make additional request attributes
   * available.
   *
   * @param Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   */
83 84 85 86
  public function setRequest(Request $request) {
    $this->request = $request;
  }

Niklas Fiekas's avatar
Niklas Fiekas committed
87 88 89 90 91 92
  /**
   * Gets the request object.
   *
   * @return Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   */
93 94 95 96
  public function getRequest() {
    return $this->request;
  }

neclimdul's avatar
neclimdul committed
97 98 99 100 101
  /**
   * {@inheritDoc}
   *
   * @api
   */
102
  public function matchRequest(Request $request) {
103
    if ($router_item = $this->matchDrupalItem($request->attributes->get('_system_path'))) {
104 105
      $ret = $this->convertDrupalItem($router_item);
      // Stash the router item in the attributes while we're transitioning.
106
      $ret['_drupal_menu_item'] = $router_item;
107 108 109 110 111

      // Most legacy controllers (aka page callbacks) are in a separate file,
      // so we have to include that.
      if ($router_item['include_file']) {
        require_once DRUPAL_ROOT . '/' . $router_item['include_file'];
neclimdul's avatar
neclimdul committed
112
      }
113

114 115 116 117 118 119
      // Flag this as a legacy request.  We need to use this for subrequest
      // handling so that we can treat older page callbacks and new routes
      // differently.
      // @todo Remove this line as soon as possible.
      $ret['_legacy'] = TRUE;

120
      return $ret;
neclimdul's avatar
neclimdul committed
121 122
    }

123 124 125
    // This matcher doesn't differentiate by method, so don't bother with those
    // exceptions.
    throw new ResourceNotFoundException();
neclimdul's avatar
neclimdul committed
126 127 128
  }

  /**
Niklas Fiekas's avatar
Niklas Fiekas committed
129
   * Get a Drupal menu item.
neclimdul's avatar
neclimdul committed
130
   *
Crell's avatar
Crell committed
131
   * @todo Make this return multiple possible candidates for the resolver to
132
   *   consider.
Crell's avatar
Crell committed
133
   *
neclimdul's avatar
neclimdul committed
134
   * @param string $path
Crell's avatar
Crell committed
135
   *   The path being looked up by
neclimdul's avatar
neclimdul committed
136 137 138 139 140 141
   */
  protected function matchDrupalItem($path) {
    // For now we can just proxy our procedural method. At some point this will
    // become more complicated because we'll need to get back candidates for a
    // path and them resolve them based on things like method and scheme which
    // we currently can't do.
142
    return menu_get_item($path);
neclimdul's avatar
neclimdul committed
143 144
  }

Niklas Fiekas's avatar
Niklas Fiekas committed
145 146 147 148 149 150 151 152 153
  /**
   * Converts a Drupal menu item to a route array.
   *
   * @param array $router_item
   *   The Drupal menu item.
   *
   * @return
   *   An array of parameters.
   */
neclimdul's avatar
neclimdul committed
154 155 156 157
  protected function convertDrupalItem($router_item) {
    $route = array(
      '_controller' => $router_item['page_callback']
    );
158

159 160
    // A few menu items have a fake page callback temporarily. Skip those,
    // we aren't going to route them.
161
    if ($router_item['page_callback'] == 'USES_ROUTE') {
162 163 164
      throw new ResourceNotFoundException();
    }

Niklas Fiekas's avatar
Niklas Fiekas committed
165 166 167 168 169 170
    // @todo menu_get_item() does not unserialize page arguments when the access
    //   is denied. Remove this temporary hack that always does that.
    if (!is_array($router_item['page_arguments'])) {
      $router_item['page_arguments'] = unserialize($router_item['page_arguments']);
    }

neclimdul's avatar
neclimdul committed
171
    // Place argument defaults on the route.
Niklas Fiekas's avatar
Niklas Fiekas committed
172
    foreach ($router_item['page_arguments'] as $k => $v) {
neclimdul's avatar
neclimdul committed
173 174
      $route[$k] = $v;
    }
175
    return $route;
neclimdul's avatar
neclimdul committed
176 177
  }
}