LegacyControllerSubscriber.php 2.57 KB
Newer Older
1 2
<?php

3 4 5 6 7
/**
 * @file
 * Definition of Drupal\Core\EventSubscriber\LegacyControllerSubscriber.
 */

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
namespace Drupal\Core\EventSubscriber;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Access subscriber for controller requests.
 */
class LegacyControllerSubscriber implements EventSubscriberInterface {

  /**
   * Wraps legacy controllers in a closure to handle old-style arguments.
   *
   * This is a backward compatibility layer only.  This is a rather ugly way
   * to piggyback Drupal's existing menu router items onto the Symfony model,
   * but it works for now.  If we did not do this, any menu router item with
   * a variable number of arguments would fail to work.  This bypasses Symfony's
   * controller argument handling entirely and lets the old-style approach work.
   *
   * @todo Convert Drupal to use the IETF-draft-RFC style {placeholders}. That
29 30 31 32 33
   *   will allow us to use the native Symfony conversion, including
   *   out-of-order argument mapping, name-based mapping, and with another
   *   listener auto-conversion of parameters to full objects. That may
   *   necessitate not using func_get_args()-based controllers. That is likely
   *   for the best, as those are quite hard to document anyway.
34
   *
35
   * @param Symfony\Component\HttpKernel\Event\FilterControllerEvent $event
36 37 38
   *   The Event to process.
   */
  public function onKernelControllerLegacy(FilterControllerEvent $event) {
39 40
    $request = $event->getRequest();
    $router_item = $request->attributes->get('drupal_menu_item');
41 42
    $controller = $event->getController();

43
    // This BC logic applies only to functions. Otherwise, skip it.
44
    if (is_string($controller) && function_exists($controller)) {
45 46 47 48 49 50
      // 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.
      $request->attributes->set('_legacy', TRUE);

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
      $new_controller = function() use ($router_item) {
        return call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
      };
      $event->setController($new_controller);
    }
  }

  /**
   * Registers the methods in this class that should be listeners.
   *
   * @return array
   *   An array of event listener definitions.
   */
  static function getSubscribedEvents() {
    $events[KernelEvents::CONTROLLER][] = array('onKernelControllerLegacy', 30);

    return $events;
  }
}