Passed
Push — 2.x ( a1962c...4a3192 )
by Terry
02:33
created

EventDispatcher::doDispatch()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 17
nc 6
nop 2
dl 0
loc 32
rs 8.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the Shieldon package.
4
 *
5
 * (c) Terry L. <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * php version 7.1.0
11
 *
12
 * @category  Web-security
13
 * @package   Shieldon
14
 * @author    Terry Lin <[email protected]>
15
 * @copyright 2019 terrylinooo
16
 * @license   https://github.com/terrylinooo/shieldon/blob/2.x/LICENSE MIT
17
 * @link      https://github.com/terrylinooo/shieldon
18
 * @see       https://shieldon.io
19
 */
20
21
declare(strict_types=1);
22
23
namespace Shieldon\Firewall;
24
25
/**
26
 * This is just a simple event dispatcher for Shieldon firewall.
27
 */
28
class EventDispatcher
29
{
30
    /**
31
     * Singleton pattern based instance.
32
     *
33
     * @var self|null
34
     */
35
    public static $instance;
36
    
37
    /**
38
     * The collection of events.
39
     *
40
     * @var array|null
41
     */
42
    public static $events;
43
44
    /**
45
     * Constructer.
46
     */
47
    private function __construct()
48
    {
49
        self::$instance = null;
50
51
        self::$events = [];
52
    }
53
54
    /**
55
     * Singleton.
56
     *
57
     * @return self
58
     */
59
    public static function instance(): self
60
    {
61
        if (!self::$instance) {
62
            self::$instance = new EventDispatcher();
63
        }
64
65
        return self::$instance;
66
    }
67
68
    /**
69
     * Add a listener.
70
     *
71
     * @param string        $name      The name of an event.
72
     * @param string|array  $func      Callable function or class.
73
     * @param int           $priority  The execution priority.
74
     *
75
     * @return bool
76
     */
77
    public function addListener($name, $func, $priority = 10)
78
    {
79
        // The priority postion has been taken.
80
        if (isset(self::$events[$name][$priority])) {
81
            return false;
82
        }
83
84
        // $func should be a function name or a callable function.
85
        self::$events[$name][$priority] = $func;
86
87
        // Or, it is an array contains Class and method name.
88
        if (is_array($func)) {
89
90
            self::$events[$name][$priority] = [
91
                $func[0],
92
                $func[1],
93
            ];
94
        }
95
        
96
        return true;
97
    }
98
99
    /**
100
     * Execute the listener.
101
     *
102
     * @param string $name The name of an event.
103
     * @param array  $args The arguments.
104
     *
105
     * @return mixed
106
     */
107
    public function doDispatch(string $name, $args = [])
108
    {
109
        if (!isset(self::$events[$name])) {
110
            return;
111
        }
112
113
        $return = null;
114
115
        ksort(self::$events[$name]);
116
        
117
        foreach (self::$events[$name] as $action) {
118
119
            if (is_string($action) && function_exists($action)) {
120
                $return = call_user_func_array(
121
                    $action, // Callable function.
122
                    $args
123
                );
124
125
            } elseif (is_array($action)) {
126
                $return = call_user_func_array(
127
                    [
128
                        $action[0], // Class.
129
                        $action[1], // The method of that class.
130
                    ],
131
                    $args
132
                );
133
            } elseif (is_callable($action)) {
134
                $return = $action($args);
135
            }
136
        }
137
138
        return $return;
139
    }
140
}
141
142