1
|
|
|
<?php |
2
|
|
|
class PluginHost { |
3
|
|
|
private $pdo; |
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 $api_methods = array(); |
11
|
|
|
private $plugin_actions = array(); |
12
|
|
|
private $owner_uid; |
13
|
|
|
private $last_registered; |
14
|
|
|
private static $instance; |
15
|
|
|
|
16
|
|
|
const API_VERSION = 2; |
17
|
|
|
|
18
|
|
|
// Hooks marked with *1 are run in global context and available |
19
|
|
|
// to plugins loaded in config.php only |
20
|
|
|
|
21
|
|
|
const HOOK_ARTICLE_BUTTON = 1; |
22
|
|
|
const HOOK_ARTICLE_FILTER = 2; |
23
|
|
|
const HOOK_PREFS_TAB = 3; |
24
|
|
|
const HOOK_PREFS_TAB_SECTION = 4; |
25
|
|
|
const HOOK_PREFS_TABS = 5; |
26
|
|
|
const HOOK_FEED_PARSED = 6; |
27
|
|
|
const HOOK_UPDATE_TASK = 7; // *1 |
28
|
|
|
const HOOK_AUTH_USER = 8; |
29
|
|
|
const HOOK_HOTKEY_MAP = 9; |
30
|
|
|
const HOOK_RENDER_ARTICLE = 10; |
31
|
|
|
const HOOK_RENDER_ARTICLE_CDM = 11; |
32
|
|
|
const HOOK_FEED_FETCHED = 12; |
33
|
|
|
const HOOK_SANITIZE = 13; |
34
|
|
|
const HOOK_RENDER_ARTICLE_API = 14; |
35
|
|
|
const HOOK_TOOLBAR_BUTTON = 15; |
36
|
|
|
const HOOK_ACTION_ITEM = 16; |
37
|
|
|
const HOOK_HEADLINE_TOOLBAR_BUTTON = 17; |
38
|
|
|
const HOOK_HOTKEY_INFO = 18; |
39
|
|
|
const HOOK_ARTICLE_LEFT_BUTTON = 19; |
40
|
|
|
const HOOK_PREFS_EDIT_FEED = 20; |
41
|
|
|
const HOOK_PREFS_SAVE_FEED = 21; |
42
|
|
|
const HOOK_FETCH_FEED = 22; |
43
|
|
|
const HOOK_QUERY_HEADLINES = 23; |
44
|
|
|
const HOOK_HOUSE_KEEPING = 24; // *1 |
45
|
|
|
const HOOK_SEARCH = 25; |
46
|
|
|
const HOOK_FORMAT_ENCLOSURES = 26; |
47
|
|
|
const HOOK_SUBSCRIBE_FEED = 27; |
48
|
|
|
const HOOK_HEADLINES_BEFORE = 28; |
49
|
|
|
const HOOK_RENDER_ENCLOSURE = 29; |
50
|
|
|
const HOOK_ARTICLE_FILTER_ACTION = 30; |
51
|
|
|
const HOOK_ARTICLE_EXPORT_FEED = 31; |
52
|
|
|
const HOOK_MAIN_TOOLBAR_BUTTON = 32; |
53
|
|
|
const HOOK_ENCLOSURE_ENTRY = 33; |
54
|
|
|
const HOOK_FORMAT_ARTICLE = 34; |
55
|
|
|
const HOOK_FORMAT_ARTICLE_CDM = 35; /* RIP */ |
56
|
|
|
const HOOK_FEED_BASIC_INFO = 36; |
57
|
|
|
const HOOK_SEND_LOCAL_FILE = 37; |
58
|
|
|
const HOOK_UNSUBSCRIBE_FEED = 38; |
59
|
|
|
const HOOK_SEND_MAIL = 39; |
60
|
|
|
const HOOK_FILTER_TRIGGERED = 40; |
61
|
|
|
const HOOK_GET_FULL_TEXT = 41; |
62
|
|
|
const HOOK_ARTICLE_IMAGE = 42; |
63
|
|
|
const HOOK_FEED_TREE = 43; |
64
|
|
|
const HOOK_IFRAME_WHITELISTED = 44; |
65
|
|
|
|
66
|
|
|
const KIND_ALL = 1; |
67
|
|
|
const KIND_SYSTEM = 2; |
68
|
|
|
const KIND_USER = 3; |
69
|
|
|
|
70
|
|
|
public static function object_to_domain($plugin) { |
71
|
|
|
return strtolower(get_class($plugin)); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
public function __construct() { |
75
|
|
|
$this->pdo = Db::pdo(); |
76
|
|
|
|
77
|
|
|
$this->storage = array(); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
private function __clone() { |
81
|
|
|
// |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
public static function getInstance() { |
85
|
|
|
if (self::$instance == null) { |
86
|
|
|
self::$instance = new self(); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
return self::$instance; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
private function register_plugin($name, $plugin) { |
93
|
|
|
//array_push($this->plugins, $plugin); |
94
|
|
|
$this->plugins[$name] = $plugin; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
// needed for compatibility with API 1 |
98
|
|
|
public function get_link() { |
99
|
|
|
return false; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
public function get_dbh() { |
103
|
|
|
return Db::get(); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
public function get_pdo() { |
107
|
|
|
return $this->pdo; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
public function get_plugin_names() { |
111
|
|
|
$names = array(); |
112
|
|
|
|
113
|
|
|
foreach ($this->plugins as $p) { |
114
|
|
|
array_push($names, get_class($p)); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return $names; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
public function get_plugins() { |
121
|
|
|
return $this->plugins; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
public function get_plugin($name) { |
125
|
|
|
return $this->plugins[strtolower($name)]; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
public function run_hooks($type, $method, $args) { |
129
|
|
|
foreach ($this->get_hooks($type) as $hook) { |
130
|
|
|
$hook->$method($args); |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
public function add_hook($type, $sender, $priority = 50) { |
135
|
|
|
$priority = (int) $priority; |
136
|
|
|
|
137
|
|
|
if (!is_array($this->hooks[$type])) { |
138
|
|
|
$this->hooks[$type] = []; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
if (!is_array($this->hooks[$type][$priority])) { |
142
|
|
|
$this->hooks[$type][$priority] = []; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
array_push($this->hooks[$type][$priority], $sender); |
146
|
|
|
ksort($this->hooks[$type]); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
public function del_hook($type, $sender) { |
150
|
|
|
if (is_array($this->hooks[$type])) { |
151
|
|
|
foreach (array_keys($this->hooks[$type]) as $prio) { |
152
|
|
|
$key = array_search($sender, $this->hooks[$type][$prio]); |
153
|
|
|
|
154
|
|
|
if ($key !== false) { |
155
|
|
|
unset($this->hooks[$type][$prio][$key]); |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
public function get_hooks($type) { |
162
|
|
|
if (isset($this->hooks[$type])) { |
163
|
|
|
$tmp = []; |
164
|
|
|
|
165
|
|
|
foreach (array_keys($this->hooks[$type]) as $prio) { |
166
|
|
|
$tmp = array_merge($tmp, $this->hooks[$type][$prio]); |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
return $tmp; |
170
|
|
|
} else { |
171
|
|
|
return []; |
172
|
|
|
} |
173
|
|
|
} |
174
|
|
|
public function load_all($kind, $owner_uid = false, $skip_init = false) { |
175
|
|
|
|
176
|
|
|
$plugins = array_merge(glob("plugins/*"), glob("plugins.local/*")); |
|
|
|
|
177
|
|
|
$plugins = array_filter($plugins, "is_dir"); |
178
|
|
|
$plugins = array_map("basename", $plugins); |
179
|
|
|
|
180
|
|
|
asort($plugins); |
181
|
|
|
|
182
|
|
|
$this->load(join(",", $plugins), $kind, $owner_uid, $skip_init); |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
public function load($classlist, $kind, $owner_uid = false, $skip_init = false) { |
186
|
|
|
$plugins = explode(",", $classlist); |
187
|
|
|
|
188
|
|
|
$this->owner_uid = (int) $owner_uid; |
189
|
|
|
|
190
|
|
|
foreach ($plugins as $class) { |
191
|
|
|
$class = trim($class); |
192
|
|
|
$class_file = strtolower(clean_filename($class)); |
193
|
|
|
|
194
|
|
|
if (!is_dir(__DIR__."/../plugins/$class_file") && |
195
|
|
|
!is_dir(__DIR__."/../plugins.local/$class_file")) { |
196
|
|
|
continue; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
// try system plugin directory first |
200
|
|
|
$file = __DIR__."/../plugins/$class_file/init.php"; |
201
|
|
|
$vendor_dir = __DIR__."/../plugins/$class_file/vendor"; |
202
|
|
|
|
203
|
|
|
if (!file_exists($file)) { |
204
|
|
|
$file = __DIR__."/../plugins.local/$class_file/init.php"; |
205
|
|
|
$vendor_dir = __DIR__."/../plugins.local/$class_file/vendor"; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
if (!isset($this->plugins[$class])) { |
209
|
|
|
if (file_exists($file)) { |
210
|
|
|
require_once $file; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
if (class_exists($class) && is_subclass_of($class, "Plugin")) { |
214
|
|
|
|
215
|
|
|
// register plugin autoloader if necessary, for namespaced classes ONLY |
216
|
|
|
// layout corresponds to tt-rss main /vendor/author/Package/Class.php |
217
|
|
|
|
218
|
|
|
if (file_exists($vendor_dir)) { |
219
|
|
|
spl_autoload_register(function($class) use ($vendor_dir) { |
220
|
|
|
|
221
|
|
|
if (strpos($class, '\\') !== false) { |
222
|
|
|
list ($namespace, $class_name) = explode('\\', $class, 2); |
223
|
|
|
|
224
|
|
|
if ($namespace && $class_name) { |
225
|
|
|
$class_file = "$vendor_dir/$namespace/".str_replace('\\', '/', $class_name).".php"; |
226
|
|
|
|
227
|
|
|
if (file_exists($class_file)) { |
228
|
|
|
require_once $class_file; |
229
|
|
|
} |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
}); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
$plugin = new $class($this); |
236
|
|
|
|
237
|
|
|
$plugin_api = $plugin->api_version(); |
238
|
|
|
|
239
|
|
|
if ($plugin_api < PluginHost::API_VERSION) { |
240
|
|
|
user_error("plugin $class is not compatible with current API version (need: ".PluginHost::API_VERSION.", got: $plugin_api)", E_USER_WARNING); |
241
|
|
|
continue; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
if (file_exists(dirname($file)."/locale")) { |
245
|
|
|
_bindtextdomain($class, dirname($file)."/locale"); |
246
|
|
|
_bind_textdomain_codeset($class, "UTF-8"); |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
$this->last_registered = $class; |
250
|
|
|
|
251
|
|
|
switch ($kind) { |
252
|
|
|
case $this::KIND_SYSTEM: |
253
|
|
|
if ($this->is_system($plugin)) { |
254
|
|
|
if (!$skip_init) { |
255
|
|
|
$plugin->init($this); |
256
|
|
|
} |
257
|
|
|
$this->register_plugin($class, $plugin); |
258
|
|
|
} |
259
|
|
|
break; |
260
|
|
|
case $this::KIND_USER: |
261
|
|
|
if (!$this->is_system($plugin)) { |
262
|
|
|
if (!$skip_init) { |
263
|
|
|
$plugin->init($this); |
264
|
|
|
} |
265
|
|
|
$this->register_plugin($class, $plugin); |
266
|
|
|
} |
267
|
|
|
break; |
268
|
|
|
case $this::KIND_ALL: |
269
|
|
|
if (!$skip_init) { |
270
|
|
|
$plugin->init($this); |
271
|
|
|
} |
272
|
|
|
$this->register_plugin($class, $plugin); |
273
|
|
|
break; |
274
|
|
|
} |
275
|
|
|
} |
276
|
|
|
} |
277
|
|
|
} |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
public function is_system($plugin) { |
281
|
|
|
$about = $plugin->about(); |
282
|
|
|
|
283
|
|
|
return @$about[3]; |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
// only system plugins are allowed to modify routing |
287
|
|
|
public function add_handler($handler, $method, $sender) { |
288
|
|
|
$handler = str_replace("-", "_", strtolower($handler)); |
289
|
|
|
$method = strtolower($method); |
290
|
|
|
|
291
|
|
|
if ($this->is_system($sender)) { |
292
|
|
|
if (!is_array($this->handlers[$handler])) { |
293
|
|
|
$this->handlers[$handler] = array(); |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
$this->handlers[$handler][$method] = $sender; |
297
|
|
|
} |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
public function del_handler($handler, $method, $sender) { |
301
|
|
|
$handler = str_replace("-", "_", strtolower($handler)); |
302
|
|
|
$method = strtolower($method); |
303
|
|
|
|
304
|
|
|
if ($this->is_system($sender)) { |
305
|
|
|
unset($this->handlers[$handler][$method]); |
306
|
|
|
} |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
public function lookup_handler($handler, $method) { |
310
|
|
|
$handler = str_replace("-", "_", strtolower($handler)); |
311
|
|
|
$method = strtolower($method); |
312
|
|
|
|
313
|
|
|
if (is_array($this->handlers[$handler])) { |
314
|
|
|
if (isset($this->handlers[$handler]["*"])) { |
315
|
|
|
return $this->handlers[$handler]["*"]; |
316
|
|
|
} else { |
317
|
|
|
return $this->handlers[$handler][$method]; |
318
|
|
|
} |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
return false; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
public function add_command($command, $description, $sender, $suffix = "", $arghelp = "") { |
325
|
|
|
$command = str_replace("-", "_", strtolower($command)); |
326
|
|
|
|
327
|
|
|
$this->commands[$command] = array("description" => $description, |
328
|
|
|
"suffix" => $suffix, |
329
|
|
|
"arghelp" => $arghelp, |
330
|
|
|
"class" => $sender); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
public function del_command($command) { |
334
|
|
|
$command = "-".strtolower($command); |
335
|
|
|
|
336
|
|
|
unset($this->commands[$command]); |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
public function lookup_command($command) { |
340
|
|
|
$command = "-".strtolower($command); |
341
|
|
|
|
342
|
|
|
if (is_array($this->commands[$command])) { |
343
|
|
|
return $this->commands[$command]["class"]; |
344
|
|
|
} else { |
345
|
|
|
return false; |
346
|
|
|
} |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
public function get_commands() { |
350
|
|
|
return $this->commands; |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
public function run_commands($args) { |
354
|
|
|
foreach ($this->get_commands() as $command => $data) { |
355
|
|
|
if (isset($args[$command])) { |
356
|
|
|
$command = str_replace("-", "", $command); |
357
|
|
|
$data["class"]->$command($args); |
358
|
|
|
} |
359
|
|
|
} |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
public function load_data() { |
363
|
|
|
if ($this->owner_uid) { |
364
|
|
|
$sth = $this->pdo->prepare("SELECT name, content FROM ttrss_plugin_storage |
365
|
|
|
WHERE owner_uid = ?"); |
366
|
|
|
$sth->execute([$this->owner_uid]); |
367
|
|
|
|
368
|
|
|
while ($line = $sth->fetch()) { |
369
|
|
|
$this->storage[$line["name"]] = unserialize($line["content"]); |
370
|
|
|
} |
371
|
|
|
} |
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
private function save_data($plugin) { |
375
|
|
|
if ($this->owner_uid) { |
376
|
|
|
$this->pdo->beginTransaction(); |
377
|
|
|
|
378
|
|
|
$sth = $this->pdo->prepare("SELECT id FROM ttrss_plugin_storage WHERE |
379
|
|
|
owner_uid= ? AND name = ?"); |
380
|
|
|
$sth->execute([$this->owner_uid, $plugin]); |
381
|
|
|
|
382
|
|
|
if (!isset($this->storage[$plugin])) { |
383
|
|
|
$this->storage[$plugin] = array(); |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
$content = serialize($this->storage[$plugin]); |
387
|
|
|
|
388
|
|
|
if ($sth->fetch()) { |
389
|
|
|
$sth = $this->pdo->prepare("UPDATE ttrss_plugin_storage SET content = ? |
390
|
|
|
WHERE owner_uid= ? AND name = ?"); |
391
|
|
|
$sth->execute([(string) $content, $this->owner_uid, $plugin]); |
392
|
|
|
|
393
|
|
|
} else { |
394
|
|
|
$sth = $this->pdo->prepare("INSERT INTO ttrss_plugin_storage |
395
|
|
|
(name,owner_uid,content) VALUES |
396
|
|
|
(?, ?, ?)"); |
397
|
|
|
$sth->execute([$plugin, $this->owner_uid, (string) $content]); |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
$this->pdo->commit(); |
401
|
|
|
} |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
public function set($sender, $name, $value, $sync = true) { |
405
|
|
|
$idx = get_class($sender); |
406
|
|
|
|
407
|
|
|
if (!isset($this->storage[$idx])) { |
408
|
|
|
$this->storage[$idx] = array(); |
409
|
|
|
} |
410
|
|
|
|
411
|
|
|
$this->storage[$idx][$name] = $value; |
412
|
|
|
|
413
|
|
|
if ($sync) { |
414
|
|
|
$this->save_data(get_class($sender)); |
415
|
|
|
} |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
public function get($sender, $name, $default_value = false) { |
419
|
|
|
$idx = get_class($sender); |
420
|
|
|
|
421
|
|
|
if (isset($this->storage[$idx][$name])) { |
422
|
|
|
return $this->storage[$idx][$name]; |
423
|
|
|
} else { |
424
|
|
|
return $default_value; |
425
|
|
|
} |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
public function get_all($sender) { |
429
|
|
|
$idx = get_class($sender); |
430
|
|
|
|
431
|
|
|
$data = $this->storage[$idx]; |
432
|
|
|
|
433
|
|
|
return $data ? $data : []; |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
public function clear_data($sender) { |
437
|
|
|
if ($this->owner_uid) { |
438
|
|
|
$idx = get_class($sender); |
439
|
|
|
|
440
|
|
|
unset($this->storage[$idx]); |
441
|
|
|
|
442
|
|
|
$sth = $this->pdo->prepare("DELETE FROM ttrss_plugin_storage WHERE name = ? |
443
|
|
|
AND owner_uid = ?"); |
444
|
|
|
$sth->execute([$idx, $this->owner_uid]); |
445
|
|
|
} |
446
|
|
|
} |
447
|
|
|
|
448
|
|
|
// Plugin feed functions are *EXPERIMENTAL*! |
449
|
|
|
|
450
|
|
|
// cat_id: only -1 is supported (Special) |
451
|
|
|
public function add_feed($cat_id, $title, $icon, $sender) { |
452
|
|
|
if (!$this->feeds[$cat_id]) { |
453
|
|
|
$this->feeds[$cat_id] = array(); |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
$id = count($this->feeds[$cat_id]); |
457
|
|
|
|
458
|
|
|
array_push($this->feeds[$cat_id], |
459
|
|
|
array('id' => $id, 'title' => $title, 'sender' => $sender, 'icon' => $icon)); |
460
|
|
|
|
461
|
|
|
return $id; |
462
|
|
|
} |
463
|
|
|
|
464
|
|
|
public function get_feeds($cat_id) { |
465
|
|
|
return $this->feeds[$cat_id]; |
466
|
|
|
} |
467
|
|
|
|
468
|
|
|
// convert feed_id (e.g. -129) to pfeed_id first |
469
|
|
|
public function get_feed_handler($pfeed_id) { |
470
|
|
|
foreach ($this->feeds as $cat) { |
471
|
|
|
foreach ($cat as $feed) { |
472
|
|
|
if ($feed['id'] == $pfeed_id) { |
473
|
|
|
return $feed['sender']; |
474
|
|
|
} |
475
|
|
|
} |
476
|
|
|
} |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
public static function pfeed_to_feed_id($label) { |
480
|
|
|
return PLUGIN_FEED_BASE_INDEX - 1 - abs($label); |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
public static function feed_to_pfeed_id($feed) { |
484
|
|
|
return PLUGIN_FEED_BASE_INDEX - 1 + abs($feed); |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
public function add_api_method($name, $sender) { |
488
|
|
|
if ($this->is_system($sender)) { |
489
|
|
|
$this->api_methods[strtolower($name)] = $sender; |
490
|
|
|
} |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
public function get_api_method($name) { |
494
|
|
|
return $this->api_methods[$name]; |
495
|
|
|
} |
496
|
|
|
|
497
|
|
|
public function add_filter_action($sender, $action_name, $action_desc) { |
498
|
|
|
$sender_class = get_class($sender); |
499
|
|
|
|
500
|
|
|
if (!isset($this->plugin_actions[$sender_class])) { |
501
|
|
|
$this->plugin_actions[$sender_class] = array(); |
502
|
|
|
} |
503
|
|
|
|
504
|
|
|
array_push($this->plugin_actions[$sender_class], |
505
|
|
|
array("action" => $action_name, "description" => $action_desc, "sender" => $sender)); |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
public function get_filter_actions() { |
509
|
|
|
return $this->plugin_actions; |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
public function get_owner_uid() { |
513
|
|
|
return $this->owner_uid; |
514
|
|
|
} |
515
|
|
|
|
516
|
|
|
// handled by classes/pluginhandler.php, requires valid session |
517
|
|
|
public function get_method_url($sender, $method, $params) { |
518
|
|
|
return get_self_url_prefix()."/backend.php?". |
519
|
|
|
http_build_query( |
520
|
|
|
array_merge( |
521
|
|
|
[ |
522
|
|
|
"op" => "pluginhandler", |
523
|
|
|
"plugin" => strtolower(get_class($sender)), |
524
|
|
|
"method" => $method |
525
|
|
|
], |
526
|
|
|
$params)); |
527
|
|
|
} |
528
|
|
|
|
529
|
|
|
// WARNING: endpoint in public.php, exposed to unauthenticated users |
530
|
|
|
public function get_public_method_url($sender, $method, $params) { |
531
|
|
|
if ($sender->is_public_method($method)) { |
532
|
|
|
return get_self_url_prefix()."/public.php?". |
533
|
|
|
http_build_query( |
534
|
|
|
array_merge( |
535
|
|
|
[ |
536
|
|
|
"op" => "pluginhandler", |
537
|
|
|
"plugin" => strtolower(get_class($sender)), |
538
|
|
|
"pmethod" => $method |
539
|
|
|
], |
540
|
|
|
$params)); |
541
|
|
|
} else { |
542
|
|
|
user_error("get_public_method_url: requested method '$method' of '".get_class($sender)."' is private."); |
543
|
|
|
} |
544
|
|
|
} |
545
|
|
|
} |
546
|
|
|
|