Completed
Push — master ( 8a4ca9...acd23c )
by Marco
02:46
created

src/Events.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php namespace Comodojo\Extender;
2
3
use \Spyc;
4
use \Exception;
5
6
/**
7
 * Extender events class
8
 *
9
 * It handle any hook fired by extender.
10
 *
11
 * There are only four available events on current extender version;
12
 *
13
 * - "extender": fires when extender is ready and brings $logger as parameter (to extend monolog via plugin)
14
 *
15
 * - "extender.tasks": fires when tasktable is composed; its parameter is the taskstable
16
 *
17
 * - "extender.schedule": fires when job schedule is composed; its parameter is the current schedule
18
 *
19
 * - "extender.result": fires when all scheduled tasks are completed; its parameter is current results (and it cannot be modified)
20
 *
21
 * - "extender.signal.[SIGNAME]": in case of signal received
22
 *
23
 * @package     Comodojo extender
24
 * @author      Marco Giovinazzi <[email protected]>
25
 * @license     GPL-3.0+
26
 *
27
 * LICENSE:
28
 * 
29
 * This program is free software: you can redistribute it and/or modify
30
 * it under the terms of the GNU Affero General Public License as
31
 * published by the Free Software Foundation, either version 3 of the
32
 * License, or (at your option) any later version.
33
 *
34
 * This program is distributed in the hope that it will be useful,
35
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37
 * GNU Affero General Public License for more details.
38
 *
39
 * You should have received a copy of the GNU Affero General Public License
40
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
41
 */
