/
BotHooks.php
executable file
·146 lines (125 loc) · 4.17 KB
/
BotHooks.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
namespace Slackbot;
require_once 'exception/ConfigException.php';
class BotHooks {
const CONFIG_FILE = 'config.ini';
const HOOK_DIR = 'hooks';
/**
* Single instance of the BotHooks object.
* @type BotHooks
*/
private static $instance = null;
/**
* List of all loaded hooks.
* @type Array
*/
private $hooks = array();
/**
* Mapping of all found triggers and their respective hooks.
* @type Array
*/
private $triggers = array();
/**
* Singleton constructor to initialize the BotHooks object.
*/
private function __construct() {
$this->initHooks();
}
/**
* Initializes and returns an instance of the BotHooks object.
*
* @return BotHooks
*/
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new BotHooks();
}
return self::$instance;
}
/**
* Returns a list of all hooks that accept the given token.
*
* @param String $token
* @return Array
*/
public function getHooksByToken($token) {
$hooks = array();
foreach ($this->hooks as $hook) {
if ($hook->isValidToken($token)) {
$hooks[] = $hook;
}
}
return $hooks;
}
/**
* Returns a list of all hooks that support the given trigger.
*
* @param String $trigger
* @return Array;
*/
public function getHooksByTrigger($trigger) {
return isset($this->triggers[$trigger]) ? $this->triggers[$trigger] : array();
}
/**
* Initializes all of the hooks found in the configured hook directory.
*/
private function initHooks() {
if (!is_dir(BotHooks::HOOK_DIR)) {
throw new Slackbot\Exception\ConfigException('Cannot locate hook directory "' . BotHooks::HOOK_DIR . '"');
}
$hookFiles = glob(BotHooks::HOOK_DIR . '/[A-Z][a-z]*Hook.php');
foreach ($hookFiles as $hookFile) {
// include the file
require_once $hookFile;
// load a class that has the same name as the file
$fileName = substr($hookFile, strrpos($hookFile, '/') + 1);
$className = 'Slackbot\\Hooks\\' . substr($fileName, 0, strlen($fileName) - 4);
$hookInstance = new $className();
if (!class_exists($className) && is_subclass_of($hookInstance, 'Slackbot\\Hooks\\Hook')) {
unset($hookInstance);
continue;
}
// store the hook
$this->hooks[$hookInstance->getName()] = $hookInstance;
// process the triggers supported by the hook
$this->loadHookTriggers($hookInstance);
}
// process the tokens supported for the hooks
$this->loadHookConfig();
}
/**
* Load and store the supported tokens for each bot.
*/
private function loadHookConfig() {
if (!is_readable(self::CONFIG_FILE)) {
throw new \Slackbot\Exception\ConfigException('Missing config file ' . self::CONFIG_FILE);
}
$config = parse_ini_file(self::CONFIG_FILE, true);
foreach ($config as $sectionName => $settings) {
if (isset($settings['token'])) {
foreach ($this->hooks as $hookName => $hook) {
if ($hookName === $sectionName) {
$hook->addTokens((array)$settings['token']);
break;
}
}
}
}
}
/**
* Generate a trigger-to-hook map for the given hook and each of it's supported triggers.
*
* @param \Slackbot\Hooks\Hook $hook
*/
private function loadHookTriggers(\Slackbot\Hooks\Hook $hook) {
$triggers = $hook->getTriggers();
foreach ($triggers as $trigger) {
if (!isset($this->triggers[$trigger])) {
$this->triggers[$trigger] = array();
}
$this->triggers[$trigger][] = $hook;
}
}
}
// auto-initialize this class upon being included =]
BotHooks::getInstance();