RuntimeManager::executeEvent()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/*
3
 * The MIT License (MIT)
4
 *
5
 * Copyright (c) 2015 zepi
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 *
25
 */
26
27
/**
28
 * The RuntimeManager registers and executes all handlers. The
29
 * handlers are saved in an object backend.
30
 * 
31
 * @package Zepi\Turbo\Manager
32
 * @author Matthias Zobrist <[email protected]>
33
 * @copyright Copyright (c) 2015 zepi
34
 */
35
36
namespace Zepi\Turbo\Manager;
37
38
use \Zepi\Turbo\Framework;
39
use \Zepi\Turbo\Backend\ObjectBackendAbstract;
40
use \Zepi\Turbo\Request\RequestAbstract;
41
use \Zepi\Turbo\FrameworkInterface\EventHandlerInterface;
42
use Zepi\Turbo\FrameworkInterface\CliEventHandlerInterface;
43
44
/**
45
 * The RuntimeManager registers and executes all handlers. The
46
 * handlers are saved in an object backend.
47
 * 
48
 * @author Matthias Zobrist <[email protected]>
49
 * @copyright Copyright (c) 2015 zepi
50
 */
51
class RuntimeManager
52
{
53
    const EVENT = 'event';
54
    const FILTER = 'filter';
55
    
56
    /**
57
     * @access protected
58
     * @var Framework
59
     */
60
    protected $framework;
61
    
62
    /**
63
     * @access protected
64
     * @var ObjectBackendAbstract
65
     */
66
    protected $handlerObjectBackend;
67
    
68
    /**
69
     * @access protected
70
     * @var array
71
     */
72
    protected $handlers = array();
73
    
74
    /**
75
     * Constructs the object
76
     * 
77
     * @access public
78
     * @param \Zepi\Turbo\Framework $framework
79
     * @param \Zepi\Turbo\Backend\ObjectBackendAbstract $handlerObjectBackend
80
     */
81 17
    public function __construct(Framework $framework, ObjectBackendAbstract $handlerObjectBackend)
82
    {
83 17
        $this->framework = $framework;
84 17
        $this->handlerObjectBackend = $handlerObjectBackend;
85 17
    }
86
    
87
    /**
88
     * Initializes the event system. The function loads all saved
89
     * events from the object backend.
90
     * 
91
     * @access public
92
     */
93 17
    public function initializeManager()
94
    {
95 17
        $handlers = $this->handlerObjectBackend->loadObject();
96 17
        if (!is_array($handlers)) {
97 17
            $handlers = array();
98
        }
99
        
100 17
        $this->handlers = $handlers;
101 17
    }
102
    
103
    /**
104
     * Executes the events for the given event name
105
     * 
106
     * @access public
107
     * @param string $eventName
108
     */
109 2
    public function executeEvent($eventName)
110
    {
111 2
        $this->executeItems(self::EVENT, $eventName);
112 2
    }
113
    
114
    /**
115
     * Executes the filter for the given filter name
116
     *
117
     * @access public
118
     * @param string $eventName
119
     * @param mixed $value
120
     */
121 2
    public function executeFilter($eventName, $value = null)
122
    {
123 2
        return $this->executeItems(self::FILTER, $eventName, $value);
124
    }
125
    
126
    /**
127
     * Executes the given event handlers. Every event handler will
128
     * be initialized and executed.
129
     * 
130
     * @access protected
131
     * @param string $type
132
     * @param string $name
133
     * @param mixed $value
134
     * @return mixed
135
     */
136 2
    protected function executeItems($type, $name, $value = null)
137
    {
138 2
        if (!isset($this->handlers[$type][$name])) {
139 2
            return $value;
140
        }
141
        
142 2
        $request = $this->framework->getRequest();
143
144 2
        foreach ($this->filterHandlers($type, $name, $request) as $handlerName) {
145 2
            $handler = $this->framework->getInstance($handlerName);
146
                
147 2
            $response = $this->framework->getResponse();
148 2
            $response->setData('_executedType', $type);
149 2
            $response->setData('_executedName', $name);
150
                
151
            // Execute the handler
152 2
            $handlerResult = $handler->execute(
153 2
                $this->framework, 
154 2
                $this->framework->getRequest(), 
155 2
                $response,
156 2
                $value
157
            );
158
                
159
            // Save the handler result to the variable if this is an filter handler
160 2
            if ($type === self::FILTER) {
161 2
                $value = $handlerResult;
162
            }
163
        }
164
        
165
        // Return the value if this is an filter handler
166 2
        if ($type === self::FILTER) {
167
            return $value;
168
        }
169 2
    }
170
    
171
    /**
172
     * Filters the handler and returns an single array with
173
     * all queued handlers
174
     *
175
     * @access protected
176
     * @param string $type            
177
     * @param string $name            
178
     * @param RequestAbstract $request            
179
     * @return array
180
     */
181 2
    protected function filterHandlers($type, $name, RequestAbstract $request)
182
    {
183 2
        $filteredHandlers = array();
184
        
185 2
        foreach ($this->handlers[$type][$name] as $priority => $handlers) {
186 2
            foreach ($handlers as $handlerName) {
187 2
                if ($type === self::EVENT && !$this->compareRequestWithInterface($request, $handlerName)) {
188
                    continue;
189
                }
190
                
191 2
                $filteredHandlers[] = $handlerName;
192
            }
193
        }
194
195 2
        return array_unique($filteredHandlers);
196
    }
197
    
198
    /**
199
     * Returns true if the event handler and the request are from the same interface,
200
     * e.g. both are from cli. If the event handler is neutral return true. Return false
201
     * if the event handler isn't neutral and the request is not from the same interface.
202
     * 
203
     * @access protected
204
     * @param RequestAbstract $request
205
     * @param string $handlerName
206
     * @return boolean
207
     */
208 2
    protected function compareRequestWithInterface(RequestAbstract $request, $handlerName)
209
    {
210 2
        $implementedInterfaces = class_implements($handlerName, true);
211
212
        // If the event is a cli event but the request isn't a cli request
213
        // we skip this event
214 2
        if (isset($implementedInterfaces['Zepi\\Turbo\\FrameworkInterface\\CliEventHandlerInterface'])
215 2
            && get_class($request) != 'Zepi\\Turbo\\Request\\CliRequest') {
216
            return false;
217
        }
218
219
        // If the event is a web event but the request isn't a web request
220
        // we skip this event
221 2
        if (isset($implementedInterfaces['Zepi\\Turbo\\FrameworkInterface\\WebEventHandlerInterface'])
222 2
            && get_class($request) != 'Zepi\\Turbo\\Request\\WebRequest') {
223
            return false;
224
        }
225
        
226 2
        return true;
227
    }
228
    
229
    /**
230
     * Adds an event handler
231
     * 
232
     * @access public
233
     * @param string $eventName
234
     * @param string $eventHandlerName
235
     * @param integer $priority
236
     */
237 2
    public function addEventHandler($eventName, $eventHandlerName, $priority = 50)
238
    {
239 2
        $this->addHandler(self::EVENT, $eventName, $eventHandlerName, $priority);
240 2
    }
241
    
242
    /**
243
     * Adds an filter handler
244
     * 
245
     * @access public
246
     * @param string $filterName
247
     * @param string $filterHandlerName
248
     * @param integer $priority
249
     */
250
    public function addFilterHandler($filterName, $filterHandlerName, $priority = 50)
251
    {
252
        $this->addHandler(self::FILTER, $filterName, $filterHandlerName, $priority);
253
    }
254
    
255
    /**
256
     * Adds a new handler
257
     * 
258
     * @access protected
259
     * @param string $type
260
     * @param string $name
261
     * @param string $handlerName
262
     * @param integer $priority
263
     */
264 2
    protected function addHandler($type, $name, $handlerName, $priority)
265
    {
266
        // If the priority isn't existing we add the priority as 
267
        // a new array.
268 2
        if (!isset($this->handlers[$type][$name][$priority])) {
269 2
            $this->handlers[$type][$name][$priority] = array();
270 2
            ksort($this->handlers[$type][$name]);
271
        }
272
        
273
        // If we had the event handler already registred, return at this point
274 2
        if (in_array($handlerName, $this->handlers[$type][$name][$priority])) {
275
            return;
276
        }
277
        
278
        // Add the event handler and save the new events array
279 2
        $this->handlers[$type][$name][$priority][] = $handlerName;
280 2
        $this->saveHandlers();
281 2
    }
282
    
283
    /**
284
     * Removes an event handler
285
     * 
286
     * @access public
287
     * @param string $eventName
288
     * @param string $eventHandlerName
289
     * @param integer $priority
290
     */
291
    public function removeEventHandler($eventName, $eventHandlerName, $priority = 50)
292
    {
293
        $this->removeHandler(self::EVENT, $eventName, $eventHandlerName, $priority);
294
    }
295
    
296
    /**
297
     * Removes an filter handler
298
     * 
299
     * @access public
300
     * @param string $filterName
301
     * @param string $filterHandlerName
302
     * @param integer $priority
303
     */
304
    public function removeFilterHandler($filterName, $filterHandlerName, $priority = 50)
305
    {
306
        $this->removeHandler(self::FILTER, $filterName, $filterHandlerName, $priority);
307
    }
308
    
309
    /**
310
     * Removes an handler
311
     * 
312
     * @access protected
313
     * @param string $type
314
     * @param string $name
315
     * @param string $handlerName
316
     * @param string $priority
317
     */
318
    protected function removeHandler($type, $name, $handlerName, $priority)
319
    {
320
        // If the event isn't set we add an array to the events array
321
        if (!isset($this->handlers[$type][$name][$priority])) {
322
            return;
323
        }
324
        
325
        // If the event handler isn't registred we return with true.
326
        if (!in_array($handlerName, $this->handlers[$type][$name][$priority])) {
327
            return;
328
        }
329
        
330
        // Remove the event handler from the array
331
        $index = array_search($handlerName, $this->handlers[$type][$name][$priority]);
332
        unset($this->handlers[$type][$name][$priority][$index]);
333
        $this->saveHandlers();
334
    }
335
    
336
    /**
337
     * Clears the handlers cache and reactivates the modules
338
     * to rebuild the cache.
339
     * 
340
     * @access public
341
     * @param boolean $reactivateModules
342
     */
343
    public function clearCache($reactivateModules = true)
344
    {
345
        $this->handlers = array();
346
        
347
        if ($reactivateModules) {
348
            $this->framework->getModuleManager()->reactivateModules();
349
        }
350
    }
351
    
352
    /**
353
     * Saves the registred handlers in the object backend.
354
     * 
355
     * @access protected
356
     */
357 2
    protected function saveHandlers()
358
    {
359 2
        $this->handlerObjectBackend->saveObject($this->handlers);
360 2
    }
361
}
362