improve plugins debugging output
[diogenes.git] / include / Plugins.php
CommitLineData
6855525e
JL
1<?php
2/*
3 * Copyright (C) 2003-2004 Polytechnique.org
4 * http://opensource.polytechnique.org/
5 *
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.
10 *
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.
15 *
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
19 */
20
21// dependency on PEAR
22require_once 'System.php';
56aefc1e
JL
23require_once 'Tree/Node.php';
24require_once 'Plugin/Skel.php';
25
6855525e
JL
26
27/** This class describes Diogenes' plugins.
28 */
29class Diogenes_Plugins
30{
6855525e
JL
31 /** Directory that holds the plugins cache files */
32 var $cachedir;
56aefc1e 33
6855525e
JL
34 /** Directory that holds the plugins */
35 var $plugdir;
56aefc1e
JL
36
37 /** Plugins that will be sent to trace */
38 var $log = array();
39
6855525e
JL
40 /** Constructs a new holder for Diogenes plugins.
41 *
42 * @param $dbh
43 * @param $plugdir
44 * @param $cachedir
45 */
46 function Diogenes_Plugins(&$dbh, $plugdir, $cachedir)
47 {
48 $this->dbh =& $dbh;
49 $this->plugdir = $plugdir;
56aefc1e 50 $this->cachedir = $cachedir;
6855525e
JL
51 }
52
53
54 /** Return the path of the cache file
55 *
56 * @param $barrel
57 */
58 function cacheFile($barrel)
59 {
60 $cachefile = $this->cachedir . "/" . ($barrel ? $barrel : "__diogenes__") . ".plugins";
61 return $cachefile;
62 }
56aefc1e 63
6855525e
JL
64 /** Return the cache entry for specified plugin
65 *
66 * @param $cache
67 * @param $barrel
68 * @param $page
69 * @param $plugin
56aefc1e 70 */
6855525e
JL
71 function cacheGet($cache, $barrel, $page, $plugin)
72 {
56aefc1e
JL
73 $p_node = $this->cacheGetPageNode($cache, $barrel, $page);
74 return $p_node->data[$plugin];
6855525e
JL
75 }
76
56aefc1e 77
6855525e
JL
78 /** Return the cache entry for a plugin at a specified position
79 *
80 * @param $cache
81 * @param $barrel
82 * @param $page
83 * @param $pos
56aefc1e 84 */
6855525e
JL
85 function cacheGetAtPos($cache, $barrel, $page, $pos)
86 {
56aefc1e
JL
87 $p_node = $this->cacheGetPageNode($cache, $barrel, $page);
88 foreach ($p_node->data as $plugname => $plugentry)
89 {
90 if ($plugentry['pos'] == $pos)
6855525e 91 {
56aefc1e 92 $plugentry['plugin'] = $plugname;
6855525e
JL
93 return $plugentry;
94 }
56aefc1e
JL
95 }
96 }
97
98
99 /** Return the cache entry for specified plugin
100 *
101 * @param $cache
102 * @param $barrel
103 * @param $page
104 * @param $plugin
105 */
106 function cacheGetPageNode($cache, $barrel, $page)
107 {
108 if ($page) {
109 $p_node = $cache->getChild($page);
110 } else {
111 $p_node = $cache;
112 }
113 return $p_node;
114 }
115
6855525e 116
6855525e
JL
117 /** List the plugins that are active in a given context
118 *
119 * @param $cache
120 * @param $barrel
16e8fac2 121 * @param $page
6855525e
JL
122 */
123 function cachedActive($cache, $barrel, $page)
124 {
56aefc1e 125 $p_node = $this->cacheGetPageNode($cache, $barrel, $page);
6855525e 126 $plugins = array();
16e8fac2
JL
127 foreach ($p_node->data as $plugname => $plugentry)
128 {
129 //echo "cachedEditable : examining $plugname (status {$plugentry['status']})<br/>\n";
130 if ($plugentry['status'] & PLUG_ACTIVE)
131 {
132 //echo "cachedActive : adding $plugname<br/>\n";
133 $plugins[$plugname] = $plugentry;
134 }
135 }
56aefc1e 136 return $plugins;
6855525e
JL
137 }
138
56aefc1e 139
6855525e
JL
140 /** Returns an array of cache entries representing the available plugins
141 * in a given context
142 *
143 * @param $cache
144 * @param $barrel
145 * @param $page
56aefc1e 146 */
16e8fac2 147 function cachedVisible($cache, $barrel, $page)
56aefc1e
JL
148 {
149 $p_node = $this->cacheGetPageNode($cache, $barrel, $page);
16e8fac2
JL
150 return $p_node->data;
151/*
152 $available = array();
56aefc1e
JL
153 foreach ($p_node->data as $plugname => $plugentry)
154 {
16e8fac2
JL
155 //echo "cachedEditable : examining $plugname (status {$plugentry['status']})<br/>\n";
156 if (!($plugentry['status'] & PLUG_LOCK) || !$barrel)
6855525e 157 {
16e8fac2 158 //echo "cachedEditable : adding $plugname<br/>\n";
56aefc1e 159 $available[$plugname] = $plugentry;
16e8fac2 160 // }
6855525e 161 }
56aefc1e 162 return $available;
16e8fac2 163*/
6855525e 164 }
56aefc1e
JL
165
166
6855525e
JL
167 /** Remove database references to plugins that are not available.
168 */
169 function clean_database(&$page)
170 {
171 /*
172 $res = $this->dbh->query("select distinct plugin from diogenes_plugin");
173 while (list($plugname) = mysql_fetch_row($res))
174 {
175 $page->info("examining $plugname..");
176 $plug = $this->load($plugname);
177 if (!is_object($plug)) {
178 $page->info("plugin $plugname is broken, removing");
179 $this->dbh->query("delete from diogenes_plugin where plugin='$plugname'");
180 }
181 }
182 mysql_free_result($res);
183 */
184 }
185
56aefc1e
JL
186
187 /** Build view for current level.
188 */
189 function compileNode($node, &$outparent, $index)
190 {
191 $outvals = array();
192 foreach ($outparent->data as $plugin => $parentval)
193 {
194 //echo "Processing plugin '$plugin' for &lt;{$node->name}&gt;<br/>\n";
195 $outval = '';
16e8fac2 196 if (($parentval['status'] & PLUG_ACTIVE) || !($parentval['status'] & PLUG_LOCK))
56aefc1e 197 {
16e8fac2 198 //echo "* plugin '$plugin' not locked off parent level<br/>\n";
56aefc1e
JL
199 $outval = $parentval;
200 if (is_array($node->data[$plugin]))
201 {
202 //echo "** plugin set at current level<br/>\n";
203 $outval['pos'] = $node->data[$plugin]['pos'];
204 $outval['params'] = $node->data[$plugin]['params'];
16e8fac2 205 if (!($parentval['status'] & PLUG_LOCK)) {
56aefc1e
JL
206 //echo "*** plugin status set to DB-specified value<br/>\n";
207 $outval['status'] = $node->data[$plugin]['status'];
208 } else {
16e8fac2 209 $outval['status'] = $parentval['status'];
56aefc1e
JL
210 }
211 } else {
212 //echo "** plugin unset at current level<br/>\n";
213 }
214 }
215
216 // add the plugin to output
217 if (is_array($outval))
218 {
219 $outvals[$plugin] = $outval;
220 }
221 }
222 $outnode = new Diogenes_Tree_Node($outvals, $node->name);
223 //echo "<hr/>";
224
225 // recurse into children
226 foreach ($node->children as $cindex => $child)
227 {
228 $this->compileNode($child, $outnode, $cindex);
229 }
230
231 // add the produced node
232 $outparent->setChild($index, $outnode);
233 }
234
235
6855525e
JL
236 /** Compile plugin cache.
237 *
6855525e
JL
238 * @param $barrel
239 */
56aefc1e 240 function compileCache($barrel, &$caller)
6855525e 241 {
56aefc1e
JL
242 $caller->info("Recompiling " .($barrel ? "plugin cache for barrel '$barrel'" : "global plugin cache"));
243
244 // get the list of all plugins present on the system
245 $allplugins = array();
246 $plugfiles = System::find($this->plugdir.' -type f -name *.php');
247 foreach ($plugfiles as $file) {
248 $name = basename($file);
249 $name = substr($name, 0, -4);
250 array_push($allplugins, $name);
6855525e
JL
251 }
252
56aefc1e
JL
253 $defcache = array();
254 // fill initial values
255 foreach ($allplugins as $plugin)
256 {
257 $plug_h = $this->load($plugin);
258 $defcache[$plugin] = $plug_h->toArray();
259 }
260
261 // get DB values
262 $dbcache = array();
263
264 $sql_limit = $barrel ? " where barrel='{$barrel}' or barrel=''" : "";
265 $sql = "select barrel, page, plugin, status, pos, params from diogenes_plugin" . $sql_limit;
266 $res = $this->dbh->query($sql);
267 while($row = mysql_fetch_row($res))
268 {
269 $c_barrel = array_shift($row);
270 $c_page = array_shift($row);
271 $plugin = array_shift($row);
272 $plugentry = array(
273 'status' => $row[0],
274 'pos' => $row[1],
275 'params' => ($row[2] ? var_decode_bin($row[2]) : array())
276 );
277 $plug_h = $this->load($plugin, $plugentry);
278 //echo "Got params from DB for '$plugin', barrel '$c_barrel', page '$c_page' : ".$row[2]."<br/>";
279 $dbcache[$c_barrel][$c_page][$plugin] = $plug_h->toArray();
280 }
281 mysql_free_result($res);
282
283 // build the input tree
284 $globals_node = new Diogenes_Tree_Node($dbcache[''][0], 'globals defaults');
285 $sql_limit = $barrel ? " where alias='{$barrel}'" : " where alias!=''";
286 $res = $this->dbh->query("select alias from diogenes_site" . $sql_limit);
287 while(list($c_barrel) = mysql_fetch_row($res))
288 {
289 $barrel_node = new Diogenes_Tree_Node($dbcache[$c_barrel][0], "barrel '$c_barrel' defaults");
290 $res2 = $this->dbh->query("select PID from {$c_barrel}_page");
291 while(list($page) = mysql_fetch_row($res2))
6855525e 292 {
56aefc1e
JL
293 $page_node = new Diogenes_Tree_Node($dbcache[$c_barrel][$page], "barrel '$c_barrel' page $page");
294 $barrel_node->setChild($page, $page_node);
6855525e 295 }
56aefc1e
JL
296 mysql_free_result($res2);
297 $globals_node->setChild($c_barrel, $barrel_node);
298 }
299 mysql_free_result($res);
6855525e 300
56aefc1e
JL
301 // compile the cache
302 $top_out_node = new Diogenes_Tree_Node($defcache, 'plugin defaults');
303 $this->compileNode($globals_node, $top_out_node, 'globals');
304 $globals_out_node = $top_out_node->getChild('globals');
305 //echo "<pre>" . $top_out_node->dump() . "</pre><hr/>";
306
307 // produce dump(s)
308 if ($barrel) {
309 $dump_node = $globals_out_node->getChild($barrel);
310 $dump_node->writeFile($this->cachefile($barrel));
16e8fac2 311 $dump_node->writeFile($this->cachefile($barrel).".txt", NODE_DUMP_TEXT);
56aefc1e
JL
312 } else {
313 $globals_out_node->writeFile($this->cachefile($barrel), NODE_DUMP_NOCHILDREN);
314 $globals_out_node->writeFile($this->cachefile($barrel).".txt", NODE_DUMP_NOCHILDREN | NODE_DUMP_TEXT);
315 foreach ($globals_out_node->children as $c_barrel => $dump_node)
316 {
317 $dump_node->writeFile($this->cachefile($c_barrel));
16e8fac2 318 $dump_node->writeFile($this->cachefile($c_barrel).".txt", NODE_DUMP_TEXT);
56aefc1e
JL
319 }
320 }
6855525e 321 }
56aefc1e
JL
322
323
6855525e
JL
324 /** Load the specified plugin
325 *
326 * @param $plugentry
327 */
56aefc1e 328 function load($plugin, $plugentry = '')
6855525e 329 {
6855525e
JL
330 $plugfile = $this->plugdir."/$plugin.php";
331 if (!file_exists($plugfile)) {
332 trigger_error("could not find plugin file '$plugfile'", E_USER_WARNING);
333 return;
334 }
6855525e 335 include_once($plugfile);
6855525e
JL
336 if (!class_exists($plugin)) {
337 trigger_error("could not find class '$plugin'", E_USER_WARNING);
338 return;
339 }
56aefc1e 340
6855525e 341 // load and register plugin
56aefc1e
JL
342 $plug_h = new $plugin();
343 if (is_array($plugentry))
344 $plug_h->fromArray($plugentry);
345
56aefc1e 346 return $plug_h;
6855525e
JL
347 }
348
349
350 /** Read the compiled plugin cache
351 *
352 * @param $cachefile
353 * @param $barrel
354 */
355 function readCache($cachefile, $barrel)
356 {
357 if (!file_exists($cachefile)) {
358 return array();
359 }
56aefc1e
JL
360
361 return Diogenes_Tree_Node::readFile($cachefile);
6855525e
JL
362 }
363
56aefc1e 364
6855525e 365 /** Prepare plugins trace for output
56aefc1e 366 */
6855525e
JL
367 function trace_format()
368 {
56aefc1e
JL
369 $out = '<table class="light" style="width: 100%; font-family: monospace">'."\n";
370 $odd = 0;
371 foreach ($this->log as $key => $val)
372 {
373 $trclass = $odd ? ' class="odd"' : '';
374 $out .= "<tr><th colspan=\"2\">{$val['name']} v{$val['version']}</th></tr>\n";
cbe74a8e 375 $out .= "<tr><td>status</td><td>{$val['status']}</td></tr>\n";
56aefc1e
JL
376 if (isset($val['pos'])) {
377 $out .= "<tr><td>position</td><td>{$val['pos']}</td></tr>\n";
6855525e 378 }
56aefc1e
JL
379 $out .= "<tr$trclass><td>type</td><td>{$val['type']}</td></tr>\n";
380 $out .= "<tr$trclass><td>description</td><td>{$val['description']}</td></tr>\n";
381 if (!empty($val['params'])) {
382 $out .= "<tr$trclass><td>parameters</td><td>".var_encode_html($val['params'])."</td></tr>\n";
6855525e 383 }
56aefc1e 384 $odd = ($odd+1) % 2;
6855525e 385 }
56aefc1e 386 $out .= "</table>\n";
6855525e
JL
387 return $out;
388 }
56aefc1e 389
6855525e
JL
390}
391
392?>