Commit e329d954 authored by catch's avatar catch
Browse files

Issue #2078855 by dawehner, pwolanin: Fixed Request::create() is slow, use a...

Issue #2078855 by dawehner, pwolanin: Fixed Request::create() is slow, use a helper to duplicate instead.
parent 2e493af3
......@@ -8,6 +8,7 @@
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Language\Language;
use Drupal\Core\Routing\RequestHelper;
use Drupal\Core\Template\Attribute;
use Drupal\menu_link\Entity\MenuLink;
use Drupal\menu_link\MenuLinkStorageController;
......@@ -969,7 +970,7 @@ function _menu_link_translate(&$item, $translate = FALSE) {
* If the system path in $href does not match the $route.
*/
function menu_item_route_access(Route $route, $href, &$map) {
$request = Request::create('/' . $href);
$request = RequestHelper::duplicate(\Drupal::request(), '/' . $href);
$request->attributes->set('_system_path', $href);
// Attempt to match this path to provide a fully built request to the
// access checker.
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Access;
use Drupal\Core\ParamConverter\ParamConverterManager;
use Drupal\Core\Routing\RequestHelper;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouteCollection;
......@@ -191,7 +192,7 @@ public function checkNamedRoute($route_name, array $parameters = array(), Reques
$route = $this->routeProvider->getRouteByName($route_name, $parameters);
if (empty($route_request)) {
// Create a request and copy the account from the current request.
$route_request = Request::create($this->urlGenerator->generate($route_name, $parameters));
$route_request = RequestHelper::duplicate($this->request, $this->urlGenerator->generate($route_name, $parameters));
$defaults = $parameters;
$defaults['_account'] = $this->request->attributes->get('_account');
$defaults[RouteObjectInterface::ROUTE_OBJECT] = $route;
......
<?php
/**
* @file
* Contains \Drupal\Core\Routing\RequestHelper.
*/
namespace Drupal\Core\Routing;
use Symfony\Component\HttpFoundation\Request;
/**
* Provides some helper methods for dealing with the request.
*/
class RequestHelper {
/**
* Duplicates a request for another path.
*
* This method does basically the same as Request::create() but keeping all
* the previous variables to speed it up.
*
* @param \Symfony\Component\HttpFoundation\Request $original_request
* The original request object to clone.
* @param string $uri
* The URI.
* @param string $method
* The HTTP method.
* @param array $parameters
* The query (GET) or request (POST) parameters.
* @param array $query
* The GET parameters.
* @param array $post
* The POST parameters.
* @param array $attributes
* The request attributes (parameters parsed from the PATH_INFO, ...).
* @param array $cookies
* The COOKIE parameters.
* @param array $files
* The FILES parameters.
* @param array $server
* The SERVER parameters.
*
* @return \Symfony\Component\HttpFoundation\Request
* The cloned request instance.
*
* @see \Symfony\Component\HttpFoundation\Request::create()
* @see \Symfony\Component\HttpFoundation\Request::duplicate()
*/
public static function duplicate(Request $original_request, $uri, $method = 'GET', $parameters = array(), array $query = NULL, array $post = NULL, array $attributes = NULL, array $cookies = NULL, array $files = NULL, array $server = NULL) {
$request = $original_request->duplicate($query, $post, $attributes, $cookies, $files, $server);
$server = array();
$server['PATH_INFO'] = '';
$server['REQUEST_METHOD'] = strtoupper($method);
$components = parse_url($uri);
if (isset($components['host'])) {
$server['SERVER_NAME'] = $components['host'];
$server['HTTP_HOST'] = $components['host'];
}
if (isset($components['scheme'])) {
if ('https' === $components['scheme']) {
$server['HTTPS'] = 'on';
$server['SERVER_PORT'] = 443;
}
else {
unset($server['HTTPS']);
$server['SERVER_PORT'] = 80;
}
}
if (isset($components['port'])) {
$server['SERVER_PORT'] = $components['port'];
$server['HTTP_HOST'] = $server['HTTP_HOST'] . ':' . $components['port'];
}
if (isset($components['user'])) {
$server['PHP_AUTH_USER'] = $components['user'];
}
if (isset($components['pass'])) {
$server['PHP_AUTH_PW'] = $components['pass'];
}
if (!isset($components['path'])) {
$components['path'] = '/';
}
switch (strtoupper($method)) {
case 'POST':
case 'PUT':
case 'DELETE':
if (!isset($server['CONTENT_TYPE'])) {
$server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
}
case 'PATCH':
$post = $parameters;
$query = array();
break;
default:
$post = array();
$query = $parameters;
break;
}
if (isset($components['query'])) {
parse_str(html_entity_decode($components['query']), $query_string);
$query = array_replace($query_string, $query);
}
$query_string = http_build_query($query, '', '&');
// Prepend a ? if there is a query string.
if ($query_string !== '') {
$query_string = '?' . $query_string;
}
$server['REQUEST_URI'] = $components['path'] . $query_string;
$server['QUERY_STRING'] = $query_string;
$request->server->add($server);
// The 'request' attribute name corresponds to $_REQUEST, but Symfony
// documents it as holding the POST parameters.
$request->request->add($post);
$request->query->add($query);
return $request;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment