X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;ds=sidebyside;f=include%2Fdiogenes.barrel.inc.php;fp=include%2Fdiogenes.barrel.inc.php;h=d217a35f7bbdd7e523c4a3908ddc01e5c264caf2;hb=6855525e48fad5de270500a5445c4f4ff85d8bda;hp=0000000000000000000000000000000000000000;hpb=e69709aa8ee6108a1197e46b45367ba8dab55a52;p=diogenes.git diff --git a/include/diogenes.barrel.inc.php b/include/diogenes.barrel.inc.php new file mode 100644 index 0000000..d217a35 --- /dev/null +++ b/include/diogenes.barrel.inc.php @@ -0,0 +1,488 @@ +DiogenesPage(); + + // break down PATH_INFO into site and location components + $mypathinfo = $override_pathinfo ? $override_pathinfo : $_SERVER['PATH_INFO']; + $this->pathinfo = $this->parsePathInfo($mypathinfo); + if (!$this->pathinfo) + $this->kill404("Invalid location specified!"); + + // Retrieve site-wide info from database + $this->barrel = new Diogenes_Barrel($this->pathinfo['alias']); + if (!$this->barrel->alias) + $this->kill404("Unknown barrel requested : {$this->pathinfo['alias']}"); + + // Legacy + $this->alias = $this->barrel->alias; + $this->table_menu = $this->barrel->table_menu; + + // Build page head + $this->makeHead(); + + // Check the requested page exists + $tdir = $this->pathinfo['dir']; + if ($tdir != 'admin') + { + if (!$this->pathinfo['PID'] = $this->barrel->getPID($tdir)) + { + $this->kill404("Unknown location specified '$tdir'!"); + } + } + } + + /** Check the user has the right permissions. + * Read the user's permissions for the current site from database. + * + * @param level the required permissions level + */ + function checkPerms($level) { + global $globals; + + if ($level != "public") + $_SESSION['session']->doAuth($this); + + $_SESSION['session']->setBarrelPerms($this->alias); + + if (!$_SESSION['session']->hasPerms($level)) + $this->kill(__("You are not authorized to view this page!"), 403); + } + + + /** Read the contents for the current location. + */ + function doContent() + { + global $globals; + + // Retrieve information specific to the current page + + // enable directory index + $file = $this->pathinfo['file'] ? $this->pathinfo['file'] : $globals->htmlfile; + + // read from Db + if (!$bpage = Diogenes_Barrel_Page::fromDb($this->barrel, $this->pathinfo['PID'])) + { + $this->kill404("Directory not found : '{$this->pathinfo['dir']}' ({$this->pathinfo['PID']}) !"); + } + $this->curpage =& $bpage; + + // check the permissions for the current location + if (!$this->pathinfo['file'] || $bpage->props['perms'] != 'public' || isset($_REQUEST['rev'])) { + $this->startSession(); + + // handle login/logout requests + if (isset($_REQUEST['dologout'])) + $this->doLogout(); + if (isset($_REQUEST['doauth'])) + $this->checkPerms('auth'); + + $this->checkPerms($bpage->props['perms']); + + // can we edit this page? + $this->canedit = $_SESSION['session']->hasPerms($bpage->props['wperms']); + } + + // now we can display the page + // check the location is valid + if (!$this->barrel->spool->checkPath($bpage->props['PID'],$file,false)) + $this->kill404("Malformed location!"); + + // check that the page is 'live' + switch ($bpage->props['status']) { + case 0: + break; + case 1: + $this->assign('page_content', "

".__("This page is currently under construction.")."

"); + $this->display(''); + exit; + default: + $this->assign('page_content', "

".__("This page is currently unavailable.")."