42
43
class Events {
44
45
    /**
46
     * Hooks database (a simple array!).
47
     *
48
     * @var     array
49
     */
50
    private $hooks = array();
51
52
    /**
53
     * Logger, injected by extender
54
     *
55
     * @var \Monolog\Logger
56
     */
57
    private $logger = null;
58
59
    /**
60
     * Events constructor
61
     *
62
     * It does nothing special: called at boot time, only notify that events
63
     * are ready.
64
     * 
65
     * @param   \Monolog\Logger    $logger
66
     *
67
     */
68 12
    final public function __construct(\Monolog\Logger $logger) {
69
70 12
        $this->logger = $logger;
71
72 12
    }
73
74
    /**
75
     * Add an event
76
     *
77
     * It link the $event to $callback that will we executed once event will be called.
78
     * Callback can also be addressed via $class->$method using third parameter
79
     * ($method).
80
     *
81
     * @param   string  $event      Event name
82
     * @param   mixed   $callback   Callback (or callback class)
83
     * @param   string  $method     (optional) callback method
84
     *
85
     * @return  bool
86
     */
87 3
    final public function add($event, $callback, $method = null) {
88
89 3
        if ( empty($event) || empty($callback) ) {
90
91
            $this->logger->warning('Unable to add hook', array(
92
                'CALLBACK' => $callback,
93
                'METHOD' => $method,
94
                'EVENT' => $event
95
            ));
96
97
            return false;
98
99 3
        } else if ( is_null($method) ) {
100
101 3
            if ( isset($this->hooks[$event]) ) array_push($this->hooks[$event], $callback);
102
103 3
            else $this->hooks[$event] = array($callback);
104
105 3
        } else {
106
107
            if ( isset($this->hooks[$event]) ) array_push($this->hooks[$event], array($callback, $method));
108
109
            else $this->hooks[$event] = array(array($callback, $method));
110
111
        }
112
113 3
        return true;
114
115
    }
116
117
    /**
118
     * Remove an event
119
     *
120
     * If optional parameter $callback is provided, only the event referring this
121
     * callback (or callback class) will be removed. Otherwise, any callback related
122
     * to event will be deleted.
123
     *
124
     * @param   string  $event      Event name
125
     * @param   string  $callback   Callback (or callback class)
126
     *
127
     * @return  bool
128
     */
129
    final public function remove($event, $callback = null) {
130
131
        if ( is_null($callback) && isset($this->hooks[$event]) ) {
132
133
            unset($this->hooks[$event]);
134
135
            return true;
136
137
        } else if ( isset($this->hooks[$event]) ) {
138
139
            foreach ( $this->hooks[$event] as $key => $hook ) {
140
141
                if ( is_array($hook) ) {
142
143
                    if ( $hook[0] == $callback ) {
144
145
                        unset($this->hooks[$event][$key]);
146
147
                        return true;
148
149
                    }
150
151
                } else {
152
153
                    if ( $hook == $callback ) {
154
155
                        unset($this->hooks[$event][$key]);
156
157
                        return true;
158
159
                    }
160
161
                }
162
163
            }
164
165
            return false;
166
167
        } else return false;
168
169
    }
170
171
    /**
172
     * Fire an event
173
     *
174
     * @param   string  $event      Event name
175
     * @param   string  $type       the type of event
176
     * @param   Object  $data       Data to provide to callback
177
     */
178 3
    final public function fire($event, $type, $data) {
179
180 3
        $this->logger->info('Firing event', array(
181
            'EVENT' =>  $event
182 3
        ));
183
184 3
        $value = $data;
185
186 3
        if ( isset($this->hooks[$event]) ) {
187
188
            foreach ( $this->hooks[$event] as $callback ) {
189
190
                $return_value = null;
191
192
                if ( is_array($callback) ) {
193
194
                    if ( is_callable(Array($callback[0], $callback[1])) ) {
195
196
                        try {
197
198
                            $return_value = call_user_func(Array($callback[0], $callback[1]), $value);
199
200
                        } catch (Exception $e) {
201
202
                            $this->logger->error('Hook error', array(
203
                                'EVENT'    => $event,
204
                                'CALLBACK' => $callback[0],
205
                                'METHOD'   => $callback[1],
206
                                'CODE'     => $e->getCode(),
207
                                'MESSAGE'  => $e->getMessage()
208
                            ));
209
210
                            continue;
211
212
                        }
213
214
                    } else {
215
216
                        $this->logger->warning('Skipping not-callable hook', array(
217
                            'EVENT'    => $event,
218
                            'CALLBACK' => $callback[0],
219
                            'METHOD'   => $callback[1]
220
                        ));
221
222
                        continue;
223
224
                    }
225
226
                } else {
227
228
                    if ( is_callable($callback) ) {
229
230
                        try {
231
232
                            $return_value = call_user_func($callback, $value);
233
234
                        } catch (Exception $e) {
235
236
                            $this->logger->error('Hook error', array(
237
                                'EVENT'    => $event,
238
                                'CALLBACK' => $callback,
239
                                'CODE'     => $e->getCode(),
240
                                'MESSAGE'  => $e->getMessage()
241
                            ));
242
243
                            continue;
244
245
                        }
246
247
                    } else {
248
249
                        $this->logger->warning('Skipping not-callable hook', array(
250
                            'EVENT'    => $event,
251
                            'CALLBACK' => $callback
252
                        ));
253
254
                        continue;
255
256
                    }
257
258
                }
259
260
                switch ( $type ) {
261
262
                    case 'TASKSTABLE':
263
264
                    $value = $return_value instanceof \Comodojo\Extender\TasksTable ? $return_value : $value;
265
266
                    break;
267
268
                    case 'SCHEDULE':
269
270
                    $value = $return_value instanceof \Comodojo\Extender\Scheduler\Schedule ? $return_value : $value;
271
272
                    break;
273
274
                    case 'VOID':
275
                    default:
276
277
                    // $value = $value;
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
278
279
                    break;
280
281
                }
282
283
            }
284
285
            return $value;
286
287
        }
288
289 3
        return $data;
290
291
    }
292
293
    /**
294
     * Create a Events controller and load plugins from EXTENDER_PLUGINS_CONFIG
295
     *
296
     * @param \Monolog\Logger $logger
297
     * 
298
     * @return array
299
     */
300 12 View Code Duplication
    public static function load(\Monolog\Logger $logger) {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
301
302 12
        $table = new Events($logger);
303
304 12
        if ( defined("EXTENDER_PLUGINS_CONFIG") && is_readable(EXTENDER_PLUGINS_CONFIG) ) {
305
306 12
            $events = Spyc::YAMLLoad(EXTENDER_PLUGINS_CONFIG);
307
308 12
            foreach ($events as $event) {
309
                
310
                $method = empty($event["data"]["method"]) ? null : $event["data"]["method"];
311
312
                $table->add($event["data"]["event"], $event["data"]["class"], $method);
313
314 12
            }
315
316 12
        }
317
318 12
        return $table;
319
320
    }
321
322
}
323