]> git.wh0rd.org Git - tt-rss.git/blob - classes/pluginhost.php
add experimental base for plugin vfeeds (3 pane mode not yet
[tt-rss.git] / classes / pluginhost.php
1 <?php
2 class PluginHost {
3         private $link;
4         private $hooks = array();
5         private $plugins = array();
6         private $handlers = array();
7         private $commands = array();
8         private $storage = array();
9         private $feeds = array();
10         private $owner_uid;
11         private $debug;
12
13         const HOOK_ARTICLE_BUTTON = 1;
14         const HOOK_ARTICLE_FILTER = 2;
15         const HOOK_PREFS_TAB = 3;
16         const HOOK_PREFS_TAB_SECTION = 4;
17         const HOOK_PREFS_TABS = 5;
18         const HOOK_FEED_PARSED = 6;
19         const HOOK_UPDATE_TASK = 7;
20         const HOOK_AUTH_USER = 8;
21         const HOOK_HOTKEY_MAP = 9;
22         const HOOK_RENDER_ARTICLE = 10;
23         const HOOK_RENDER_ARTICLE_CDM = 11;
24         const HOOK_FEED_FETCHED = 12;
25         const HOOK_SANITIZE = 13;
26         const HOOK_RENDER_ARTICLE_API = 14;
27
28         const KIND_ALL = 1;
29         const KIND_SYSTEM = 2;
30         const KIND_USER = 3;
31
32         function __construct($link) {
33                 $this->link = $link;
34
35                 $this->storage = $_SESSION["plugin_storage"];
36
37                 if (!$this->storage) $this->storage = array();
38         }
39
40         private function register_plugin($name, $plugin) {
41                 //array_push($this->plugins, $plugin);
42                 $this->plugins[$name] = $plugin;
43         }
44
45         function get_link() {
46                 return $this->link;
47         }
48
49         function get_plugins() {
50                 return $this->plugins;
51         }
52
53         function get_plugin($name) {
54                 return $this->plugins[$name];
55         }
56
57         function run_hooks($type, $method, $args) {
58                 foreach ($this->get_hooks($type) as $hook) {
59                         $hook->$method($args);
60                 }
61         }
62
63         function add_hook($type, $sender) {
64                 if (!is_array($this->hooks[$type])) {
65                         $this->hooks[$type] = array();
66                 }
67
68                 array_push($this->hooks[$type], $sender);
69         }
70
71         function del_hook($type, $sender) {
72                 if (is_array($this->hooks[$type])) {
73                         $key = array_Search($this->hooks[$type], $sender);
74                         if ($key !== FALSE) {
75                                 unset($this->hooks[$type][$key]);
76                         }
77                 }
78         }
79
80         function get_hooks($type) {
81                 if (isset($this->hooks[$type])) {
82                         return $this->hooks[$type];
83                 } else {
84                         return array();
85                 }
86         }
87         function load_all($kind, $owner_uid = false) {
88                 $plugins = array_map("basename", glob("plugins/*"));
89                 $this->load(join(",", $plugins), $kind, $owner_uid);
90         }
91
92         function load($classlist, $kind, $owner_uid = false) {
93                 $plugins = explode(",", $classlist);
94
95                 $this->owner_uid = (int) $owner_uid;
96
97                 foreach ($plugins as $class) {
98                         $class = trim($class);
99                         $class_file = strtolower(basename($class));
100                         $file = dirname(__FILE__)."/../plugins/$class_file/init.php";
101
102                         if (!isset($this->plugins[$class])) {
103                                 if (file_exists($file)) require_once $file;
104
105                                 if (class_exists($class) && is_subclass_of($class, "Plugin")) {
106                                         $plugin = new $class($this);
107
108                                         switch ($kind) {
109                                         case $this::KIND_SYSTEM:
110                                                 if ($this->is_system($plugin)) {
111                                                         $plugin->init($this);
112                                                         $this->register_plugin($class, $plugin);
113                                                 }
114                                                 break;
115                                         case $this::KIND_USER:
116                                                 if (!$this->is_system($plugin)) {
117                                                         $plugin->init($this);
118                                                         $this->register_plugin($class, $plugin);
119                                                 }
120                                                 break;
121                                         case $this::KIND_ALL:
122                                                 $plugin->init($this);
123                                                 $this->register_plugin($class, $plugin);
124                                                 break;
125                                         }
126                                 }
127                         }
128                 }
129         }
130
131         function is_system($plugin) {
132                 $about = $plugin->about();
133
134                 return @$about[3];
135         }
136
137         // only system plugins are allowed to modify routing
138         function add_handler($handler, $method, $sender) {
139                 $handler = str_replace("-", "_", strtolower($handler));
140                 $method = strtolower($method);
141
142                 if ($this->is_system($sender)) {
143                         if (!is_array($this->handlers[$handler])) {
144                                 $this->handlers[$handler] = array();
145                         }
146
147                         $this->handlers[$handler][$method] = $sender;
148                 }
149         }
150
151         function del_handler($handler, $method) {
152                 $handler = str_replace("-", "_", strtolower($handler));
153                 $method = strtolower($method);
154
155                 if ($this->is_system($sender)) {
156                         unset($this->handlers[$handler][$method]);
157                 }
158         }
159
160         function lookup_handler($handler, $method) {
161                 $handler = str_replace("-", "_", strtolower($handler));
162                 $method = strtolower($method);
163
164                 if (is_array($this->handlers[$handler])) {
165                         if (isset($this->handlers[$handler]["*"])) {
166                                 return $this->handlers[$handler]["*"];
167                         } else {
168                                 return $this->handlers[$handler][$method];
169                         }
170                 }
171
172                 return false;
173         }
174
175         function add_command($command, $description, $sender) {
176                 $command = str_replace("-", "_", strtolower($command));
177
178                 $this->commands[$command] = array("description" => $description,
179                         "class" => $sender);
180         }
181
182         function del_command($command) {
183                 $command = "-" . strtolower($command);
184
185                 unset($this->commands[$command]);
186         }
187
188         function lookup_command($command) {
189                 $command = "-" . strtolower($command);
190
191                 if (is_array($this->commands[$command])) {
192                         return $this->commands[$command]["class"];
193                 } else {
194                         return false;
195                 }
196
197                 return false;
198         }
199
200         function get_commands() {
201                 return $this->commands;
202         }
203
204         function run_commands($args) {
205                 foreach ($this->get_commands() as $command => $data) {
206                         if (isset($args[$command])) {
207                                 $command = str_replace("-", "", $command);
208                                 $data["class"]->$command($args);
209                         }
210                 }
211         }
212
213         function load_data($force = false) {
214                 if ($this->owner_uid && (!$_SESSION["plugin_storage"] || $force))  {
215                         $plugin = db_escape_string($this->link, $plugin);
216
217                         $result = db_query($this->link, "SELECT name, content FROM ttrss_plugin_storage
218                                 WHERE owner_uid = '".$this->owner_uid."'");
219
220                         while ($line = db_fetch_assoc($result)) {
221                                 $this->storage[$line["name"]] = unserialize($line["content"]);
222                         }
223
224                         $_SESSION["plugin_storage"] = $this->storage;
225                 }
226         }
227
228         private function save_data($plugin) {
229                 if ($this->owner_uid) {
230                         $plugin = db_escape_string($this->link, $plugin);
231
232                         db_query($this->link, "BEGIN");
233
234                         $result = db_query($this->link,"SELECT id FROM ttrss_plugin_storage WHERE
235                                 owner_uid= '".$this->owner_uid."' AND name = '$plugin'");
236
237                         if (!isset($this->storage[$plugin]))
238                                 $this->storage[$plugin] = array();
239
240                         $content = db_escape_string($this->link, serialize($this->storage[$plugin]));
241
242                         if (db_num_rows($result) != 0) {
243                                 db_query($this->link, "UPDATE ttrss_plugin_storage SET content = '$content'
244                                         WHERE owner_uid= '".$this->owner_uid."' AND name = '$plugin'");
245
246                         } else {
247                                 db_query($this->link, "INSERT INTO ttrss_plugin_storage
248                                         (name,owner_uid,content) VALUES
249                                         ('$plugin','".$this->owner_uid."','$content')");
250                         }
251
252                         db_query($this->link, "COMMIT");
253                 }
254         }
255
256         function set($sender, $name, $value, $sync = true) {
257                 $idx = get_class($sender);
258
259                 if (!isset($this->storage[$idx]))
260                         $this->storage[$idx] = array();
261
262                 $this->storage[$idx][$name] = $value;
263
264                 $_SESSION["plugin_storage"] = $this->storage;
265
266                 if ($sync) $this->save_data(get_class($sender));
267         }
268
269         function get($sender, $name, $default_value = false) {
270                 $idx = get_class($sender);
271
272                 if (isset($this->storage[$idx][$name])) {
273                         return $this->storage[$idx][$name];
274                 } else {
275                         return $default_value;
276                 }
277         }
278
279         function get_all($sender) {
280                 $idx = get_class($sender);
281
282                 return $this->storage[$idx];
283         }
284
285         function clear_data($sender) {
286                 if ($this->owner_uid) {
287                         $idx = get_class($sender);
288
289                         unset($this->storage[$idx]);
290
291                         db_query($this->link, "DELETE FROM ttrss_plugin_storage WHERE name = '$idx'
292                                 AND owner_uid = " . $this->owner_uid);
293
294                         $_SESSION["plugin_storage"] = $this->storage;
295                 }
296         }
297
298         function set_debug($debug) {
299                 $this->debug = $debug;
300         }
301
302         function get_debug() {
303                 return $this->debug;
304         }
305
306         // Plugin feed functions are *EXPERIMENTAL*!
307
308         // cat_id: only -1 is supported (Special)
309         function add_feed($cat_id, $title, $icon, $sender) {
310                 if (!$this->feeds[$cat_id]) $this->feeds[$cat_id] = array();
311
312                 $id = count($this->feeds[$cat_id]);
313
314                 array_push($this->feeds[$cat_id],
315                         array('id' => $id, 'title' => $title, 'sender' => $sender, 'icon' => $icon));
316
317                 return $id;
318         }
319
320         function get_feeds($cat_id) {
321                 return $this->feeds[$cat_id];
322         }
323
324         // convert feed_id (e.g. -129) to pfeed_id first
325         function get_feed_handler($pfeed_id) {
326                 foreach ($this->feeds as $cat) {
327                         foreach ($cat as $feed) {
328                                 if ($feed['id'] == $pfeed_id) {
329                                         return $feed['sender'];
330                                 }
331                         }
332                 }
333         }
334
335         static function pfeed_to_feed_id($label) {
336                 return PLUGIN_FEED_BASE_INDEX - 1 - abs($label);
337         }
338
339         static function feed_to_pfeed_id($feed) {
340                 return PLUGIN_FEED_BASE_INDEX - 1 + abs($feed);
341         }
342
343 }
344 ?>