Commit 02a32e3f authored by catch's avatar catch

Issue #2284103 by alexpott, fabpot, damiankloip, Xano, Xen, Berdir: Fixed...

Issue #2284103 by alexpott, fabpot, damiankloip, Xano, Xen, Berdir: Fixed Remove the request from the container.
parent 48fb187d
......@@ -279,10 +279,6 @@ services:
parent: default_plugin_manager
plugin.cache_clearer:
class: Drupal\Core\Plugin\CachedDiscoveryClearer
request:
class: Symfony\Component\HttpFoundation\Request
synthetic: true
synchronized: true
request_stack:
class: Symfony\Component\HttpFoundation\RequestStack
tags:
......@@ -304,9 +300,8 @@ services:
class: Drupal\Core\Controller\TitleResolver
arguments: ['@controller_resolver', '@string_translation']
http_kernel:
class: Drupal\Core\HttpKernel
class: Symfony\Component\HttpKernel\HttpKernel
arguments: ['@event_dispatcher', '@controller_resolver', '@request_stack']
parent: container.trait
language_manager:
class: Drupal\Core\Language\LanguageManager
arguments: ['@language.default']
......@@ -371,9 +366,8 @@ services:
- { name: service_collector, tag: route_filter, call: addRouteFilter }
url_generator:
class: Drupal\Core\Routing\UrlGenerator
arguments: ['@router.route_provider', '@path_processor_manager', '@route_processor_manager', '@config.factory', '@settings', '@logger.channel.default']
arguments: ['@router.route_provider', '@path_processor_manager', '@route_processor_manager', '@config.factory', '@settings', '@logger.channel.default', '@request_stack']
calls:
- [setRequest, ['@?request']]
- [setContext, ['@?router.request_context']]
link_generator:
class: Drupal\Core\Utility\LinkGenerator
......@@ -566,10 +560,9 @@ services:
class: Drupal\Core\Access\AccessArgumentsResolver
access_manager:
class: Drupal\Core\Access\AccessManager
arguments: ['@router.route_provider', '@url_generator', '@paramconverter_manager', '@access_arguments_resolver']
arguments: ['@router.route_provider', '@url_generator', '@paramconverter_manager', '@access_arguments_resolver', '@request_stack']
calls:
- [setContainer, ['@service_container']]
- [setRequest, ['@?request']]
access_subscriber:
class: Drupal\Core\EventSubscriber\AccessSubscriber
arguments: ['@access_manager', '@current_user']
......@@ -627,13 +620,11 @@ services:
tags:
- { name: event_subscriber }
arguments: ['@language_manager', '@config.factory']
scope: request
redirect_response_subscriber:
class: Drupal\Core\EventSubscriber\RedirectResponseSubscriber
arguments: ['@url_generator']
tags:
- { name: event_subscriber }
scope: request
request_close_subscriber:
class: Drupal\Core\EventSubscriber\RequestCloseSubscriber
tags:
......@@ -804,7 +795,7 @@ services:
arguments: ['@authentication']
current_user:
class: Drupal\Core\Session\AccountProxy
arguments: ['@authentication', '@request']
arguments: ['@authentication', '@request_stack']
session_manager:
class: Drupal\Core\Session\SessionManager
arguments: ['@request_stack', '@database', '@session_manager.metadata_bag', '@settings']
......
......@@ -1731,7 +1731,7 @@ function _drupal_add_js($data = NULL, $options = NULL) {
// @todo Make this less hacky: http://drupal.org/node/1547376.
$scriptPath = $GLOBALS['script_path'];
$pathPrefix = '';
$current_query = \Drupal::service('request')->query->all();
$current_query = \Drupal::service('request_stack')->getCurrentRequest()->query->all();
url('', array('script' => &$scriptPath, 'prefix' => &$pathPrefix));
$current_path = current_path();
$current_path_is_admin = FALSE;
......
......@@ -355,10 +355,12 @@ function install_begin_request(&$install_state) {
$environment = 'prod';
}
$kernel = InstallerKernel::createFromRequest($request, drupal_classloader(), $environment);
// Only allow dumping the container once the hash salt has been created.
$kernel = InstallerKernel::createFromRequest($request, drupal_classloader(), $environment, (bool) Settings::get('hash_salt', FALSE));
$kernel->setSitePath($site_path);
$kernel->boot();
$container = $kernel->getContainer();
$container->get('request_stack')->push($request);
// Register the file translation service.
if (isset($GLOBALS['config']['locale.settings']['translation.path'])) {
......
......@@ -60,8 +60,8 @@ function current_path() {
// @todo Remove the check for whether the request service exists and the
// fallback code below, once the path alias logic has been figured out in
// http://drupal.org/node/1269742.
if (\Drupal::getContainer()->isScopeActive('request')) {
$path = \Drupal::request()->attributes->get('_system_path');
if ($request = \Drupal::request()) {
$path = $request->attributes->get('_system_path');
if ($path !== NULL) {
return $path;
}
......
......@@ -158,7 +158,7 @@ public static function hasService($id) {
* TRUE if there is a currently active request object, FALSE otherwise.
*/
public static function hasRequest() {
return static::$container && static::$container->has('request') && static::$container->initialized('request') && static::$container->isScopeActive('request');
return static::$container && static::$container->has('request_stack') && static::$container->get('request_stack')->getCurrentRequest() !== NULL;
}
/**
......@@ -184,7 +184,7 @@ public static function hasRequest() {
* The currently active request object.
*/
public static function request() {
return static::$container->get('request');
return static::$container->get('request_stack')->getCurrentRequest();
}
/**
......
......@@ -18,6 +18,7 @@
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
......@@ -94,11 +95,11 @@ class AccessManager implements ContainerAwareInterface {
protected $argumentsResolver;
/**
* A request object.
* A request stack object.
*
* @var \Symfony\Component\HttpFoundation\Request
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $request;
protected $requestStack;
/**
* Constructs a AccessManager instance.
......@@ -111,25 +112,15 @@ class AccessManager implements ContainerAwareInterface {
* The param converter manager.
* @param \Drupal\Core\Access\AccessArgumentsResolverInterface $arguments_resolver
* The access arguments resolver.
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack object.
*/
public function __construct(RouteProviderInterface $route_provider, UrlGeneratorInterface $url_generator, ParamConverterManagerInterface $paramconverter_manager, AccessArgumentsResolverInterface $arguments_resolver) {
public function __construct(RouteProviderInterface $route_provider, UrlGeneratorInterface $url_generator, ParamConverterManagerInterface $paramconverter_manager, AccessArgumentsResolverInterface $arguments_resolver, RequestStack $requestStack) {
$this->routeProvider = $route_provider;
$this->urlGenerator = $url_generator;
$this->paramConverterManager = $paramconverter_manager;
$this->argumentsResolver = $arguments_resolver;
}
/**
* 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.
*/
public function setRequest(Request $request) {
$this->request = $request;
$this->requestStack = $requestStack;
}
/**
......@@ -222,7 +213,7 @@ public function checkNamedRoute($route_name, array $parameters = array(), Accoun
if (empty($route_request)) {
// Create a request and copy the account from the current request.
$defaults = $parameters + $route->getDefaults();
$route_request = RequestHelper::duplicate($this->request, $this->urlGenerator->generate($route_name, $defaults));
$route_request = RequestHelper::duplicate($this->requestStack->getCurrentRequest(), $this->urlGenerator->generate($route_name, $defaults));
$defaults[RouteObjectInterface::ROUTE_OBJECT] = $route;
$route_request->attributes->add($this->paramConverterManager->convert($defaults, $route_request));
}
......
......@@ -29,7 +29,7 @@ public function applies(Request $request);
/**
* Authenticates the user.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\HttpFoundation\Request|null $request
* The request object.
*
* @return \Drupal\Core\Session\AccountInterface|null
......
......@@ -22,7 +22,6 @@
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
/**
......@@ -41,10 +40,6 @@ class CoreServiceProvider implements ServiceProviderInterface {
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
// The 'request' scope and service enable services to depend on the Request
// object and get reconstructed when the request object changes (e.g.,
// during a subrequest).
$container->addScope(new Scope('request'));
$this->registerTwig($container);
$this->registerUuid($container);
$this->registerTest($container);
......
......@@ -10,6 +10,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder as SymfonyContainerBuilder;
use Symfony\Component\DependencyInjection\Container as SymfonyContainer;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
/**
* Drupal's dependency injection container builder.
......@@ -19,13 +20,11 @@
class ContainerBuilder extends SymfonyContainerBuilder {
/**
* Overrides Symfony\Component\DependencyInjection\ContainerBuilder::addObjectResource().
*
* Drupal does not use Symfony's Config component, so we override
* addObjectResource() with an empty implementation to prevent errors during
* container compilation.
* {@inheritdoc}
*/
public function addObjectResource($object) {
public function __construct(ParameterBagInterface $parameterBag = NULL) {
$this->setResourceTracking(FALSE);
parent::__construct($parameterBag);
}
/**
......
......@@ -425,23 +425,12 @@ protected function preHandle(Request $request) {
// Initialize cookie globals.
$this->initializeCookieGlobals($request);
// Ensure container has a request scope so we can load file stream wrappers.
if (!$this->container->isScopeActive('request')) {
// Enter the request scope so that current_user service is available for
// locale/translation sake.
$this->container->enterScope('request');
$this->container->set('request', $request, 'request');
$this->container->get('request_stack')->push($request);
}
// Put the request on the stack.
$this->container->get('request_stack')->push($request);
// Make sure all stream wrappers are registered.
file_get_stream_wrappers();
// Back out scope required to initialize the file stream wrappers.
if ($this->container->isScopeActive('request')) {
$this->container->leaveScope('request');
}
// Set the allowed protocols once we have the config available.
$allowed_protocols = $this->container->get('config.factory')->get('system.filter')->get('protocols');
if (!isset($allowed_protocols)) {
......@@ -582,8 +571,6 @@ public function prepareLegacyRequest(Request $request) {
$this->preHandle($request);
// Enter the request scope so that current_user service is available for
// locale/translation sake.
$this->container->enterScope('request');
$this->container->set('request', $request);
$this->container->get('request_stack')->push($request);
$this->container->get('router.request_context')->fromRequest($request);
return $this;
......@@ -680,21 +667,8 @@ protected function getKernelParameters() {
*/
protected function initializeContainer($rebuild = FALSE) {
$this->containerNeedsDumping = FALSE;
// The request service requires custom persisting logic, since it is also
// potentially scoped.
$request_scope = FALSE;
$request_stack = $request = NULL;
$session_manager_state = 0;
if (isset($this->container)) {
if ($this->container->isScopeActive('request')) {
$request_scope = TRUE;
}
if ($this->container->initialized('request')) {
$request = $this->container->get('request');
}
if ($this->container->initialized('request_stack')) {
$request_stack = $this->container->get('request_stack');
}
// If there is a session manager, close and save the session.
if ($this->container->initialized('session_manager')) {
$session_manager = $this->container->get('session_manager');
......@@ -730,7 +704,7 @@ protected function initializeContainer($rebuild = FALSE) {
$container = $this->compileContainer();
}
$this->attachSynthetic($container, $request, $request_stack, $request_scope);
$this->attachSynthetic($container);
$this->container = $container;
if ($session_manager_state & 0x1) {
......@@ -996,15 +970,10 @@ public function rebuildContainer() {
*
* @param ContainerInterface $container
* Container object
* @param Request $request
* Request object.
* @param RequestStack $request_stack
* Request stack.
* @param null $request_scope
*
* @return ContainerInterface
*/
protected function attachSynthetic(ContainerInterface $container, Request $request = NULL, RequestStack $request_stack = NULL, $request_scope = NULL) {
protected function attachSynthetic(ContainerInterface $container) {
$persist = array();
if (isset($this->container)) {
$persist = $this->getServicesToPersist($this->container);
......@@ -1019,16 +988,6 @@ protected function attachSynthetic(ContainerInterface $container, Request $reque
// Set the class loader which was registered as a synthetic service.
$container->set('class_loader', $this->classLoader);
// If we have a request set it back to the new container.
if ($request_scope) {
$container->enterScope('request');
}
if (isset($request)) {
$container->set('request', $request);
}
if (isset($request_stack)) {
$container->set('request_stack', $request_stack);
}
return $container;
}
......
......@@ -14,7 +14,7 @@
use Drupal\Core\Routing\UrlGeneratorTrait;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Provides a base class for forms.
......@@ -26,11 +26,11 @@ abstract class FormBase implements FormInterface, ContainerInjectionInterface {
use UrlGeneratorTrait;
/**
* The current request.
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\Request
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $request;
protected $requestStack;
/**
* The config factory.
......@@ -127,22 +127,22 @@ public function resetConfigFactory() {
* The request object.
*/
protected function getRequest() {
if (!$this->request) {
$this->request = $this->container()->get('request');
if (!$this->requestStack) {
$this->requestStack = \Drupal::service('request_stack');
}
return $this->request;
return $this->requestStack->getCurrentRequest();
}
/**
* Sets the request object to use.
* Sets the request stack object to use.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack object.
*
* @return $this
*/
public function setRequest(Request $request) {
$this->request = $request;
public function setRequestStack(RequestStack $request_stack) {
$this->requestStack = $request_stack;
return $this;
}
......
......@@ -13,7 +13,6 @@
use Drupal\Core\Access\CsrfTokenGenerator;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\HttpKernel;
use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Site\Settings;
......@@ -21,6 +20,7 @@
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
......@@ -67,7 +67,7 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS
/**
* The HTTP kernel to handle forms returning response objects.
*
* @var \Drupal\Core\HttpKernel
* @var \Symfony\Component\HttpKernel\HttpKernel
*/
protected $httpKernel;
......
<?php
/**
* @file
* Definition of Drupal\Core\HttpKernel.
*
* @todo This file is copied verbatim, with the exception of the namespace
* change and this commment block, from Symfony full stack's FrameworkBundle.
* Once the FrameworkBundle is available as a Composer package we should switch
* to pulling it via Composer.
*/
namespace Drupal\Core;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\HttpKernel as BaseHttpKernel;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
/**
* This HttpKernel is used to manage scope changes of the DI container.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class HttpKernel extends BaseHttpKernel implements ContainerAwareInterface {
use ContainerAwareTrait;
private $esiSupport;
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
$request->headers->set('X-Php-Ob-Level', ob_get_level());
$this->container->enterScope('request');
$this->container->set('request', $request, 'request');
try {
$response = parent::handle($request, $type, $catch);
} catch (\Exception $e) {
$this->container->leaveScope('request');
throw $e;
}
$this->container->leaveScope('request');
return $response;
}
/**
* Forwards the request to another controller.
*
* @param string|null $controller
* The controller name (a string like BlogBundle:Post:index).
* @param array $attributes
* An array of request attributes.
* @param array $query
* An array of request query parameters.
*
* @return Response
* A Response instance
*/
public function forward($controller, array $attributes = array(), array $query = array())
{
$subrequest = $this->setupSubrequest($controller, $attributes, $query);
return $this->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
}
/**
* Renders a Controller and returns the Response content.
*
* Note that this method generates an esi:include tag only when both the standalone
* option is set to true and the request has ESI capability (@see Symfony\Component\HttpKernel\HttpCache\ESI).
*
* Available options:
*
* * attributes: An array of request attributes (only when the first argument is a controller)
* * query: An array of request query parameters (only when the first argument is a controller)
* * ignore_errors: true to return an empty string in case of an error
* * alt: an alternative controller to execute in case of an error (can be a controller, a URI, or an array with the controller, the attributes, and the query arguments)
* * standalone: whether to generate an esi:include tag or not when ESI is supported
* * comment: a comment to add when returning an esi:include tag
*
* @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI
* @param array $options An array of options
*
* @return string The Response content
*/
public function render($controller, array $options = array())
{
$options = array_merge(array(
'attributes' => array(),
'query' => array(),
'ignore_errors' => !$this->container->getParameter('kernel.debug'),
'alt' => array(),
'standalone' => false,
'comment' => '',
), $options);
if (!is_array($options['alt'])) {
$options['alt'] = array($options['alt']);
}
if (null === $this->esiSupport) {
$this->esiSupport = $this->container->has('esi') && $this->container->get('esi')->hasSurrogateEsiCapability($this->container->get('request'));
}
if ($this->esiSupport && (true === $options['standalone'] || 'esi' === $options['standalone'])) {
$uri = $this->generateInternalUri($controller, $options['attributes'], $options['query']);
$alt = '';
if ($options['alt']) {
$alt = $this->generateInternalUri($options['alt'][0], isset($options['alt'][1]) ? $options['alt'][1] : array(), isset($options['alt'][2]) ? $options['alt'][2] : array());
}
return $this->container->get('esi')->renderIncludeTag($uri, $alt, $options['ignore_errors'], $options['comment']);
}
if ('js' === $options['standalone']) {
$uri = $this->generateInternalUri($controller, $options['attributes'], $options['query'], false);
$defaultContent = null;
if ($template = $this->container->getParameter('templating.hinclude.default_template')) {
$defaultContent = $this->container->get('templating')->render($template);
}
return $this->renderHIncludeTag($uri, $defaultContent);
}
$request = $this->container->get('request');
// controller or URI?
if (0 === strpos($controller, '/')) {
$subRequest = Request::create($request->getUriForPath($controller), 'get', array(), $request->cookies->all(), array(), $request->server->all());
if ($session = $request->getSession()) {
$subRequest->setSession($session);
}
} else {
$options['attributes']['_controller'] = $controller;
if (!isset($options['attributes']['_format'])) {
$options['attributes']['_format'] = $request->getRequestFormat();
}
$options['attributes'][RouteObjectInterface::ROUTE_OBJECT] = '_internal';
$subRequest = $request->duplicate($options['query'], null, $options['attributes']);
$subRequest->setMethod('GET');
}
$level = ob_get_level();
try {
$response = $this->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
if (!$response->isSuccessful()) {
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $request->getUri(), $response->getStatusCode()));
}
if (!$response instanceof StreamedResponse) {
return $response->getContent();
}
$response->sendContent();
} catch (\Exception $e) {
if ($options['alt']) {
$alt = $options['alt'];
unset($options['alt']);
$options['attributes'] = isset($alt[1]) ? $alt[1] : array();
$options['query'] = isset($alt[2]) ? $alt[2] : array();
return $this->render($alt[0], $options);
}
if (!$options['ignore_errors']) {
throw $e;
}
// let's clean up the output buffers that were created by the sub-request
while (ob_get_level() > $level) {
ob_get_clean();
}
}
}
/**
* Generates an internal URI for a given controller.
*
* This method uses the "_internal" route, which should be available.
*
* @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI
* @param array $attributes An array of request attributes
* @param array $query An array of request query parameters
* @param boolean $secure
*
* @return string An internal URI
*/
public function generateInternalUri($controller, array $attributes = array(), array $query = array(), $secure = true)
{
if (0 === strpos($controller, '/')) {
return $controller;
}
$path = http_build_query($attributes, '', '&');
$uri = $this->container->get('router')->generate($secure ? '_internal' : '_internal_public', array(
'controller' => $controller,
'path' => $path ?: 'none',
'_format' => $this->container->get('request')->getRequestFormat(),
));
if ($queryString = http_build_query($query, '', '&')) {
$uri .= '?'.$queryString;
}
return $uri;
}
/**
* Renders an HInclude tag.
*
* @param string $uri A URI
* @param string $defaultContent Default content
*/
public function renderHIncludeTag($uri, $defaultContent = null)
{
return sprintf('<hx:include src="%s">%s</hx:include>', $uri, $defaultContent);
}
public function hasEsiSupport()
{
return $this->esiSupport;
}
/**
* Creates a request object for a subrequest.
*
* @param string $controller
* The controller name (a string like BlogBundle:Post:index)
* @param array $attributes
* An array of request attributes.
* @param array $query
* An array of request query parameters.
*
* @return \Symfony\Component\HttpFoundation\Request
* Returns the new request.
*/
public function setupSubrequest($controller, array $attributes, array $query) {
// Don't override the controller if it's NULL.
if (isset($controller)) {
$attributes['_controller'] = $controller;
}
else {
unset($attributes['_controller']);
}
return $this->container->get('request')->duplicate($query, NULL, $attributes);
}
}
......@@ -25,12 +25,4 @@ protected function initializeContainer($rebuild = TRUE) {
return $container;
}
/**
* {@inheritdoc}
*/
protected function dumpDrupalContainer(ContainerBuilder $container, $baseClass) {
if (Settings::get('hash_salt')) {
return parent::dumpDrupalContainer($container, $baseClass);
}
}
}
......@@ -11,7 +11,7 @@
use Psr\Log\LoggerInterface;
use Psr\Log\LoggerTrait;