Commit 92f93a1c authored by catch's avatar catch

Issue #2004086 by dawehner, pwolanin, katbailey, tim.plunkett, vijaycs85,...

Issue #2004086 by dawehner, pwolanin, katbailey, tim.plunkett, vijaycs85, fabpot: The Request service must be synthetic.
parent fc04601c
...@@ -211,17 +211,12 @@ services: ...@@ -211,17 +211,12 @@ services:
plugin.manager.menu.local_task: plugin.manager.menu.local_task:
class: Drupal\Core\Menu\LocalTaskManager class: Drupal\Core\Menu\LocalTaskManager
arguments: ['@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@cache.cache', '@language_manager', '@access_manager', '@current_user'] arguments: ['@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@cache.cache', '@language_manager', '@access_manager', '@current_user']
scope: request
plugin.manager.menu.contextual_link: plugin.manager.menu.contextual_link:
class: Drupal\Core\Menu\ContextualLinkManager class: Drupal\Core\Menu\ContextualLinkManager
arguments: ['@controller_resolver', '@module_handler', '@cache.cache', '@language_manager', '@access_manager', '@current_user'] arguments: ['@controller_resolver', '@module_handler', '@cache.cache', '@language_manager', '@access_manager', '@current_user']
request: request:
class: Symfony\Component\HttpFoundation\Request class: Symfony\Component\HttpFoundation\Request
# @TODO the synthetic setting must be uncommented whenever drupal_session_initialize() synthetic: true
# is run after there is a request and the following two lines should be removed.
factory_class: Symfony\Component\HttpFoundation\Request
factory_method: createFromGlobals
#synthetic: true
event_dispatcher: event_dispatcher:
class: Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher class: Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher
arguments: ['@service_container'] arguments: ['@service_container']
...@@ -365,6 +360,10 @@ services: ...@@ -365,6 +360,10 @@ services:
tags: tags:
- { name: event_subscriber } - { name: event_subscriber }
arguments: ['@settings'] arguments: ['@settings']
ajax_response_subscriber:
class: Drupal\Core\EventSubscriber\AjaxResponseSubscriber
tags:
- { name: event_subscriber }
route_enhancer.authentication: route_enhancer.authentication:
class: Drupal\Core\Routing\Enhancer\AuthenticationEnhancer class: Drupal\Core\Routing\Enhancer\AuthenticationEnhancer
calls: calls:
...@@ -436,7 +435,6 @@ services: ...@@ -436,7 +435,6 @@ services:
- [setCurrentUser, ['@?current_user']] - [setCurrentUser, ['@?current_user']]
tags: tags:
- { name: event_subscriber } - { name: event_subscriber }
scope: request
access_route_subscriber: access_route_subscriber:
class: Drupal\Core\EventSubscriber\AccessRouteSubscriber class: Drupal\Core\EventSubscriber\AccessRouteSubscriber
tags: tags:
......
...@@ -1552,7 +1552,7 @@ function watchdog($type, $message, array $variables = NULL, $severity = WATCHDOG ...@@ -1552,7 +1552,7 @@ function watchdog($type, $message, array $variables = NULL, $severity = WATCHDOG
$log_entry['referer'] = $request->headers->get('Referer', ''); $log_entry['referer'] = $request->headers->get('Referer', '');
$log_entry['ip'] = $request->getClientIP(); $log_entry['ip'] = $request->getClientIP();
} }
catch (\InvalidArgumentException $e) { catch (DependencyInjectionRuntimeException $e) {
// We are not in a request context. // We are not in a request context.
} }
...@@ -1718,9 +1718,18 @@ function drupal_set_title($title = NULL, $output = Title::CHECK_PLAIN) { ...@@ -1718,9 +1718,18 @@ function drupal_set_title($title = NULL, $output = Title::CHECK_PLAIN) {
* The user session object. * The user session object.
*/ */
function drupal_anonymous_user() { function drupal_anonymous_user() {
try {
$request = \Drupal::request();
$hostname = $request->getClientIP();
}
catch (DependencyInjectionRuntimeException $e) {
// We are not in a request context.
$hostname = '';
}
$values = array( $values = array(
'uid' => 0, 'uid' => 0,
'hostname' => \Drupal::request()->getClientIP(), 'hostname' => $hostname,
'roles' => array(DRUPAL_ANONYMOUS_RID), 'roles' => array(DRUPAL_ANONYMOUS_RID),
); );
return new UserSession($values); return new UserSession($values);
...@@ -1861,10 +1870,13 @@ function drupal_handle_request($test_only = FALSE) { ...@@ -1861,10 +1870,13 @@ function drupal_handle_request($test_only = FALSE) {
// @todo Remove this once everything in the bootstrap has been // @todo Remove this once everything in the bootstrap has been
// converted to services in the DIC. // converted to services in the DIC.
$kernel->boot(); $kernel->boot();
drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
// Create a request object from the HttpFoundation. // Create a request object from the HttpFoundation.
$request = Request::createFromGlobals(); $request = Request::createFromGlobals();
\Drupal::getContainer()->set('request', $request);
drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
$response = $kernel->handle($request)->prepare($request)->send(); $response = $kernel->handle($request)->prepare($request)->send();
$kernel->terminate($request, $response); $kernel->terminate($request, $response);
...@@ -1994,6 +2006,8 @@ function _drupal_bootstrap_kernel() { ...@@ -1994,6 +2006,8 @@ function _drupal_bootstrap_kernel() {
if (!\Drupal::getContainer()) { if (!\Drupal::getContainer()) {
$kernel = new DrupalKernel('prod', drupal_classloader()); $kernel = new DrupalKernel('prod', drupal_classloader());
$kernel->boot(); $kernel->boot();
$request = Request::createFromGlobals();
\Drupal::getContainer()->set('request', $request);
} }
} }
......
...@@ -625,10 +625,19 @@ function drupal_install_system() { ...@@ -625,10 +625,19 @@ function drupal_install_system() {
// Create tables. // Create tables.
drupal_install_schema('system'); drupal_install_schema('system');
if (!drupal_container()->has('kernel')) { if (!\Drupal::getContainer()->has('kernel')) {
// Immediately boot a kernel to have real services ready. // Immediately boot a kernel to have real services ready. If there's already
// an initialized request object in the pre-kernel container, persist it in
// the post-kernel container.
if (\Drupal::getContainer()->initialized('request')) {
$request = \Drupal::request();
}
$kernel = new DrupalKernel('install', drupal_classloader(), FALSE); $kernel = new DrupalKernel('install', drupal_classloader(), FALSE);
$kernel->boot(); $kernel->boot();
if (isset($request)) {
\Drupal::getContainer()->set('request', $request);
}
} }
$system_path = drupal_get_path('module', 'system'); $system_path = drupal_get_path('module', 'system');
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/** /**
* JSON response object for AJAX requests. * JSON response object for AJAX requests.
...@@ -46,17 +47,25 @@ public function addCommand($command, $prepend = FALSE) { ...@@ -46,17 +47,25 @@ public function addCommand($command, $prepend = FALSE) {
} }
/** /**
* Sets the response's data to be the array of AJAX commands. * {@inheritdoc}
*
* @param Request $request
* A request object.
* *
* @return Response * Sets the response's data to be the array of AJAX commands.
* The current response.
*/ */
public function prepare(Request $request) { public function prepare(Request $request) {
$this->prepareResponse($request);
return $this;
}
/**
* Sets the rendered AJAX right before the response is prepared.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*/
public function prepareResponse(Request $request) {
if ($this->data == '{}') {
$this->setData($this->ajaxRender($request)); $this->setData($this->ajaxRender($request));
return parent::prepare($request); }
} }
/** /**
......
...@@ -369,11 +369,18 @@ protected function getKernelParameters() { ...@@ -369,11 +369,18 @@ protected function getKernelParameters() {
protected function initializeContainer() { protected function initializeContainer() {
$this->containerNeedsDumping = FALSE; $this->containerNeedsDumping = FALSE;
$persist = $this->getServicesToPersist(); $persist = $this->getServicesToPersist();
// If we are rebuilding the kernel and we are in a request scope, store // The request service requires custom persisting logic, since it is also
// request info so we can add them back after the rebuild. // potentially scoped. During Drupal installation, there is a request
if (isset($this->container) && $this->container->hasScope('request')) { // service without a request scope.
$request_scope = FALSE;
if (isset($this->container)) {
if ($this->container->isScopeActive('request')) {
$request_scope = TRUE;
}
if ($this->container->initialized('request')) {
$request = $this->container->get('request'); $request = $this->container->get('request');
} }
}
$this->container = NULL; $this->container = NULL;
$class = $this->getClassName(); $class = $this->getClassName();
$cache_file = $class . '.php'; $cache_file = $class . '.php';
...@@ -445,8 +452,10 @@ protected function initializeContainer() { ...@@ -445,8 +452,10 @@ protected function initializeContainer() {
// Set the class loader which was registered as a synthetic service. // Set the class loader which was registered as a synthetic service.
$this->container->set('class_loader', $this->classLoader); $this->container->set('class_loader', $this->classLoader);
// If we have a request set it back to the new container. // If we have a request set it back to the new container.
if (isset($request)) { if ($request_scope) {
$this->container->enterScope('request'); $this->container->enterScope('request');
}
if (isset($request)) {
$this->container->set('request', $request); $this->container->set('request', $request);
} }
\Drupal::setContainer($this->container); \Drupal::setContainer($this->container);
......
<?php
/**
* @file
* Contains \Drupal\Core\EventSubscriber\AjaxResponseSubscriber.
*/
namespace Drupal\Core\EventSubscriber;
use Drupal\Core\Ajax\AjaxResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
class AjaxResponseSubscriber implements EventSubscriberInterface {
/**
* Renders the ajax commands right before preparing the result.
*
* @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
* The response event, which contains the possible AjaxResponse object.
*/
public function onResponse(FilterResponseEvent $event) {
$response = $event->getResponse();
if ($response instanceof AjaxResponse) {
$response->prepareResponse($event->getRequest());
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::RESPONSE][] = array('onResponse', -100);
return $events;
}
}
...@@ -216,10 +216,10 @@ public function id() { ...@@ -216,10 +216,10 @@ public function id() {
public function preSave(EntityStorageControllerInterface $storage_controller) { public function preSave(EntityStorageControllerInterface $storage_controller) {
parent::preSave($storage_controller); parent::preSave($storage_controller);
global $user; $user = \Drupal::currentUser();
if (!isset($this->status->value)) { if (!isset($this->status->value)) {
$this->status->value = user_access('skip comment approval') ? COMMENT_PUBLISHED : COMMENT_NOT_PUBLISHED; $this->status->value = $user->hasPermission('skip comment approval') ? COMMENT_PUBLISHED : COMMENT_NOT_PUBLISHED;
} }
if ($this->isNew()) { if ($this->isNew()) {
// Add the comment to database. This next section builds the thread field. // Add the comment to database. This next section builds the thread field.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Reference;
use Drupal\Core\Database\Database; use Drupal\Core\Database\Database;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
/** /**
* Base test case class for Drupal unit tests. * Base test case class for Drupal unit tests.
...@@ -188,7 +189,8 @@ public function containerBuild(ContainerBuilder $container) { ...@@ -188,7 +189,8 @@ public function containerBuild(ContainerBuilder $container) {
$definition = $container->getDefinition('path_processor_alias'); $definition = $container->getDefinition('path_processor_alias');
$definition->clearTag('path_processor_inbound')->clearTag('path_processor_outbound'); $definition->clearTag('path_processor_inbound')->clearTag('path_processor_outbound');
} }
$request = Request::create('/');
$this->container->set('request', $request);
} }
/** /**
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
use Drupal\Core\DrupalKernel; use Drupal\Core\DrupalKernel;
use Drupal\Core\Language\Language; use Drupal\Core\Language\Language;
use Drupal\Core\StreamWrapper\PublicStream; use Drupal\Core\StreamWrapper\PublicStream;
use Symfony\Component\HttpFoundation\Request;
/** /**
* Base class for Drupal tests. * Base class for Drupal tests.
...@@ -973,6 +974,10 @@ protected function prepareEnvironment() { ...@@ -973,6 +974,10 @@ protected function prepareEnvironment() {
// Register info parser. // Register info parser.
$this->container->register('info_parser', 'Drupal\Core\Extension\InfoParser'); $this->container->register('info_parser', 'Drupal\Core\Extension\InfoParser');
$request = Request::create('/');
$this->container->set('request', $request);
$this->container->set('current_user', $GLOBALS['user']);
\Drupal::setContainer($this->container); \Drupal::setContainer($this->container);
// Unset globals. // Unset globals.
...@@ -1035,12 +1040,16 @@ protected function prepareConfigDirectories() { ...@@ -1035,12 +1040,16 @@ protected function prepareConfigDirectories() {
* enabled modules to be immediately available in the same request. * enabled modules to be immediately available in the same request.
*/ */
protected function rebuildContainer() { protected function rebuildContainer() {
// Preserve the request object after the container rebuild.
$request = \Drupal::request();
$this->kernel = new DrupalKernel('testing', drupal_classloader(), FALSE); $this->kernel = new DrupalKernel('testing', drupal_classloader(), FALSE);
$this->kernel->boot(); $this->kernel->boot();
// DrupalKernel replaces the container in \Drupal::getContainer() with a // DrupalKernel replaces the container in \Drupal::getContainer() with a
// different object, so we need to replace the instance on this test class. // different object, so we need to replace the instance on this test class.
$this->container = \Drupal::getContainer(); $this->container = \Drupal::getContainer();
// The global $user is set in TestBase::prepareEnvironment(). // The global $user is set in TestBase::prepareEnvironment().
$this->container->set('request', $request);
$this->container->set('current_user', $GLOBALS['user']); $this->container->set('current_user', $GLOBALS['user']);
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
use Drupal\views\ViewExecutable; use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\PluginBase; use Drupal\views\Plugin\views\PluginBase;
use Drupal\views\Views; use Drupal\views\Views;
use Symfony\Component\DependencyInjection\Exception\RuntimeException as DependencyInjectionRuntimeException;
/** /**
* @defgroup views_display_plugins Views display plugins * @defgroup views_display_plugins Views display plugins
...@@ -886,9 +887,16 @@ public function getHandlers($type) { ...@@ -886,9 +887,16 @@ public function getHandlers($type) {
// If this is during form submission and there are temporary options // If this is during form submission and there are temporary options
// which can only appear if the view is in the edit cache, use those // which can only appear if the view is in the edit cache, use those
// options instead. This is used for AJAX multi-step stuff. // options instead. This is used for AJAX multi-step stuff.
if (\Drupal::request()->request->get('form_id') && isset($this->view->temporary_options[$type][$id])) { // @todo Remove dependency on Request object
// https://drupal.org/node/2059003.
try {
$request = \Drupal::request();
if ($request->request->get('form_id') && isset($this->view->temporary_options[$type][$id])) {
$info = $this->view->temporary_options[$type][$id]; $info = $this->view->temporary_options[$type][$id];
} }
}
catch (DependencyInjectionRuntimeException $e) {
}
if ($info['id'] != $id) { if ($info['id'] != $id) {
$info['id'] = $id; $info['id'] = $id;
......
...@@ -81,11 +81,14 @@ public function testPageResponses() { ...@@ -81,11 +81,14 @@ public function testPageResponses() {
$response = $this->container->get('http_kernel')->handle($subrequest, HttpKernelInterface::SUB_REQUEST); $response = $this->container->get('http_kernel')->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
$this->assertEqual($response->getStatusCode(), 200); $this->assertEqual($response->getStatusCode(), 200);
$subrequest = Request::create('/test_page_display_200', 'GET');
\Drupal::getContainer()->set('request', $subrequest);
// Test accessing a disabled page for a view. // Test accessing a disabled page for a view.
$view = views_get_view('test_page_display'); $view = views_get_view('test_page_display');
// Disable the view, rebuild menu, and request the page again. // Disable the view, rebuild menu, and request the page again.
$view->storage->disable()->save(); $view->storage->disable()->save();
$subrequest = Request::create('/test_page_display_200', 'GET');
$response = $this->container->get('http_kernel')->handle($subrequest, HttpKernelInterface::SUB_REQUEST); $response = $this->container->get('http_kernel')->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
$this->assertEqual($response->getStatusCode(), 404); $this->assertEqual($response->getStatusCode(), 404);
} }
......
...@@ -39,6 +39,10 @@ ...@@ -39,6 +39,10 @@
exit; exit;
} }
simpletest_classloader_register(); simpletest_classloader_register();
// We have to add a Request.
$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
$container = \Drupal::getContainer();
$container->set('request', $request);
if ($args['clean']) { if ($args['clean']) {
// Clean up left-over times and directories. // Clean up left-over times and directories.
...@@ -477,8 +481,11 @@ function simpletest_script_run_one_test($test_id, $test_class) { ...@@ -477,8 +481,11 @@ function simpletest_script_run_one_test($test_id, $test_class) {
try { try {
// Bootstrap Drupal. // Bootstrap Drupal.
drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE); drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
simpletest_classloader_register(); simpletest_classloader_register();
// We have to add a Request.
$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
$container = \Drupal::getContainer();
$container->set('request', $request);
// Override configuration according to command line parameters. // Override configuration according to command line parameters.
$conf['simpletest.settings']['verbose'] = $args['verbose']; $conf['simpletest.settings']['verbose'] = $args['verbose'];
......
...@@ -450,13 +450,14 @@ function update_check_requirements($skip_warnings = FALSE) { ...@@ -450,13 +450,14 @@ function update_check_requirements($skip_warnings = FALSE) {
// Determine if the current user has access to run update.php. // Determine if the current user has access to run update.php.
drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES); drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES);
require_once DRUPAL_ROOT . '/' . settings()->get('session_inc', 'core/includes/session.inc');
drupal_session_initialize();
// A request object from the HTTPFoundation to tell us about the request. // A request object from the HTTPFoundation to tell us about the request.
$request = Request::createFromGlobals(); $request = Request::createFromGlobals();
\Drupal::getContainer()->set('request', $request); \Drupal::getContainer()->set('request', $request);
require_once DRUPAL_ROOT . '/' . settings()->get('session_inc', 'core/includes/session.inc');
drupal_session_initialize();
// Ensure that URLs generated for the home and admin pages don't have 'update.php' // Ensure that URLs generated for the home and admin pages don't have 'update.php'
// in them. // in them.
$generator = \Drupal::urlGenerator(); $generator = \Drupal::urlGenerator();
......
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