first shot at reworking plugin system
authorJeremy Laine <jeremy.laine@m4x.org>
Sat, 20 May 2006 19:29:42 +0000 (19:29 +0000)
committerJeremy Laine <jeremy.laine@m4x.org>
Sat, 20 May 2006 19:29:42 +0000 (19:29 +0000)
config/db/diogenes.sql
config/updatedb.php
htdocs/toplevel/plugins.php
include/Plugin/Editor.php
include/Plugin/Skel.php
include/Plugins.php
include/Tree/Node.php
templates/plugin-editor.tpl

index dad6e88..70c6571 100644 (file)
@@ -115,6 +115,7 @@ CREATE TABLE `diogenes_plugin` (
   `page` int(10) unsigned NOT NULL default '0',
   `pos` int(10) unsigned NOT NULL default '0',
   `params` text NOT NULL,
+  `status` int(1) unsigned NOT NULL default '0',
   PRIMARY KEY  (`plugin`,`barrel`,`page`),
   KEY `pos` (`pos`)
 ) TYPE=MyISAM;
index 3012f23..c6f0be6 100755 (executable)
@@ -13,7 +13,7 @@ require_once("diogenes/diogenes.database-creator.inc.php");
 class DiogenesDbInit extends DiogenesDatabaseCreator
 {
   /** database versions history */
-  var $versions = array("0.9.9.3", "0.9.10", "0.9.12", "0.9.15", "0.9.16", "0.9.16+0.9.17pre15", "0.9.16+0.9.17pre19", "0.9.16+0.9.17pre21");
+  var $versions = array("0.9.9.3", "0.9.10", "0.9.12", "0.9.15", "0.9.16", "0.9.16+0.9.17pre15", "0.9.16+0.9.17pre19", "0.9.16+0.9.17pre21", "0.9.18+0.9.19pre1");
 
   /**
    * Upgrades the database from one version to the next
@@ -38,6 +38,7 @@ class DiogenesDbInit extends DiogenesDatabaseCreator
     // upgrade master tables
     $this->info("* Upgrading master tables : diogenes_*");
     $this->upgradeMaster($newversion);
+    exit(1);
   }
 
   
@@ -213,6 +214,13 @@ class DiogenesDbInit extends DiogenesDatabaseCreator
       $this->dbh->query("INSERT INTO diogenes_logactions VALUES (16, 'page_plugins', 'the page plugins were modified');");
       break;
 
+    case "0.9.18+0.9.19pre1":
+      $this->info(" - adding 'status' field to 'diogenes_plugin' table");
+      $this->dbh->query("ALTER TABLE `diogenes_plugin` ADD `status` INT( 1 ) UNSIGNED NOT NULL default '0'");
+      $this->dbh->query("update diogenes_plugin set status=1 where page=0");
+      $this->dbh->query("update diogenes_plugin set status=2 where page!=0");
+      break;
+    
     default:
       $this->info(" - no changes needed.");
       break;
index c874d4d..dee6ce2 100644 (file)
@@ -23,26 +23,9 @@ if ($barrel)
 
 /* plugin editor */
 $editor = new Diogenes_Plugin_Editor($barrel, 0);
-$editor->hide_params(1);
+//$editor->hide_params(1);
 $editor->run($page,'editor_content');
 
-// if necessary, rebuild site plugin caches
-if ($action == "update" && !$barrel)
-{
-  $res = $globals->db->query("select alias,flags from diogenes_site");
-  while (list($p_alias, $p_flags) = mysql_fetch_row($res))
-  {
-    $flags = new flagset($p_flags);
-    if ($p_alias && $flags->hasFlag('plug')) 
-    {
-      $page->info(sprintf( __("Rebuilding plugin cache for barrel '%s'"), $p_alias));
-      $cachefile = $globals->plugins->cacheFile($p_alias);
-      $globals->plugins->compileCache($cachefile, $p_alias);
-    }
-  }
-  mysql_free_result($res);
-}
-
 // translations
 $page->assign('msg_clean_database', __('Clean plugins database'));
 $page->assign('msg_clean_database_text', __("If you are having problems with references to plugins that no longer exist, you can have Diogenes remove such entries from the database."));
index 539b8f0..f0b283d 100644 (file)
@@ -52,8 +52,8 @@ class Diogenes_Plugin_Editor {
     $this->plug_page = $plug_page;
     $this->plug_page_wperms = $plug_page_wperms;
   }
-  
-  
+
+
   /** Run the plugin editor.
    *
    * @param $page
@@ -62,185 +62,154 @@ class Diogenes_Plugin_Editor {
   function run(&$page, $outputvar = '')
   {
     global $globals;
-    
+
     $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';    
     $target = isset($_REQUEST['plug_target']) ? $_REQUEST['plug_target'] : '';
-         
+
     // load all available plugins
     $cachefile = $globals->plugins->cacheFile($this->plug_barrel);
-    
-    // if the tree cache does not exits, try to init it
-    if (!file_exists($cachefile)) {
-      $globals->plugins->compileCache($cachefile, $this->plug_barrel);
-    }        
+
+    // if the tree cache does not exits try to init it
+    if(!file_exists($cachefile))
+    {
+      $globals->plugins->compileCache($this->plug_barrel, $page);
+    }
     $cache = $globals->plugins->readCache($cachefile, $this->plug_barrel);
     $available = $globals->plugins->cachedAvailable($cache, $this->plug_barrel, $this->plug_page);
-           
-    
+
     // handle updates
+    $rebuild_cache = 0;
     switch ($action) {
     case "move_up": case "move_down":
       if ($this->readonly) die("Sorry, this plugin view is read-only.");
-      
+
       $delta = ($action == "move_down") ? 1 : -1;
-      //$page->info("moving plugin '$target'..");
+      $page->info("moving plugin '$target'..");
       $plugcache_a = $globals->plugins->cacheGet($cache, $this->plug_barrel, $this->plug_page, $target);
-      $plug_a =& $globals->plugins->load($plugcache_a);
-      //$plug_a =& $globals->plugins->get($target);
-      
+      $plug_a =& $globals->plugins->load($plugcache_a['name'], $plugcache_a);
+
       if (is_object($plug_a) && ($plug_a->active)) {
         $old_pos = $plug_a->pos;
-        //$plug_b =& $globals->plugins->getAtPos($old_pos + $delta);        
         $plugcache_b = $globals->plugins->cacheGetAtPos($cache, $this->plug_barrel, $this->plug_page, $old_pos + $delta);
-        
+
         if (is_array($plugcache_b))
         {
-          $plug_b =& $globals->plugins->load($plugcache_b);
-  
+          $plug_b =& $globals->plugins->load($plugcache_b['name'], $plugcache_b);
+
           // swap the current plugin and the next plugin
           if (is_object($plug_b) && ($plug_b->active)) 
           {
-            $plug_a->writeParams($this->plug_barrel, $this->plug_page, $old_pos + $delta);        
-            $plug_b->writeParams($this->plug_barrel, $this->plug_page, $old_pos);
-          }        
+            $plug_a->toDatabase($this->plug_barrel, $this->plug_page, $old_pos + $delta);
+            $plug_b->toDatabase($this->plug_barrel, $this->plug_page, $old_pos);
+          }
         }
-      }     
-      $globals->plugins->compileCache($cachefile, $this->plug_barrel);
-      $cache = $globals->plugins->readCache($cachefile, $this->plug_barrel);  
-      $available = $globals->plugins->cachedAvailable($cache, $this->plug_barrel, $this->plug_page);       
+      }
+      $rebuild_cache = 1;
       break;
-      
+
     case "update":
       if ($this->readonly) die("Sorry, this plugin view is read-only.");
-    
-      // list of active plugins
-      $active = array();
-      if (isset($_REQUEST['plugins_active'])) {
-        $active = array_values($_REQUEST['plugins_active']);
-      }
-      
-      foreach ($available as $plugin) {  
-        $plugentry = $globals->plugins->cacheGet($cache, $this->plug_barrel, $this->plug_page, $plugin);
-        if (!is_array($plugentry) and $this->plug_page) {
-          $plugentry = $globals->plugins->cacheGet($cache, $this->plug_barrel, 0, $plugin);
-          if (is_array($plugentry))
-          {
-            $plugentry['active'] = 0;
-          }
-        }
-        
+      foreach ($available as $plugin => $plugentry)
+      {
         // check we have a valid cache entry
         if (!is_array($plugentry)) {
-          $page->info("could not find plugin '$plugin' in cache for barrel '{$this->plug_barrel}'");          
+          $page->info("could not find plugin '$plugin' in cache for barrel '{$this->plug_barrel}'");
           return;
         }
-        
-        $plug_h =& $globals->plugins->load($plugentry);
-        
-        if (is_object($plug_h) && is_array($plugentry)) {
-          $pos = array_search($plugin, $active);
-          
-          if ($pos !== false) {
-            // check the plugin is allowed in the current context
-            if ($this->plug_barrel and $this->plug_page) {
-              $wperms = $this->plug_page_wperms;
-              
-              // $page->info("checking plugin '$plugin' vs. write permissions '$wperms'..");
-              if (!$plug_h->allow_wperms($wperms))
-              {
-                $page->info("plugin '$plugin' is not allowed with write permissions '$wperms'!");
-                break;
-              }             
-            }
-            
-            // retrieve parameters from REQUEST
-            foreach ($plug_h->getParamNames() as $key)
+
+        $plug_h =& $globals->plugins->load($plugin, $plugentry);
+        if (!is_object($plug_h)) {
+          $page->info("could not load plugin '$plugin' in cache for barrel '{$this->plug_barrel}'");
+          return;
+        }
+
+        if ($pos !== false) {
+          // check the plugin is allowed in the current context
+          if ($this->plug_barrel and $this->plug_page) {
+            $wperms = $this->plug_page_wperms;
+
+            // $page->info("checking plugin '$plugin' vs. write permissions '$wperms'..");
+            if (!$plug_h->allow_wperms($wperms))
             {
-              if (isset($_REQUEST[$plug_h->name."_".$key])) {
-                $plug_h->setParamValue($key, $_REQUEST[$plug_h->name."_".$key]);              
-              }
+              $page->info("plugin '$plugin' is not allowed with write permissions '$wperms'!");
+              break;
             }
-            
-            // write parameters to database
-            $plug_h->writeParams($this->plug_barrel, $this->plug_page, $pos);
-          } else {        
-            // erase parameters from database
-            $plug_h->eraseParams($this->plug_barrel, $this->plug_page);          
-          }        
+          }
+
+          // retrieve parameters from REQUEST
+          if (isset($_REQUEST[$plug_h->name."_status"])) 
+         {
+            $plug_h->status = $_REQUEST[$plug_h->name."_status"];
+          }
+          foreach ($plug_h->getParamNames() as $key)
+          {
+            if (isset($_REQUEST[$plug_h->name."_".$key])) {
+              $plug_h->setParamValue($key, $_REQUEST[$plug_h->name."_".$key]);
+            }
+          }
+
+          // write parameters to database
+          $plug_h->toDatabase($this->plug_barrel, $this->plug_page, $pos);
+          $rebuild_cache = 1;
         }
       }
-      
+      break;
+    }
+
+    // if necessary, rebuild the plugin cache
+    if ($rebuild_cache)
+    {
       // log this action
       if ($this->plug_barrel)
       { 
         if ($this->plug_page)
         {
-          $page->log('page_plugins', $this->plug_barrel.":".$this->plug_page);        
+          $page->log('page_plugins', $this->plug_barrel.":".$this->plug_page);
         } else {
-          $page->log('barrel_plugins', $this->plug_barrel.":*");        
+          $page->log('barrel_plugins', $this->plug_barrel.":*");
         }
       }
-      
-      $globals->plugins->compileCache($cachefile, $this->plug_barrel);
-      $cache = $globals->plugins->readCache($cachefile, $this->plug_barrel);  
-      $available = $globals->plugins->cachedAvailable($cache, $this->plug_barrel, $this->plug_page);    
-      break;
+      // rebuild plugin cache
+      $globals->plugins->compileCache($this->plug_barrel, $page);
+      $cache = $globals->plugins->readCache($cachefile, $this->plug_barrel);
+      $available = $globals->plugins->cachedAvailable($cache, $this->plug_barrel, $this->plug_page);
     }
     
     // get dump of plugins to fill out form
     $page->assign('plug_barrel', $this->plug_barrel);
     $page->assign('plug_page', $this->plug_page);
-    
     $plugs = array();
     
     // start by adding the active plugins
-    foreach ($cache as $plugcache)
+    foreach ($available as $plugname => $plugcache)
     {
-      if (in_array($plugcache['plugin'], $available) and ($plugcache['page'] == $this->plug_page) and ($plugcache['active']))
+      if ($plugcache['status'] == PLUG_ACTIVE)
       {
-        // check we have a valid plugin handle
-        $plug_h = $globals->plugins->load($plugcache);
-        if (!is_object($plug_h)) {
-
-          $page->info("could not load disabled plugin '{$plugcache['plugin']}' in barrel '{$this->plug_barrel}'"); 
-
-        } else {
-                
-          $plugentry = $plug_h->dump();
-          $plugentry['icon'] = $globals->icons->get_action_icon('plugins');            
-          $type = $plugentry['type'];        
-          if (!empty($plugs[$type])) {
+         $plugentry = $plugcache;
+         $plugentry['icon'] = $globals->icons->get_action_icon('plugins');
+         $type = $plugentry['type'];
+         if (!empty($plugs[$type])) {
             $plugentry['move_up'] = 1;
             $last = count($plugs[$type]) - 1;
-            $plugs[$type][$last]['move_down'] = 1;              
+            $plugs[$type][$last]['move_down'] = 1;
           } else {
-            $plugs[$type] = array();      
-          }                
+            $plugs[$type] = array();
+          }
           array_push($plugs[$type], $plugentry);
-
-       }
-      }    
+      }
     }
-    
-    // next we add the disabled plugins
+
+    // next we add the inactive plugins
     if (!$this->readonly)
     {
-      foreach ($available as $plugname)
+      foreach ($available as $plugname => $plugcache)
       {
-        $plugcache = $globals->plugins->cacheGet($cache, $this->plug_barrel, $this->plug_page, $plugname);
-        if (!is_array($plugcache) or !$plugcache['active'])
+        if ( ($plugcache['status'] == PLUG_AVAILABLE) ||
+             (($plugcache['status'] == PLUG_DISABLED) && !$this->plug_barrel) )
         {
-          $plugcache = $globals->plugins->cacheGet($cache, $this->plug_barrel, 0, $plugname);
-          $plugcache['active'] = 0;        
-          $plug_h = $globals->plugins->load($plugcache);
-          if (!is_object($plug_h)) {
-            $page->info("could not load disabled plugin '$plugname' in barrel '{$this->plug_barrel}'"); 
-            return;
-          }
-                    
-          $plugentry = $plug_h->dump();        
-          $plugentry['icon'] = $globals->icons->get_action_icon('plugins');                        
-          $type = $plugentry['type'];          
+          $plugentry = $plugcache;
+          $plugentry['icon'] = $globals->icons->get_action_icon('plugins');
+          $type = $plugentry['type'];
           if (empty($plugs[$type])) {
             $plugs[$type] = array();
           }
@@ -248,17 +217,14 @@ class Diogenes_Plugin_Editor {
         }
       }
     }
-    
-    /*
-    echo "plugins <pre>";
-    print_r($plugs);
-    echo "</pre>";
-    */
+
     $page->assign('plugins', $plugs);
-    
+
     // values
     $page->assign('show_params', $this->show_params);
     $page->assign('readonly',$this->readonly);
+    $statusvals = array(0 => 'disabled', '1' => 'available', 2 => 'enabled');
+    $page->assign('statusvals', $statusvals);
 
     // translations    
     $page->assign('msg_submit', __("Submit"));
@@ -268,7 +234,7 @@ class Diogenes_Plugin_Editor {
     $page->assign('msg_plugedit_parameters', __("parameters"));
     $page->assign('msg_move_up', __("move up"));
     $page->assign('msg_move_down', __("move down"));
-    
+
     // if requested, assign the content to be displayed
     if (!empty($outputvar)) {
       $page->assign($outputvar, $page->fetch('plugin-editor.tpl'));
index 7e86546..0116d10 100644 (file)
 
 // dependency on PEAR
 require_once 'System.php';
+require_once 'Tree/Node.php';
+
+define('PLUG_DISABLED', 0);
+define('PLUG_AVAILABLE', 1);
+define('PLUG_ACTIVE', 2);
 
 /** Recursive stripslashes.
  *
@@ -38,7 +43,7 @@ function stripslashes_recurse($value)
  */
 class Diogenes_Plugin_Skel {
   /** Plugin type (object, filter) */
-  var $type;
+  var $type = '';
   
   /** Array of plugin parameters */
   var $params = array();
@@ -53,11 +58,10 @@ class Diogenes_Plugin_Skel {
   var $version = "0.1";
 
   /** Position of the plugin */
-  var $pos;
-  
-  /** Is the plugin active ? */
-  var $active = 0;
+  var $pos = 0;
   
+  /** The plugin status (disabled, available, active) */
+  var $status = PLUG_AVAILABLE;
   
   /** Is the plugin allowed with respect to a given write permission on a page ?
    *
@@ -91,54 +95,30 @@ class Diogenes_Plugin_Skel {
   {
     return isset($this->params[$key]) ? $this->params[$key] : '';
   }
+
+
   /** Set the value of a parameter of the plugin.
    */
   function setParamValue($key, $val)
   {
     if (isset($this->params[$key])) {
-      //echo "$this->name : Calling setParamValue($key, $val)<br/>\n";
       $this->params[$key] = $val; 
     } else {
-      //echo "$this->name : skipping setParamValue($key, $val)<br/>\n";
     }
   }
-  /** Set plugin parameters.
-   *
-   * @param $params
-   */
-  function setParams($params)
-  {
-    $bits = explode("\0", $params);
-    foreach ($bits as $bit)
-    {
-      $frags = explode("=", $bit, 2);
-      $key = $frags[0];
-      if (!empty($key))
-      {
-        $val = isset($frags[1]) ? $frags[1] : '';
-        $this->setParamValue($key, $val);
-      }
-    }
-  }
-  
-  
+
+
   /** Erase parameters from database.
    *
    * @param $barrel
    * @param $page
    */
-  function eraseParams($barrel = '', $page = 0)
+  function eraseParameters($barrel = '', $page = 0)
   {
     global $globals;
-    
     //echo $this->name . " : eraseParams($barrel, $page)<br/>\n";
     $globals->db->query("delete from diogenes_plugin where plugin='{$this->name}' and barrel='$barrel' and page='$page'");
-    
-    $this->active = 0;
+
     unset($this->pos);
     foreach ($this->getParamNames() as $key)
     {
@@ -146,50 +126,53 @@ class Diogenes_Plugin_Skel {
       $this->setParamValue($key, '');
     }
   }
-   
-    
+
+
+  /** Read parameters from an array.
+    */
+  function fromArray($plugentry)
+  {
+      $this->pos = $plugentry['pos'];
+      $this->status = $plugentry['status'];
+      foreach ($plugentry['params'] as $key => $val)
+      {
+        $this->setParamValue($key, $val);
+      }
+  }
+
+
   /** Store parameters to database.
    *
    * @param $barrel
    * @param $page
-   * @param $pos   
+   * @param $pos
    */
-  function writeParams($barrel = '', $page = 0, $pos = 0)
+  function toDatabase($barrel = '', $page = 0, $pos = 0)
   {
     global $globals;
 
     $this->pos = $pos;
-    $this->active = 1;
-    
-    $params = '';
-    foreach ($this->getParamNames() as $key)
-    {
-      $val = $this->getParamValue($key);
-      //echo "$this->name : $key = $val<br/>\n";
-      $params .= "$key=$val\0";     
-    }        
-    $globals->db->query("replace into diogenes_plugin set plugin='{$this->name}', barrel='$barrel', page='$page', pos='$pos', params='$params'");
+    $params = var_encode_bin($this->params);
+    //echo "toDatabase called for '{$this->name}' in barrel '$barrel' (status : {$this->status}, params : '$params')<br/>";
+    $globals->db->query("replace into diogenes_plugin set plugin='{$this->name}', status='{$this->status}', barrel='$barrel', page='$page', pos='$pos', params='$params'");
   }
-  
-  
+
+
   /** Dump parameters to a table.
    */
-  function dump()
+  function toArray()
   {
     $plugentr = array();
 
     // copy over properties
-    $props = array('active', 'name', 'params', 'description', 'version', 'type', 'pos');
+    $props = array('status', 'name', 'params', 'description', 'version', 'type', 'pos');
     foreach ($props as $prop)
     {
-      if (isset($this->$prop))
-      {
-        $plugentr[$prop] =  stripslashes_recurse($this->$prop);
-      }
-    }    
+      $plugentr[$prop] =  stripslashes_recurse($this->$prop);
+    }
     return $plugentr;
   }
-  
+
 }
   
 ?>
index dc55ac7..c2f4423 100644 (file)
 
 // dependency on PEAR
 require_once 'System.php';
+require_once 'Tree/Node.php';
+require_once 'Plugin/Skel.php';
+
 
 /** This class describes Diogenes' plugins. 
  */
 class Diogenes_Plugins
 {
-  /** Array of currently loaded plugins */
-  var $loaded = array();
-
   /** Directory that holds the plugins cache files */
   var $cachedir;
-  
+
   /** Directory that holds the plugins */
   var $plugdir;
-  
-  
+
+  /** Plugins that will be sent to trace */
+  var $log = array();
+
   /** Constructs a new holder for Diogenes plugins.
    *
    * @param $dbh
@@ -45,7 +47,7 @@ class Diogenes_Plugins
   {
     $this->dbh =& $dbh;
     $this->plugdir = $plugdir;
-    $this->cachedir = $cachedir;    
+    $this->cachedir = $cachedir;
   }
   
   
@@ -58,47 +60,60 @@ class Diogenes_Plugins
     $cachefile = $this->cachedir . "/" . ($barrel ? $barrel : "__diogenes__") . ".plugins";
     return $cachefile;
   }
-    
-  
+
   /** Return the cache entry for specified plugin
    *
    * @param $cache
    * @param $barrel
    * @param $page
    * @param $plugin
-   */    
+   */
   function cacheGet($cache, $barrel, $page, $plugin)
   {
-    foreach ($cache as $plugentry)
-    {      
-      if (($plugentry['plugin'] == $plugin) && ($plugentry['page'] == $page))
-      {
-        return $plugentry;
-      }
-    }
-    return;     
+    $p_node = $this->cacheGetPageNode($cache, $barrel, $page);
+    return $p_node->data[$plugin];
   }
 
-  
+
   /** Return the cache entry for a plugin at a specified position
    *
    * @param $cache
    * @param $barrel
    * @param $page
    * @param $pos
-   */  
+   */
   function cacheGetAtPos($cache, $barrel, $page, $pos)
   {
-    foreach ($cache as $plugentry)
-    {      
-      if (($plugentry['pos'] == $pos) && ($plugentry['page'] == $page))
+    $p_node = $this->cacheGetPageNode($cache, $barrel, $page);
+    foreach ($p_node->data as $plugname => $plugentry)
+    {
+      if ($plugentry['pos'] == $pos)
       {
+        $plugentry['plugin'] = $plugname;
         return $plugentry;
       }
-    }  
-  }  
+    }
+  }
+
+
+  /** Return the cache entry for specified plugin
+   *
+   * @param $cache
+   * @param $barrel
+   * @param $page
+   * @param $plugin
+   */
+  function cacheGetPageNode($cache, $barrel, $page)
+  {
+    if ($page) {
+      $p_node = $cache->getChild($page);
+    } else {
+      $p_node = $cache;
+    }
+    return $p_node;
+  }
+
 
-  
   /** List the plugins that are active in a given context
    *
    * @param $cache
@@ -107,40 +122,35 @@ class Diogenes_Plugins
    */
   function cachedActive($cache, $barrel, $page)
   {
+    $p_node = $this->cacheGetPageNode($cache, $barrel, $page);
     $plugins = array();
-    foreach ($cache as $plug)
-    {
-      if ($plug['page'] == $page) 
-      {
-        array_push($plugins, $plug);
-      }
-    }
-    return $plugins;    
+    return $plugins;
   }
 
-    
+
   /** Returns an array of cache entries representing the available plugins
    *  in a given context
    *
    * @param $cache
    * @param $barrel
    * @param $page
-   */  
+   */
   function cachedAvailable($cache, $barrel, $page)
-  {      
-    $available = array();
-    foreach ($cache as $plugentry)
-    {      
-      $plugfile = $this->plugdir."/".$plugentry['plugin'].".php";
-      if (file_exists($plugfile) and ($plugentry['page'] == 0) and (!$page or $plugentry['active']))
+  {
+    $p_node = $this->cacheGetPageNode($cache, $barrel, $page);
+    //echo "<pre>".var_encode_text($p_node)."</pre>";
+    foreach ($p_node->data as $plugname => $plugentry)
+    {
+      $plugfile = $this->plugdir."/".$plugname.".php";
+      if (file_exists($plugfile) and (!$barrel || ($plugentry['status'] != PLUG_DISABLED)))
       {
-        array_push($available, $plugentry['plugin']);
+        $available[$plugname] = $plugentry;
       }
     }
-    return $available;    
+    return $available;
   }
-  
-  
+
+
   /** Remove database references to plugins that are not available.
    */
   function clean_database(&$page)
@@ -160,109 +170,168 @@ class Diogenes_Plugins
     */
   }
 
-    
+
+  /** Build view for current level.
+  */
+  function compileNode($node, &$outparent, $index)
+  {
+    $outvals = array();
+    foreach ($outparent->data as $plugin => $parentval)
+    {
+      //echo "Processing plugin '$plugin' for &lt;{$node->name}&gt;<br/>\n";
+      $outval = '';
+      if ($parentval['status'] != PLUG_DISABLED)
+      {
+        //echo "* plugin available/enabled at parent level<br/>\n";
+        $outval = $parentval;
+        if (is_array($node->data[$plugin]))
+        {
+          //echo "** plugin set at current level<br/>\n";
+          $outval['pos'] = $node->data[$plugin]['pos'];
+          $outval['params'] = $node->data[$plugin]['params'];
+          if ($parentval['status'] == PLUG_AVAILABLE) {
+            //echo "*** plugin status set to DB-specified value<br/>\n";
+            $outval['status'] = $node->data[$plugin]['status'];
+          } else {
+            //echo "*** plugin forced on at parent level<br/>\n";
+          }
+        } else {
+          //echo "** plugin unset at current level<br/>\n";
+        }
+      }
+
+      // add the plugin to output
+      if (is_array($outval))
+      {
+        $outvals[$plugin] = $outval;
+      }
+    }
+    $outnode = new Diogenes_Tree_Node($outvals, $node->name);
+    //echo "<hr/>";
+
+    // recurse into children
+    foreach ($node->children as $cindex => $child)
+    {
+      $this->compileNode($child, $outnode, $cindex);
+    }
+
+    // add the produced node
+    $outparent->setChild($index, $outnode);
+  }
+
+
   /** Compile plugin cache.
    *
-   * @param $cachefile
    * @param $barrel
    */
-  function compileCache($cachefile, $barrel)
+  function compileCache($barrel, &$caller)
   {
-    if (!$fp = fopen($cachefile, "w")) {
-      trigger_error("failed to open '$cachefile' for writing", E_USER_ERROR);
+    $caller->info("Recompiling " .($barrel ? "plugin cache for barrel '$barrel'" : "global plugin cache"));
+
+    // get the list of all plugins present on the system
+    $allplugins = array();
+    $plugfiles = System::find($this->plugdir.' -type f -name *.php');
+    foreach ($plugfiles as $file) {
+      $name = basename($file);
+      $name = substr($name, 0, -4);
+      array_push($allplugins, $name);
     }
 
-    // get the list of available plugins
-    $available = array();            
-    if (!$barrel) {
-    
-      $plugfiles = System::find($this->plugdir.' -type f -name *.php');  
-      foreach ($plugfiles as $file) {
-        $name = basename($file);
-        $name = substr($name, 0, -4);      
-        array_push($available, $name);
-      }      
-      
-    } else {
-            
-      $sql = "select plugin from diogenes_plugin where page=0 AND barrel=''";
-      $res = $this->dbh->query($sql);
-      while (list($plugin) = mysql_fetch_row($res))
+    $defcache = array();
+    // fill initial values
+    foreach ($allplugins as $plugin)
+    {
+      $plug_h = $this->load($plugin);
+      $defcache[$plugin] = $plug_h->toArray();
+    }
+
+    // get DB values
+    $dbcache = array();
+
+    $sql_limit = $barrel ? " where barrel='{$barrel}' or barrel=''" : "";
+    $sql = "select barrel, page, plugin, status, pos, params from diogenes_plugin" . $sql_limit;
+    $res = $this->dbh->query($sql);
+    while($row = mysql_fetch_row($res))
+    {
+      $c_barrel = array_shift($row);
+      $c_page = array_shift($row);
+      $plugin = array_shift($row);
+      $plugentry = array(
+        'status' => $row[0],
+        'pos' => $row[1],
+        'params' => ($row[2] ? var_decode_bin($row[2]) : array())
+      );
+      $plug_h = $this->load($plugin, $plugentry);
+      //echo "Got params from DB for '$plugin', barrel '$c_barrel', page '$c_page' : ".$row[2]."<br/>";
+      $dbcache[$c_barrel][$c_page][$plugin] = $plug_h->toArray();
+    }
+    mysql_free_result($res);
+
+    // build the input tree
+    $globals_node = new Diogenes_Tree_Node($dbcache[''][0], 'globals defaults');
+    $sql_limit = $barrel ? " where alias='{$barrel}'" : " where alias!=''";
+    $res = $this->dbh->query("select alias from diogenes_site" . $sql_limit);
+    while(list($c_barrel) = mysql_fetch_row($res))
+    {
+      $barrel_node = new Diogenes_Tree_Node($dbcache[$c_barrel][0], "barrel '$c_barrel' defaults");
+      $res2 = $this->dbh->query("select PID from {$c_barrel}_page");
+      while(list($page) = mysql_fetch_row($res2))
       {
-        array_push($available, $plugin);
+        $page_node = new Diogenes_Tree_Node($dbcache[$c_barrel][$page], "barrel '$c_barrel' page $page"); 
+        $barrel_node->setChild($page, $page_node);
       }
-      mysql_free_result($res);
-   }
-    
-/*
-   echo "compile : available <pre>";
-   print_r($available);
-   echo "</pre>";
-*/   
-   // get active plugins
-   $sql = "select page, pos, plugin, params from diogenes_plugin where barrel='{$barrel}' order by page, pos";
-   $res = $this->dbh->query($sql);
-   $active = array();
-   while ($row = mysql_fetch_row($res))
-   {
-     $plugin = $row[2];
-     if (in_array($plugin, $available)) {
-       array_unshift($row, 1); 
-       fputs($fp, join("\t", $row) . "\n");       
-       if (!$row[1]) {
-         array_push($active, $plugin);
-         //echo "compileCache : adding active plugin $plugin<br/>";       
-       }
-     }
-   }
-   mysql_free_result($res);    
-   
-   // add inactive plugins
-   foreach ($available as $plugin)
-   {
-     if (!in_array($plugin, $active))
-     {
-       //echo "compileCache : adding inactive plugin $plugin<br/>";
-       $row = array(0, 0, 0, $plugin, '');
-       fputs($fp, join("\t", $row) . "\n");     
-     }
-   }
-   
-   fclose($fp);
-   
-   //$this->log("rcs_commit","{$this->alias}:$dir/$file:$message");
+      mysql_free_result($res2);
+      $globals_node->setChild($c_barrel, $barrel_node);
+    }
+    mysql_free_result($res);
 
+    // compile the cache
+    $top_out_node = new Diogenes_Tree_Node($defcache, 'plugin defaults');
+    $this->compileNode($globals_node, $top_out_node, 'globals');
+    $globals_out_node = $top_out_node->getChild('globals');
+    //echo "<pre>" . $top_out_node->dump() . "</pre><hr/>";
+
+    // produce dump(s)
+    if ($barrel) {
+      $dump_node = $globals_out_node->getChild($barrel);
+      $dump_node->writeFile($this->cachefile($barrel));
+    } else {
+      $globals_out_node->writeFile($this->cachefile($barrel), NODE_DUMP_NOCHILDREN);
+      $globals_out_node->writeFile($this->cachefile($barrel).".txt", NODE_DUMP_NOCHILDREN | NODE_DUMP_TEXT);
+      foreach ($globals_out_node->children as $c_barrel => $dump_node)
+      {
+        $dump_node->writeFile($this->cachefile($c_barrel));
+      }
+    }
   }
-  
-   
+
+
   /** Load the specified plugin
    *
    * @param $plugentry
    */
-  function load($plugentry)
+  function load($plugin, $plugentry = '')
   {
-    $plugin = $plugentry['plugin'];
     $plugfile = $this->plugdir."/$plugin.php";
     if (!file_exists($plugfile)) {
       trigger_error("could not find plugin file '$plugfile'", E_USER_WARNING);
       return;
     }
-     
     include_once($plugfile);
-  
     if (!class_exists($plugin)) {
       trigger_error("could not find class '$plugin'", E_USER_WARNING);
       return;
     }
-    
+
     // load and register plugin
-    $plug = new $plugin();
-    $plug->pos = $plugentry['pos'];
-    $plug->active = $plugentry['active'];
-    $plug->setParams($plugentry['params']);
-    $this->loaded[$plugin] =& $plug;      
-    
-    return $plug;
+    $plug_h = new $plugin();
+    if (is_array($plugentry))
+      $plug_h->fromArray($plugentry);
+
+    $plug_log = $plug_h->toArray();
+    //$pluglog['name'] = 'foo';
+    array_push($this->log, $plug_log);
+    return $plug_h;
   }
     
 
@@ -276,62 +345,35 @@ class Diogenes_Plugins
     if (!file_exists($cachefile)) {
         return array();
     }
-    
-    if (!$fp = fopen($cachefile, "r")) {
-      trigger_error("failed to open '$cachefile' for reading", E_USER_WARNING);
-      return;
-    }
-    
-    $plugins = array();
-    while ($line = fgets($fp))
-    {
-      // drop end of line
-      $line = substr($line, 0, -1);
-      $bits = explode("\t", $line);
-      $plug = array(
-        'active' => $bits[0],
-        'page'   => $bits[1],
-        'pos'    => $bits[2],
-        'plugin' => $bits[3],
-        'params' => $bits[4],
-      );        
-      array_push($plugins, $plug);
-    }
-        
-    fclose($fp);
-    
-    return $plugins;
+
+    return Diogenes_Tree_Node::readFile($cachefile);
   }
 
-      
+
   /** Prepare plugins trace for output
-   */    
+   */
   function trace_format()
   {
-    $out = "";
-    foreach ($this->loaded as $key => $val)
-    {      
-      $out .= '<table class="light" style="width: 100%; font-family: monospace">';
-      $out .= '<tr><th colspan="2">'.$key.' v'.$val->version.'</th></tr>';
-      if (isset($val->pos)) {
-        $out .= '<tr><td>position</td><td>'.$val->pos.'</td></tr>';
+    $out = '<table class="light" style="width: 100%; font-family: monospace">'."\n";
+    $odd = 0;
+    foreach ($this->log as $key => $val)
+    {
+      $trclass = $odd ? ' class="odd"' : '';
+      $out .= "<tr><th colspan=\"2\">{$val['name']} v{$val['version']}</th></tr>\n";
+      if (isset($val['pos'])) {
+        $out .= "<tr><td>position</td><td>{$val['pos']}</td></tr>\n";
       }
-      $out .= '<tr><td>type</td><td>'.$val->type.'</td></tr>';
-      $out .= '<tr><td>description</td><td>'.$val->description.'</td></tr>';
-      if (empty($val->params)) {
-        $out .= '<tr class="odd"><td colspan="2">parameters</td></tr>';
-        foreach ($val->params as $skey => $sval) 
-        {
-          $out .= "<tr><td>$skey</td><td>$sval</td></tr>";
-        }
+      $out .= "<tr$trclass><td>type</td><td>{$val['type']}</td></tr>\n";
+      $out .= "<tr$trclass><td>description</td><td>{$val['description']}</td></tr>\n";
+      if (!empty($val['params'])) {
+        $out .= "<tr$trclass><td>parameters</td><td>".var_encode_html($val['params'])."</td></tr>\n";
       }
-      $out .= "</table><br/>";
+      $odd = ($odd+1) % 2;
     }
+    $out .= "</table>\n";
     return $out;
   }
-  
-  
-  
+
 }
 
 ?>
index 65f1f1f..04668ba 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+require_once 'diogenes/diogenes.misc.inc.php';
+
 define('NODE_DUMP_BINARY', 0);
 define('NODE_DUMP_TEXT', 1);
 define('NODE_DUMP_NOCHILDREN', 2);
@@ -59,15 +61,18 @@ function var_encode_text($var, $level = 0, $no_children = FALSE, $tabstr = '  ',
     //$code = chop($code, ','); //remove unnecessary coma
     $code .= str_repeat($tabstr, $level) . ")";
     return $code;
-  } elseif (is_string($var)) {
+  } elseif (is_scalar($var)) {
     return "'".$var."'";
-  } elseif (is_bool($var)) {
-    return ($code ? 'TRUE' : 'FALSE');
   } else {
     return 'NULL';
   }
 }
 
+function var_encode_html($var, $level = 0, $no_children = FALSE)
+{
+  return var_encode_text($var, $level, $no_children, '&nbsp;&nbsp;', $eol = "<br/>\n");
+}
+
 function var_encode_bin($var, $no_children = FALSE)
 {
   if (is_object($var) && (get_class($var) == 'Diogenes_Tree_Node')) {
@@ -158,13 +163,6 @@ class Diogenes_Tree_Node
     $this->children = $children;
   }
 
-  /** Add a child for this node.
-   */
-  function pushChild($node, $index)
-  {
-    array_push($this->children, $node);
-  }
-
   /** Return the specified child of this node.
    */
   function getChild($index)
index 14155d5..2ab20de 100644 (file)
 {foreach from=$plugins key=plugtype item=plugarr}
 <table class="light" style="width:80%">
 <tr>
-  <th colspan="{if $show_params}4{else}3{/if}">{$plugtype} {$msg_plugedit_plugins}</th>
+  <th colspan="3">{$plugtype} {$msg_plugedit_plugins}</th>
 </tr>
-{counter start=0 assign=cnt print=0}
 {foreach from=$plugarr item=plug}
-<tr{if $cnt % 2} class="odd"{/if}>
-  <td style="width:30px">
-    <img class="fileicon" src="{$plug.icon}" />
+<tr class="odd">
+  <td style="width:30px"><img class="fileicon" src="{$plug.icon}"/>&nbsp;{$plug.name}&nbsp;v{$plug.version}
   </td>
-  <td>    
-    <div class="name">{if !$readonly}<input type="checkbox" name="plugins_active[]" value="{$plug.name}"{if $plug.active} checked="checked"{/if} />&nbsp;{/if}{$plug.name}&nbsp;v{$plug.version}</div>
+  <td>
 {if !$readonly}
+    <select name="{$plug.name}_status">{html_options options=$statusvals selected=$plug.status}</select>
     <a class="action"{if $plug.move_up}href="javascript:move_up('{$plug.name}');"{/if}>{$msg_move_up}</a>&nbsp;<a class="action"{if $plug.move_down}href="javascript:move_down('{$plug.name}');"{/if}>{$msg_move_down}</a>
 {/if}
   </td>
-  <td>
-  <div class="description">{$plug.description}</div>
-  </td>  
-{if !$readonly && $show_params}       
-  <td>
-    <table>
+</tr>
+<tr>
+{if $show_params}
+  <td><div class="description">{$plug.description}</div></td>
+  <td colspan="2">
+    <table class="plugparams">
 {foreach from=$plug.params key=key item=val}
     <tr>
       <td>{$key}</td>
@@ -59,7 +57,6 @@
   </td>
 {/if}  
 </tr>
-{counter}
 {/foreach}
 </table>
 <br/>