Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 1354a08

Browse files
committed
refactor: Have SharedEventManager extend PrioritizedIdentifierListenerProvider
Doing so will allow us to use it in a PrioritizedAggregateListenerProvider within the EventManager later. Required a couple changes to tests, as PrioritizedIdentifierListenerProvider widens what are allowed as events and identifiers when retrieving listeners.
1 parent 23feede commit 1354a08

File tree

3 files changed

+10
-219
lines changed

3 files changed

+10
-219
lines changed

TODO-PSR-14.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
- [x] `getListenersByEvent()` will loop through each, in order, calling the
4646
`getListenersForEventByPriority()` method of each, returning the
4747
aggregated listeners in priority order.
48+
- [x] Make `SharedEventManager` an extension of `PrioritizedIdentifierListenerProvider`
4849
- [ ] Create `ListenerSubscriberInterface`
4950
- [ ] `attach(PrioritizedListenerAttachmentInterface $provider, $priority = 1)`
5051
- [ ] `detach(PrioritizedListenerAttachmentInterface $provider)`

src/SharedEventManager.php

Lines changed: 4 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -15,221 +15,10 @@
1515
* Allows attaching to EMs composed by other classes without having an instance first.
1616
* The assumption is that the SharedEventManager will be injected into EventManager
1717
* instances, and then queried for additional listeners when triggering an event.
18+
*
19+
* @deprecated since 3.3.0. This class will be removed in version 4.0; use
20+
* listener providers instead.
1821
*/
19-
class SharedEventManager implements SharedEventManagerInterface
22+
class SharedEventManager extends ListenerProvider\PrioritizedIdentifierListenerProvider
2023
{
21-
/**
22-
* Identifiers with event connections
23-
* @var array
24-
*/
25-
protected $identifiers = [];
26-
27-
/**
28-
* Attach a listener to an event emitted by components with specific identifiers.
29-
*
30-
* Allows attaching a listener to an event offered by an identifying
31-
* components. As an example, the following connects to the "getAll" event
32-
* of both an AbstractResource and EntityResource:
33-
*
34-
* <code>
35-
* $sharedEventManager = new SharedEventManager();
36-
* foreach (['My\Resource\AbstractResource', 'My\Resource\EntityResource'] as $identifier) {
37-
* $sharedEventManager->attach(
38-
* $identifier,
39-
* 'getAll',
40-
* function ($e) use ($cache) {
41-
* if (!$id = $e->getParam('id', false)) {
42-
* return;
43-
* }
44-
* if (!$data = $cache->load(get_class($resource) . '::getOne::' . $id )) {
45-
* return;
46-
* }
47-
* return $data;
48-
* }
49-
* );
50-
* }
51-
* </code>
52-
*
53-
* @param string $identifier Identifier for event emitting component.
54-
* @param string $event
55-
* @param callable $listener Listener that will handle the event.
56-
* @param int $priority Priority at which listener should execute
57-
* @return void
58-
* @throws Exception\InvalidArgumentException for invalid identifier arguments.
59-
* @throws Exception\InvalidArgumentException for invalid event arguments.
60-
*/
61-
public function attach($identifier, $event, callable $listener, $priority = 1)
62-
{
63-
if (! is_string($identifier) || empty($identifier)) {
64-
throw new Exception\InvalidArgumentException(sprintf(
65-
'Invalid identifier provided; must be a string; received "%s"',
66-
(is_object($identifier) ? get_class($identifier) : gettype($identifier))
67-
));
68-
}
69-
70-
if (! is_string($event) || empty($event)) {
71-
throw new Exception\InvalidArgumentException(sprintf(
72-
'Invalid event provided; must be a non-empty string; received "%s"',
73-
(is_object($event) ? get_class($event) : gettype($event))
74-
));
75-
}
76-
77-
$this->identifiers[$identifier][$event][(int) $priority][] = $listener;
78-
}
79-
80-
/**
81-
* @inheritDoc
82-
*/
83-
public function detach(callable $listener, $identifier = null, $eventName = null, $force = false)
84-
{
85-
// No identifier or wildcard identifier: loop through all identifiers and detach
86-
if (null === $identifier || ('*' === $identifier && ! $force)) {
87-
foreach (array_keys($this->identifiers) as $identifier) {
88-
$this->detach($listener, $identifier, $eventName, true);
89-
}
90-
return;
91-
}
92-
93-
if (! is_string($identifier) || empty($identifier)) {
94-
throw new Exception\InvalidArgumentException(sprintf(
95-
'Invalid identifier provided; must be a string, received %s',
96-
(is_object($identifier) ? get_class($identifier) : gettype($identifier))
97-
));
98-
}
99-
100-
// Do we have any listeners on the provided identifier?
101-
if (! isset($this->identifiers[$identifier])) {
102-
return;
103-
}
104-
105-
if (null === $eventName || ('*' === $eventName && ! $force)) {
106-
foreach (array_keys($this->identifiers[$identifier]) as $eventName) {
107-
$this->detach($listener, $identifier, $eventName, true);
108-
}
109-
return;
110-
}
111-
112-
if (! is_string($eventName) || empty($eventName)) {
113-
throw new Exception\InvalidArgumentException(sprintf(
114-
'Invalid event name provided; must be a string, received %s',
115-
(is_object($eventName) ? get_class($eventName) : gettype($eventName))
116-
));
117-
}
118-
119-
if (! isset($this->identifiers[$identifier][$eventName])) {
120-
return;
121-
}
122-
123-
foreach ($this->identifiers[$identifier][$eventName] as $priority => $listeners) {
124-
foreach ($listeners as $index => $evaluatedListener) {
125-
if ($evaluatedListener !== $listener) {
126-
continue;
127-
}
128-
129-
// Found the listener; remove it.
130-
unset($this->identifiers[$identifier][$eventName][$priority][$index]);
131-
132-
// Is the priority queue empty?
133-
if (empty($this->identifiers[$identifier][$eventName][$priority])) {
134-
unset($this->identifiers[$identifier][$eventName][$priority]);
135-
break;
136-
}
137-
}
138-
139-
// Is the event queue empty?
140-
if (empty($this->identifiers[$identifier][$eventName])) {
141-
unset($this->identifiers[$identifier][$eventName]);
142-
break;
143-
}
144-
}
145-
146-
// Is the identifier queue now empty? Remove it.
147-
if (empty($this->identifiers[$identifier])) {
148-
unset($this->identifiers[$identifier]);
149-
}
150-
}
151-
152-
/**
153-
* Retrieve all listeners for a given identifier and event
154-
*
155-
* @param string[] $identifiers
156-
* @param string $eventName
157-
* @return array[]
158-
* @throws Exception\InvalidArgumentException
159-
*/
160-
public function getListeners(array $identifiers, $eventName)
161-
{
162-
if ('*' === $eventName || ! is_string($eventName) || empty($eventName)) {
163-
throw new Exception\InvalidArgumentException(sprintf(
164-
'Event name passed to %s must be a non-empty, non-wildcard string',
165-
__METHOD__
166-
));
167-
}
168-
169-
$returnListeners = [];
170-
171-
foreach ($identifiers as $identifier) {
172-
if ('*' === $identifier || ! is_string($identifier) || empty($identifier)) {
173-
throw new Exception\InvalidArgumentException(sprintf(
174-
'Identifier names passed to %s must be non-empty, non-wildcard strings',
175-
__METHOD__
176-
));
177-
}
178-
179-
if (isset($this->identifiers[$identifier])) {
180-
$listenersByIdentifier = $this->identifiers[$identifier];
181-
if (isset($listenersByIdentifier[$eventName])) {
182-
foreach ($listenersByIdentifier[$eventName] as $priority => $listeners) {
183-
$returnListeners[$priority][] = $listeners;
184-
}
185-
}
186-
if (isset($listenersByIdentifier['*'])) {
187-
foreach ($listenersByIdentifier['*'] as $priority => $listeners) {
188-
$returnListeners[$priority][] = $listeners;
189-
}
190-
}
191-
}
192-
}
193-
194-
if (isset($this->identifiers['*'])) {
195-
$wildcardIdentifier = $this->identifiers['*'];
196-
if (isset($wildcardIdentifier[$eventName])) {
197-
foreach ($wildcardIdentifier[$eventName] as $priority => $listeners) {
198-
$returnListeners[$priority][] = $listeners;
199-
}
200-
}
201-
if (isset($wildcardIdentifier['*'])) {
202-
foreach ($wildcardIdentifier['*'] as $priority => $listeners) {
203-
$returnListeners[$priority][] = $listeners;
204-
}
205-
}
206-
}
207-
208-
foreach ($returnListeners as $priority => $listOfListeners) {
209-
$returnListeners[$priority] = array_merge(...$listOfListeners);
210-
}
211-
212-
return $returnListeners;
213-
}
214-
215-
/**
216-
* @inheritDoc
217-
*/
218-
public function clearListeners($identifier, $eventName = null)
219-
{
220-
if (! isset($this->identifiers[$identifier])) {
221-
return false;
222-
}
223-
224-
if (null === $eventName) {
225-
unset($this->identifiers[$identifier]);
226-
return;
227-
}
228-
229-
if (! isset($this->identifiers[$identifier][$eventName])) {
230-
return;
231-
}
232-
233-
unset($this->identifiers[$identifier][$eventName]);
234-
}
23524
}

