d217a35f7bbdd7e523c4a3908ddc01e5c264caf2
3 * Copyright (C) 2003-2005 Polytechnique.org
4 * http://opensource.polytechnique.org/
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 require_once 'diogenes.page.inc.php';
23 require_once 'Barrel.php';
25 /** This class is used to display a page of a Diogenes barrel,
26 * that is an RCS-managed website with a virtual directory
29 class DiogenesBarrel
extends DiogenesPage
31 // barrel definition info
33 /** The database table holding the menus */
36 /** The barrel's alias. */
39 /** The Diogenes_Barrel representing the barrel */
43 /** A Diogenes_Barrel_Page representing the current page */
46 /** Information about the current location */
49 /** Can the current user edit this page? */
53 /** Constructs a Smarty-derived object to display contents within a barrel.
55 * @param $override_pathinfo
57 function DiogenesBarrel($override_pathinfo = null
)
61 // call parent constructor
62 $this->DiogenesPage();
64 // break down PATH_INFO into site and location components
65 $mypathinfo = $override_pathinfo ?
$override_pathinfo : $_SERVER['PATH_INFO'];
66 $this->pathinfo
= $this->parsePathInfo($mypathinfo);
68 $this->kill404("Invalid location specified!");
70 // Retrieve site-wide info from database
71 $this->barrel
= new Diogenes_Barrel($this->pathinfo
['alias']);
72 if (!$this->barrel
->alias
)
73 $this->kill404("Unknown barrel requested : {$this->pathinfo['alias']}");
76 $this->alias
= $this->barrel
->alias
;
77 $this->table_menu
= $this->barrel
->table_menu
;
82 // Check the requested page exists
83 $tdir = $this->pathinfo
['dir'];
86 if (!$this->pathinfo
['PID'] = $this->barrel
->getPID($tdir))
88 $this->kill404("Unknown location specified '$tdir'!");
93 /** Check the user has the right permissions.
94 * Read the user's permissions for the current site from database.
96 * @param level the required permissions level
98 function checkPerms($level) {
101 if ($level != "public")
102 $_SESSION['session']->doAuth($this);
104 $_SESSION['session']->setBarrelPerms($this->alias
);
106 if (!$_SESSION['session']->hasPerms($level))
107 $this->kill(__("You are not authorized to view this page!"), 403);
111 /** Read the contents for the current location.
117 // Retrieve information specific to the current page
119 // enable directory index
120 $file = $this->pathinfo
['file'] ?
$this->pathinfo
['file'] : $globals->htmlfile
;
123 if (!$bpage = Diogenes_Barrel_Page
::fromDb($this->barrel
, $this->pathinfo
['PID']))
125 $this->kill404("Directory not found : '{$this->pathinfo['dir']}' ({$this->pathinfo['PID']}) !");
127 $this->curpage
=& $bpage;
129 // check the permissions for the current location
130 if (!$this->pathinfo
['file'] ||
$bpage->props
['perms'] != 'public' ||
isset($_REQUEST['rev'])) {
131 $this->startSession();
133 // handle login/logout requests
134 if (isset($_REQUEST['dologout']))
136 if (isset($_REQUEST['doauth']))
137 $this->checkPerms('auth');
139 $this->checkPerms($bpage->props
['perms']);
141 // can we edit this page?
142 $this->canedit
= $_SESSION['session']->hasPerms($bpage->props
['wperms']);
145 // now we can display the page
146 // check the location is valid
147 if (!$this->barrel
->spool
->checkPath($bpage->props
['PID'],$file,false
))
148 $this->kill404("Malformed location!");
150 // check that the page is 'live'
151 switch ($bpage->props
['status']) {
155 $this->assign('page_content', "<p>".__("This page is currently under construction.")."<p>");
159 $this->assign('page_content', "<p>".__("This page is currently unavailable.")."<p>");
164 // if necessary, do a checkout
165 if (isset($_REQUEST['rev'])) {
166 $rcs = $this->getRcs();
167 $path = $rcs->checkout($bpage->props
['PID'],$file,$_REQUEST['rev'],System
::mktemp("-d"));
169 $path = $this->barrel
->spool
->spoolPath($bpage->props
['PID'],$file);
173 $this->kill404("File not found : $path!");
175 if (!$this->pathinfo
['file']) {
176 // this is a page, display it within header/footer framework
177 $this->doPage($path, $bpage);
179 // otherwise, we send back the raw file
180 $type = get_mime_type($path);
181 if (is_mime_multipart($type)) {
182 $boundary = get_mime_boundary($path);
183 if ($boundary) $type = "$type; boundary=\"$boundary\"";
185 header("Content-Type:$type");
186 header("Content-Length:".filesize($path));
187 header("Last-modified:".gmdate("D, d M Y H:i:s T", filemtime($path)));
194 /** Display a page within the header/footer framework.
196 * @param path the path of the file
197 * @param bpage a Diogenes_Barrel_Page representing the current page
199 function doPage($path, $bpage)
203 $this->assign('page',stripslashes($bpage->props
['title']));
206 $this->barrel
->readPlugins();
207 $active_plugins = $this->barrel
->loadPlugins($bpage);
209 // search for rendering pluging
211 foreach ($active_plugins as $plugname => $plugobj) {
212 if (is_object($plugobj) && ($plugobj->type
== "render")) {
213 $render_plugin = $plugobj;
216 // source page or pass it to a rendering plugin
217 if (is_object($render_plugin)) {
218 $content = $render_plugin->render($path);
220 $content = file_get_contents($path);
223 // apply plugin filtering
224 foreach ($active_plugins as $plugname => $plugobj) {
225 if (is_object($plugobj) && ($plugobj->type
== "filter")) {
226 $content = $plugobj->filter($content);
229 $this->assign('page_content', $content);
231 parent
::display('', $this->getTemplate($bpage->props
['template']));
235 /** Return an RCS handle. */
239 return new $globals->rcs($this,$this->alias
,$_SESSION['session']->username
);
243 /** Returns the master template for the current context.
247 function getTemplate($template = '')
251 // we have a page-specific template, get its full path
252 $tpl = $this->templatePath($template);
253 } else if ($this->barrel
->options
->template
) {
254 // we have default site template, get is full path
255 $tpl = $this->templatePath($this->barrel
->options
->template
);
257 // fall back on the system-wide default template
258 $tpl = parent
::getTemplate();
264 /** Returns the available master templates. */
265 function getTemplates()
267 // the system-wide templates
268 $templates = parent
::getTemplates();
269 $bbarrel =& $this->barrel
;
271 // lookup templates in the template directory
272 if ($bbarrel->hasFlag('tpl') && $bbarrel->options
->template_dir
) {
273 $dir = $bbarrel->spool
->spoolPath($bbarrel->options
->template_dir
);
274 $files = System
::find($dir.' -maxdepth 1 -name *.tpl');
275 foreach ($files as $file)
276 $templates["barrel:".basename($file)] = "[barrel] ".basename($file);
282 /** Is the user an administrator for the current barrel ? */
284 return isset($_SESSION['session']) && $_SESSION['session']->hasPerms('admin');
288 /** Build the page's "head" tag.
290 function makeHead() {
292 $bbarrel =& $this->barrel
;
295 $this->assign('site', stripslashes($bbarrel->options
->title
));
298 array_push($this->head
, '<meta name="description" content="'.stripslashes($bbarrel->options
->description
).'" />');
299 array_push($this->head
, '<meta name="keywords" content="'.stripslashes($bbarrel->options
->keywords
).'" />');
302 $this->sheets
= array();
303 array_push($this->sheets
, $this->url("common.css"));
304 if ($bbarrel->options
->menu_style
== 1 ||
$bbarrel->options
->menu_style
== 2)
305 array_push($this->sheets
, $this->url("phplayersmenu/{$bbarrel->options->menu_theme}/style.css"));
306 array_push($this->sheets
, $this->urlSite("", $globals->cssfile
));
308 // add stylesheets to head
309 foreach ($this->sheets
as $mysheet) {
310 array_push($this->head
, '<link rel="stylesheet" href="'.$mysheet.'" type="text/css" />');
313 if ($bbarrel->options
->favicon
)
314 array_push($this->head
, '<link rel="icon" href="'.$this->urlSite("", $bbarrel->options
->favicon
).'" type="image/png" />');
318 /** Build the barrel's menu.
320 function makeMenu() {
322 $bbarrel =& $this->barrel
;
324 // menu style & theme
325 $this->assign('menustyle', $bbarrel->options
->menu_style
);
326 $this->assign('menutheme', $bbarrel->options
->menu_theme
);
328 $PID = $this->curpage
->props
['PID'];
330 // build the Diogenes part of the menu
331 if (!$bbarrel->options
->menu_hide_diogenes
) {
332 array_push($this->menu
,array(0,__("Home"),$this->urlSite(""), 1));
333 if ($this->isLogged()) {
334 array_push($this->menu
, array(1,__("Logout"), "?dologout=1") );
335 array_push($this->menu
, array(1,__("Preferences"), $this->urlSite("admin", "prefs")));
337 array_push($this->menu
, array(1,__("Login"), "?doauth=1") );
340 if ($this->isAdmin()) {
341 array_push($this->menu
, array(1, __("Administration"), $this->urlSite("admin")));
343 array_push($this->menu
, array(1, __("Page properties"), $this->urlSite("admin", "pages?dir=$PID")));
344 } elseif ($this->canedit
&& $PID) {
345 array_push($this->menu
, array(0, __("Edit this page"), "", 1));
346 array_push($this->menu
, array(1, __("Raw editor"), $this->urlSite("admin", "edit?dir=$PID&file={$globals->htmlfile}")));
347 array_push($this->menu
, array(1, __("HTML editor"), $this->urlSite("admin" , "compose?dir=$PID&file={$globals->htmlfile}")));
351 // if this is an error page, we need to bail out here
352 if (!isset($this->table_menu
))
355 // try to figure out the current MID from the current PID
356 // and build filiation
357 $filiation = array();
358 $res = $this->dbh
->query("select MID from {$this->table_menu} where PID='$PID'");
359 while (list($MID) = mysql_fetch_row($res))
360 $filiation = $this->menuToRoot($MID, $filiation);
361 mysql_free_result($res);
363 // add the user-defined part of the menu
364 $this->menu
= array_merge($this->menu
,$this->menuRecurse(0,$filiation,0));
368 /** Return the filiation to get to the root element.
373 function menuToRoot($MID, $path) {
374 /* add ourself to the path */
375 array_push($path,$MID);
379 $res = $this->dbh
->query("select MIDpere from {$this->table_menu} where MID=$MID");
380 list($MIDpere) = mysql_fetch_row($res);
381 mysql_free_result($res);
383 return $this->menuToRoot($MIDpere, $path);
391 /** Recursively add menu entries
397 function menuRecurse($MIDpere, $filiation, $level) {
398 // the produced output
401 $res = $this->dbh
->query("select m.MID,m.title,m.link,m.PID ".
402 "from {$this->table_menu} as m ".
403 "where MIDpere=$MIDpere order by ordre");
405 while(list($mid,$title,$link,$pid) = mysql_fetch_row($res)) {
406 $location = $this->barrel
->getLocation($pid);
407 // echo "pid : $pid, location : $location<br/>";
408 $title = stripslashes($title);
409 $entry = htmlentities(stripslashes($title), ENT_QUOTES
);
410 $link = $pid ?
$this->urlSite($location) : $link;
411 // decide whether this menu should be expanded
412 $expanded = ($this->barrel
->options
->menu_min_level
== 0) ||
413 ($level+
1 < $this->barrel
->options
->menu_min_level
) ||
414 in_array($mid, $filiation);
415 array_push($out, array($level, $entry, $link, $expanded));
416 $out = array_merge($out, $this->menuRecurse($mid, $filiation, $level+
1));
419 // free MySQL result and return output
420 mysql_free_result($res);
426 * Break down a PATH_INFO into site, page id and file
427 * Directories *must* be accessed with a final slash.
429 * @param path the path to parse
431 function parsePathInfo($path) {
432 if (empty($path) ||
!preg_match("/^\/([^\/]+)\/((.+)\/)?([^\/]*)$/",$path,$asplit))
435 $split['alias'] = $asplit[1];
436 $split['dir'] = isset($asplit[3]) ?
$asplit[3] : "";
437 $split['file'] = isset($asplit[4]) ?
$asplit[4] : "";
442 /** Return the current URI.
444 function script_uri()
446 if ($this->barrel
->vhost
)
447 return preg_replace("/^(.*)\/site(\.php)?\/{$this->alias}\/(.*)/", "/\$3",$_SERVER['REQUEST_URI']);
449 return $_SERVER['REQUEST_URI'];
453 /** Returns the path to a given template. */
454 function templatePath($template)
458 $bits = split(":", $template);
461 $path = $globals->template_dir
."/". $bits[1];
464 $path = $this->barrel
->spool
->spoolPath($this->barrel
->options
->template_dir
, $bits[1]);
467 $path = parent
::templatePath($template);
473 /** Returns the URL to one of the barrel's pages relative to
474 * the current location.
479 function urlSite($dir, $file = '') {
481 $tosite = strlen($this->pathinfo
['dir']) ?
str_repeat("../",1+
substr_count($this->pathinfo
['dir'],"/")) : '';
482 $url = $tosite . (strlen($dir) ?
"$dir/" : "") . $file;
483 return strlen($url) ?
$url : "./";