[Contracts][EventDispatcher] add EventDispatcherInterface to symfony/contracts and use it where possible

This commit is contained in:
Nicolas Grekas 2019-03-25 17:04:58 +01:00
parent 8585317c85
commit 3c3db2f14a
55 changed files with 197 additions and 93 deletions

View File

@ -49,6 +49,7 @@
<tag name="container.hot_path" />
</service>
<service id="Symfony\Component\EventDispatcher\EventDispatcherInterface" alias="event_dispatcher" />
<service id="Symfony\Contracts\EventDispatcher\EventDispatcherInterface" alias="event_dispatcher" />
<service id="http_kernel" class="Symfony\Component\HttpKernel\HttpKernel" public="true">
<argument type="service" id="event_dispatcher" />

View File

@ -13,7 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Auto
use Doctrine\Common\Annotations\Reader;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class AutowiredServices
{

View File

@ -20,7 +20,7 @@
"ext-xml": "*",
"symfony/cache": "~4.3",
"symfony/config": "~4.2",
"symfony/contracts": "^1.0.2",
"symfony/contracts": "^1.1",
"symfony/dependency-injection": "^4.3",
"symfony/http-foundation": "^4.3",
"symfony/http-kernel": "^4.3",

View File

@ -30,6 +30,8 @@ class FirewallListener extends Firewall
public function __construct(FirewallMapInterface $map, EventDispatcherInterface $dispatcher, LogoutUrlGenerator $logoutUrlGenerator)
{
// the type-hint will be updated to the "EventDispatcherInterface" from symfony/contracts in 5.0
$this->map = $map;
$this->logoutUrlGenerator = $logoutUrlGenerator;

View File

@ -17,7 +17,6 @@ use Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener;
use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
@ -34,6 +33,7 @@ use Symfony\Component\Security\Core\Role\RoleHierarchy;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Http\FirewallMapInterface;
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SecurityDataCollectorTest extends TestCase
{

View File

@ -91,6 +91,9 @@ class Application
$this->defaultCommand = 'list';
}
/**
* @final since Symfony 4.3, the type-hint will be updated to the interface from symfony/contracts in 5.0
*/
public function setDispatcher(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);

View File

@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/contracts": "^1.0",
"symfony/contracts": "^1.1",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8"
},

View File

@ -226,16 +226,7 @@ class AutowirePass extends AbstractRecursivePass
if ($parameter->isDefaultValueAvailable()) {
$value = $parameter->getDefaultValue();
} elseif (!$parameter->allowsNull()) {
if (\function_exists('xdebug_disable')) {
xdebug_disable();
}
try {
throw new AutowiringFailedException($this->currentId, $failureMessage);
} finally {
if (\function_exists('xdebug_enable')) {
xdebug_enable();
}
}
throw new AutowiringFailedException($this->currentId, $failureMessage);
}
}

View File

