buildGlobals(); $globals->init(); /* Get the current session: assign first, then activate the session. */ $session = $this->buildSession(); if (!$session->startAvailableAuth()) { Platal::page()->trigError("Données d'authentification invalides."); } $modules = func_get_args(); if (isset($modules[0]) && is_array($modules[0])) { $modules = $modules[0]; } $this->path = trim(Get::_get('n', null), '/'); $this->__mods = array(); $this->__hooks = array(); array_unshift($modules, 'core'); foreach ($modules as $module) { $module = strtolower($module); $this->__mods[$module] = $m = PLModule::factory($module); $this->__hooks = $m->handlers() + $this->__hooks; } if ($globals->mode == '') { pl_redirect('index.html'); } } public function pl_self($n = null) { if (is_null($n)) return $this->path; if ($n >= 0) return join('/', array_slice($this->argv, 0, $n + 1)); if ($n <= -count($this->argv)) return $this->argv[0]; return join('/', array_slice($this->argv, 0, $n)); } public static function wiki_hook($auth = AUTH_PUBLIC, $perms = 'user', $type = DO_AUTH) { return array('hook' => PL_WIKI_HOOK, 'auth' => $auth, 'perms' => $perms, 'type' => $type); } protected function find_hook() { $p = $this->path; while ($p) { if (array_key_exists($p, $this->__hooks)) break; $p = substr($p, 0, strrpos($p, '/')); } if (empty($this->__hooks[$p])) { return null; } $hook = $this->__hooks[$p]; if (!is_callable($hook['hook']) && $hook['hook'] != PL_WIKI_HOOK) { return null; } $this->https = ($hook['type'] & NO_HTTPS) ? false : true; $this->argv = explode('/', substr($this->path, strlen($p))); $this->argv[0] = $p; return $hook; } protected function find_nearest_key($key, array &$array) { $keys = array_keys($array); if (in_array($key, $keys)) { return $key; } if (($pos = strpos($key, '.php')) !== false) { $key = substr($key, 0, $pos); } $has_end = in_array("#final#", $keys); if (strlen($key) > 24 && $has_end) { return "#final#"; } foreach ($keys as $k) { if ($k == "#final#") { continue; } $lev = levenshtein($key, $k); 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 if (isset($best)) { return $best; } return null; } public function near_hook() { $hooks = array(); $leafs = array(); foreach ($this->__hooks as $hook=>$handler) { if (!$this->check_perms($handler['perms'])) { continue; } $parts = split('/', $hook); $place =& $hooks; foreach ($parts as $part) { if (!isset($place[$part])) { $place[$part] = array(); } $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 = ''; foreach ($p as $k) { if (!isset($ended)) { $key = $this->find_nearest_key($k, $place); } else { $key = $k; } if ($key == "#final#") { if (!array_key_exists($link, $this->__hooks)) { $link = ''; break; } $key = $k; $ended = true; } if (!is_null($key)) { if (!empty($link)) { $link .= '/'; } $link .= $key; $place =& $place[$key]; } else { $link = ''; break; } } if ($link == $this->path) { $link = ''; } if ($link && levenshtein($link, $this->path) < strlen($link)/3) { return $link; } // 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; } 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(PlPage &$page) { $hook = $this->find_hook(); if (empty($hook)) { return PL_NOT_FOUND; } global $globals, $session; 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; if ($hook['auth'] > S::v('auth', AUTH_PUBLIC)) { if ($hook['type'] & DO_AUTH) { if (!$session->start($hook['auth'])) { $this->force_login($page); } } else { return PL_FORBIDDEN; } } if ($hook['auth'] != AUTH_PUBLIC && !$this->check_perms($hook['perms'])) { if (self::notAllowed()) { return PL_FORBIDDEN; } } if ($hook['hook'] == PL_WIKI_HOOK) { return PL_WIKI; } $val = call_user_func_array($hook['hook'], $args); if ($val == PL_DO_AUTH) { // The handler need a better auth with the current args if (!$session->start($session->loggedLevel())) { $this->force_login($page); } $val = call_user_func_array($hook['hook'], $args); } return $val; } /** Show the authentication form. */ abstract public function force_login(PlPage& $page); public function run() { $page =& self::page(); if (empty($this->path)) { $this->path = 'index'; } $page->assign('platal', $this); switch ($this->call_hook($page)) { case PL_FORBIDDEN: $this->__mods['core']->handler_403($page); break; case PL_NOT_FOUND: $this->__mods['core']->handler_404($page); break; case PL_WIKI: return PL_WIKI; } $page->assign('platal', $this); $page->run(); } public function error403() { $page =& self::page(); $this->__mods['core']->handler_403($page); $page->assign('platal', $this); $page->run(); } public function error404() { $page =& self::page(); $this->__mods['core']->handler_404($page); $page->assign('platal', $this); $page->run(); } public static function notAllowed() { if (S::admin()) { self::page()->trigWarning('Tu accèdes à cette page car tu es administrateur du site.'); return false; } else { return true; } } public static function load($modname, $include = null) { global $platal; $modname = strtolower($modname); if (isset($platal->__mods[$modname])) { if (is_null($include)) { return; } $platal->__mods[$modname]->load($include); } else { if (is_null($include)) { require_once PLModule::path($modname) . '.php'; } else { require_once PLModule::path($modname) . '/' . $include; } } } public static function assert($cond, $error, $userfriendly) { global $globals; if ($cond === false) { header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error'); $file = fopen($globals->spoolroot . '/spool/tmp/assert_erros', 'a'); fwrite($file, '
' . pl_entities($error) . '
\n'); fclose($file); Platal::page()->kill($userfriendly); } } public function &buildLogger($uid, $suid = 0) { if (defined('PL_LOGGER_CLASS')) { $class = PL_LOGGER_CLASS; return new $class($uid, $suid); } else { return PlLogger::dummy($uid, $suid); } } protected function &buildPage() { $pageclass = PL_PAGE_CLASS; $page = new $pageclass(); return $page; } static public function &page() { if (is_null(self::$_page)) { global $platal; self::$_page = $platal->buildPage(); } return self::$_page; } protected function &buildSession() { $sessionclass = PL_SESSION_CLASS; $session = new $sessionclass(); return $session; } static public function &session() { global $session; return $session; } protected function &buildGlobals() { $globalclass = PL_GLOBALS_CLASS; $globals = new $globalclass(); return $globals; } static public function &globals() { global $globals; return $globals; } } // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: ?>