"); + $this->display(''); + exit; + } + + // if necessary, do a checkout + if (isset($_REQUEST['rev'])) { + $rcs = $this->getRcs(); + $path = $rcs->checkout($bpage->props['PID'],$file,$_REQUEST['rev'],System::mktemp("-d")); + } else { + $path = $this->barrel->spool->spoolPath($bpage->props['PID'],$file); + } + + if (!is_file($path)) + $this->kill404("File not found : $path!"); + + if (!$this->pathinfo['file']) { + // this is a page, display it within header/footer framework + $this->doPage($path, $bpage); + } else { + // otherwise, we send back the raw file + $type = get_mime_type($path); + if (is_mime_multipart($type)) { + $boundary = get_mime_boundary($path); + if ($boundary) $type = "$type; boundary=\"$boundary\""; + } + header("Content-Type:$type"); + header("Content-Length:".filesize($path)); + header("Last-modified:".gmdate("D, d M Y H:i:s T", filemtime($path))); + readfile($path); + } + + } + + + /** Display a page within the header/footer framework. + * + * @param path the path of the file + * @param bpage a Diogenes_Barrel_Page representing the current page + */ + function doPage($path, $bpage) + { + global $globals; + + $this->assign('page',stripslashes($bpage->props['title'])); + + // load plugins + $this->barrel->readPlugins(); + $active_plugins = $this->barrel->loadPlugins($bpage); + + // search for rendering pluging + $render_plugin = ''; + foreach ($active_plugins as $plugname => $plugobj) { + if (is_object($plugobj) && ($plugobj->type == "render")) { + $render_plugin = $plugobj; + } + } + // source page or pass it to a rendering plugin + if (is_object($render_plugin)) { + $content = $render_plugin->render($path); + } else { + $content = file_get_contents($path); + } + + // apply plugin filtering + foreach ($active_plugins as $plugname => $plugobj) { + if (is_object($plugobj) && ($plugobj->type == "filter")) { + $content = $plugobj->filter($content); + } + } + $this->assign('page_content', $content); + + parent::display('', $this->getTemplate($bpage->props['template'])); + } + + + /** Return an RCS handle. */ + function getRcs() + { + global $globals; + return new $globals->rcs($this,$this->alias,$_SESSION['session']->username); + } + + + /** Returns the master template for the current context. + * + * @param template + */ + function getTemplate($template = '') + { + if ($template) + { + // we have a page-specific template, get its full path + $tpl = $this->templatePath($template); + } else if ($this->barrel->options->template) { + // we have default site template, get is full path + $tpl = $this->templatePath($this->barrel->options->template); + } else { + // fall back on the system-wide default template + $tpl = parent::getTemplate(); + } + return $tpl; + } + + + /** Returns the available master templates. */ + function getTemplates() + { + // the system-wide templates + $templates = parent::getTemplates(); + $bbarrel =& $this->barrel; + + // lookup templates in the template directory + if ($bbarrel->hasFlag('tpl') && $bbarrel->options->template_dir) { + $dir = $bbarrel->spool->spoolPath($bbarrel->options->template_dir); + $files = System::find($dir.' -maxdepth 1 -name *.tpl'); + foreach ($files as $file) + $templates["barrel:".basename($file)] = "[barrel] ".basename($file); + } + return $templates; + } + + + /** Is the user an administrator for the current barrel ? */ + function isAdmin() { + return isset($_SESSION['session']) && $_SESSION['session']->hasPerms('admin'); + } + + + /** Build the page's "head" tag. + */ + function makeHead() { + global $globals; + $bbarrel =& $this->barrel; + + // site name + $this->assign('site', stripslashes($bbarrel->options->title)); + + // meta + array_push($this->head, ''); + array_push($this->head, ''); + + // stylesheets + $this->sheets = array(); + array_push($this->sheets, $this->url("common.css")); + if ($bbarrel->options->menu_style == 1 || $bbarrel->options->menu_style == 2) + array_push($this->sheets, $this->url("phplayersmenu/{$bbarrel->options->menu_theme}/style.css")); + array_push($this->sheets, $this->urlSite("", $globals->cssfile)); + + // add stylesheets to head + foreach ($this->sheets as $mysheet) { + array_push($this->head, ''); + } + // favicon + if ($bbarrel->options->favicon) + array_push($this->head, 'options->favicon).'" type="image/png" />'); + } + + + /** Build the barrel's menu. + */ + function makeMenu() { + global $globals; + $bbarrel =& $this->barrel; + + // menu style & theme + $this->assign('menustyle', $bbarrel->options->menu_style); + $this->assign('menutheme', $bbarrel->options->menu_theme); + + $PID = $this->curpage->props['PID']; + + // build the Diogenes part of the menu + if (!$bbarrel->options->menu_hide_diogenes) { + array_push($this->menu,array(0,__("Home"),$this->urlSite(""), 1)); + if ($this->isLogged()) { + array_push($this->menu, array(1,__("Logout"), "?dologout=1") ); + array_push($this->menu, array(1,__("Preferences"), $this->urlSite("admin", "prefs"))); + } else { + array_push($this->menu, array(1,__("Login"), "?doauth=1") ); + } + + if ($this->isAdmin()) { + array_push($this->menu, array(1, __("Administration"), $this->urlSite("admin"))); + if ($PID) + array_push($this->menu, array(1, __("Page properties"), $this->urlSite("admin", "pages?dir=$PID"))); + } elseif ($this->canedit && $PID) { + array_push($this->menu, array(0, __("Edit this page"), "", 1)); + array_push($this->menu, array(1, __("Raw editor"), $this->urlSite("admin", "edit?dir=$PID&file={$globals->htmlfile}"))); + array_push($this->menu, array(1, __("HTML editor"), $this->urlSite("admin" , "compose?dir=$PID&file={$globals->htmlfile}"))); + } + } + + // if this is an error page, we need to bail out here + if (!isset($this->table_menu)) + return; + + // try to figure out the current MID from the current PID + // and build filiation + $filiation = array(); + $res = $this->dbh->query("select MID from {$this->table_menu} where PID='$PID'"); + while (list($MID) = mysql_fetch_row($res)) + $filiation = $this->menuToRoot($MID, $filiation); + mysql_free_result($res); + + // add the user-defined part of the menu + $this->menu = array_merge($this->menu,$this->menuRecurse(0,$filiation,0)); + } + + + /** Return the filiation to get to the root element. + * + * @param MID + * @param path + */ + function menuToRoot($MID, $path) { + /* add ourself to the path */ + array_push($path,$MID); + + if ($MID) { + /* recursion */ + $res = $this->dbh->query("select MIDpere from {$this->table_menu} where MID=$MID"); + list($MIDpere) = mysql_fetch_row($res); + mysql_free_result($res); + + return $this->menuToRoot($MIDpere, $path); + } else { + /* termination */ + return $path; + } + } + + + /** Recursively add menu entries + * + * @param MIDpere + * @param filiation + * @param level + */ + function menuRecurse($MIDpere, $filiation, $level) { + // the produced output + $out = array(); + + $res = $this->dbh->query("select m.MID,m.title,m.link,m.PID ". + "from {$this->table_menu} as m ". + "where MIDpere=$MIDpere order by ordre"); + + while(list($mid,$title,$link,$pid) = mysql_fetch_row($res)) { + $location = $this->barrel->getLocation($pid); +// echo "pid : $pid, location : $location
"; + $title = stripslashes($title); + $entry = htmlentities(stripslashes($title), ENT_QUOTES); + $link = $pid ? $this->urlSite($location) : $link; + // decide whether this menu should be expanded + $expanded = ($this->barrel->options->menu_min_level == 0) || + ($level+1 < $this->barrel->options->menu_min_level) || + in_array($mid, $filiation); + array_push($out, array($level, $entry, $link, $expanded)); + $out = array_merge($out, $this->menuRecurse($mid, $filiation, $level+1)); + } + + // free MySQL result and return output + mysql_free_result($res); + return $out; + } + + + /** + * Break down a PATH_INFO into site, page id and file + * Directories *must* be accessed with a final slash. + * + * @param path the path to parse + */ + function parsePathInfo($path) { + if (empty($path) || !preg_match("/^\/([^\/]+)\/((.+)\/)?([^\/]*)$/",$path,$asplit)) + return false; + + $split['alias'] = $asplit[1]; + $split['dir'] = isset($asplit[3]) ? $asplit[3] : ""; + $split['file'] = isset($asplit[4]) ? $asplit[4] : ""; + return $split; + } + + + /** Return the current URI. + */ + function script_uri() + { + if ($this->barrel->vhost) + return preg_replace("/^(.*)\/site(\.php)?\/{$this->alias}\/(.*)/", "/\$3",$_SERVER['REQUEST_URI']); + else + return $_SERVER['REQUEST_URI']; + } + + + /** Returns the path to a given template. */ + function templatePath($template) + { + global $globals; + + $bits = split(":", $template); + switch ($bits[0]) { + case "global": + $path = $globals->template_dir."/". $bits[1]; + break; + case "barrel": + $path = $this->barrel->spool->spoolPath($this->barrel->options->template_dir, $bits[1]); + break; + default: + $path = parent::templatePath($template); + } + return $path; + } + + + /** Returns the URL to one of the barrel's pages relative to + * the current location. + * + * @param dir + * @param file + */ + function urlSite($dir, $file = '') { + global $page; + $tosite = strlen($this->pathinfo['dir']) ? str_repeat("../",1+substr_count($this->pathinfo['dir'],"/")) : ''; + $url = $tosite . (strlen($dir) ? "$dir/" : "") . $file; + return strlen($url) ? $url : "./"; + } + +} + +?>