+ protected function __construct($auth = AUTH_PUBLIC, $perms = 'user', $type = DO_AUTH)
+ {
+ $this->auth = $auth;
+ $this->perms = $perms;
+ $this->type = $type;
+ }
+
+ public function needAuth()
+ {
+ return $this->auth > S::i('auth', AUTH_PUBLIC);
+ }
+
+ public function checkPerms()
+ {
+ if (!$this->perms || $this->auth == AUTH_PUBLIC) { // No perms, no check
+ return true;
+ }
+ $s_perms = S::v('perms');
+ return $s_perms->hasFlagCombination($this->perms);
+ }
+
+ public function hasType($type)
+ {
+ return ($this->type & $type) == $type;
+ }
+
+ abstract protected function run(PlPage &$page, array $args);
+
+ public function call(PlPage &$page, array $args)
+ {
+ global $globals, $session, $platal;
+ if ($this->needAuth()) {
+ if ($this->hasType(DO_AUTH)) {
+ if (!$session->start($this->auth)) {
+ $platal->force_login($page);
+ return PL_FORBIDDEN;
+ }
+ } else {
+ return PL_FORBIDDEN;
+ }
+ }
+ if (!$this->checkPerms()) {
+ if (Platal::notAllowed()) {
+ return PL_FORBIDDEN;
+ }
+ }
+ return $this->run($page, $args);
+ }
+}
+
+class PlStdHook extends PlHook
+{
+ private $hook;
+
+ public function __construct($callback, $auth = AUTH_PUBLIC, $perms = 'user', $type = DO_AUTH)
+ {
+ parent::__construct($auth, $perms, $type);
+ $this->hook = $callback;
+ }
+
+ protected function run(PlPage &$page, array $args)
+ {
+ global $session, $platal;
+
+ $args[0] = $page;
+ $val = call_user_func_array($this->hook, $args);
+ if ($val == PL_DO_AUTH) {
+ if (!$session->start($session->loggedLevel())) {
+ $platal->force_login($page);
+ }
+ $val = call_user_func_array($this->hook, $args);
+ }
+ return $val;
+ }
+}
+
+class PlWikiHook extends PlHook
+{
+ public function __construct($auth = AUTH_PUBLIC, $perms = 'user', $type = DO_AUTH)
+ {
+ parent::__construct($auth, $perms, $type);
+ }
+
+ protected function run(PlPage &$page, array $args)
+ {
+ return PL_WIKI;
+ }
+}
+
+class PlHookTree
+{
+ public $hook = null;
+ public $aliased = null;
+ public $children = array();
+
+ public function addChild(array $path, PlHook $hook)
+ {
+ global $platal;
+ $next = array_shift($path);
+ $alias = null;
+ if ($next && $next{0} == '%') {
+ $alias = $next;
+ $next = $platal->hook_map(substr($next, 1));
+ }
+ if (!$next) {
+ return;
+ }
+ @$child =& $this->children[$next];
+ if (!$child) {
+ $child = new PlHookTree();
+ $this->children[$next] =& $child;
+ $child->aliased = $alias;
+ }
+ if (empty($path)) {
+ $child->hook = $hook;
+ } else {
+ $child->addChild($path, $hook);
+ }
+ }
+
+ private function findChildAux(array $remain, array $matched, array $aliased)
+ {
+ $next = @$remain[0];
+ if ($this->aliased) {
+ $aliased = $matched;
+ }
+ if (!empty($next)) {
+ $child = @$this->children[$next];
+ if ($child) {
+ array_shift($remain);
+ $matched[] = $next;
+ return $child->findChildAux($remain, $matched, $aliased);
+ }
+ }
+ return array($this->hook, $matched, $remain, $aliased);
+ }