[EventDispatcher] A compiler pass for aliased userland events.
This commit is contained in:
parent
496346c88e
commit
34efe40371
@ -23,10 +23,6 @@
|
|||||||
<parameter key="Symfony\Component\HttpKernel\Event\ViewEvent">kernel.view</parameter>
|
<parameter key="Symfony\Component\HttpKernel\Event\ViewEvent">kernel.view</parameter>
|
||||||
<parameter key="Symfony\Component\HttpKernel\Event\ExceptionEvent">kernel.exception</parameter>
|
<parameter key="Symfony\Component\HttpKernel\Event\ExceptionEvent">kernel.exception</parameter>
|
||||||
<parameter key="Symfony\Component\HttpKernel\Event\TerminateEvent">kernel.terminate</parameter>
|
<parameter key="Symfony\Component\HttpKernel\Event\TerminateEvent">kernel.terminate</parameter>
|
||||||
<parameter key="Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent">security.authentication.success</parameter>
|
|
||||||
<parameter key="Symfony\Component\Security\Core\Event\AuthenticationFailureEvent">security.authentication.failure</parameter>
|
|
||||||
<parameter key="Symfony\Component\Security\Http\Event\InteractiveLoginEvent">security.interactive_login</parameter>
|
|
||||||
<parameter key="Symfony\Component\Security\Http\Event\SwitchUserEvent">security.switch_user</parameter>
|
|
||||||
<parameter key="Symfony\Component\Workflow\Event\GuardEvent">workflow.guard</parameter>
|
<parameter key="Symfony\Component\Workflow\Event\GuardEvent">workflow.guard</parameter>
|
||||||
<parameter key="Symfony\Component\Workflow\Event\LeaveEvent">workflow.leave</parameter>
|
<parameter key="Symfony\Component\Workflow\Event\LeaveEvent">workflow.leave</parameter>
|
||||||
<parameter key="Symfony\Component\Workflow\Event\TransitionEvent">workflow.transition</parameter>
|
<parameter key="Symfony\Component\Workflow\Event\TransitionEvent">workflow.transition</parameter>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
"symfony/messenger": "<4.3",
|
"symfony/messenger": "<4.3",
|
||||||
"symfony/mime": "<4.4",
|
"symfony/mime": "<4.4",
|
||||||
"symfony/property-info": "<3.4",
|
"symfony/property-info": "<3.4",
|
||||||
|
"symfony/security-bundle": "<4.4",
|
||||||
"symfony/serializer": "<4.2",
|
"symfony/serializer": "<4.2",
|
||||||
"symfony/stopwatch": "<3.4",
|
"symfony/stopwatch": "<3.4",
|
||||||
"symfony/translation": "<4.4",
|
"symfony/translation": "<4.4",
|
||||||
|
@ -33,7 +33,14 @@ use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMe
|
|||||||
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\LdapFactory;
|
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\LdapFactory;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\EventDispatcher\DependencyInjection\AddEventAliasesPass;
|
||||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
|
use Symfony\Component\Security\Core\AuthenticationEvents;
|
||||||
|
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
|
||||||
|
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
|
||||||
|
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||||
|
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
|
||||||
|
use Symfony\Component\Security\Http\SecurityEvents;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle.
|
* Bundle.
|
||||||
@ -68,5 +75,12 @@ class SecurityBundle extends Bundle
|
|||||||
$container->addCompilerPass(new AddSessionDomainConstraintPass(), PassConfig::TYPE_BEFORE_REMOVING);
|
$container->addCompilerPass(new AddSessionDomainConstraintPass(), PassConfig::TYPE_BEFORE_REMOVING);
|
||||||
$container->addCompilerPass(new RegisterCsrfTokenClearingLogoutHandlerPass());
|
$container->addCompilerPass(new RegisterCsrfTokenClearingLogoutHandlerPass());
|
||||||
$container->addCompilerPass(new RegisterTokenUsageTrackingPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 200);
|
$container->addCompilerPass(new RegisterTokenUsageTrackingPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 200);
|
||||||
|
|
||||||
|
$container->addCompilerPass(new AddEventAliasesPass([
|
||||||
|
AuthenticationSuccessEvent::class => AuthenticationEvents::AUTHENTICATION_SUCCESS,
|
||||||
|
AuthenticationFailureEvent::class => AuthenticationEvents::AUTHENTICATION_FAILURE,
|
||||||
|
InteractiveLoginEvent::class => SecurityEvents::INTERACTIVE_LOGIN,
|
||||||
|
SwitchUserEvent::class => SecurityEvents::SWITCH_USER,
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
<?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\Bundle\SecurityBundle\Tests\Functional\Bundle\EventBundle\DependencyInjection;
|
||||||
|
|
||||||
|
use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\EventBundle\EventSubscriber\TestSubscriber;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Extension\Extension;
|
||||||
|
|
||||||
|
final class EventExtension extends Extension
|
||||||
|
{
|
||||||
|
public function load(array $configs, ContainerBuilder $container): void
|
||||||
|
{
|
||||||
|
$container->register('test_subscriber', TestSubscriber::class)
|
||||||
|
->setPublic(true)
|
||||||
|
->addTag('kernel.event_subscriber');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?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\Bundle\SecurityBundle\Tests\Functional\Bundle\EventBundle;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
|
|
||||||
|
final class EventBundle extends Bundle
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?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\Bundle\SecurityBundle\Tests\Functional\Bundle\EventBundle\EventSubscriber;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
|
||||||
|
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
|
||||||
|
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||||
|
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
|
||||||
|
|
||||||
|
final class TestSubscriber implements EventSubscriberInterface
|
||||||
|
{
|
||||||
|
public $calledMethods = [];
|
||||||
|
|
||||||
|
public static function getSubscribedEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AuthenticationSuccessEvent::class => 'onAuthenticationSuccess',
|
||||||
|
AuthenticationFailureEvent::class => 'onAuthenticationFailure',
|
||||||
|
InteractiveLoginEvent::class => 'onInteractiveLogin',
|
||||||
|
SwitchUserEvent::class => 'onSwitchUser',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __call(string $name, array $arguments)
|
||||||
|
{
|
||||||
|
$this->calledMethods[$name] = ($this->calledMethods[$name] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
<?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\Bundle\SecurityBundle\Tests\Functional;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
|
use Symfony\Component\Security\Core\AuthenticationEvents;
|
||||||
|
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
|
||||||
|
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||||
|
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
|
||||||
|
use Symfony\Component\Security\Http\SecurityEvents;
|
||||||
|
|
||||||
|
final class EventAliasTest extends AbstractWebTestCase
|
||||||
|
{
|
||||||
|
public function testAliasedEvents(): void
|
||||||
|
{
|
||||||
|
$client = $this->createClient(['test_case' => 'AliasedEvents', 'root_config' => 'config.yml']);
|
||||||
|
$container = $client->getContainer();
|
||||||
|
$dispatcher = $container->get('event_dispatcher');
|
||||||
|
|
||||||
|
$dispatcher->dispatch(new AuthenticationSuccessEvent($this->createMock(TokenInterface::class)), AuthenticationEvents::AUTHENTICATION_SUCCESS);
|
||||||
|
$dispatcher->dispatch(new AuthenticationFailureEvent($this->createMock(TokenInterface::class), new AuthenticationException()), AuthenticationEvents::AUTHENTICATION_FAILURE);
|
||||||
|
$dispatcher->dispatch(new InteractiveLoginEvent($this->createMock(Request::class), $this->createMock(TokenInterface::class)), SecurityEvents::INTERACTIVE_LOGIN);
|
||||||
|
$dispatcher->dispatch(new SwitchUserEvent($this->createMock(Request::class), $this->createMock(UserInterface::class), $this->createMock(TokenInterface::class)), SecurityEvents::SWITCH_USER);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
[
|
||||||
|
'onAuthenticationSuccess' => 1,
|
||||||
|
'onAuthenticationFailure' => 1,
|
||||||
|
'onInteractiveLogin' => 1,
|
||||||
|
'onSwitchUser' => 1,
|
||||||
|
],
|
||||||
|
$container->get('test_subscriber')->calledMethods
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
<?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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
||||||
|
use Symfony\Bundle\SecurityBundle\SecurityBundle;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\EventBundle\EventBundle;
|
||||||
|
|
||||||
|
return [
|
||||||
|
new FrameworkBundle(),
|
||||||
|
new SecurityBundle(),
|
||||||
|
new EventBundle(),
|
||||||
|
];
|
@ -0,0 +1,2 @@
|
|||||||
|
imports:
|
||||||
|
- { resource: ./../config/framework.yml }
|
@ -1,6 +1,11 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
4.4.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* `AddEventAliasesPass` has been added, allowing applications and bundles to extend the event alias mapping used by `RegisterListenersPass`.
|
||||||
|
|
||||||
4.3.0
|
4.3.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
<?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\EventDispatcher\DependencyInjection;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This pass allows bundles to extend the list of event aliases.
|
||||||
|
*
|
||||||
|
* @author Alexander M. Turek <me@derrabus.de>
|
||||||
|
*/
|
||||||
|
class AddEventAliasesPass implements CompilerPassInterface
|
||||||
|
{
|
||||||
|
private $eventAliases;
|
||||||
|
private $eventAliasesParameter;
|
||||||
|
|
||||||
|
public function __construct(array $eventAliases, string $eventAliasesParameter = 'event_dispatcher.event_aliases')
|
||||||
|
{
|
||||||
|
$this->eventAliases = $eventAliases;
|
||||||
|
$this->eventAliasesParameter = $eventAliasesParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(ContainerBuilder $container): void
|
||||||
|
{
|
||||||
|
$eventAliases = $container->hasParameter($this->eventAliasesParameter) ? $container->getParameter($this->eventAliasesParameter) : [];
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
$this->eventAliasesParameter,
|
||||||
|
array_merge($eventAliases, $this->eventAliases)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
use Symfony\Component\EventDispatcher\DependencyInjection\AddEventAliasesPass;
|
||||||
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
|
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
|
||||||
@ -67,6 +68,9 @@ class RegisterListenersPassTest extends TestCase
|
|||||||
$builder->register('my_event_subscriber', AliasedSubscriber::class)
|
$builder->register('my_event_subscriber', AliasedSubscriber::class)
|
||||||
->addTag('kernel.event_subscriber');
|
->addTag('kernel.event_subscriber');
|
||||||
|
|
||||||
|
$eventAliasPass = new AddEventAliasesPass([CustomEvent::class => 'custom_event']);
|
||||||
|
$eventAliasPass->process($builder);
|
||||||
|
|
||||||
$registerListenersPass = new RegisterListenersPass();
|
$registerListenersPass = new RegisterListenersPass();
|
||||||
$registerListenersPass->process($builder);
|
$registerListenersPass->process($builder);
|
||||||
|
|
||||||
@ -79,6 +83,14 @@ class RegisterListenersPassTest extends TestCase
|
|||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'addListener',
|
||||||
|
[
|
||||||
|
'custom_event',
|
||||||
|
[new ServiceClosureArgument(new Reference('my_event_subscriber')), 'onCustomEvent'],
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
$this->assertEquals($expectedCalls, $builder->getDefinition('event_dispatcher')->getMethodCalls());
|
$this->assertEquals($expectedCalls, $builder->getDefinition('event_dispatcher')->getMethodCalls());
|
||||||
}
|
}
|
||||||
@ -202,8 +214,12 @@ class RegisterListenersPassTest extends TestCase
|
|||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
$container->setParameter('event_dispatcher.event_aliases', [AliasedEvent::class => 'aliased_event']);
|
$container->setParameter('event_dispatcher.event_aliases', [AliasedEvent::class => 'aliased_event']);
|
||||||
$container->register('foo', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => AliasedEvent::class, 'method' => 'onEvent']);
|
$container->register('foo', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => AliasedEvent::class, 'method' => 'onEvent']);
|
||||||
|
$container->register('bar', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => CustomEvent::class, 'method' => 'onEvent']);
|
||||||
$container->register('event_dispatcher');
|
$container->register('event_dispatcher');
|
||||||
|
|
||||||
|
$eventAliasPass = new AddEventAliasesPass([CustomEvent::class => 'custom_event']);
|
||||||
|
$eventAliasPass->process($container);
|
||||||
|
|
||||||
$registerListenersPass = new RegisterListenersPass();
|
$registerListenersPass = new RegisterListenersPass();
|
||||||
$registerListenersPass->process($container);
|
$registerListenersPass->process($container);
|
||||||
|
|
||||||
@ -217,6 +233,14 @@ class RegisterListenersPassTest extends TestCase
|
|||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'addListener',
|
||||||
|
[
|
||||||
|
'custom_event',
|
||||||
|
[new ServiceClosureArgument(new Reference('bar')), 'onEvent'],
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
$this->assertEquals($expectedCalls, $definition->getMethodCalls());
|
$this->assertEquals($expectedCalls, $definition->getMethodCalls());
|
||||||
}
|
}
|
||||||
@ -249,6 +273,7 @@ final class AliasedSubscriber implements EventSubscriberInterface
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
AliasedEvent::class => 'onAliasedEvent',
|
AliasedEvent::class => 'onAliasedEvent',
|
||||||
|
CustomEvent::class => 'onCustomEvent',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,3 +281,7 @@ final class AliasedSubscriber implements EventSubscriberInterface
|
|||||||
final class AliasedEvent
|
final class AliasedEvent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class CustomEvent
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"php": "^7.1.3",
|
"php": "^7.1.3",
|
||||||
"symfony/error-handler": "^4.4|^5.0",
|
"symfony/error-handler": "^4.4|^5.0",
|
||||||
"symfony/error-renderer": "^4.4|^5.0",
|
"symfony/error-renderer": "^4.4|^5.0",
|
||||||
"symfony/event-dispatcher": "^4.3",
|
"symfony/event-dispatcher": "^4.4",
|
||||||
"symfony/http-foundation": "^4.4|^5.0",
|
"symfony/http-foundation": "^4.4|^5.0",
|
||||||
"symfony/polyfill-ctype": "^1.8",
|
"symfony/polyfill-ctype": "^1.8",
|
||||||
"symfony/polyfill-php73": "^1.9",
|
"symfony/polyfill-php73": "^1.9",
|
||||||
|
Reference in New Issue
Block a user