test/SharedEventManagerTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,15 +284,16 @@ public function testDetachingWithInvalidEventTypeRaisesException($eventName)
284284
$this->manager->detach($this->callback, 'IDENTIFIER', $eventName);
285285
}
286286

287-
public function invalidListenersAndEventNamesForFetchingListeners()
287+
public function invalidEventNamesForFetchingListeners()
288288
{
289289
$events = $this->invalidIdentifiers();
290290
$events['wildcard'] = ['*'];
291+
unset($events['non-traversable-object']);
291292
return $events;
292293
}
293294

294295
/**
295-
* @dataProvider invalidListenersAndEventNamesForFetchingListeners
296+
* @dataProvider invalidEventNamesForFetchingListeners
296297
*/
297298
public function testGetListenersRaisesExceptionForInvalidEventName($eventName)
298299
{
@@ -302,12 +303,12 @@ public function testGetListenersRaisesExceptionForInvalidEventName($eventName)
302303
}
303304

304305
/**
305-
* @dataProvider invalidListenersAndEventNamesForFetchingListeners
306+
* @dataProvider invalidIdentifiers
306307
*/
307308
public function testGetListenersRaisesExceptionForInvalidIdentifier($identifier)
308309
{
309310
$this->expectException(Exception\InvalidArgumentException::class);
310-
$this->expectExceptionMessage('non-empty, non-wildcard');
311+
$this->expectExceptionMessage('non-empty');
311312
$this->manager->getListeners([$identifier], 'EVENT');
312313
}
313314
}

0 commit comments

Comments
 (0)