$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)) {
<?php
-class Handler {
+class Handler implements IHandler {
protected $link;
protected $args;
--- /dev/null
+<?php
+interface IHandler {
+ function csrf_ignore($method);
+ function before($method);
+ function after();
+}
+?>
private $link;
private $hooks = array();
private $plugins = array();
+ private $handlers = array();
const HOOK_ARTICLE_BUTTON = 1;
const HOOK_ARTICLE_FILTER = 2;
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;
}
}
+ 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;
+ }
}
?>
return $rc;
}
+ function implements_interface($class, $interface) {
+ return in_array($interface, class_implements($class));
+ }
+
?>
--- /dev/null
+<?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;
+ }
+
+}
+?>
$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')) {