summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2012-12-23 23:05:51 +0400
committerAndrew Dolgov <[email protected]>2012-12-23 23:05:51 +0400
commit8dcb2b47628346226b18940b5cde7849f7a24687 (patch)
treeca3ee70e34095455614f4c2c7f9d69ce9f1ed27c
parent5cedb389d24861a94c1183d1562900dbe59ee3fb (diff)
implement plugin routing masks, add example plugin
-rw-r--r--backend.php14
-rw-r--r--classes/handler.php2
-rw-r--r--classes/ihandler.php7
-rw-r--r--classes/pluginhost.php31
-rw-r--r--include/functions.php4
-rw-r--r--plugins/example_routing/example_routing.php46
-rw-r--r--public.php11
7 files changed, 108 insertions, 7 deletions
diff --git a/backend.php b/backend.php
index 8aaf10016..2cac8232b 100644
--- a/backend.php
+++ b/backend.php
@@ -118,10 +118,18 @@
$op = str_replace("-", "_", $op);
- if (class_exists($op)) {
- $handler = new $op($link, $_REQUEST);
+ global $pluginhost;
+ $override = $pluginhost->lookup_handler($op, $method);
- if ($handler && is_subclass_of($handler, 'Handler')) {
+ if (class_exists($op) || $override) {
+
+ if ($override) {
+ $handler = $override;
+ } else {
+ $handler = new $op($link, $_REQUEST);
+ }
+
+ if ($handler && implements_interface($handler, 'IHandler')) {
if (validate_csrf($csrf_token) || $handler->csrf_ignore($method)) {
if ($handler->before($method)) {
if ($method && method_exists($handler, $method)) {
diff --git a/classes/handler.php b/classes/handler.php
index e00b36aa3..68b16eac1 100644
--- a/classes/handler.php
+++ b/classes/handler.php
@@ -1,5 +1,5 @@
<?php
-class Handler {
+class Handler implements IHandler {
protected $link;
protected $args;
diff --git a/classes/ihandler.php b/classes/ihandler.php
new file mode 100644
index 000000000..e3c8a535f
--- /dev/null
+++ b/classes/ihandler.php
@@ -0,0 +1,7 @@
+<?php
+interface IHandler {
+ function csrf_ignore($method);
+ function before($method);
+ function after();
+}
+?>
diff --git a/classes/pluginhost.php b/classes/pluginhost.php
index d7926fa4e..b28d2511d 100644
--- a/classes/pluginhost.php
+++ b/classes/pluginhost.php
@@ -3,6 +3,7 @@ class PluginHost {
private $link;
private $hooks = array();
private $plugins = array();
+ private $handlers = array();
const HOOK_ARTICLE_BUTTON = 1;
const HOOK_ARTICLE_FILTER = 2;
@@ -62,7 +63,7 @@ class PluginHost {
foreach ($plugins as $class) {
$class = trim($class);
- $class_file = str_replace("_", "/", strtolower(basename($class)));
+ $class_file = strtolower(basename($class));
$file = dirname(__FILE__)."/../plugins/$class_file/$class_file.php";
if (file_exists($file)) require_once $file;
@@ -75,5 +76,33 @@ class PluginHost {
}
}
+ function add_handler($handler, $method, $sender) {
+ $handler = strtolower($handler);
+ $method = strtolower($method);
+
+ if (!is_array($this->handlers[$handler])) {
+ $this->handlers[$handler] = array();
+ }
+
+ $this->handlers[$handler][$method] = $sender;
+ }
+
+ function del_handler($handler, $method) {
+ $handler = strtolower($handler);
+ $method = strtolower($method);
+
+ unset($this->handlers[$handler][$method]);
+ }
+
+ function lookup_handler($handler, $method) {
+ $handler = strtolower($handler);
+ $method = strtolower($method);
+
+ if (is_array($this->handlers[$handler])) {
+ return $this->handlers[$handler][$method];
+ }
+
+ return false;
+ }
}
?>
diff --git a/include/functions.php b/include/functions.php
index a4caf9fde..b338bde5b 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -5576,4 +5576,8 @@
return $rc;
}
+ function implements_interface($class, $interface) {
+ return in_array($interface, class_implements($class));
+ }
+
?>
diff --git a/plugins/example_routing/example_routing.php b/plugins/example_routing/example_routing.php
new file mode 100644
index 000000000..a5c4e6139
--- /dev/null
+++ b/plugins/example_routing/example_routing.php
@@ -0,0 +1,46 @@
+<?php
+class Example_Routing extends Plugin implements IHandler {
+
+ // Demonstrates adding a custom handler and method:
+ // backend.php?op=test&method=example
+ // and masking a system builtin public method:
+ // public.php?op=getUnread
+
+ // Plugin class must implelement IHandler interface and has
+ // a public method of same name as being registered.
+ //
+ // Any system method may be masked by plugins.
+
+ private $link;
+ private $host;
+
+ function __construct($host) {
+ $this->link = $host->get_link();
+ $this->host = $host;
+
+ $host->add_handler("test", "example", $this);
+ $host->add_handler("public", "getunread", $this);
+ }
+
+ function getunread() {
+ print rand(0,100); # yeah right
+ }
+
+ function example() {
+ print "example method called";
+ }
+
+ function csrf_ignore($method) {
+ return true;
+ }
+
+ function before($method) {
+ return true;
+ }
+
+ function after() {
+ return true;
+ }
+
+}
+?>
diff --git a/public.php b/public.php
index 59e0ef2e3..4cf7653f9 100644
--- a/public.php
+++ b/public.php
@@ -40,9 +40,16 @@
$method = $_REQUEST["op"];
- $handler = new Handler_Public($link, $_REQUEST);
+ global $pluginhost;
+ $override = $pluginhost->lookup_handler("public", $method);
- if ($handler->before($method)) {
+ if ($override) {
+ $handler = $override;
+ } else {
+ $handler = new Handler_Public($link, $_REQUEST);
+ }
+
+ if (implements_interface($handler, "IHandler") && $handler->before($method)) {
if ($method && method_exists($handler, $method)) {
$handler->$method();
} else if (method_exists($handler, 'index')) {