@ -23,6 +23,10 @@ class AutowiringFailedException extends RuntimeException
{
$this->serviceId = $serviceId;
if ($message instanceof \Closure && \function_exists('xdebug_is_enabled') && xdebug_is_enabled()) {
$message = $message();
}
if (!$message instanceof \Closure) {
parent::__construct($message, $code, $previous);

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\EventDispatcher\Debug;
use Psr\EventDispatcher\StoppableEventInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@ -133,7 +134,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$eventName = 1 < \func_num_args() ? \func_get_arg(1) : null;
if ($event instanceof Event) {
if (\is_object($event)) {
$eventName = $eventName ?? \get_class($event);
} else {
@trigger_error(sprintf('Calling the "%s::dispatch()" method with the event name as first argument is deprecated since Symfony 4.3, pass it second and provide the event object first instead.', EventDispatcherInterface::class), E_USER_DEPRECATED);
@ -146,13 +147,13 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
}
}
if (null !== $this->logger && $event->isPropagationStopped()) {
if (null !== $this->logger && ($event instanceof Event || $event instanceof StoppableEventInterface) && $event->isPropagationStopped()) {
$this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName));
}
$this->preProcess($eventName);
try {
$this->preDispatch($eventName, $event);
$this->beforeDispatch($eventName, $event);
try {
$e = $this->stopwatch->start($eventName, 'section');
try {
@ -163,7 +164,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
}
}
} finally {
$this->postDispatch($eventName, $event);
$this->afterDispatch($eventName, $event);
}
} finally {
$this->postProcess($eventName);
@ -262,18 +263,32 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
/**
* Called before dispatching the event.
*
* @param string $eventName The event name
* @param Event $event The event
* @param object $event
*/
protected function beforeDispatch(string $eventName, $event)
{
$this->preDispatch($eventName, $event);
}
/**
* Called after dispatching the event.
*
* @param object $event
*/
protected function afterDispatch(string $eventName, $event)
{
$this->postDispatch($eventName, $event);
}
/**
* @deprecated since Symfony 4.3, will be removed in 5.0, use beforeDispatch instead
*/
protected function preDispatch($eventName, Event $event)
{
}
/**
* Called after dispatching the event.
*
* @param string $eventName The event name
* @param Event $event The event
* @deprecated since Symfony 4.3, will be removed in 5.0, use afterDispatch instead
*/
protected function postDispatch($eventName, Event $event)
{

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\EventDispatcher\Debug;
use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Stopwatch\Stopwatch;
@ -18,6 +19,8 @@ use Symfony\Component\VarDumper\Caster\ClassStub;
/**
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3: the "Event" type-hint on __invoke() will be replaced by "object" in 5.0
*/
class WrappedListener
{
@ -120,7 +123,7 @@ class WrappedListener
$e->stop();
}
if ($event->isPropagationStopped()) {
if (($event instanceof Event || $event instanceof StoppableEventInterface) && $event->isPropagationStopped()) {
$this->stoppedPropagation = true;
}
}

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\EventDispatcher;
use Psr\EventDispatcher\StoppableEventInterface;
/**
* The EventDispatcherInterface is the central point of Symfony's event listener system.
*
@ -48,7 +50,7 @@ class EventDispatcher implements EventDispatcherInterface
{
$eventName = 1 < \func_num_args() ? \func_get_arg(1) : null;
if ($event instanceof Event) {
if (\is_object($event)) {
$eventName = $eventName ?? \get_class($event);
} else {
@trigger_error(sprintf('Calling the "%s::dispatch()" method with the event name as first argument is deprecated since Symfony 4.3, pass it second and provide the event object first instead.', EventDispatcherInterface::class), E_USER_DEPRECATED);
@ -223,12 +225,22 @@ class EventDispatcher implements EventDispatcherInterface
*
* @param callable[] $listeners The event listeners
* @param string $eventName The name of the event to dispatch
* @param Event $event The event object to pass to the event handlers/listeners
* @param object $event The event object to pass to the event handlers/listeners
*/
protected function callListeners(iterable $listeners, string $eventName, $event)
{
$this->doDispatch($listeners, $eventName, $event);
}
/**
* @deprecated since Symfony 4.3, use callListeners() instead
*/
protected function doDispatch($listeners, $eventName, Event $event)
{
$stoppable = $event instanceof Event || $event instanceof StoppableEventInterface;
foreach ($listeners as $listener) {
if ($event->isPropagationStopped()) {
if ($stoppable && $event->isPropagationStopped()) {
break;
}
$listener($event, $eventName, $this);

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\EventDispatcher;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as ContractsEventDispatcherInterface;
/**
* The EventDispatcherInterface is the central point of Symfony's event listener system.
* Listeners are registered on the manager and events are dispatched through the
@ -18,19 +20,8 @@ namespace Symfony\Component\EventDispatcher;
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface EventDispatcherInterface
interface EventDispatcherInterface extends ContractsEventDispatcherInterface
{
/**
* Dispatches an event to all registered listeners.
*
* @param Event $event The event to pass to the event handlers/listeners
* @param string|null $eventName The name of the event to dispatch. If not supplied,
* the class of $event should be used instead.
*
* @return Event
*/
public function dispatch($event/*, string $eventName = null*/);
/**
* Adds an event listener that listens on the specified events.
*

View File

@ -11,6 +11,9 @@
namespace Symfony\Component\EventDispatcher;
use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* An helper class to provide BC/FC with the legacy signature of EventDispatcherInterface::dispatch().
*
@ -51,7 +54,7 @@ final class LegacyEventDispatcherProxy implements EventDispatcherInterface
{
$eventName = 1 < \func_num_args() ? \func_get_arg(1) : null;
if ($event instanceof Event) {
if (\is_object($event)) {
$eventName = $eventName ?? \get_class($event);
} else {
@trigger_error(sprintf('Calling the "%s::dispatch()" method with the event name as first argument is deprecated since Symfony 4.3, pass it second and provide the event object first instead.', EventDispatcherInterface::class), E_USER_DEPRECATED);
@ -65,9 +68,10 @@ final class LegacyEventDispatcherProxy implements EventDispatcherInterface
}
$listeners = $this->getListeners($eventName);
$stoppable = $event instanceof Event || $event instanceof StoppableEventInterface;
foreach ($listeners as $listener) {
if ($event->isPropagationStopped()) {
if ($stoppable && $event->isPropagationStopped()) {
break;
}
$listener($event, $eventName, $this);

View File

@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/contracts": "^1.0"
"symfony/contracts": "^1.1"
},
"require-dev": {
"symfony/dependency-injection": "~3.4|~4.0",
@ -29,6 +29,10 @@
"conflict": {
"symfony/dependency-injection": "<3.4"
},
"provide": {
"psr/event-dispatcher-implementation": "1.0",
"symfony/event-dispatcher-implementation": "1.1"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\Form\Test;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\Test\Traits\ValidatorExtensionTrait;
@ -25,7 +25,7 @@ abstract class TypeTestCase extends FormIntegrationTestCase
protected $builder;
/**
* @var EventDispatcher
* @var EventDispatcherInterface
*/
protected $dispatcher;
@ -33,7 +33,7 @@ abstract class TypeTestCase extends FormIntegrationTestCase
{
parent::setUp();
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->dispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$this->builder = new FormBuilder('', null, $this->dispatcher, $this->factory);
}

View File

@ -13,9 +13,9 @@ namespace Symfony\Component\HttpKernel\DataCollector;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Service\ResetInterface;
/**

View File

@ -27,7 +27,7 @@ class TraceableEventDispatcher extends BaseTraceableEventDispatcher
/**
* {@inheritdoc}
*/
protected function preDispatch($eventName, Event $event)
protected function beforeDispatch(string $eventName, $event)
{
switch ($eventName) {
case KernelEvents::REQUEST:
@ -58,7 +58,7 @@ class TraceableEventDispatcher extends BaseTraceableEventDispatcher
/**
* {@inheritdoc}
*/
protected function postDispatch($eventName, Event $event)
protected function afterDispatch(string $eventName, $event)
{
switch ($eventName) {
case KernelEvents::CONTROLLER_ARGUMENTS:

View File

@ -54,6 +54,10 @@ class ExceptionListener implements EventSubscriberInterface
$this->logException($event->getException(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()));
}
/**
* @param string $eventName
* @param EventDispatcherInterface $eventDispatcher
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
if (null === $this->controller) {

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\HttpKernel\Fragment;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@ -20,6 +19,7 @@ use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\HttpCache\SubRequestHandler;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* Implements the inline rendering strategy where the Request is rendered by the current HTTP kernel.

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\HttpKernel;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
use Symfony\Component\HttpFoundation\Request;
@ -32,6 +31,7 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\ControllerDoesNotReturnResponseException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* HttpKernel notifies events to convert a Request object to a Response one.

View File

@ -21,6 +21,7 @@ use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class InlineFragmentRendererTest extends TestCase
{
@ -73,7 +74,7 @@ class InlineFragmentRendererTest extends TestCase
*/
public function testRenderExceptionNoIgnoreErrors()
{
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$dispatcher->expects($this->never())->method('dispatch');
$strategy = new InlineFragmentRenderer($this->getKernel($this->throwException(new \RuntimeException('foo'))), $dispatcher);
@ -87,7 +88,7 @@ class InlineFragmentRendererTest extends TestCase
$kernel = $this->getKernel($this->throwException($exception));
$request = Request::create('/');
$expectedEvent = new ExceptionEvent($kernel, $request, $kernel::SUB_REQUEST, $exception);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$dispatcher->expects($this->once())->method('dispatch')->with($expectedEvent, KernelEvents::EXCEPTION);
$strategy = new InlineFragmentRenderer($kernel, $dispatcher);

View File

@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/contracts": "^1.0.2",
"symfony/contracts": "^1.1",
"symfony/event-dispatcher": "^4.3",
"symfony/http-foundation": "^4.1.1",
"symfony/debug": "~3.4|~4.0",

View File

@ -20,12 +20,12 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Messenger\RoutableMessageBus;
use Symfony\Component\Messenger\Transport\Receiver\StopWhenMemoryUsageIsExceededReceiver;
use Symfony\Component\Messenger\Transport\Receiver\StopWhenMessageCountIsExceededReceiver;
use Symfony\Component\Messenger\Transport\Receiver\StopWhenTimeLimitIsReachedReceiver;
use Symfony\Component\Messenger\Worker;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* @author Samuel Roze <samuel.roze@gmail.com>

View File

@ -11,13 +11,12 @@
namespace Symfony\Component\Messenger\Event;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Messenger\Envelope;
/**
* @experimental in 4.3
*/
abstract class AbstractWorkerMessageEvent extends Event
abstract class AbstractWorkerMessageEvent
{
private $envelope;
private $receiverName;

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Messenger\Event;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Messenger\Envelope;
/**
@ -23,7 +22,7 @@ use Symfony\Component\Messenger\Envelope;
*
* @author Ryan Weaver <ryan@symfonycasts.com>
*/
class SendMessageToTransportsEvent extends Event
class SendMessageToTransportsEvent
{
private $envelope;

View File

@ -13,13 +13,13 @@ namespace Symfony\Component\Messenger\Middleware;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\SendMessageToTransportsEvent;
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
use Symfony\Component\Messenger\Stamp\RedeliveryStamp;
use Symfony\Component\Messenger\Stamp\SentStamp;
use Symfony\Component\Messenger\Transport\Sender\SendersLocatorInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* @author Samuel Roze <samuel.roze@gmail.com>

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Messenger\Tests\Middleware;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\SendMessageToTransportsEvent;
use Symfony\Component\Messenger\Middleware\SendMessageMiddleware;
@ -24,6 +23,7 @@ use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessageInterface;
use Symfony\Component\Messenger\Transport\Sender\SenderInterface;
use Symfony\Component\Messenger\Transport\Sender\SendersLocator;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SendMessageMiddlewareTest extends MiddlewareTestCase
{

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Messenger\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
@ -26,6 +25,7 @@ use Symfony\Component\Messenger\Stamp\SentStamp;
use Symfony\Component\Messenger\Tests\Fixtures\CallbackReceiver;
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
use Symfony\Component\Messenger\Worker;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class WorkerTest extends TestCase
{

View File

@ -12,8 +12,6 @@
namespace Symfony\Component\Messenger;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent;
@ -25,6 +23,7 @@ use Symfony\Component\Messenger\Stamp\ReceivedStamp;
use Symfony\Component\Messenger\Stamp\RedeliveryStamp;
use Symfony\Component\Messenger\Stamp\SentStamp;
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* @author Samuel Roze <samuel.roze@gmail.com>
@ -141,7 +140,7 @@ class Worker
});
}
private function dispatchEvent(Event $event)
private function dispatchEvent($event)
{
if (null === $this->eventDispatcher) {
return;

View File

@ -51,6 +51,9 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface
$this->eraseCredentials = $eraseCredentials;
}
/**
* @final since Symfony 4.3, the type-hint will be updated to the interface from symfony/contracts in 5.0
*/
public function setEventDispatcher(EventDispatcherInterface $dispatcher)
{
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);

View File

@ -11,9 +11,10 @@
namespace Symfony\Component\Security\Core\Authorization\Voter;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Event\VoteEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* Decorates voter classes to send result events.
@ -30,14 +31,14 @@ class TraceableVoter implements VoterInterface
public function __construct(VoterInterface $voter, EventDispatcherInterface $eventDispatcher)
{
$this->voter = $voter;
$this->eventDispatcher = $eventDispatcher;
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
}
public function vote(TokenInterface $token, $subject, array $attributes)
{
$result = $this->voter->vote($token, $subject, $attributes);
$this->eventDispatcher->dispatch('debug.security.authorization.vote', new VoteEvent($this->voter, $subject, $attributes, $result));
$this->eventDispatcher->dispatch(new VoteEvent($this->voter, $subject, $attributes, $result), 'debug.security.authorization.vote');
return $result;
}

View File

@ -12,11 +12,11 @@
namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\TraceableVoter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Event\VoteEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class TraceableVoterTest extends TestCase
{
@ -44,7 +44,7 @@ class TraceableVoterTest extends TestCase
$eventDispatcher
->expects($this->once())
->method('dispatch')
->with('debug.security.authorization.vote', new VoteEvent($voter, 'anysubject', ['attr1'], VoterInterface::ACCESS_DENIED));
->with(new VoteEvent($voter, 'anysubject', ['attr1'], VoterInterface::ACCESS_DENIED), 'debug.security.authorization.vote');
$sut = new TraceableVoter($voter, $eventDispatcher);
$result = $sut->vote($token, 'anysubject', ['attr1']);

View File

@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/contracts": "^1.0"
"symfony/contracts": "^1.1"
},
"require-dev": {
"psr/container": "^1.0",

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Security\Guard;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@ -22,6 +21,7 @@ use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* A utility class that does much of the *work* during the guard authentication process.

View File

@ -14,11 +14,15 @@ namespace Symfony\Component\Security\Guard\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class GuardAuthenticatorHandlerTest extends TestCase
{
@ -158,11 +162,11 @@ class GuardAuthenticatorHandlerTest extends TestCase
protected function setUp()
{
$this->tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$this->tokenStorage = $this->getMockBuilder(TokenStorageInterface::class)->getMock();
$this->dispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$this->token = $this->getMockBuilder(TokenInterface::class)->getMock();
$this->request = new Request([], [], [], [], [], []);
$this->sessionStrategy = $this->getMockBuilder('Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface')->getMock();
$this->sessionStrategy = $this->getMockBuilder(SessionAuthenticationStrategyInterface::class)->getMock();
$this->guardAuthenticator = $this->getMockBuilder(AuthenticatorInterface::class)->getMock();
}

View File

@ -38,6 +38,8 @@ class Firewall implements EventSubscriberInterface
public function __construct(FirewallMapInterface $map, EventDispatcherInterface $dispatcher)
{
// the type-hint will be updated to the "EventDispatcherInterface" from symfony/contracts in 5.0
$this->map = $map;
$this->dispatcher = $dispatcher;
$this->exceptionListeners = new \SplObjectStorage();

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@ -31,6 +30,7 @@ use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* The AbstractAuthenticationListener is the preferred base class for all

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
@ -25,6 +24,7 @@ use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* AbstractPreAuthenticatedListener is the base class for all listener that

View File

@ -39,7 +39,7 @@ use Symfony\Component\Security\Http\Util\TargetPathTrait;
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3
* @final since Symfony 4.3, EventDispatcherInterface type-hints will be updated to the interface from symfony/contracts in 5.0
*/
class ExceptionListener
{

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
@ -23,6 +22,7 @@ use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* RememberMeListener implements authentication capabilities via a cookie.

View File

@ -12,11 +12,11 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* REMOTE_USER authentication listener.

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@ -30,6 +29,7 @@ use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* SwitchUserListener allows a user to impersonate another one temporarily

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
@ -28,6 +27,7 @@ use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerI
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* UsernamePasswordFormAuthenticationListener is the default implementation of

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@ -35,6 +34,7 @@ use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* UsernamePasswordJsonAuthenticationListener is a stateless implementation of

View File

@ -12,11 +12,11 @@
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* X509 authentication listener.

View File

@ -18,6 +18,7 @@ use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Firewall\RememberMeListener;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class RememberMeListenerTest extends TestCase
{
@ -447,7 +448,7 @@ class RememberMeListenerTest extends TestCase
protected function getDispatcher()
{
return $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
return $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
}
private function getSessionStrategy()

View File

@ -23,6 +23,7 @@ use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
use Symfony\Component\Security\Http\Firewall\SwitchUserListener;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class SwitchUserListenerTest extends TestCase
{
@ -138,7 +139,7 @@ class SwitchUserListenerTest extends TestCase
$this->tokenStorage->setToken(new SwitchUserToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken, false)], $originalToken));
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$dispatcher
->expects($this->once())
->method('dispatch')
@ -165,7 +166,7 @@ class SwitchUserListenerTest extends TestCase
$this->tokenStorage->setToken(new SwitchUserToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken, false)], $originalToken));
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$dispatcher
->expects($this->never())
->method('dispatch')
@ -267,7 +268,7 @@ class SwitchUserListenerTest extends TestCase
->method('loadUserByUsername')->with('kuba')
->will($this->returnValue($user));
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$dispatcher
->expects($this->once())
->method('dispatch')

View File

@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/contracts": "^1.0",
"symfony/contracts": "^1.1",
"symfony/http-foundation": "~3.4|~4.0",
"symfony/http-kernel": "^4.3",
"symfony/property-access": "~3.4|~4.0"

View File

@ -11,9 +11,9 @@
namespace Symfony\Component\Workflow;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>

View File

@ -3,13 +3,13 @@
namespace Symfony\Component\Workflow\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Workflow\Definition;
use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface;
use Symfony\Component\Workflow\SupportStrategy\WorkflowSupportStrategyInterface;
use Symfony\Component\Workflow\Workflow;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class RegistryTest extends TestCase
{

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Workflow;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\Workflow\Event\AnnounceEvent;
use Symfony\Component\Workflow\Event\CompletedEvent;
@ -26,6 +25,7 @@ use Symfony\Component\Workflow\Exception\UndefinedTransitionException;
use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface;
use Symfony\Component\Workflow\MarkingStore\MultipleStateMarkingStore;
use Symfony\Component\Workflow\Metadata\MetadataStoreInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* @author Fabien Potencier <fabien@symfony.com>

View File

@ -5,6 +5,7 @@ CHANGELOG
-----
* added `HttpClient` namespace with contracts for implementing flexible HTTP clients
* added `EventDispatcher\EventDispatcherInterface`
1.0.0
-----

View File

@ -0,0 +1,58 @@
<?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\Contracts\EventDispatcher;
use Psr\EventDispatcher\EventDispatcherInterface as PsrEventDispatcherInterface;
if (interface_exists(PsrEventDispatcherInterface::class)) {
/**
* Allows providing hooks on domain-specific lifecycles by dispatching events.
*/
interface EventDispatcherInterface extends PsrEventDispatcherInterface
{
/**
* Dispatches an event to all registered listeners.
*
* For BC with Symfony 4, the $eventName argument is not declared explicitly on the
* signature of the method. Implementations that are not bound by this BC contraint
* MUST declare it explicitly, as allowed by PHP.
*
* @param object $event The event to pass to the event handlers/listeners
* @param string|null $eventName The name of the event to dispatch. If not supplied,
* the class of $event should be used instead.
*
* @return object The passed $event MUST be returned
*/
public function dispatch($event/*, string $eventName = null*/);
}
} else {
/**
* Allows providing hooks on domain-specific lifecycles by dispatching events.
*/
interface EventDispatcherInterface
{
/**
* Dispatches an event to all registered listeners.
*
* For BC with Symfony 4, the $eventName argument is not declared explicitly on the
* signature of the method. Implementations that are not bound by this BC contraint
* MUST declare it explicitly, as allowed by PHP.
*
* @param object $event The event to pass to the event handlers/listeners
* @param string|null $eventName The name of the event to dispatch. If not supplied,
* the class of $event should be used instead.
*
* @return object The passed $event MUST be returned
*/
public function dispatch($event/*, string $eventName = null*/);
}
}

View File

@ -27,6 +27,7 @@
"psr/cache": "When using the Cache contracts",
"psr/container": "When using the Service contracts",
"symfony/cache-contracts-implementation": "",
"symfony/event-dispatcher-implementation": "",
"symfony/http-client-contracts-implementation": "",
"symfony/service-contracts-implementation": "",
"symfony/translation-contracts-implementation": ""