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

Commit 64ac503

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 5569b4e commit 64ac503

File tree

3 files changed

+10
-218
lines changed

3 files changed

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

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)