diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php index a4ec691..f29e0b0 100644 --- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php @@ -10,6 +10,7 @@ use Drupal\Core\Language\LanguageManager; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -41,6 +42,10 @@ public function __construct(LanguageManager $language_manager) { * The event to process. */ public function onRespond(FilterResponseEvent $event) { + if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) { + return; + } + $response = $event->getResponse(); // Set the X-UA-Compatible HTTP header to force IE to use the most recent diff --git a/core/lib/Drupal/Core/HtmlPageController.php b/core/lib/Drupal/Core/HtmlPageController.php index 7d14ac0..b94e8fc 100644 --- a/core/lib/Drupal/Core/HtmlPageController.php +++ b/core/lib/Drupal/Core/HtmlPageController.php @@ -52,7 +52,7 @@ public function content(Request $request, $_content) { // require an _internal route. For examples, see: // https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml // https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.php - $attributes = $request->attributes; + $attributes = clone $request->attributes; $controller = $_content; // We need to clean off the derived information and such so that the @@ -62,8 +62,12 @@ public function content(Request $request, $_content) { $response = $this->container->get('http_kernel')->forward($controller, $attributes->all(), $request->query->all()); - $page_content = $response->getContent(); + // For successful (HTTP status 200) responses, decorate with blocks. + if ($response->isOk()) { + $page_content = $response->getContent(); + $response = new Response(drupal_render_page($page_content)); + } - return new Response(drupal_render_page($page_content)); + return $response; } } diff --git a/core/lib/Drupal/Core/Routing/PathMatcher.php b/core/lib/Drupal/Core/Routing/PathMatcher.php index f037d9a..9b5bd5e 100644 --- a/core/lib/Drupal/Core/Routing/PathMatcher.php +++ b/core/lib/Drupal/Core/Routing/PathMatcher.php @@ -56,7 +56,21 @@ public function __construct(Connection $connection, $table = 'router') { */ public function matchRequestPartial(Request $request) { - $path = rtrim($request->getPathInfo(), '/'); + // The 'system_path' has language prefix stripped and path alias resolved, + // whereas getPathInfo() returns the requested path. In Drupal, the request + // always contains a system_path attribute, but this component may get + // adopted by non-Drupal projects. Some unit tests also skip initializing + // 'system_path'. + // @todo Consider abstracting this to a separate object. + if ($request->attributes->has('system_path')) { + // system_path never has leading or trailing slashes. + $path = '/' . $request->attributes->get('system_path'); + } + else { + // getPathInfo() always has leading slash, and might or might not have a + // trailing slash. + $path = rtrim($request->getPathInfo(), '/'); + } $parts = array_slice(array_filter(explode('/', $path)), 0, MatcherDumper::MAX_PARTS); diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php index 0780250..6769107 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php @@ -299,4 +299,27 @@ function testOutlinePathNoMatch() { } + /** + * Confirms that system_path attribute overrides request path. + */ + function testSystemPathMatch() { + $connection = Database::getConnection(); + $matcher = new PathMatcher($connection, 'test_routes'); + + $this->fixtures->createTables($connection); + + $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper->addRoutes($this->fixtures->sampleRouteCollection()); + $dumper->dump(); + + $request = Request::create('/path/one', 'GET'); + $request->attributes->set('system_path', 'path/two'); + + $routes = $matcher->matchRequestPartial($request); + + foreach ($routes as $route) { + $this->assertEqual($route->getPattern(), '/path/two', 'Found path has correct pattern'); + } + } + } diff --git a/core/modules/user/lib/Drupal/user/UserRouteController.php b/core/modules/user/lib/Drupal/user/UserRouteController.php new file mode 100644 index 0000000..e4423fd --- /dev/null +++ b/core/modules/user/lib/Drupal/user/UserRouteController.php @@ -0,0 +1,32 @@ +uid; } -function user_register() { - $account = entity_create('user', array()); - return entity_get_form($account, 'register'); -} - function user_register_access() { return user_is_anonymous() && (config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY); } @@ -1160,9 +1155,14 @@ function user_menu() { $items['user/register'] = array( 'title' => 'Create new account', - 'page callback' => 'user_register', - 'access callback' => 'user_register_access', 'type' => MENU_LOCAL_TASK, + // @todo This route is now declared in user.routing.yml, so the below are + // only needed for drupal_valid_path(). Without a non-empty (but not + // necessarily valid) page callback, _menu_router_build() overrides the + // access callback to 0. Remove once drupal_valid_path works with the new + // routing system: http://drupal.org/node/1793520. + 'page callback' => 'NOT_USED', + 'access callback' => 'user_register_access', ); $items['user/password'] = array( diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml new file mode 100644 index 0000000..5e11fab --- /dev/null +++ b/core/modules/user/user.routing.yml @@ -0,0 +1,4 @@ +user_register: + pattern: '/user/register' + defaults: + _content: '\Drupal\user\UserRouteController::register'