Completed
Push — master ( b3f98f...654a3a )
by Arman
20s queued 16s
created

HookManager::on()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.9.7
13
 */
14
15
namespace Quantum\Hook;
16
17
use Quantum\Config\Exceptions\ConfigException;
18
use Quantum\Hook\Exceptions\HookException;
19
use Quantum\Di\Exceptions\DiException;
20
use Quantum\Loader\Setup;
21
use ReflectionException;
22
23
/**
24
 * Class HookManager
25
 * @package Quantum\Hooks
26
 */
27
class HookManager
28
{
29
30
    /**
31
     * Core hooks 
32
     */
33
    const CORE_HOOKS = [];
34
35
    /**
36
     * Registered hooks store
37
     * @var array
38
     */
39
    private static $store = [];
40
41
    /**
42
     * @var HookManager|null
43
     */
44
    private static $instance = null;
45
46
    /**
47
     * @throws HookException
48
     * @throws ConfigException
49
     * @throws DiException
50
     * @throws ReflectionException
51
     */
52
    private function __construct()
53
    {
54
        if (!config()->has('hooks')) {
55
            config()->import(new Setup('config', 'hooks'));
56
        }
57
58
        $registeredHooks = array_merge(self::CORE_HOOKS, config()->get('hooks') ?: []);
59
60
        foreach ($registeredHooks as $hookName) {
61
            $this->register($hookName);
62
        }
63
    }
64
65
    /**
66
     * HookManager instance
67
     * @return HookManager
68
     */
69
    public static function getInstance(): HookManager
70
    {
71
        if (self::$instance == null) {
72
            self::$instance = new self();
73
        }
74
75
        return self::$instance;
76
    }
77
78
    /**
79
     * Adds new listener for given hook
80
     * @param string $name
81
     * @param callable $function
82
     * @throws HookException
83
     */
84
    public function on(string $name, callable $function)
85
    {
86
        if (!$this->exists($name)) {
87
            throw HookException::unregisteredHookName($name);
88
        }
89
90
        self::$store[$name][] = $function;
91
    }
92
93
    /**
94
     * Fires the hook
95
     * @param string $name
96
     * @param array|null $args
97
     * @throws HookException
98
     */
99
    public function fire(string $name, ?array $args = null)
100
    {
101
        if (!$this->exists($name)) {
102
            throw HookException::unregisteredHookName($name);
103
        }
104
105
        foreach (self::$store[$name] as $index => $fn) {
106
            unset(self::$store[$name][$index]);
107
            $fn($args);
108
        }
109
    }
110
111
    /**
112
     * Gets all registered hooks
113
     * @return array
114
     */
115
    public static function getRegistered(): array
116
    {
117
        return self::$store;
118
    }
119
120
    /**
121
     * Registers new hook 
122
     * @param string $name
123
     * @throws HookException
124
     */
125
    protected function register(string $name)
126
    {
127
        if ($this->exists($name)) {
128
            throw HookException::hookDuplicateName($name);
129
        }
130
131
        self::$store[$name] = [];
132
    }
133
134
    /**
135
     * Checks if hooks registered
136
     * @param string $name
137
     * @return bool
138
     */
139
    protected function exists(string $name): bool
140
    {
141
        return key_exists($name, self::$store);
142
    }
143
}
144