diff --git a/core/authorize.php b/core/authorize.php index d033b7e..dbab02f 100644 --- a/core/authorize.php +++ b/core/authorize.php @@ -51,7 +51,6 @@ * TRUE if the current user can run authorize.php, and FALSE if not. */ function authorize_access_allowed() { - \Drupal::service('session_manager')->start(); return Settings::get('allow_authorize_operations', TRUE) && \Drupal::currentUser()->hasPermission('administer software updates'); } diff --git a/core/core.services.yml b/core/core.services.yml index 9f5d6fc..9fe8324 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -475,6 +475,11 @@ services: arguments: ['@kernel'] tags: - { name: http_middleware, priority: 100 } + http_middleware.session: + class: Drupal\Core\StackMiddleware\Session + arguments: ['@session'] + tags: + - { name: http_middleware, priority: 50 } language_manager: class: Drupal\Core\Language\LanguageManager arguments: ['@language.default'] @@ -993,7 +998,7 @@ services: arguments: ['@module_handler', '@cache.discovery', '@language_manager', '@cache_tags.invalidator'] batch.storage: class: Drupal\Core\Batch\BatchStorage - arguments: ['@database', '@session_manager', '@csrf_token'] + arguments: ['@database', '@session', '@csrf_token'] tags: - { name: backend_overridable } replica_database_ignore__subscriber: @@ -1089,6 +1094,15 @@ services: session_configuration: class: Drupal\Core\Session\SessionConfiguration arguments: ['%session.storage.options%'] + session: + class: Symfony\Component\HttpFoundation\Session\Session + arguments: ['@session_manager', '@session.attribute_bag', '@session.flash_bag'] + session.flash_bag: + class: Symfony\Component\HttpFoundation\Session\Flash\FlashBag + public: false + session.attribute_bag: + class: Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag + public: false session_manager: class: Drupal\Core\Session\SessionManager arguments: ['@request_stack', '@database', '@session_manager.metadata_bag', '@session_configuration'] diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index f98c64d..34187f2 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -21,9 +21,11 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Url; use Drupal\language\Entity\ConfigurableLanguage; +use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Route; use GuzzleHttp\Exception\RequestException; @@ -396,7 +398,6 @@ function install_begin_request($class_loader, &$install_state) { $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'])) { @@ -442,13 +443,15 @@ function install_begin_request($class_loader, &$install_state) { if ($profile && !$module_handler->moduleExists($profile)) { $module_handler->addProfile($profile, $install_state['profiles'][$profile]->getPath()); } - // After setting up a custom and finite module list in a custom low-level - // bootstrap like here, ensure to use ModuleHandler::loadAll() so that - // ModuleHandler::isLoaded() returns TRUE, since that is a condition being - // checked by other subsystems (e.g., the theme system). - $module_handler->loadAll(); - $kernel->prepareLegacyRequest($request); + // Load all modules and perform request related initialization. + $kernel->preHandle($request); + + // Initialize a route on this legacy request similar to + // \Drupal\Core\DrupalKernel::prepareLegacyRequest() since normal routing + // will not happen. + $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route('')); + $request->attributes->set(RouteObjectInterface::ROUTE_NAME, ''); // Prepare for themed output. We need to run this at the beginning of the // page request to avoid a different theme accidentally getting set. (We also @@ -593,7 +596,7 @@ function install_run_task($task, &$install_state) { $response = batch_process($url, clone $url); if ($response instanceof Response) { // Save $_SESSION data from batch. - \Drupal::service('session_manager')->save(); + \Drupal::service('session')->save(); // Send the response. $response->send(); exit; @@ -1548,7 +1551,7 @@ function install_load_profile(&$install_state) { * An array of information about the current installation state. */ function install_bootstrap_full() { - \Drupal::service('session_manager')->start(); + \Drupal::service('session')->start(); } /** diff --git a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php index 5f88c47..e36275f 100644 --- a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php +++ b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php @@ -18,27 +18,10 @@ class Cookie implements AuthenticationProviderInterface { /** - * The session manager. - * - * @var \Drupal\Core\Session\SessionManagerInterface - */ - protected $sessionManager; - - /** - * Constructs a new Cookie authentication provider instance. - * - * @param \Drupal\Core\Session\SessionManagerInterface $session_manager - * The session manager. - */ - public function __construct(SessionManagerInterface $session_manager) { - $this->sessionManager = $session_manager; - } - - /** * {@inheritdoc} */ public function applies(Request $request) { - return TRUE; + return $request->hasSession(); } /** @@ -47,10 +30,11 @@ public function applies(Request $request) { public function authenticate(Request $request) { // Global $user is deprecated, but the session system is still based on it. global $user; - $this->sessionManager->start(); - if ($this->sessionManager->isStarted()) { + + if ($request->getSession()->start()) { return $user; } + return NULL; } @@ -58,7 +42,6 @@ public function authenticate(Request $request) { * {@inheritdoc} */ public function cleanup(Request $request) { - $this->sessionManager->save(); } /** diff --git a/core/lib/Drupal/Core/Batch/BatchStorage.php b/core/lib/Drupal/Core/Batch/BatchStorage.php index da0fe94..5742fd2 100644 --- a/core/lib/Drupal/Core/Batch/BatchStorage.php +++ b/core/lib/Drupal/Core/Batch/BatchStorage.php @@ -8,7 +8,7 @@ namespace Drupal\Core\Batch; use Drupal\Core\Database\Connection; -use Drupal\Core\Session\SessionManager; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Drupal\Core\Access\CsrfTokenGenerator; class BatchStorage implements BatchStorageInterface { @@ -21,11 +21,11 @@ class BatchStorage implements BatchStorageInterface { protected $connection; /** - * The session manager. + * The session. * - * @var \Drupal\Core\Session\SessionManager + * @var \Symfony\Component\HttpFoundation\Session\SessionInterface */ - protected $sessionManager; + protected $session; /** * The CSRF token generator. @@ -39,14 +39,14 @@ class BatchStorage implements BatchStorageInterface { * * @param \Drupal\Core\Database\Connection $connection * The database connection. - * @param \Drupal\Core\Session\SessionManager $session_manager - * The session manager. + * @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session + * The session. * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token * The CSRF token generator. */ - public function __construct(Connection $connection, SessionManager $session_manager, CsrfTokenGenerator $csrf_token) { + public function __construct(Connection $connection, SessionInterface $session, CsrfTokenGenerator $csrf_token) { $this->connection = $connection; - $this->sessionManager = $session_manager; + $this->session = $session; $this->csrfToken = $csrf_token; } @@ -55,7 +55,7 @@ public function __construct(Connection $connection, SessionManager $session_mana */ public function load($id) { // Ensure that a session is started before using the CSRF token generator. - $this->sessionManager->start(); + $this->session->start(); $batch = $this->connection->query("SELECT batch FROM {batch} WHERE bid = :bid AND token = :token", array( ':bid' => $id, ':token' => $this->csrfToken->get($id), @@ -100,7 +100,7 @@ public function cleanup() { */ public function create(array $batch) { // Ensure that a session is started before using the CSRF token generator. - $this->sessionManager->start(); + $this->session->start(); $this->connection->insert('batch') ->fields(array( 'bid' => $batch['id'], diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index bc36c15..bfa2c98 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -571,8 +571,9 @@ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = public function prepareLegacyRequest(Request $request) { $this->boot(); $this->preHandle($request); - // Enter the request scope so that current_user service is available for - // locale/translation sake. + // Setup services which are normally initialized from within stack + // middleware or during the request kernel event. + $request->setSession($this->container->get('session')); $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route('')); $request->attributes->set(RouteObjectInterface::ROUTE_NAME, ''); $this->container->get('request_stack')->push($request); @@ -718,6 +719,16 @@ protected function initializeContainer($rebuild = FALSE) { if ($session_manager_started) { $this->container->get('session_manager')->start(); } + + // The request stack is preserved accross container rebuilds. Reinject the + // new session into the master request if one was present before. + if (($request_stack = $this->container->get('request_stack', ContainerInterface::NULL_ON_INVALID_REFERENCE))) { + if ($request = $request_stack->getMasterRequest()) { + if ($request->hasSession()) { + $request->setSession($this->container->get('session')); + } + } + } \Drupal::setContainer($this->container); // If needs dumping flag was set, dump the container. diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index 62c464d..a767326 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -650,9 +650,9 @@ protected function initializeTranslation($langcode) { $translation->translations = &$this->translations; $translation->enforceIsNew = &$this->enforceIsNew; $translation->translationInitialize = FALSE; - // Reset language-dependent properties. + // The label is the only entity key that can change based on the language, + // so unset that in case it is currently set. unset($translation->entityKeys['label']); - $translation->typedData = NULL; return $translation; } diff --git a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php index 9535abf..f757aa7 100644 --- a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php @@ -111,6 +111,11 @@ protected function makeSubrequest(GetResponseForExceptionEvent $event, $path, $s // Persist the 'exception' attribute to the subrequest. $sub_request->attributes->set('exception', $request->attributes->get('exception')); + // Carry over the session to the subrequest. + if ($session = $request->getSession()) { + $sub_request->setSession($session); + } + $response = $this->httpKernel->handle($sub_request, HttpKernelInterface::SUB_REQUEST); $response->setStatusCode($status_code); $event->setResponse($response); diff --git a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php index 96b5e73..83a7845 100644 --- a/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php +++ b/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php @@ -59,9 +59,6 @@ public function register(ContainerBuilder $container) { // @todo Convert installer steps into routes; add an installer.routing.yml. $definition = $container->getDefinition('router.builder'); $definition->setClass('Drupal\Core\Installer\InstallerRouteBuilder'); - - // Remove dependencies on Drupal's default session handling. - $container->removeDefinition('authentication.cookie'); } /** diff --git a/core/lib/Drupal/Core/Session/SessionManager.php b/core/lib/Drupal/Core/Session/SessionManager.php index c354cec..2a143b7 100644 --- a/core/lib/Drupal/Core/Session/SessionManager.php +++ b/core/lib/Drupal/Core/Session/SessionManager.php @@ -338,7 +338,7 @@ protected function getSessionDataMask() { // Ignore attribute bags when they do not contain any data. foreach ($this->bags as $bag) { $key = $bag->getStorageKey(); - $mask[$key] = empty($_SESSION[$key]); + $mask[$key] = !empty($_SESSION[$key]); } return array_intersect_key($mask, $_SESSION); diff --git a/core/lib/Drupal/Core/StackMiddleware/Session.php b/core/lib/Drupal/Core/StackMiddleware/Session.php new file mode 100644 index 0000000..b45a16e --- /dev/null +++ b/core/lib/Drupal/Core/StackMiddleware/Session.php @@ -0,0 +1,63 @@ +httpKernel = $http_kernel; + $this->session = $session; + } + + /** + * {@inheritdoc} + */ + public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) { + if ($type === self::MASTER_REQUEST) { + $request->setSession($this->session); + } + + $result = $this->httpKernel->handle($request, $type, $catch); + + if ($type === self::MASTER_REQUEST && $request->hasSession()) { + $request->getSession()->save(); + } + + return $result; + } + +} diff --git a/core/modules/comment/src/Controller/CommentController.php b/core/modules/comment/src/Controller/CommentController.php index 84fbf72..69be36a 100644 --- a/core/modules/comment/src/Controller/CommentController.php +++ b/core/modules/comment/src/Controller/CommentController.php @@ -130,6 +130,10 @@ public function commentPermalink(Request $request, CommentInterface $comment) { // @todo: Cleaner sub request handling. $redirect_request = Request::create($entity->url(), 'GET', $request->query->all(), $request->cookies->all(), array(), $request->server->all()); $redirect_request->query->set('page', $page); + // Carry over the session to the subrequest. + if ($session = $request->getSession()) { + $redirect_request->setSession($session); + } // @todo: Convert the pager to use the request object. $request->query->set('page', $page); return $this->httpKernel->handle($redirect_request, HttpKernelInterface::SUB_REQUEST); diff --git a/core/modules/migrate/src/Entity/Migration.php b/core/modules/migrate/src/Entity/Migration.php index ba563f1..f07ba40 100644 --- a/core/modules/migrate/src/Entity/Migration.php +++ b/core/modules/migrate/src/Entity/Migration.php @@ -14,6 +14,7 @@ use Drupal\migrate\MigrateSkipRowException; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\Plugin\RequirementsInterface; +use Drupal\Component\Utility\NestedArray; /** * Defines the Migration entity. @@ -406,6 +407,19 @@ public function setProcess(array $process) { /** * {@inheritdoc} */ + public function setProcessOfProperty($field_name, $process, $merge = TRUE) { + if (isset($this->process[$field_name]) && is_array($process) && $merge) { + $this->process = NestedArray::mergeDeepArray([$this->process, [$field_name => $process]], TRUE); + } + else { + $this->process[$field_name] = $process; + } + return $this; + } + + /** + * {@inheritdoc} + */ public function getSystemOfRecord() { return $this->systemOfRecord; } diff --git a/core/modules/migrate/src/Entity/MigrationInterface.php b/core/modules/migrate/src/Entity/MigrationInterface.php index 09cc770..ca9ac03 100644 --- a/core/modules/migrate/src/Entity/MigrationInterface.php +++ b/core/modules/migrate/src/Entity/MigrationInterface.php @@ -198,6 +198,23 @@ public function getProcess(); public function setProcess(array $process); /** + * Set the process for an individual destination field. + * + * @param string $field_name + * The field name of which to set the process. + * @param array $process + * An array of process data. + * @param boolean $merge + * (optional) TRUE if we should merge the process arrays otherwise FALSE. + * + * @return $this + * The migration entity. + * + * @see Drupal\migrate_drupal\Plugin\migrate\load\LoadEntity::processLinkField(). + */ + public function setProcessOfProperty($field_name, $process, $merge = TRUE); + + /** * Get the current system of record of the migration. * * @return string diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/load/LoadEntity.php b/core/modules/migrate_drupal/src/Plugin/migrate/load/LoadEntity.php index c9db0e7..7de8883 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/load/LoadEntity.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/load/LoadEntity.php @@ -98,9 +98,7 @@ public function loadMultiple(EntityStorageInterface $storage, array $sub_ids = N $this->processTextField($field_name, $data, $migration); break; default: - $process = $migration->getProcess(); - $process[$field_name] = $field_name; - $migration->setProcess($process); + $migration->setProcessOfProperty($field_name, $field_name); } } } @@ -134,12 +132,11 @@ protected function processTextField($field_name, $field_data, MigrationInterface $value_key = $field_data['db_storage'] ? $field_name : "$field_name/value"; $format_key = $field_data['db_storage'] ? $field_name . '_format' : "$field_name/format" ; - $process = $migration->getProcess(); + $migration->setProcessOfProperty("$field_name/value", $value_key); - $process["$field_name/value"] = $value_key; // See d6_user, signature_format for an example of the YAML that // represents this process array. - $process["$field_name/format"] = [ + $process = [ [ 'plugin' => 'static_map', 'bypass' => TRUE, @@ -153,8 +150,7 @@ protected function processTextField($field_name, $field_data, MigrationInterface 'source' => $format_key, ], ]; - - $migration->setProcess($process); + $migration->setProcessOfProperty("$field_name/format", $process); } /** @@ -168,8 +164,7 @@ protected function processTextField($field_name, $field_data, MigrationInterface * The migration entity. */ protected function processFileField($field_name, $field_data, MigrationInterface $migration) { - $process = $migration->getProcess(); - $process[$field_name] = [ + $process = [ 'plugin' => 'd6_cck_file', 'source' => [ $field_name, @@ -177,7 +172,7 @@ protected function processFileField($field_name, $field_data, MigrationInterface $field_name . '_data', ], ]; - $migration->setProcess($process); + $migration->setProcessOfProperty($field_name, $process); } /** @@ -193,8 +188,7 @@ protected function processFileField($field_name, $field_data, MigrationInterface protected function processLinkField($field_name, $field_data, MigrationInterface $migration) { // Specifically process the link field until core is fixed. // @see https://www.drupal.org/node/2235457 - $process = $migration->getProcess(); - $process[$field_name] = [ + $process = [ 'plugin' => 'd6_cck_link', 'source' => [ $field_name, @@ -202,7 +196,7 @@ protected function processLinkField($field_name, $field_data, MigrationInterface $field_name . '_attributes', ], ]; - $migration->setProcess($process); + $migration->setProcessOfProperty($field_name, $process); } } diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationTest.php index 65bb740..2e8a3b3 100644 --- a/core/modules/system/src/Tests/Entity/EntityTranslationTest.php +++ b/core/modules/system/src/Tests/Entity/EntityTranslationTest.php @@ -7,7 +7,6 @@ namespace Drupal\system\Tests\Entity; -use Drupal\Component\Utility\String; use Drupal\Core\Language\LanguageInterface; use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\language\Entity\ConfigurableLanguage; @@ -666,28 +665,4 @@ protected function doTestLanguageChange($entity_type) { } } - /** - * Tests how entity adapters work with translations. - */ - function testEntityAdapter() { - $entity_type = 'entity_test'; - $default_langcode = 'en'; - $values[$default_langcode] = array('name' => $this->randomString()); - $controller = $this->entityManager->getStorage($entity_type); - /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ - $entity = $controller->create($values[$default_langcode]); - - foreach ($this->langcodes as $langcode) { - $values[$langcode] = array('name' => $this->randomString()); - $entity->addTranslation($langcode, $values[$langcode]); - } - - $langcodes = array_merge(array($default_langcode), $this->langcodes); - foreach ($langcodes as $langcode) { - $adapter = $entity->getTranslation($langcode)->getTypedData(); - $name = $adapter->get('name')->value; - $this->assertEqual($name, $values[$langcode]['name'], String::format('Name correctly retrieved from "@langcode" adapter', array('@langcode' => $langcode))); - } - } - } diff --git a/core/modules/system/tests/modules/session_test/session_test.services.yml b/core/modules/system/tests/modules/session_test/session_test.services.yml index 281b09d..8ef2e20 100644 --- a/core/modules/system/tests/modules/session_test/session_test.services.yml +++ b/core/modules/system/tests/modules/session_test/session_test.services.yml @@ -1,6 +1,5 @@ services: session_test.subscriber: class: Drupal\session_test\EventSubscriber\SessionTestSubscriber - arguments: ['@session_manager'] tags: - { name: event_subscriber } diff --git a/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php b/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php index 9029093..a17cd5a 100644 --- a/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php +++ b/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php @@ -7,7 +7,6 @@ namespace Drupal\session_test\EventSubscriber; -use Drupal\Core\Session\SessionManagerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\KernelEvents; @@ -20,13 +19,6 @@ class SessionTestSubscriber implements EventSubscriberInterface { /** - * The session manager. - * - * @var \Drupal\Core\Session\SessionManagerInterface - */ - protected $sessionManager; - - /** * Stores whether $_SESSION is empty at the beginning of the request. * * @var bool @@ -34,20 +26,14 @@ class SessionTestSubscriber implements EventSubscriberInterface { protected $emptySession; /** - * Constructs a new session test subscriber. - */ - public function __construct(SessionManagerInterface $session_manager) { - $this->sessionManager = $session_manager; - } - - /** * Set header for session testing. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event * The Event to process. */ public function onKernelRequestSessionTest(GetResponseEvent $event) { - $this->emptySession = (int) !$this->sessionManager->start(); + $session = $event->getRequest()->getSession(); + $this->emptySession = (int) !($session && $session->start()); } /** diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index 8be2e5e..a2c3a47 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -128,7 +128,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { if ($this->pass->value != $this->original->pass->value) { $session_manager->delete($this->id()); if ($this->id() == \Drupal::currentUser()->id()) { - $session_manager->regenerate(); + \Drupal::service('session')->migrate(); } } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 86c063d..e09ff03 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -609,7 +609,7 @@ function user_login_finalize(UserInterface $account) { // This is called before hook_user_login() in case one of those functions // fails or incorrectly does a redirect which would leave the old session // in place. - \Drupal::service('session_manager')->regenerate(); + \Drupal::service('session')->migrate(); \Drupal::moduleHandler()->invokeAll('user_login', array($account)); } @@ -840,7 +840,7 @@ function _user_cancel($edit, $account, $method) { function _user_cancel_session_regenerate() { // Regenerate the users session instead of calling session_destroy() as we // want to preserve any messages that might have been set. - \Drupal::service('session_manager')->regenerate(); + \Drupal::service('session')->migrate(); } /** @@ -1484,6 +1484,10 @@ function user_logout() { \Drupal::moduleHandler()->invokeAll('user_logout', array($user)); // Destroy the current session, and reset $user to the anonymous user. + // Note: In Symfony the session is intended to be destroyed with + // Session::invalidate(). Regrettably this method is currently broken and may + // lead to the creation of spurious session records in the database. + // @see https://github.com/symfony/symfony/issues/12375 session_destroy(); } diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml index 3b6e451..8a4f4f0 100644 --- a/core/modules/user/user.services.yml +++ b/core/modules/user/user.services.yml @@ -17,7 +17,6 @@ services: - { name: access_check, applies_to: _user_is_logged_in } authentication.cookie: class: Drupal\Core\Authentication\Provider\Cookie - arguments: ['@session_manager'] tags: - { name: authentication_provider, priority: 0 } cache_context.user: