a1ba57438913e4f535075da97cef156a2cb7e750
3 * Copyright (C) 2003-2004 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
21 require_once 'Barrel/Page.php';
22 require_once 'Barrel/Options.php';
23 require_once 'diogenes/diogenes.flagset.inc.php';
26 /** This class describes a Diogenes Barrel.
30 /** The barrel's alias. */
33 /** The database table holding the menus */
36 /** The database table holding the pages */
39 /** The site's flags. */
42 /** The site's options. */
45 /** Cache of the homepage ID */
48 /** Handle to the spool */
51 /** If the barrel is running on a virtualhost. */
57 /** File containing the tree cache. */
60 /** Cache of the plugins */
63 /** File containing the plugin cache. */
64 var $pluginsCacheFile;
67 /** Construct a Diogenes Barrel.
71 function Diogenes_Barrel($alias)
76 // Retrieve site-wide info from database
77 $res = $globals->db
->query("select alias,vhost,flags from diogenes_site where alias='$alias'");
78 if (!list($this->alias
,$this->vhost
,$flags) = mysql_fetch_row($res)) {
81 mysql_free_result($res);
83 $this->table_menu
= "{$this->alias}_menu";
84 $this->table_page
= "{$this->alias}_page";
85 $this->treeCacheFile
= $globals->spoolroot
."/diogenes_c/". $this->alias
.".tree";
86 $this->pluginsCacheFile
= $globals->plugins
->cacheFile($this->alias
);
88 $this->flags
= new flagset($flags);
89 $this->options
= new Diogenes_Barrel_Options($this->alias
);
90 $this->spool
= new Diogenes_VCS_Spool($this,$this->alias
);
96 /** Create a new Diogenes barrel. This creates the database, RCS and
97 * spool entries for the new barrel.
102 function create($alias, &$caller)
107 if (!preg_match("/^[a-zA-Z0-9_]+$/",$alias) or
108 in_array($alias, $globals->invalidaliases
))
110 $caller->info("Invalid barrel name!");
114 $res = $globals->db
->query("select alias from diogenes_site where alias='$alias'");
115 if (mysql_num_rows($res) > 0) {
116 $caller->info("Entry '{$alias}' already exists in table 'diogenes_site'!");
120 if (file_exists("{$globals->rcsroot}/$alias")) {
121 $caller->info("Directory '{$globals->rcsroot}/$alias' already exists!");
125 if (!is_dir($globals->rcsroot
) ||
!is_writable($globals->rcsroot
)) {
126 $caller->info("Directory '{$globals->rcsroot}' is not writable!");
131 $caller->log("barrel_create","$alias:*");
133 /* create DB entry */
134 $globals->db
->query("insert into diogenes_site set alias='$alias'");
136 $globals->db
->query("CREATE TABLE {$alias}_menu ("
137 . "MID int(10) unsigned NOT NULL auto_increment,"
138 . "MIDpere int(10) unsigned NOT NULL,"
139 . "ordre int(10) unsigned NOT NULL,"
140 . "title tinytext NOT NULL,"
141 . "link text NOT NULL,"
142 . "PID int(10) unsigned NOT NULL,"
143 . "PRIMARY KEY (MID)"
146 $globals->db
->query("CREATE TABLE {$alias}_page ("
147 . "PID int(10) unsigned NOT NULL auto_increment,"
148 . "parent INT( 10 ) UNSIGNED NOT NULL default '0',"
149 . "location tinytext NOT NULL,"
150 . "title tinytext NOT NULL,"
151 . "status tinyint(1) unsigned NOT NULL default '0',"
152 . "perms enum('public','auth','user','admin','forbidden') NOT NULL default 'public',"
153 . "wperms enum('public','auth','user','admin','forbidden') NOT NULL default 'admin',"
154 . "template varchar(255) NOT NULL,"
155 . "PRIMARY KEY (PID)"
158 /* set the barrel's title */
159 $opt = new Diogenes_Barrel_Options($alias);
160 $opt->updateOption('title',$alias);
162 /* create entry for the homepage */
163 $globals->db
->query("insert into {$alias}_page set location='temp'");
164 $homepage = mysql_insert_id();
165 $globals->db
->query("update {$alias}_page set location='',title='Home',perms='public' where PID='$homepage'");
167 /* create home page */
168 $rcs = new $globals->rcs($caller,$alias,$_SESSION['session']->username
,true
);
169 $rcs->newdir("",$homepage);
170 $rcs->commit($homepage,$globals->htmlfile
,"");
172 /* copy CSS template */
173 $def_css = file_get_contents("{$globals->root}/styles/{$globals->barrel_style_sheet}.css");
174 $rcs->commit($homepage,$globals->cssfile
, $def_css);
178 /** Destroy a Diogenes barrel. This removes the related database, RCS
184 function destroy($alias, &$caller) {
189 $caller->info("Empty alias supplied!");
194 $caller->log("barrel_delete","$alias:*");
196 system(escapeshellcmd("rm -rf ".escapeshellarg("{$globals->spoolroot}/$alias")));
197 system(escapeshellcmd("rm -rf ".escapeshellarg("{$globals->rcsroot}/$alias")));
198 system(escapeshellcmd("rm -f ".escapeshellarg("{$globals->spoolroot}/diogenes_c/$alias.tree")));
199 system(escapeshellcmd("rm -f ".escapeshellarg($globals->plugins
->cacheFile($alias))));
200 $globals->db
->query("drop table {$alias}_menu");
201 $globals->db
->query("drop table {$alias}_page");
202 $globals->db
->query("delete from diogenes_perm where alias='$alias'");
203 $globals->db
->query("delete from diogenes_site where alias='$alias'");
204 $globals->db
->query("delete from diogenes_option where barrel='$alias'");
205 $globals->db
->query("delete from diogenes_plugin where barrel='$alias'");
209 /** Return the location corresponding to a given page ID
213 function getLocation($PID)
215 return array_search($PID, $this->treeCache
);
220 /** Return all the barrel's pages.
227 $res = $globals->db
->query("select * from {$this->table_page}");
228 while ($props = mysql_fetch_assoc($res)) {
229 $bpages[$props['PID']] = new Diogenes_Barrel_Page($this, $props);
231 mysql_free_result($res);
236 /** Return the page ID matching a given directory location
240 function getPID($dir)
242 if (isset($this->treeCache
[$dir]))
243 return $this->treeCache
[$dir];
249 /** List the plugins that are active in a given context
253 function getPlugins($page = 0)
256 foreach ($this->pluginsCache
as $plug)
258 if ($plug['page'] == $page)
260 array_push($plugins, $plug);
267 /** Check whether the barrel has a given flag
271 function hasFlag($flag)
273 return $this->flags
->hasFlag($flag);
277 /** Create a page with the given path, and return its PID.
282 function makePath($path, &$caller)
284 $pathbits = split("/", $path);
286 $curpid = $this->getPID($curpath);;
287 foreach ($pathbits as $pathbit)
289 $newpath = ($curpath ?
"$curpath/" : "") . $pathbit;
290 $newpid = $this->getPID($newpath);
293 $tpage = new Diogenes_Barrel_Page($this, array('parent' => $curpid, 'location' => $pathbit));
294 $tpage->toDb(0, $caller);
295 $newpid = $this->getPID($newpath);
304 /** Recursively delete a given path.
309 function rmPath($path, &$caller)
314 $caller->info("rmPath: will not delete from root!");
317 $curpid = $this->getPID($path);
319 $caller->info("rmPath: could not find '$path'");
324 $res = $globals->db
->query("select PID from {$this->table_page} where parent=$curpid");
326 while (list($child) = mysql_fetch_row($res))
327 array_push($children, $child);
328 mysql_free_result($res);
330 // recurse into children
331 foreach ($children as $child)
333 $childpath = $this->getLocation($child);
335 if (!$this->rmPath($childpath, $caller))
341 return Diogenes_Barrel_Page
::delete($this, $curpid, $caller);
344 /** Compile the directory tree
346 function compileTree()
350 if (!$fp = fopen($this->treeCacheFile
, "w")) {
351 trigger_error("failed to open '{$this->treeCacheFile}' for writing", E_USER_ERROR
);
355 // load all the pages
356 $res = $globals->db
->query("select * from {$this->table_page}");
358 while ($props = mysql_fetch_assoc($res))
360 $tpage = new Diogenes_Barrel_Page($this, $props);
361 $tpages[$props['PID']] = $tpage;
362 if (!strlen($props['location']))
364 $homepage = $props['PID'];
368 // recursively build the tree, starting at the homepage
369 $str = $this->compilePageTree($tpages, $homepage, '');
375 /** Compile a single page
377 function compilePageTree(&$tpages, $PID, $ploc)
381 $cpage = $tpages[$PID];
382 $ploc = ($ploc ?
"$ploc/" : "") . $cpage->props
['location'];
385 $out = "$ploc\t$PID\t".$cpage->props
['parent']."\n";
388 $res = $globals->db
->query("select PID from {$this->table_page} where parent='$PID'");
389 while (list($child) = mysql_fetch_row($res))
391 $out .= $this->compilePageTree($tpages, $child, $ploc);
393 mysql_free_result($res);
398 /** Load all plugins for the specified page.
402 function loadPlugins(&$bpage)
406 $plugins = $this->getPlugins($bpage->props
['PID']);
409 foreach ($plugins as $plugentry)
411 $loaded[$plugentry['plugin']] =& $globals->plugins
->load($plugentry);
417 /** Read the compiled plugin cache
419 function readPlugins()
423 $this->pluginsCache
= $globals->plugins
->readCache($this->pluginsCacheFile
, $this->alias
);
427 /** Read the compiled directory tree
433 // if the tree cache does not exits, try to init it
434 if (!file_exists($this->treeCacheFile
)) {
435 $this->compileTree();
438 if (!$fp = fopen($this->treeCacheFile
, "r")) {
439 trigger_error("failed to open '{$this->treeCacheFile}' for reading", E_USER_ERROR
);
443 $locations = array();
444 while ($line = fgets($fp))
446 $line = substr($line, 0, -1);
447 $bits = explode("\t", $line);
448 list($loc, $pid, $parent) = $bits;
449 $locations[$loc] = $pid;
453 $this->treeCache
= $locations;