Passed
Push — master ( 0f91e9...e0eb75 )
by Sebastian
03:48
created

EventHandler::onTokenAppended()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * File containing the class {@see \Mailcode\Parser\Statement\Tokenizer\EventHandler}.
4
 *
5
 * @package Mailcode
6
 * @subpackage Parser
7
 * @see \Mailcode\Parser\Statement\Tokenizer\EventHandler
8
 */
9
10
declare(strict_types=1);
11
12
namespace Mailcode\Parser\Statement\Tokenizer;
13
14
use Mailcode\Mailcode_Parser_Statement_Tokenizer;
15
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token;
16
use Mailcode\Mailcode_Parser_Statement_Tokenizer_Token_Keyword;
17
18
/**
19
 * Event handler for the command parameter tokenizer:
20
 * allows listening to modifications of the token
21
 * collection.
22
 *
23
 * @package Mailcode
24
 * @subpackage Parser
25
 * @author Sebastian Mordziol <[email protected]>
26
 */
27
class EventHandler
28
{
29
    private Mailcode_Parser_Statement_Tokenizer $tokenizer;
30
31
    public function __construct(Mailcode_Parser_Statement_Tokenizer $tokenizer)
32
    {
33
        $this->tokenizer = $tokenizer;
34
    }
35
36
    // region: _Listeners
37
38
    /**
39
     * @var array<string,array<int,callable>>
40
     */
41
    private array $listeners = array();
42
43
    /**
44
     * Callback arguments:
45
     *
46
     * 1. Tokenizer instance
47
     *
48
     * @param callable $callback
49
     * @return void
50
     */
51
    public function onKeywordsChanged(callable $callback) : void
52
    {
53
        $this->addListener(self::EVENT_KEYWORDS_CHANGED, $callback);
54
    }
55
56
    /**
57
     * Callback arguments:
58
     *
59
     * 1. Tokenizer instance
60
     * 2. Keyword name
61
     *
62
     * @param callable $callback
63
     * @return void
64
     */
65
    public function onKeywordRemoved(callable $callback) : void
66
    {
67
        $this->addListener(self::EVENT_KEYWORD_REMOVED, $callback);
68
    }
69
70
    /**
71
     * Callback arguments:
72
     *
73
     * 1. Tokenizer instance
74
     * 2. Keyword name
75
     *
76
     * @param callable $callback
77
     * @return void
78
     */
79
    public function onKeywordAdded(callable $callback) : void
80
    {
81
        $this->addListener(self::EVENT_KEYWORD_ADDED, $callback);
82
    }
83
84
    /**
85
     * Callback arguments:
86
     *
87
     * 1. Tokenizer instance
88
     * 2. Token instance
89
     *
90
     * @param callable $callback
91
     * @return void
92
     */
93
    public function onTokenRemoved(callable $callback) : void
94
    {
95
        $this->addListener(self::EVENT_TOKEN_REMOVED, $callback);
96
    }
97
98
    /**
99
     * Callback arguments:
100
     *
101
     * 1. Tokenizer instance
102
     * 2. Token instance
103
     *
104
     * @param callable $callback
105
     * @return void
106
     */
107
    public function onTokenAdded(callable $callback) : void
108
    {
109
        $this->addListener(self::EVENT_TOKEN_ADDED, $callback);
110
    }
111
112
    /**
113
     * Callback arguments:
114
     *
115
     * 1. Tokenizer instance
116
     * 2. Token instance
117
     *
118
     * @param callable $callback
119
     * @return void
120
     */
121
    public function onTokenAppended(callable $callback) : void
122
    {
123
        $this->addListener(self::EVENT_TOKEN_APPENDED, $callback);
124
    }
125
126
    /**
127
     * Callback arguments:
128
     *
129
     * 1. Tokenizer instance
130
     * 2. Token instance
131
     *
132
     * @param callable $callback
133
     * @return void
134
     */
135
    public function onTokenPrepended(callable $callback) : void
136
    {
137
        $this->addListener(self::EVENT_TOKEN_PREPENDED, $callback);
138
    }
139
140
    /**
141
     * Callback arguments:
142
     *
143
     * 1. Tokenizer instance
144
     *
145
     * @param callable $callback
146
     * @return void
147
     */
148
    public function onTokensChanged(callable $callback) : void
149
    {
150
        $this->addListener(self::EVENT_TOKENS_CHANGED, $callback);
151
    }
152
153
    private function addListener(string $eventName, callable $listener) : void
154
    {
155
        if(!isset($this->listeners[$eventName]))
156
        {
157
            $this->listeners[$eventName] = array();
158
        }
159
160
        $this->listeners[$eventName][] = $listener;
161
    }
162
163
    // endregion
164
165
    // region: Event handlers
166
167
    public function handleTokenRemoved(Mailcode_Parser_Statement_Tokenizer_Token $token) : void
168
    {
169
        $this->triggerTokenRemoved($token);
170
    }
171
172
    public function handleTokenAppended(Mailcode_Parser_Statement_Tokenizer_Token $token) : void
173
    {
174
        $this->triggerTokenAppended($token);
175
    }
176
177
    public function handleTokenPrepended(Mailcode_Parser_Statement_Tokenizer_Token $token) : void
178
    {
179
        $this->triggerTokenPrepended($token);
180
    }
181
182
    // endregion
183
184
    // region: Event triggers
185
186
    public const EVENT_TOKENS_CHANGED = 'TokensChanged';
187
    public const EVENT_TOKEN_ADDED = 'TokenAdded';
188
    public const EVENT_TOKEN_APPENDED = 'TokenAppended';
189
    public const EVENT_TOKEN_PREPENDED = 'TokenPrepended';
190
    public const EVENT_TOKEN_REMOVED = 'TokenRemoved';
191
    public const EVENT_KEYWORD_ADDED = 'KeywordAdded';
192
    public const EVENT_KEYWORD_REMOVED = 'KeywordRemoved';
193
    public const EVENT_KEYWORDS_CHANGED = 'KeywordsChanged';
194
195
    private function triggerTokenRemoved(Mailcode_Parser_Statement_Tokenizer_Token $token) : void
196
    {
197
        $this->triggerEvent(self::EVENT_TOKEN_REMOVED, $token);
198
199
        if($token instanceof Mailcode_Parser_Statement_Tokenizer_Token_Keyword)
200
        {
201
            $this->triggerKeywordRemoved($token->getKeyword());
202
        }
203
204
        $this->triggerTokensChanged();
205
    }
206
207
    private function triggerTokenAppended(Mailcode_Parser_Statement_Tokenizer_Token $token) : void
208
    {
209
        $this->triggerEvent(self::EVENT_TOKEN_APPENDED, $token);
210
211
        $this->triggerTokenAdded($token);
212
    }
213
214
    private function triggerTokenPrepended(Mailcode_Parser_Statement_Tokenizer_Token $token) : void
215
    {
216
        $this->triggerEvent(self::EVENT_TOKEN_PREPENDED, $token);
217
218
        $this->triggerTokenAdded($token);
219
    }
220
221
    private function triggerTokenAdded(Mailcode_Parser_Statement_Tokenizer_Token $token) : void
222
    {
223
        $this->triggerEvent(self::EVENT_TOKEN_ADDED, $token);
224
225
        if($token instanceof Mailcode_Parser_Statement_Tokenizer_Token_Keyword)
226
        {
227
            $this->triggerKeywordAdded($token->getKeyword());
228
        }
229
230
        $this->triggerTokensChanged();
231
    }
232
233
    private function triggerTokensChanged() : void
234
    {
235
        $this->triggerEvent(self::EVENT_TOKENS_CHANGED);
236
    }
237
238
    private function triggerKeywordRemoved(string $keyword) : void
239
    {
240
        $this->triggerEvent(self::EVENT_KEYWORD_REMOVED, $keyword);
241
242
        $this->triggerKeywordsChanged();
243
    }
244
245
    private function triggerKeywordAdded(string $keyword) : void
246
    {
247
        $this->triggerEvent(self::EVENT_KEYWORD_ADDED, $keyword);
248
249
        $this->triggerKeywordsChanged();
250
    }
251
252
    private function triggerKeywordsChanged() : void
253
    {
254
        $this->triggerEvent(self::EVENT_KEYWORDS_CHANGED);
255
    }
256
257
    /**
258
     * @param string $eventName
259
     * @param mixed ...$listenerArgs
260
     * @return void
261
     */
262
    private function triggerEvent(string $eventName, ...$listenerArgs) : void
263
    {
264
        if(!isset($this->listeners[$eventName]))
265
        {
266
            return;
267
        }
268
269
        foreach($this->listeners[$eventName] as $listener)
270
        {
271
            $listener($this->tokenizer, ...$listenerArgs);
272
        }
273
    }
274
275
    // endregion
276
277
}
278