feature #21625 Remove some container injections in favor of service locators (nicolas-grekas, chalasr)
This PR was merged into the 3.3-dev branch. Discussion ---------- Remove some container injections in favor of service locators | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | https://github.com/symfony/symfony/pull/21553#issuecomment-279214666 | License | MIT | Doc PR | n/a Commits -------8293b753cf
Replace some container injections by service locators0be9ea8ba1
[EventDispatcher] Fix abstract event subscribers registration
This commit is contained in:
commit
77f7a47dc5
@ -71,11 +71,22 @@ FrameworkBundle
|
||||
deprecated and will be removed in 4.0. Use the `Symfony\Component\Form\DependencyInjection\FormPass`
|
||||
class instead.
|
||||
|
||||
* The `Symfony\Bundle\FrameworkBundle\EventListener\SessionListener` class has been
|
||||
deprecated and will be removed in 4.0. Use the `Symfony\Component\HttpKernel\EventListener\SessionListener`
|
||||
class instead.
|
||||
|
||||
* The `Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListener` class has been
|
||||
deprecated and will be removed in 4.0. Use the `Symfony\Component\HttpKernel\EventListener\TestSessionListener`
|
||||
class instead.
|
||||
|
||||
HttpKernel
|
||||
-----------
|
||||
|
||||
* The `Psr6CacheClearer::addPool()` method has been deprecated. Pass an array of pools indexed
|
||||
by name to the constructor instead.
|
||||
|
||||
* The `LazyLoadingFragmentHandler::addRendererService()` method has been deprecated and
|
||||
will be removed in 4.0.
|
||||
|
||||
Process
|
||||
-------
|
||||
@ -127,6 +138,12 @@ TwigBridge
|
||||
* The `TwigRendererEngine::setEnvironment()` method has been deprecated and will be removed
|
||||
in 4.0. Pass the Twig Environment as second argument of the constructor instead.
|
||||
|
||||
TwigBundle
|
||||
----------
|
||||
|
||||
* The `ContainerAwareRuntimeLoader` class has been deprecated and will be removed in 4.0.
|
||||
Use the Twig `Twig_ContainerRuntimeLoader` class instead.
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
|
@ -188,6 +188,13 @@ FrameworkBundle
|
||||
* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass` class has been
|
||||
removed. Use the `Symfony\Component\Form\DependencyInjection\FormPass` class instead.
|
||||
|
||||
* The `Symfony\Bundle\FrameworkBundle\EventListener\SessionListener` class has been removed.
|
||||
Use the `Symfony\Component\HttpKernel\EventListener\SessionListener` class instead.
|
||||
|
||||
* The `Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListener` class has been
|
||||
removed. Use the `Symfony\Component\HttpKernel\EventListener\TestSessionListener`
|
||||
class instead.
|
||||
|
||||
HttpFoundation
|
||||
---------------
|
||||
|
||||
@ -229,6 +236,8 @@ HttpKernel
|
||||
|
||||
* The `Psr6CacheClearer::addPool()` method has been removed. Pass an array of pools indexed
|
||||
by name to the constructor instead.
|
||||
|
||||
* The `LazyLoadingFragmentHandler::addRendererService()` method has been removed.
|
||||
|
||||
Ldap
|
||||
----
|
||||
@ -285,6 +294,12 @@ Translation
|
||||
|
||||
* Removed the backup feature from the file dumper classes.
|
||||
|
||||
TwigBundle
|
||||
----------
|
||||
|
||||
* The `ContainerAwareRuntimeLoader` class has been removed. Use the
|
||||
Twig `Twig_ContainerRuntimeLoader` class instead.
|
||||
|
||||
TwigBridge
|
||||
----------
|
||||
|
||||
|
@ -15,6 +15,8 @@ CHANGELOG
|
||||
* Added configurable paths for validation files
|
||||
* Deprecated `SerializerPass`, use `Symfony\Component\Serializer\DependencyInjection\SerializerPass` instead
|
||||
* Deprecated `FormPass`, use `Symfony\Component\Form\DependencyInjection\FormPass` instead
|
||||
* Deprecated `SessionListener`
|
||||
* Deprecated `TestSessionListener`
|
||||
|
||||
3.2.0
|
||||
-----
|
||||
|
@ -12,31 +12,16 @@
|
||||
namespace Symfony\Bundle\FrameworkBundle\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\EventListener\SessionListener as BaseSessionListener;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
@trigger_error(sprintf('The %s class is deprecated since version 3.3 and will be removed in 4.0. Use %s instead.', SessionListener::class, BaseSessionListener::class), E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Sets the session in the request.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0. Use {@link BaseSessionListener} instead
|
||||
*/
|
||||
class SessionListener extends BaseSessionListener
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
protected function getSession()
|
||||
{
|
||||
if (!$this->container->has('session')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->container->get('session');
|
||||
}
|
||||
}
|
||||
|
@ -11,15 +11,19 @@
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\EventListener\TestSessionListener as BaseTestSessionListener;
|
||||
@trigger_error(sprintf('The %s class is deprecated since version 3.3 and will be removed in 4.0. Use Symfony\Component\HttpKernel\EventListener\TestSessionListener instead.', TestSessionListener::class), E_USER_DEPRECATED);
|
||||
|
||||
use Symfony\Component\HttpKernel\EventListener\AbstractTestSessionListener;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* TestSessionListener.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
class TestSessionListener extends BaseTestSessionListener
|
||||
class TestSessionListener extends AbstractTestSessionListener
|
||||
{
|
||||
protected $container;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<services>
|
||||
<service id="fragment.handler" class="Symfony\Component\HttpKernel\DependencyInjection\LazyLoadingFragmentHandler">
|
||||
<argument type="service" id="service_container" />
|
||||
<argument /> <!-- fragment renderer locator -->
|
||||
<argument type="service" id="request_stack" />
|
||||
<argument>%kernel.debug%</argument>
|
||||
</service>
|
||||
|
@ -47,9 +47,11 @@
|
||||
|
||||
<service id="session.handler.write_check" class="Symfony\Component\HttpFoundation\Session\Storage\Handler\WriteCheckSessionHandler" public="false" />
|
||||
|
||||
<service id="session_listener" class="Symfony\Bundle\FrameworkBundle\EventListener\SessionListener">
|
||||
<service id="session_listener" class="Symfony\Component\HttpKernel\EventListener\SessionListener">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
<argument type="service" id="service_container" />
|
||||
<argument type="service-locator">
|
||||
<argument key="session" type="service" id="session" on-invalid="null" />
|
||||
</argument>
|
||||
</service>
|
||||
|
||||
<service id="session.save_listener" class="Symfony\Component\HttpKernel\EventListener\SaveSessionListener">
|
||||
|
@ -20,9 +20,11 @@
|
||||
|
||||
<service id="test.client.cookiejar" class="Symfony\Component\BrowserKit\CookieJar" shared="false" />
|
||||
|
||||
<service id="test.session.listener" class="Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListener">
|
||||
<argument type="service" id="service_container" />
|
||||
<service id="test.session.listener" class="Symfony\Component\HttpKernel\EventListener\TestSessionListener">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
<argument type="service-locator">
|
||||
<argument key="session" type="service" id="session" on-invalid="null" />
|
||||
</argument>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* Deprecated `ContainerAwareRuntimeLoader`
|
||||
|
||||
2.7.0
|
||||
-----
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Bundle\TwigBundle;
|
||||
|
||||
@trigger_error(sprintf('The %s class is deprecated since version 3.3 and will be removed in 4.0. Use the Twig_ContainerRuntimeLoader class instead.'), ContainerAwareRuntimeLoader::class);
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
@ -18,6 +20,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
* Loads Twig extension runtimes via the service container.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since version 3.3, will be removed in 4.0. Use \Twig_ContainerRuntimeLoader instead.
|
||||
*/
|
||||
class ContainerAwareRuntimeLoader implements \Twig_RuntimeLoaderInterface
|
||||
{
|
||||
|
@ -11,9 +11,10 @@
|
||||
|
||||
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Registers Twig runtime services.
|
||||
@ -31,17 +32,13 @@ class RuntimeLoaderPass implements CompilerPassInterface
|
||||
foreach ($container->findTaggedServiceIds('twig.runtime') as $id => $attributes) {
|
||||
$def = $container->getDefinition($id);
|
||||
|
||||
if (!$def->isPublic()) {
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" must be public as it can be lazy-loaded.', $id));
|
||||
}
|
||||
|
||||
if ($def->isAbstract()) {
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as it can be lazy-loaded.', $id));
|
||||
continue;
|
||||
}
|
||||
|
||||
$mapping[$def->getClass()] = $id;
|
||||
$mapping[$def->getClass()] = new Reference($id);
|
||||
}
|
||||
|
||||
$definition->replaceArgument(1, $mapping);
|
||||
$definition->replaceArgument(0, new ServiceLocatorArgument($mapping));
|
||||
}
|
||||
}
|
||||
|
@ -138,10 +138,8 @@
|
||||
<argument /> <!-- thousands separator, set in TwigExtension -->
|
||||
</service>
|
||||
|
||||
<service id="twig.runtime_loader" class="Symfony\Bundle\TwigBundle\ContainerAwareRuntimeLoader" public="false">
|
||||
<argument type="service" id="service_container" />
|
||||
<argument type="collection" /> <!-- the mapping between class names and service names -->
|
||||
<argument type="service" id="logger" on-invalid="null" />
|
||||
<service id="twig.runtime_loader" class="Twig_ContainerRuntimeLoader" public="false">
|
||||
<argument /> <!-- runtime locator -->
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
@ -15,6 +15,9 @@ use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Bundle\TwigBundle\ContainerAwareRuntimeLoader;
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
class ContainerAwareRuntimeLoaderTest extends TestCase
|
||||
{
|
||||
public function testLoad()
|
||||
|
@ -244,7 +244,7 @@ class TwigExtensionTest extends TestCase
|
||||
$container->compile();
|
||||
|
||||
$loader = $container->getDefinition('twig.runtime_loader');
|
||||
$args = $loader->getArgument(1);
|
||||
$args = $loader->getArgument(0)->getValues();
|
||||
$this->assertArrayHasKey('Symfony\Bridge\Twig\Form\TwigRenderer', $args);
|
||||
$this->assertArrayHasKey('FooClass', $args);
|
||||
$this->assertContains('twig.form.renderer', $args);
|
||||
|
@ -21,7 +21,7 @@
|
||||
"symfony/twig-bridge": "^3.2.1",
|
||||
"symfony/http-foundation": "~2.8|~3.0",
|
||||
"symfony/http-kernel": "~2.8.16|~3.1.9|^3.2.2",
|
||||
"twig/twig": "~1.28|~2.0"
|
||||
"twig/twig": "^1.32|^2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/asset": "~2.8|~3.0",
|
||||
|
@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Compiler pass to register tagged services for an event dispatcher.
|
||||
@ -105,8 +106,8 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
}
|
||||
$container->addObjectResource($class);
|
||||
|
||||
$r = new \ReflectionClass($class);
|
||||
$extractingDispatcher->addSubscriber($r->newInstanceWithoutConstructor());
|
||||
ExtractingEventDispatcher::$subscriber = $class;
|
||||
$extractingDispatcher->addSubscriber($extractingDispatcher);
|
||||
foreach ($extractingDispatcher->listeners as $args) {
|
||||
$args[1] = new ClosureProxyArgument($id, $args[1]);
|
||||
$definition->addMethodCall('addListener', $args);
|
||||
@ -119,12 +120,21 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ExtractingEventDispatcher extends EventDispatcher
|
||||
class ExtractingEventDispatcher extends EventDispatcher implements EventSubscriberInterface
|
||||
{
|
||||
public $listeners = array();
|
||||
|
||||
public static $subscriber;
|
||||
|
||||
public function addListener($eventName, $listener, $priority = 0)
|
||||
{
|
||||
$this->listeners[] = array($eventName, $listener[1], $priority);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
$callback = array(self::$subscriber, 'getSubscribedEvents');
|
||||
|
||||
return $callback();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,13 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* Deprecated `LazyLoadingFragmentHandler::addRendererService()`
|
||||
* Added `SessionListener`
|
||||
* Added `TestSessionListener`
|
||||
|
||||
3.2.0
|
||||
-----
|
||||
|
||||
|
@ -11,9 +11,11 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface;
|
||||
|
||||
/**
|
||||
@ -43,14 +45,11 @@ class FragmentRendererPass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition($this->handlerService);
|
||||
$renderers = array();
|
||||
foreach ($container->findTaggedServiceIds($this->rendererTag) as $id => $tags) {
|
||||
$def = $container->getDefinition($id);
|
||||
if (!$def->isPublic()) {
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" must be public as fragment renderer are lazy-loaded.', $id));
|
||||
}
|
||||
|
||||
if ($def->isAbstract()) {
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as fragment renderer are lazy-loaded.', $id));
|
||||
continue;
|
||||
}
|
||||
|
||||
$class = $container->getParameterBag()->resolveValue($def->getClass());
|
||||
@ -63,8 +62,10 @@ class FragmentRendererPass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
$definition->addMethodCall('addRendererService', array($tag['alias'], $id));
|
||||
$renderers[$tag['alias']] = new Reference($id);
|
||||
}
|
||||
}
|
||||
|
||||
$definition->replaceArgument(0, new ServiceLocatorArgument($renderers));
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
|
||||
|
||||
@ -23,7 +23,11 @@ use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
|
||||
class LazyLoadingFragmentHandler extends FragmentHandler
|
||||
{
|
||||
private $container;
|
||||
/**
|
||||
* @deprecated since version 3.3, to be removed in 4.0
|
||||
*/
|
||||
private $rendererIds = array();
|
||||
private $initialized = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -44,9 +48,13 @@ class LazyLoadingFragmentHandler extends FragmentHandler
|
||||
*
|
||||
* @param string $name The service name
|
||||
* @param string $renderer The render service id
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0
|
||||
*/
|
||||
public function addRendererService($name, $renderer)
|
||||
{
|
||||
@trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$this->rendererIds[$name] = $renderer;
|
||||
}
|
||||
|
||||
@ -55,10 +63,17 @@ class LazyLoadingFragmentHandler extends FragmentHandler
|
||||
*/
|
||||
public function render($uri, $renderer = 'inline', array $options = array())
|
||||
{
|
||||
// BC 3.x, to be removed in 4.0
|
||||
if (isset($this->rendererIds[$renderer])) {
|
||||
$this->addRenderer($this->container->get($this->rendererIds[$renderer]));
|
||||
|
||||
unset($this->rendererIds[$renderer]);
|
||||
|
||||
return parent::render($uri, $renderer, $options);
|
||||
}
|
||||
|
||||
if (!isset($this->initialized[$renderer]) && $this->container->has($renderer)) {
|
||||
$this->addRenderer($this->container->get($renderer));
|
||||
$this->initialized[$renderer] = true;
|
||||
}
|
||||
|
||||
return parent::render($uri, $renderer, $options);
|
||||
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Sets the session in the request.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
abstract class AbstractSessionListener implements EventSubscriberInterface
|
||||
{
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
if (!$event->isMasterRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
$session = $this->getSession();
|
||||
if (null === $session || $request->hasSession()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request->setSession($session);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => array('onKernelRequest', 128),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the session object.
|
||||
*
|
||||
* @return SessionInterface|null A SessionInterface instance or null if no session is available
|
||||
*/
|
||||
abstract protected function getSession();
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* TestSessionListener.
|
||||
*
|
||||
* Saves session in test environment.
|
||||
*
|
||||
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class AbstractTestSessionListener implements EventSubscriberInterface
|
||||
{
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
if (!$event->isMasterRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// bootstrap the session
|
||||
$session = $this->getSession();
|
||||
if (!$session) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cookies = $event->getRequest()->cookies;
|
||||
|
||||
if ($cookies->has($session->getName())) {
|
||||
$session->setId($cookies->get($session->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if session was initialized and saves if current request is master
|
||||
* Runs on 'kernel.response' in test environment.
|
||||
*
|
||||
* @param FilterResponseEvent $event
|
||||
*/
|
||||
public function onKernelResponse(FilterResponseEvent $event)
|
||||
{
|
||||
if (!$event->isMasterRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$session = $event->getRequest()->getSession();
|
||||
if ($session && $session->isStarted()) {
|
||||
$session->save();
|
||||
$params = session_get_cookie_params();
|
||||
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => array('onKernelRequest', 192),
|
||||
KernelEvents::RESPONSE => array('onKernelResponse', -128),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the session object.
|
||||
*
|
||||
* @return SessionInterface|null A SessionInterface instance or null if no session is available
|
||||
*/
|
||||
abstract protected function getSession();
|
||||
}
|
@ -11,43 +11,30 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Sets the session in the request.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final since version 3.3
|
||||
*/
|
||||
abstract class SessionListener implements EventSubscriberInterface
|
||||
class SessionListener extends AbstractSessionListener
|
||||
{
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
if (!$event->isMasterRequest()) {
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
protected function getSession()
|
||||
{
|
||||
if (!$this->container->has('session')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
$session = $this->getSession();
|
||||
if (null === $session || $request->hasSession()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request->setSession($session);
|
||||
return $this->container->get('session');
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => array('onKernelRequest', 128),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the session object.
|
||||
*
|
||||
* @return SessionInterface|null A SessionInterface instance or null if no session is available
|
||||
*/
|
||||
abstract protected function getSession();
|
||||
}
|
||||
|
@ -11,73 +11,30 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* TestSessionListener.
|
||||
* Sets the session in the request.
|
||||
*
|
||||
* Saves session in test environment.
|
||||
*
|
||||
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final since version 3.3
|
||||
*/
|
||||
abstract class TestSessionListener implements EventSubscriberInterface
|
||||
class TestSessionListener extends AbstractTestSessionListener
|
||||
{
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
if (!$event->isMasterRequest()) {
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
protected function getSession()
|
||||
{
|
||||
if (!$this->container->has('session')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// bootstrap the session
|
||||
$session = $this->getSession();
|
||||
if (!$session) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cookies = $event->getRequest()->cookies;
|
||||
|
||||
if ($cookies->has($session->getName())) {
|
||||
$session->setId($cookies->get($session->getName()));
|
||||
}
|
||||
return $this->container->get('session');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if session was initialized and saves if current request is master
|
||||
* Runs on 'kernel.response' in test environment.
|
||||
*
|
||||
* @param FilterResponseEvent $event
|
||||
*/
|
||||
public function onKernelResponse(FilterResponseEvent $event)
|
||||
{
|
||||
if (!$event->isMasterRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$session = $event->getRequest()->getSession();
|
||||
if ($session && $session->isStarted()) {
|
||||
$session->save();
|
||||
$params = session_get_cookie_params();
|
||||
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => array('onKernelRequest', 192),
|
||||
KernelEvents::RESPONSE => array('onKernelResponse', -128),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the session object.
|
||||
*
|
||||
* @return SessionInterface|null A SessionInterface instance or null if no session is available
|
||||
*/
|
||||
abstract protected function getSession();
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
namespace Symfony\Component\HttpKernel\Tests\DependencyInjection;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass;
|
||||
use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface;
|
||||
@ -60,19 +62,13 @@ class FragmentRendererPassTest extends TestCase
|
||||
$renderer = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock();
|
||||
$renderer
|
||||
->expects($this->once())
|
||||
->method('addMethodCall')
|
||||
->with('addRendererService', array('foo', 'my_content_renderer'))
|
||||
;
|
||||
->method('replaceArgument')
|
||||
->with(0, $this->equalTo(new ServiceLocatorArgument(array('foo' => new Reference('my_content_renderer')))));
|
||||
|
||||
$definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock();
|
||||
$definition->expects($this->atLeastOnce())
|
||||
->method('getClass')
|
||||
->will($this->returnValue('Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService'));
|
||||
$definition
|
||||
->expects($this->once())
|
||||
->method('isPublic')
|
||||
->will($this->returnValue(true))
|
||||
;
|
||||
|
||||
$builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition', 'getReflectionClass'))->getMock();
|
||||
$builder->expects($this->any())
|
||||
|
@ -18,7 +18,11 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class LazyLoadingFragmentHandlerTest extends TestCase
|
||||
{
|
||||
public function test()
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation The Symfony\Component\HttpKernel\DependencyInjection\LazyLoadingFragmentHandler::addRendererService() method is deprecated since version 3.3 and will be removed in 4.0.
|
||||
*/
|
||||
public function testRenderWithLegacyMapping()
|
||||
{
|
||||
$renderer = $this->getMockBuilder('Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface')->getMock();
|
||||
$renderer->expects($this->once())->method('getName')->will($this->returnValue('foo'));
|
||||
@ -38,4 +42,25 @@ class LazyLoadingFragmentHandlerTest extends TestCase
|
||||
// second call should not lazy-load anymore (see once() above on the get() method)
|
||||
$handler->render('/foo', 'foo');
|
||||
}
|
||||
|
||||
public function testRender()
|
||||
{
|
||||
$renderer = $this->getMockBuilder('Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface')->getMock();
|
||||
$renderer->expects($this->once())->method('getName')->will($this->returnValue('foo'));
|
||||
$renderer->expects($this->any())->method('render')->will($this->returnValue(new Response()));
|
||||
|
||||
$requestStack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->getMock();
|
||||
$requestStack->expects($this->any())->method('getCurrentRequest')->will($this->returnValue(Request::create('/')));
|
||||
|
||||
$container = $this->getMockBuilder('Psr\Container\ContainerInterface')->getMock();
|
||||
$container->expects($this->once())->method('has')->with('foo')->willReturn(true);
|
||||
$container->expects($this->once())->method('get')->will($this->returnValue($renderer));
|
||||
|
||||
$handler = new LazyLoadingFragmentHandler($container, $requestStack, false);
|
||||
|
||||
$handler->render('/foo', 'foo');
|
||||
|
||||
// second call should not lazy-load anymore (see once() above on the get() method)
|
||||
$handler->render('/foo', 'foo');
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class TestSessionListenerTest extends TestCase
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->listener = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\EventListener\TestSessionListener');
|
||||
$this->listener = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\EventListener\AbstractTestSessionListener');
|
||||
$this->session = $this->getSession();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user