Barrel.php

00001 <?php
00002 /*
00003  * Copyright (C) 2003-2004 Polytechnique.org
00004  * http://opensource.polytechnique.org/
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 require_once 'Barrel/Page.php';
00022 require_once 'Barrel/Options.php';
00023 require_once 'diogenes/diogenes.flagset.inc.php';
00024  
00025 
00028 class Diogenes_Barrel
00029 {
00031   var $alias;
00032 
00034   var $table_menu;
00035 
00037   var $table_page;
00038     
00040   var $flags;
00041   
00043   var $options;
00044   
00046   var $homepage;
00047 
00049   var $spool;
00050   
00052   var $vhost;
00053 
00055   var $treeCache;
00056   
00058   var $treeCacheFile;
00059 
00061   var $pluginsCache;
00062     
00064   var $pluginsCacheFile;
00065    
00066   
00071   function Diogenes_Barrel($alias)
00072   {
00073     global $globals;
00074     $webdav = '';
00075     
00076     // Retrieve site-wide info from database
00077     $res = $globals->db->query("select alias,vhost,flags from diogenes_site where alias='$alias'");
00078     if (!list($this->alias,$this->vhost,$flags) = mysql_fetch_row($res)) {
00079       return;      
00080     }
00081     mysql_free_result($res);
00082     
00083     $this->table_menu = "{$this->alias}_menu";
00084     $this->table_page = "{$this->alias}_page";
00085     $this->treeCacheFile = $globals->spoolroot."/diogenes_c/". $this->alias.".tree";
00086     $this->pluginsCacheFile = $globals->plugins->cacheFile($this->alias);
00087 
00088     $this->flags = new flagset($flags);    
00089     $this->options = new Diogenes_Barrel_Options($this->alias);
00090     $this->spool = new Diogenes_VCS_Spool($this,$this->alias);
00091     
00092     $this->readTree();
00093   }
00094   
00095   
00102   function create($alias, &$caller)
00103   {
00104     global $globals;
00105 
00106     /* sanity check */
00107     if (!preg_match("/^[a-zA-Z0-9_]+$/",$alias) or
00108         in_array($alias, $globals->invalidaliases)) 
00109     {
00110       $caller->info("Invalid barrel name!");
00111       return;
00112     }
00113 
00114     $res = $globals->db->query("select alias from diogenes_site where alias='$alias'");
00115     if (mysql_num_rows($res) > 0) {
00116       $caller->info("Entry '{$alias}' already exists in table 'diogenes_site'!");
00117       return;
00118     }
00119 
00120     if (file_exists("{$globals->rcsroot}/$alias")) {
00121       $caller->info("Directory '{$globals->rcsroot}/$alias' already exists!");
00122       return;
00123     }
00124 
00125     if (!is_dir($globals->rcsroot) || !is_writable($globals->rcsroot)) {
00126       $caller->info("Directory '{$globals->rcsroot}' is not writable!");
00127       return;
00128     }
00129 
00130     /* log this event */
00131     $caller->log("barrel_create","$alias:*");
00132 
00133     /* create DB entry */
00134     $globals->db->query("insert into diogenes_site set alias='$alias'");
00135 
00136     $globals->db->query("CREATE TABLE {$alias}_menu ("
00137     . "MID int(10) unsigned NOT NULL auto_increment,"
00138     . "MIDpere int(10) unsigned NOT NULL,"
00139     . "ordre int(10) unsigned NOT NULL,"
00140     . "title tinytext NOT NULL,"
00141     . "link text NOT NULL,"
00142     . "PID int(10) unsigned NOT NULL,"
00143     . "PRIMARY KEY  (MID)"
00144     . ") TYPE=MyISAM;");
00145 
00146     $globals->db->query("CREATE TABLE {$alias}_page ("
00147     . "PID int(10) unsigned NOT NULL auto_increment,"
00148     . "parent INT( 10 ) UNSIGNED NOT NULL default '0',"
00149     . "location tinytext NOT NULL,"
00150     . "title tinytext NOT NULL,"
00151     . "status tinyint(1) unsigned NOT NULL default '0',"
00152     . "perms enum('public','auth','user','admin','forbidden') NOT NULL default 'public',"
00153     . "wperms enum('public','auth','user','admin','forbidden') NOT NULL default 'admin',"
00154     . "template varchar(255) NOT NULL,"
00155     . "PRIMARY KEY  (PID)"
00156     . ") TYPE=MyISAM;");
00157     
00158     /* set the barrel's title */
00159     $opt = new Diogenes_Barrel_Options($alias);
00160     $opt->updateOption('title',$alias);
00161 
00162     /* create entry for the homepage */
00163     $globals->db->query("insert into {$alias}_page set location='temp'");
00164     $homepage = mysql_insert_id();
00165     $globals->db->query("update {$alias}_page set location='',title='Home',perms='public' where PID='$homepage'");
00166 
00167     /* create home page */
00168     $rcs = new $globals->rcs($caller,$alias,$_SESSION['session']->username,true);
00169     $rcs->newdir("",$homepage);
00170     $rcs->commit($homepage,$globals->htmlfile,"");
00171 
00172     /* copy CSS template */
00173     $def_css = file_get_contents("{$globals->root}/styles/{$globals->barrel_style_sheet}.css");
00174     $rcs->commit($homepage,$globals->cssfile, $def_css);
00175   }
00176 
00177   
00184   function destroy($alias, &$caller) {
00185     global $globals;
00186 
00188     if (!$alias) {
00189       $caller->info("Empty alias supplied!");
00190       return;
00191     }
00192 
00193     /* log this event */
00194     $caller->log("barrel_delete","$alias:*");
00195 
00196     system(escapeshellcmd("rm -rf ".escapeshellarg("{$globals->spoolroot}/$alias")));
00197     system(escapeshellcmd("rm -rf ".escapeshellarg("{$globals->rcsroot}/$alias")));
00198     system(escapeshellcmd("rm -f ".escapeshellarg("{$globals->spoolroot}/diogenes_c/$alias.tree")));
00199     system(escapeshellcmd("rm -f ".escapeshellarg($globals->plugins->cacheFile($alias))));
00200     $globals->db->query("drop table {$alias}_menu");
00201     $globals->db->query("drop table {$alias}_page");
00202     $globals->db->query("delete from diogenes_perm where alias='$alias'");
00203     $globals->db->query("delete from diogenes_site where alias='$alias'");
00204     $globals->db->query("delete from diogenes_option where barrel='$alias'");    
00205     $globals->db->query("delete from diogenes_plugin where barrel='$alias'");
00206   }
00207   
00208     
00213   function getLocation($PID)
00214   {
00215     return array_search($PID, $this->treeCache);
00216   }
00217     
00218   
00219   
00222   function getPages()
00223   {
00224     global $globals;
00225     $bpages = array();
00226     
00227     $res = $globals->db->query("select * from {$this->table_page}");
00228     while ($props = mysql_fetch_assoc($res)) {
00229       $bpages[$props['PID']] = new Diogenes_Barrel_Page($this, $props);
00230     }
00231     mysql_free_result($res);
00232     return $bpages;  
00233   }
00234   
00235       
00240   function getPID($dir)
00241   {
00242     if (isset($this->treeCache[$dir]))
00243       return $this->treeCache[$dir];
00244     else
00245       return;
00246   }
00247   
00248   
00253   function getPlugins($page = 0)
00254   {
00255     $plugins = array();
00256     foreach ($this->pluginsCache as $plug)
00257     {
00258       if ($plug['page'] == $page) 
00259       {
00260         array_push($plugins, $plug);
00261       }
00262     }
00263     return $plugins;    
00264   }
00265 
00266   
00271   function hasFlag($flag)
00272   {
00273     return $this->flags->hasFlag($flag);
00274   }
00275 
00276 
00282   function makePath($path, &$caller)
00283   {
00284     $pathbits = split("/", $path);
00285     $curpath = '';
00286     $curpid = $this->getPID($curpath);;
00287     foreach ($pathbits as $pathbit)
00288     {
00289       $newpath = ($curpath ? "$curpath/" : "") . $pathbit;
00290       $newpid = $this->getPID($newpath);
00291       if (!$newpid)
00292       {
00293         $tpage = new Diogenes_Barrel_Page($this, array('parent' => $curpid, 'location' => $pathbit));
00294         $tpage->toDb(0, $caller);
00295         $newpid = $this->getPID($newpath);
00296       }
00297       $curpath = $newpath;
00298       $curpid = $newpid;
00299     }
00300     return $curpid;
00301   }
00302   
00303 
00309   function rmPath($path, &$caller)
00310   {
00311     global $globals;
00312 
00313     if (!$path) {
00314       $caller->info("rmPath: will not delete from root!");
00315       return false;
00316     }
00317     $curpid = $this->getPID($path);
00318     if (!$curpid) {
00319       $caller->info("rmPath: could not find '$path'");
00320       return false;
00321     }
00322 
00323     // lookup children
00324     $res = $globals->db->query("select PID from {$this->table_page} where parent=$curpid");
00325     $children = array();
00326     while (list($child) = mysql_fetch_row($res))
00327       array_push($children, $child);
00328     mysql_free_result($res);
00329 
00330     // recurse into children
00331     foreach ($children as $child)
00332     {
00333       $childpath = $this->getLocation($child);
00334       if ($childpath) {
00335         if (!$this->rmPath($childpath, $caller)) 
00336           return false;
00337       }
00338     }
00339     
00340     // delete this page
00341     return Diogenes_Barrel_Page::delete($this, $curpid, $caller);
00342   }
00343 
00346   function compileTree()
00347   {
00348     global $globals;
00349     
00350     if (!$fp = fopen($this->treeCacheFile, "w")) {
00351       trigger_error("failed to open '{$this->treeCacheFile}' for writing", E_USER_ERROR);
00352       return;
00353     }
00354     
00355     // load all the pages
00356     $res = $globals->db->query("select * from {$this->table_page}");
00357     $tpages = array();
00358     while ($props = mysql_fetch_assoc($res))
00359     {      
00360       $tpage = new Diogenes_Barrel_Page($this, $props);
00361       $tpages[$props['PID']] = $tpage;
00362       if (!strlen($props['location']))
00363       {
00364         $homepage = $props['PID'];
00365       }
00366     }      
00367         
00368     // recursively build the tree, starting at the homepage 
00369     $str = $this->compilePageTree($tpages, $homepage, '');
00370     fputs($fp, $str);
00371     fclose($fp);    
00372   }
00373   
00374   
00377   function compilePageTree(&$tpages, $PID, $ploc)
00378   {
00379     global $globals;
00380     
00381     $cpage = $tpages[$PID];
00382     $ploc = ($ploc ? "$ploc/" : "") . $cpage->props['location'];
00383           
00384     // add this page
00385     $out = "$ploc\t$PID\t".$cpage->props['parent']."\n";      
00386     
00387     // add children
00388     $res = $globals->db->query("select PID from {$this->table_page} where parent='$PID'");    
00389     while (list($child) = mysql_fetch_row($res))
00390     {           
00391       $out .= $this->compilePageTree($tpages, $child, $ploc);
00392     }      
00393     mysql_free_result($res);
00394     return $out;
00395   }
00396 
00397   
00402   function loadPlugins(&$bpage)
00403   {
00404     global $globals;
00405   
00406     $plugins = $this->getPlugins($bpage->props['PID']);
00407     
00408     $loaded = array();
00409     foreach ($plugins as $plugentry) 
00410     {
00411       $loaded[$plugentry['plugin']] =& $globals->plugins->load($plugentry);
00412     }
00413     return $loaded;
00414   }
00415   
00416   
00419   function readPlugins()
00420   {
00421     global $globals;
00422 
00423     $this->pluginsCache = $globals->plugins->readCache($this->pluginsCacheFile, $this->alias);
00424   }
00425   
00426     
00429   function readTree()
00430   {
00431     global $globals;
00432     
00433     // if the tree cache does not exits, try to init it
00434     if (!file_exists($this->treeCacheFile)) {
00435       $this->compileTree();
00436     }
00437     
00438     if (!$fp = fopen($this->treeCacheFile, "r")) {
00439       trigger_error("failed to open '{$this->treeCacheFile}' for reading", E_USER_ERROR);
00440       return;
00441     }
00442     
00443     $locations = array();
00444     while ($line = fgets($fp))
00445     {
00446       $line = substr($line, 0, -1);
00447       $bits = explode("\t", $line);
00448       list($loc, $pid, $parent) = $bits;       
00449       $locations[$loc] = $pid;
00450     }
00451     fclose($fp);
00452 
00453     $this->treeCache = $locations;    
00454   }
00455    
00456 }

Generated on Fri Jan 11 01:20:08 2008 for Diogenes by  doxygen 1.5.1