X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=classes%2Fplatal.php;h=24a0066a67e0194ed4a8fee1fb4ae15938b53f03;hb=6d407683b0fcb3bd2550f7554c486df08b9dabcd;hp=ac3f9824ead4e48cd856e50b7fdb94254c9e1a7b;hpb=604d53754382a8514a38c3d5e822508e1a74b6a9;p=platal.git diff --git a/classes/platal.php b/classes/platal.php index ac3f982..24a0066 100644 --- a/classes/platal.php +++ b/classes/platal.php @@ -25,16 +25,21 @@ define('PL_NOT_FOUND', 404); class Platal { - var $__mods; - var $__hooks; + private $__mods; + private $__hooks; - var $ns; - var $path; - var $argv; + protected $https; - function Platal() + public $ns; + public $path; + public $argv; + + public function __construct() { $modules = func_get_args(); + if (is_array($modules[0])) { + $modules = $modules[0]; + } $this->path = trim(Get::_get('n', null), '/'); $this->__mods = array(); @@ -42,12 +47,13 @@ class Platal array_unshift($modules, 'core'); foreach ($modules as $module) { + $module = strtolower($module); $this->__mods[$module] = $m = PLModule::factory($module); $this->__hooks += $m->handlers(); } } - function pl_self($n = null) + public function pl_self($n = null) { if (is_null($n)) return $this->path; @@ -61,7 +67,7 @@ class Platal return join('/', array_slice($this->argv, 0, $n)); } - function find_hook() + protected function find_hook() { $p = $this->path; @@ -82,13 +88,14 @@ class Platal return null; } + $this->https = ($hook['type'] & NO_HTTPS) ? false : true; $this->argv = explode('/', substr($this->path, strlen($p))); $this->argv[0] = $p; return $hook; } - function find_nearest_key($key, &$array) + protected function find_nearest_key($key, array &$array) { $keys = array_keys($array); if (in_array($key, $keys)) { @@ -109,24 +116,27 @@ class Platal continue; } $lev = levenshtein($key, $k); - if ((!isset($val) || $lev < $val) && $lev <= (strlen($k)*2)/3) { + + if ((!isset($val) || $lev < $val) + && ($lev <= strlen($k)/2 || strpos($k, $key) !== false || strpos($key, $k) !== false)) { $val = $lev; $best = $k; } } if (!isset($best) && $has_end) { return "#final#"; - } else { + } else if (isset($best)) { return $best; } return null; } - function near_hook() + public function near_hook() { $hooks = array(); + $leafs = array(); foreach ($this->__hooks as $hook=>$handler) { - if (!empty($handler['perms']) && $handler['perms'] != S::v('perms')) { + if (!$this->check_perms($handler['perms'])) { continue; } $parts = split('/', $hook); @@ -135,11 +145,20 @@ class Platal if (!isset($place[$part])) { $place[$part] = array(); } - $place =& $place[$part]; + $place =& $place[$part]; + } + $leaf = $parts[count($parts)-1]; + if (!isset($leafs[$leaf])) { + $leafs[$leaf] = $hook; + } else if (is_array($leafs[$leaf])) { + $leafs[$leaf][] = $hook; + } else { + $leafs[$leaf] = array($hook, $leafs[$leaf]); } $place["#final#"] = array(); } + // search for the nearest full path $p = split('/', $this->path); $place =& $hooks; $link = ''; @@ -151,7 +170,8 @@ class Platal } if ($key == "#final#") { if (!array_key_exists($link, $this->__hooks)) { - return null; + $link = ''; + break; } $key = $k; $ended = true; @@ -163,29 +183,65 @@ class Platal $link .= $key; $place =& $place[$key]; } else { - return null; + $link = ''; + break; } } - if ($link != $this->path) { + if ($link == $this->path) { + $link = ''; + } + if ($link && levenshtein($link, $this->path) < strlen($link)/3) { return $link; } - return null; + + // search for missing namespace (the given name is a leaf) + $leaf = array_shift($p); + $args = count($p) ? '/' . implode('/', $p) : ''; + if (isset($leafs[$leaf]) && !is_array($leafs[$leaf]) && $leafs[$leaf] != $this->path) { + return $leafs[$leaf] . $args; + } + unset($val); + $best = null; + foreach ($leafs as $k=>&$path) { + if (is_array($path)) { + continue; + } + $lev = levenshtein($leaf, $k); + + if ((!isset($val) || $lev < $val) + && ($lev <= strlen($k)/2 || strpos($k, $leaf) !== false || strpos($leaf, $k) !== false)) { + $val = $lev; + $best = $path; + } + } + return $best == null ? ( $link ? $link : null ) : $best . $args; } - function call_hook(&$page) + protected function check_perms($perms) + { + if (!$perms) { // No perms, no check + return true; + } + $s_perms = S::v('perms'); + return $s_perms->hasFlagCombination($perms); + } + + private function call_hook(PlatalPage &$page) { $hook = $this->find_hook(); if (empty($hook)) { return PL_NOT_FOUND; } + global $globals; + if ($this->https && !$_SERVER['HTTPS'] && $globals->core->secure_domain) { + http_redirect('https://' . $globals->core->secure_domain . $_SERVER['REQUEST_URI']); + } - $args = $this->argv; - $args[0] = &$page; + $args = $this->argv; + $args[0] =& $page; if ($hook['auth'] > S::v('auth', AUTH_PUBLIC)) { - if ($hook['type'] == DO_AUTH) { - global $globals; - + if ($hook['type'] & DO_AUTH) { if (!call_user_func(array($globals->session, 'doAuth'))) { $this->force_login($page); } @@ -193,14 +249,12 @@ class Platal return PL_FORBIDDEN; } } - - if (!empty($hook['perms']) && $hook['perms'] != S::v('perms')) { + if ($hook['auth'] != AUTH_PUBLIC && !$this->check_perms($hook['perms'])) { return PL_FORBIDDEN; } $val = call_user_func_array($hook['hook'], $args); - if ($val == PL_DO_AUTH) { - global $globals; + if ($val & PL_DO_AUTH) { // The handler need a better auth with the current args if (!call_user_func(array($globals->session, 'doAuth'))) { $this->force_login($page); @@ -210,7 +264,7 @@ class Platal return $val; } - function force_login(&$page) + public function force_login(PlatalPage &$page) { if (S::logged()) { $page->changeTpl('core/password_prompt_logged.tpl'); @@ -223,7 +277,7 @@ class Platal $page->run(); } - function run() + public function run() { global $page; @@ -248,7 +302,7 @@ class Platal $page->run(); } - function on_subscribe($forlife, $uid, $promo, $pass) + public function on_subscribe($forlife, $uid, $promo, $pass) { $args = func_get_args(); foreach ($this->__mods as $mod) {