-
-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #372 from thephpleague/event-dispatcher
Implement event dispatching
- Loading branch information
Showing
10 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
--- | ||
layout: default | ||
title: Event Dispatcher | ||
--- | ||
|
||
Event Dispatcher | ||
================ | ||
|
||
This library includes basic event dispatcher functionality. This makes it possible to add hook points throughout the library and third-party extensions which other code can listen for and execute code. If you're familiar with [Symfony's EventDispatcher](https://symfony.com/doc/current/components/event_dispatcher.html) or [PSR-14](https://www.php-fig.org/psr/psr-14/) then this should be very familiar to you. | ||
|
||
## Event Class | ||
|
||
All events must extend from the `AbstractEvent` class: | ||
|
||
```php | ||
use League\CommonMark\Event\AbstractEvent; | ||
|
||
class MyCustomEvent extends AbstractEvent {} | ||
``` | ||
|
||
An event can have any number of methods on it which return useful information the listeners can use or modify. | ||
|
||
## Registering Listeners | ||
|
||
Listeners can be registered with the `Environment` using the `addEventListener()` method: | ||
|
||
```php | ||
public function addEventListener(string $eventClass, callable $listener, int $priority = 0) | ||
``` | ||
|
||
The parameters for this method are: | ||
|
||
1. The fully-qualified name of the event class you wish to observe | ||
2. Any PHP callable to execute when that type of event is dispatched | ||
3. An optional priority (defaults to `0`) | ||
|
||
For example: | ||
|
||
```php | ||
// Telling the environment which method to call: | ||
$customListener = new MyCustomListener(); | ||
$environment->addEventListener(MyCustomEvent::class, [$customListener, 'onDocumentParsed']); | ||
|
||
// Or if MyCustomerListener has an __invoke() method: | ||
$environment->addEventListener(MyCustomEvent::class, new MyCustomListener(), 10); | ||
|
||
// Or use any other type of callable you wish! | ||
$environment->addEventListener(MyCustomEvent::class, function (MyCustomEvent $event) { | ||
// TODO: Stuff | ||
}, 10); | ||
``` | ||
|
||
## Dispatching Events | ||
|
||
Events can be dispatched via the `$environment->dispatch()` method which takes a single argument - an instance of `AbstractEvent` to dispatch: | ||
|
||
```php | ||
$environment->dispatch(new MyCustomEvent()); | ||
``` | ||
|
||
Listeners will be called in order of priority (higher priorities will be called first). If multiple listeners have the same priority, they'll be called in the order in which they were registered. If you'd like your listener to prevent other subsequent events from running, simply call `$event->stopPropagation()`. | ||
|
||
Listeners may call any method on the event to get more information about the event, make changes to event data, etc. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the league/commonmark package. | ||
* | ||
* (c) Colin O'Dell <colinodell@gmail.com> | ||
* | ||
* Original code based on the Symfony EventDispatcher "Event" contract | ||
* - (c) 2018-2019 Fabien Potencier | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace League\CommonMark\Event; | ||
|
||
/** | ||
* Base class for classes containing event data. | ||
* | ||
* This class contains no event data. It is used by events that do not pass | ||
* state information to an event handler when an event is raised. | ||
* | ||
* You can call the method stopPropagation() to abort the execution of | ||
* further listeners in your event listener. | ||
*/ | ||
abstract class AbstractEvent | ||
{ | ||
private $propagationStopped = false; | ||
|
||
/** | ||
* Returns whether further event listeners should be triggered. | ||
*/ | ||
final public function isPropagationStopped(): bool | ||
{ | ||
return $this->propagationStopped; | ||
} | ||
|
||
/** | ||
* Stops the propagation of the event to further event listeners. | ||
* | ||
* If multiple event listeners are connected to the same event, no | ||
* further event listener will be triggered once any trigger calls | ||
* stopPropagation(). | ||
*/ | ||
final public function stopPropagation(): void | ||
{ | ||
$this->propagationStopped = true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the league/commonmark package. | ||
* | ||
* (c) Colin O'Dell <colinodell@gmail.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace League\CommonMark\Tests\Unit\Event; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
|
||
final class AbstractEventTest extends TestCase | ||
{ | ||
public function testStopPropagation() | ||
{ | ||
$event = new FakeEvent(); | ||
|
||
$this->assertFalse($event->isPropagationStopped()); | ||
|
||
$event->stopPropagation(); | ||
$this->assertTrue($event->isPropagationStopped()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the league/commonmark package. | ||
* | ||
* (c) Colin O'Dell <colinodell@gmail.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace League\CommonMark\Tests\Unit\Event; | ||
|
||
use League\CommonMark\Event\AbstractEvent; | ||
|
||
final class FakeEvent extends AbstractEvent | ||
{ | ||
} |