Commit a32a88cb authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2372389 by znerol, almaudoh: Expose session handler in container

parent 08f02073
Loading
Loading
Loading
Loading
+18 −1
Changes for core/core.services.yml: 18 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -1107,11 +1107,28 @@ services:
  session.attribute_bag:
    class: Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag
    public: false
  session_handler:
    alias: session_handler.storage
  session_handler.storage:
    class: Drupal\Core\Session\SessionHandler
    arguments: ['@request_stack', '@database']
    tags:
      - { name: backend_overridable }
  session_handler.write_check:
    class: Symfony\Component\HttpFoundation\Session\Storage\Handler\WriteCheckSessionHandler
    tags:
      - { name: session_handler_proxy, priority: 100 }
  session_handler.write_safe:
    class: Drupal\Core\Session\WriteSafeSessionHandler
    tags:
      - { name: session_handler_proxy, priority: 150 }
  session_manager:
    class: Drupal\Core\Session\SessionManager
    arguments: ['@request_stack', '@database', '@session_manager.metadata_bag', '@session_configuration']
    arguments: ['@request_stack', '@database', '@session_manager.metadata_bag', '@session_configuration', '@session_handler']
    tags:
      - { name: backend_overridable }
    calls:
      - [setWriteSafeHandler, ['@session_handler.write_safe']]
  session_manager.metadata_bag:
    class: Drupal\Core\Session\MetadataBag
    arguments: ['@settings']
+3 −0
Changes for core/lib/Drupal/Core/CoreServiceProvider.php: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
use Drupal\Core\DependencyInjection\Compiler\RegisterLazyRouteFilters;
use Drupal\Core\DependencyInjection\Compiler\DependencySerializationTraitPass;
use Drupal\Core\DependencyInjection\Compiler\StackedKernelPass;
use Drupal\Core\DependencyInjection\Compiler\StackedSessionHandlerPass;
use Drupal\Core\DependencyInjection\Compiler\RegisterStreamWrappersPass;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
@@ -63,6 +64,8 @@ public function register(ContainerBuilder $container) {

    $container->addCompilerPass(new StackedKernelPass());

    $container->addCompilerPass(new StackedSessionHandlerPass());

    $container->addCompilerPass(new MainContentRenderersPass());

    // Collect tagged handler services as method calls on consumer services.
+51 −0
Changes for core/lib/Drupal/Core/DependencyInjection/Compiler/StackedSessionHandlerPass.php: 51 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Contains \Drupal\Core\DependencyInjection\Compiler\StackedSessionHandlerPass.
 */

namespace Drupal\Core\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Provides a compiler pass for stacked session save handlers.
 */
class StackedSessionHandlerPass implements CompilerPassInterface {

  /**
   * {@inheritdoc}
   */
  public function process(ContainerBuilder $container) {

    if ($container->hasDefinition('session_handler')) {
      return;
    }

    $session_handler_proxies = [];
    $priorities = [];

    foreach ($container->findTaggedServiceIds('session_handler_proxy') as $id => $attributes) {
      $priorities[$id] = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
      $session_handler_proxies[$id] = $container->getDefinition($id);
    }

    array_multisort($priorities, SORT_ASC, $session_handler_proxies);

    $decorated_id = 'session_handler.storage';
    foreach ($session_handler_proxies as $id => $decorator) {
      // Prepend the inner session handler as first constructor argument.
      $arguments = $decorator->getArguments();
      array_unshift($arguments, new Reference($decorated_id));
      $decorator->setArguments($arguments);

      $decorated_id = $id;
    }

    $container->setAlias('session_handler', $decorated_id);
  }

}
+13 −12
Changes for core/lib/Drupal/Core/Session/SessionManager.php: 13 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Database\Connection;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\WriteCheckSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;

/**
@@ -63,10 +62,8 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
  /**
   * The write safe session handler.
   *
   * @todo: The write safe session handler should be exposed in the
   *   container and this reference should be removed once all database queries
   * @todo: This reference should be removed once all database queries
   *   are removed from the session manager class.
   * @see https://www.drupal.org/node/2372389
   *
   * @var \Drupal\Core\Session\WriteSafeSessionHandlerInterface
   */
@@ -83,20 +80,17 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
   *   The session metadata bag.
   * @param \Drupal\Core\Session\SessionConfigurationInterface $session_configuration
   *   The session configuration interface.
   * @param \Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy|Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler|\SessionHandlerInterface|NULL $handler
   *   The object to register as a PHP session handler.
   *   @see \Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage::setSaveHandler()
   */
  public function __construct(RequestStack $request_stack, Connection $connection, MetadataBag $metadata_bag, SessionConfigurationInterface $session_configuration) {
  public function __construct(RequestStack $request_stack, Connection $connection, MetadataBag $metadata_bag, SessionConfigurationInterface $session_configuration, $handler = NULL) {
    $options = array();
    $this->sessionConfiguration = $session_configuration;
    $this->requestStack = $request_stack;
    $this->connection = $connection;

    // Register the default session handler.
    // @todo Extract session storage from session handler into a service.
    $save_handler = new SessionHandler($this->requestStack, $this->connection);
    $write_check_handler = new WriteCheckSessionHandler($save_handler);
    $this->writeSafeHandler = new WriteSafeSessionHandler($write_check_handler);

    parent::__construct($options, $this->writeSafeHandler, $metadata_bag);
    parent::__construct($options, $handler, $metadata_bag);

    // @todo When not using the Symfony Session object, the list of bags in the
    //   NativeSessionStorage will remain uninitialized. This will lead to
@@ -292,6 +286,13 @@ public function enable() {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setWriteSafeHandler(WriteSafeSessionHandlerInterface $handler) {
    $this->writeSafeHandler = $handler;
  }

  /**
   * Returns whether the current PHP process runs on CLI.
   *
+19 −0
Changes for core/lib/Drupal/Core/Session/SessionManagerInterface.php: 19 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ public function delete($uid);
   *
   * @return bool
   *   FALSE if writing session data has been disabled. TRUE otherwise.
   *
   * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.0.0
   *   Use \Drupal\Core\Session\WriteSafeSessionHandler::isSessionWritable()
   */
  public function isEnabled();

@@ -40,6 +43,9 @@ public function isEnabled();
   * @see https://drupal.org/node/218104
   *
   * @return $this
   *
   * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.0.0
   *   Use \Drupal\Core\Session\WriteSafeSessionHandler::setSessionWritable(FALSE)
   */
  public function disable();

@@ -47,7 +53,20 @@ public function disable();
   * Re-enables saving of session data.
   *
   * @return $this
   *
   * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.0.0
   *   Use \Drupal\Core\Session\WriteSafeSessionHandler::setSessionWritable(True)
   */
  public function enable();

  /**
   * Sets the write safe session handler.
   *
   * @todo: This should be removed once all database queries are removed from
   *   the session manager class.
   *
   * @var \Drupal\Core\Session\WriteSafeSessionHandlerInterface
   */
  public function setWriteSafeHandler(WriteSafeSessionHandlerInterface $handler);

}
Loading