implement plugin routing masks, add example plugin

This commit is contained in:
Andrew Dolgov 2012-12-23 23:05:51 +04:00
parent 5cedb389d2
commit 8dcb2b4762
7 changed files with 108 additions and 7 deletions

View File

@ -118,10 +118,18 @@
$op = str_replace("-", "_", $op); $op = str_replace("-", "_", $op);
if (class_exists($op)) { global $pluginhost;
$handler = new $op($link, $_REQUEST); $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 (validate_csrf($csrf_token) || $handler->csrf_ignore($method)) {
if ($handler->before($method)) { if ($handler->before($method)) {
if ($method && method_exists($handler, $method)) { if ($method && method_exists($handler, $method)) {

View File

@ -1,5 +1,5 @@
<?php <?php
class Handler { class Handler implements IHandler {
protected $link; protected $link;
protected $args; protected $args;

7
classes/ihandler.php Normal file
View File

@ -0,0 +1,7 @@
<?php
interface IHandler {
function csrf_ignore($method);
function before($method);
function after();
}
?>

View File

@ -3,6 +3,7 @@ class PluginHost {
private $link; private $link;
private $hooks = array(); private $hooks = array();
private $plugins = array(); private $plugins = array();
private $handlers = array();
const HOOK_ARTICLE_BUTTON = 1; const HOOK_ARTICLE_BUTTON = 1;
const HOOK_ARTICLE_FILTER = 2; const HOOK_ARTICLE_FILTER = 2;
@ -62,7 +63,7 @@ class PluginHost {
foreach ($plugins as $class) { foreach ($plugins as $class) {
$class = trim($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"; $file = dirname(__FILE__)."/../plugins/$class_file/$class_file.php";
if (file_exists($file)) require_once $file; 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;
}
} }
?> ?>

View File

@ -5576,4 +5576,8 @@
return $rc; return $rc;
} }
function implements_interface($class, $interface) {
return in_array($interface, class_implements($class));
}
?> ?>

View File

@ -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;
}
}
?>

View File

@ -40,9 +40,16 @@
$method = $_REQUEST["op"]; $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)) { if ($method && method_exists($handler, $method)) {
$handler->$method(); $handler->$method();
} else if (method_exists($handler, 'index')) { } else if (method_exists($handler, 'index')) {