GenericEventDispatcher::removeListener()   B
last analyzed

Complexity

Conditions 7
Paths 5

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 15
cts 15
cp 1
rs 8.6666
c 0
b 0
f 0
cc 7
nc 5
nop 2
crap 7
1
<?php
2
3
namespace Onoi\EventDispatcher\Dispatcher;
4
5
use Onoi\EventDispatcher\Subscriber;
6
use Onoi\EventDispatcher\EventDispatcher;
7
use Onoi\EventDispatcher\EventListener;
8
use Onoi\EventDispatcher\EventListenerCollection;
9
use Onoi\EventDispatcher\DispatchContext;
10
use Onoi\EventDispatcher\Exception\EventNotDispatchableException;
11
use InvalidArgumentException;
12
use RuntimeException;
13
use Traversable;
14
15
/**
16
 * Dispatches events to registered listeners
17
 *
18
 * @license GNU GPL v2+
19
 * @since 1.0
20
 *
21
 * @author mwjames
22
 */
23
class GenericEventDispatcher implements EventDispatcher, Subscriber {
24
25
	/**
26
	 * @var array
27
	 */
28
	private $dispatchableListeners = array();
29
30
	/**
31
	 * @var boolean
32
	 */
33
	private $throwOnMissingEvent = false;
34
35
	/**
36
	 * @since 1.0
37
	 *
38
	 * {@inheritDoc}
39
	 *
40
	 * @throws RuntimeException
41
	 */
42 4
	public function addListenerCollection( EventListenerCollection $listenerCollection ) {
43
44 4
		$collection = $listenerCollection->getCollection();
45
46 4
		 if( !is_array( $collection ) && !$collection instanceof Traversable ) {
47 1
		 	throw new RuntimeException( "Expected a traversable object" );
48
		 }
49
50 3
		foreach ( $collection as $event => $listeners ) {
51 3
			foreach ( $listeners as $listener ) {
52 3
				$this->addListener( $event, $listener );
53 3
			}
54 3
		}
55 3
	}
56
57
	/**
58
	 * @since 1.0
59
	 *
60
	 * {@inheritDoc}
61
	 *
62
	 * @throws InvalidArgumentException
63
	 */
64 12
	public function addListener( $event, EventListener $listener ) {
65
66 12
		if ( !is_string( $event ) ) {
67 1
			throw new InvalidArgumentException( "Expected a string" );
68
		}
69
70 11
		$event = strtolower( $event );
71
72 11
		if ( !isset( $this->dispatchableListeners[$event] ) ) {
73 11
			$this->dispatchableListeners[$event] = array();
74 11
		}
75
76 11
		$this->dispatchableListeners[$event][] = $listener;
77 11
	}
78
79
	/**
80
	 * @since 1.0
81
	 *
82
	 * {@inheritDoc}
83
	 */
84 3
	public function removeListener( $event, EventListener $listener = null ) {
85
86 3
		$event = strtolower( $event );
87
88 3
		if ( !$this->hasEvent( $event ) ) {
89 1
			return;
90
		}
91
92 2
		if ( $listener !== null ) {
93 1
			foreach ( $this->dispatchableListeners[$event] as $key => $dispatchableListener ) {
94 1
				if ( $dispatchableListener == $listener ) {
95 1
					unset( $this->dispatchableListeners[$event][$key] );
96 1
				}
97 1
			}
98 1
		}
99
100 2
		if ( $listener === null || $this->dispatchableListeners[$event] === array() ) {
101 2
			unset( $this->dispatchableListeners[$event] );
102 2
		}
103 2
	}
104
105
	/**
106
	 * @since 1.1
107
	 *
108
	 * @param boolean $throwOnMissingEvent
109
	 */
110 1
	public function throwOnMissingEvent( $throwOnMissingEvent ) {
111 1
		$this->throwOnMissingEvent = (bool)$throwOnMissingEvent;
112 1
	}
113
114
	/**
115
	 * @since 1.0
116
	 *
117
	 * {@inheritDoc}
118
	 */
119 12
	public function hasEvent( $event ) {
120 12
		return isset( $this->dispatchableListeners[strtolower( $event )] );
121
	}
122
123
	/**
124
	 * @since 1.0
125
	 *
126
	 * {@inheritDoc}
127
	 */
128 8
	public function dispatch( $event, $dispatchContext = null ) {
129
130 8
		$event = strtolower( $event );
131
132 8
		if ( !$this->hasEvent( $event ) && $this->throwOnMissingEvent ) {
133 1
			throw new EventNotDispatchableException( $event );
134 7
		} elseif( !$this->hasEvent( $event ) ) {
135 1
			return;
136
		}
137
138 7
		if ( is_array( $dispatchContext ) ) {
139 1
			$dispatchContext = DispatchContext::newFromArray( $dispatchContext );
140 1
		}
141
142 7
		foreach ( $this->dispatchableListeners[$event] as $listener ) {
143
144 7
			$listener->execute( $dispatchContext );
145
146 7
			if ( $listener->isPropagationStopped() || ( $dispatchContext !== null && $dispatchContext->isPropagationStopped() ) ) {
147 2
				break;
148
			}
149 7
		}
150 7
	}
151
152
}
153