update template for new events system
[diogenes.git] / include / phplayersmenu / PHPLIB.php
CommitLineData
6855525e
JL
1<?php
2// vim: set expandtab tabstop=4 shiftwidth=4:
3// This code that was derived from the original PHPLIB Template class
4// is copyright by Kristian Koehntopp, NetUSE AG and was released
5// under the LGPL.
6//
7// Authors: Kristian Koehntopp <kris@koehntopp.de> (original from PHPLIB)
8// Bjoern Schotte <bjoern@rent-a-phpwizard.de> (PEARification)
9// Martin Jansen <mj@php.net> (PEAR conformance)
10//
11
12//require_once "PEAR.php";
13
14/**
15 * Converted PHPLIB Template class
16 *
17 * For those who want to use PHPLIB's fine template class,
18 * here's a PEAR conforming class with the original PHPLIB
19 * template code from phplib-stable CVS. Original author
20 * was Kristian Koehntopp <kris@koehntopp.de>
21 *
22 * @author Bjoern Schotte <bjoern@rent-a-phpwizard.de>
23 * @author Martin Jansen <mj@php.net> (PEAR conformance)
24 * @version 1.0
25 */
26class Template_PHPLIB
27{
28 /**
29 * If set, echo assignments
30 * @var bool
31 */
32 var $debug = false;
33
34 /**
35 * $file[handle] = "filename";
36 * @var array
37 */
38 var $file = array();
39
40 /**
41 * fallback paths that should be defined in a child class
42 * @var array
43 */
44 var $file_fallbacks = array();
45
46 /**
47 * Relative filenames are relative to this pathname
48 * @var string
49 */
50 var $root = "";
51
52 /*
53 * $_varKeys[key] = "key"
54 * @var array
55 */
56 var $_varKeys = array();
57
58 /**
59 * $_varVals[key] = "value";
60 * @var array
61 */
62 var $_varVals = array();
63
64 /**
65 * "remove" => remove undefined variables
66 * "comment" => replace undefined variables with comments
67 * "keep" => keep undefined variables
68 * @var string
69 */
70 var $unknowns = "remove";
71
72 /**
73 * "yes" => halt, "report" => report error, continue, "no" => ignore error quietly
74 * @var string
75 */
76 var $haltOnError = "report";
77
78 /**
79 * The last error message is retained here
80 * @var string
81 * @see halt
82 */
83 var $_lastError = "";
84
85
86 /**
87 * Constructor
88 *
89 * @access public
90 * @param string template root directory
91 * @param string how to handle unknown variables
92 * @param array fallback paths
93 */
94 function Template_PHPLIB($root = ".", $unknowns = "remove", $fallback="")
95 {
96 $this->setRoot($root);
97 $this->setUnknowns($unknowns);
98 if (is_array($fallback)) $this->file_fallbacks = $fallback;
99 }
100
101 /**
102 * Sets the template directory
103 *
104 * @access public
105 * @param string new template directory
106 * @return bool
107 */
108 function setRoot($root)
109 {
110 if (!is_dir($root)) {
111 $this->halt("setRoot: $root is not a directory.");
112 return false;
113 }
114
115 $this->root = $root;
116
117 return true;
118 }
119
120 /**
121 * What to do with unknown variables
122 *
123 * three possible values:
124 *
125 * - "remove" will remove unknown variables
126 * (don't use this if you define CSS in your page)
127 * - "comment" will replace undefined variables with comments
128 * - "keep" will keep undefined variables as-is
129 *
130 * @access public
131 * @param string unknowns
132 */
133 function setUnknowns($unknowns = "keep")
134 {
135 $this->unknowns = $unknowns;
136 }
137
138 /**
139 * Set appropriate template files
140 *
141 * With this method you set the template files you want to use.
142 * Either you supply an associative array with key/value pairs
143 * where the key is the handle for the filname and the value
144 * is the filename itself, or you define $handle as the file name
145 * handle and $filename as the filename if you want to define only
146 * one template.
147 *
148 * @access public
149 * @param mixed handle for a filename or array with handle/name value pairs
150 * @param string name of template file
151 * @return bool
152 */
153 function setFile($handle, $filename = "")
154 {
155 if (!is_array($handle)) {
156
157 if ($filename == "") {
158 $this->halt("setFile: For handle $handle filename is empty.");
159 return false;
160 }
161
162 $this->file[$handle] = $this->_filename($filename);
163
164 } else {
165
166 reset($handle);
167 while (list($h, $f) = each($handle)) {
168 $this->file[$h] = $this->_filename($f);
169 }
170 }
171 }
172
173 /**
174 * Set a block in the appropriate template handle
175 *
176 * By setting a block like that:
177 *
178 * &lt;!-- BEGIN blockname --&gt;
179 * html code
180 * &lt;!-- END blockname --&gt;
181 *
182 * you can easily do repeating HTML code, i.e. output
183 * database data nice formatted into a HTML table where
184 * each DB row is placed into a HTML table row which is
185 * defined in this block.
186 * It extracts the template $handle from $parent and places
187 * variable {$name} instead.
188 *
189 * @access public
190 * @param string parent handle
191 * @param string block name handle
192 * @param string variable substitution name
193 */
194 function setBlock($parent, $handle, $name = "")
195 {
196 if (!$this->_loadFile($parent)) {
197 $this->halt("setBlock: unable to load $parent.");
198 return false;
199 }
200
201 if ($name == "") {
202 $name = $handle;
203 }
204
205 $str = $this->getVar($parent);
206 $reg = "/[ \t]*<!--\s+BEGIN $handle\s+-->\s*?\n?(\s*.*?\n?)\s*<!--\s+END $handle\s+-->\s*?\n?/sm";
207 preg_match_all($reg, $str, $m);
208 $str = preg_replace($reg, "{" . "$name}", $str);
209
210 if (isset($m[1][0])) $this->setVar($handle, $m[1][0]);
211 $this->setVar($parent, $str);
212 }
213
214 /**
215 * Set corresponding substitutions for placeholders
216 *
217 * @access public
218 * @param string name of a variable that is to be defined or an array of variables with value substitution as key/value pairs
219 * @param string value of that variable
220 * @param boolean if true, the value is appended to the variable's existing value
221 */
222 function setVar($varname, $value = "", $append = false)
223 {
224 if (!is_array($varname)) {
225
226 if (!empty($varname))
227 if ($this->debug) print "scalar: set *$varname* to *$value*<br>\n";
228
229 $this->_varKeys[$varname] = $this->_varname($varname);
230 ($append) ? $this->_varVals[$varname] .= $value : $this->_varVals[$varname] = $value;
231
232 } else {
233 reset($varname);
234
235 while (list($k, $v) = each($varname)) {
236 if (!empty($k))
237 if ($this->debug) print "array: set *$k* to *$v*<br>\n";
238
239 $this->_varKeys[$k] = $this->_varname($k);
240 ($append) ? $this->_varVals[$k] .= $v : $this->_varVals[$k] = $v;
241 }
242 }
243 }
244
245 /**
246 * Substitute variables in handle $handle
247 *
248 * @access public
249 * @param string name of handle
250 * @return mixed string substituted content of handle
251 */
252 function subst($handle)
253 {
254 if (!$this->_loadFile($handle)) {
255 $this->halt("subst: unable to load $handle.");
256 return false;
257 }
258
259 return @str_replace($this->_varKeys, $this->_varVals, $this->getVar($handle));
260 }
261
262 /**
263 * Same as subst but printing the result
264 *
265 * @access public
266 * @brother subst
267 * @param string handle of template
268 * @return bool always false
269 */
270 function pSubst($handle)
271 {
272 print $this->subst($handle);
273 return false;
274 }
275
276 /**
277 * Parse handle into target
278 *
279 * Parses handle $handle into $target, eventually
280 * appending handle at $target if $append is defined
281 * as TRUE.
282 *
283 * @access public
284 * @param string target handle to parse into
285 * @param string which handle should be parsed
286 * @param boolean append it to $target or not?
287 * @return string parsed handle
288 */
289 function parse($target, $handle, $append = false)
290 {
291 if (!is_array($handle)) {
292 $str = $this->subst($handle);
293
294 ($append) ? $this->setVar($target, $this->getVar($target) . $str) : $this->setVar($target, $str);
295 } else {
296 reset($handle);
297
298 while (list(, $h) = each($handle)) {
299 $str = $this->subst($h);
300 $this->setVar($target, $str);
301 }
302 }
303
304 return $str;
305 }
306
307 /**
308 * Same as parse, but printing it.
309 *
310 * @access public
311 * @brother parse
312 * @param string target to parse into
313 * @param string handle which should be parsed
314 * @param should $handle be appended to $target?
315 * @return bool
316 */
317 function pParse($target, $handle, $append = false)
318 {
319 print $this->finish($this->parse($target, $handle, $append));
320 return false;
321 }
322
323 /**
324 * Return all defined variables and their values
325 *
326 * @access public
327 * @return array with all defined variables and their values
328 */
329 function getVars()
330 {
331 reset($this->_varKeys);
332
333 while (list($k, ) = each($this->_varKeys)) {
334 $result[$k] = $this->getVar($k);
335 }
336
337 return $result;
338 }
339
340 /**
341 * Return one or more specific variable(s) with their values.
342 *
343 * @access public
344 * @param mixed array with variable names or one variable name as a string
345 * @return mixed array of variable names with their values or value of one specific variable
346 */
347 function getVar($varname)
348 {
349 if (!is_array($varname)) {
350 if (isset($this->_varVals[$varname])) {
351 return $this->_varVals[$varname];
352 } else {
353 return "";
354 }
355 } else {
356 reset($varname);
357
358 while (list($k, ) = each($varname)) {
359 $result[$k] = (isset($this->_varVals[$k])) ? $this->_varVals[$k] : "";
360 }
361
362 return $result;
363 }
364 }
365
366 /**
367 * Get undefined values of a handle
368 *
369 * @access public
370 * @param string handle name
371 * @return mixed false if an error occured or the undefined values
372 */
373 function getUndefined($handle)
374 {
375 if (!$this->_loadFile($handle)) {
376 $this->halt("getUndefined: unable to load $handle.");
377 return false;
378 }
379
380 preg_match_all("/{([^ \t\r\n}]+)}/", $this->getVar($handle), $m);
381 $m = $m[1];
382 if (!is_array($m)) {
383 return false;
384 }
385
386 reset($m);
387 while (list(, $v) = each($m)) {
388 if (!isset($this->_varKeys[$v])) {
389 $result[$v] = $v;
390 }
391 }
392
393 if (isset($result) && count($result)) {
394 return $result;
395 } else {
396 return false;
397 }
398 }
399
400 /**
401 * Finish string
402 *
403 * @access public
404 * @param string string to finish
405 * @return finished, i.e. substituted string
406 */
407 function finish($str)
408 {
409 switch ($this->unknowns) {
410 case "remove":
411 $str = preg_replace('/{[^ \t\r\n}]+}/', "", $str);
412 break;
413
414 case "comment":
415 $str = preg_replace('/{([^ \t\r\n}]+)}/', "<!-- Template $handle: Variable \\1 undefined -->", $str);
416 break;
417 }
418
419 return $str;
420 }
421
422 /**
423 * Print variable to the browser
424 *
425 * @access public
426 * @param string name of variable to print
427 */
428 function p($varname)
429 {
430 print $this->finish($this->getVar($varname));
431 }
432
433 /**
434 * Get finished variable
435 *
436 * @access public public
437 * @param string variable to get
438 * @return string string with finished variable
439 */
440 function get($varname)
441 {
442 return $this->finish($this->getVar($varname));
443 }
444
445 /**
446 * Complete filename
447 *
448 * Complete filename, i.e. testing it for slashes
449 *
450 * @access private
451 * @param string filename to be completed
452 * @return string completed filename
453 */
454 function _filename($filename)
455 {
456// if (substr($filename, 0, 1) != "/") {
457// $filename = $this->root."/".$filename;
458// }
459
460 if (file_exists($filename)) return $filename;
461 if (is_array($this->file_fallbacks) && count($this->file_fallbacks) > 0) {
462 reset($this->file_fallbacks);
463 while (list(,$v) = each($this->file_fallbacks)) {
464 if (file_exists($v.basename($filename))) return $v.basename($filename);
465 }
466 $this->halt(sprintf("filename: file %s does not exist in the fallback paths %s.",$filename,implode(",",$this->file_fallbacks)));
467 return false;
468 } else {
469 $this->halt(sprintf("filename: file %s does not exist.",$filename));
470 return false;
471 }
472
473 return $filename;
474 }
475
476 /**
477 * Protect a replacement variable
478 *
479 * @access private
480 * @param string name of replacement variable
481 * @return string replaced variable
482 */
483 function _varname($varname)
484 {
485 return "{".$varname."}";
486 }
487
488 /**
489 * load file defined by handle if it is not loaded yet
490 *
491 * @access private
492 * @param string handle
493 * @return bool FALSE if error, true if all is ok
494 */
495 function _loadFile($handle)
496 {
497 if (isset($this->_varKeys[$handle]) and !empty($this->_varVals[$handle])) {
498 return true;
499 }
500
501 if (!isset($this->file[$handle])) {
502 $this->halt("loadfile: $handle is not a valid handle.");
503 return false;
504 }
505
506 $filename = $this->file[$handle];
507 if (function_exists("file_get_contents")) {
508 $str = file_get_contents($filename);
509 } else {
510 if (!$fp = @fopen($filename,"r")) {
511 $this->halt("loadfile: couldn't open $filename");
512 return false;
513 }
514
515 $str = fread($fp,filesize($filename));
516 fclose($fp);
517 }
518
519 if ($str=='') {
520 $this->halt("loadfile: While loading $handle, $filename does not exist or is empty.");
521 return false;
522 }
523
524 $this->setVar($handle, $str);
525
526 return true;
527 }
528
529 /**
530 * Error function. Halt template system with message to show
531 *
532 * @access public
533 * @param string message to show
534 * @return bool
535 */
536 function halt($msg)
537 {
538 $this->_lastError = $msg;
539
540 if ($this->haltOnError != "no") {
541// return $this->haltMsg($msg);
542 $this->haltMsg($msg);
543 }
544
545 if ($this->haltOnError == "yes") {
546 die("<b>Halted.</b>");
547 }
548
549 return false;
550 }
551
552 /**
553 * printf error message to show
554 *
555 * @access public
556 * @param string message to show
557 * @return object PEAR error object
558 */
559 function haltMsg($msg)
560 {
561// PEAR::raiseError(sprintf("<b>Template Error:</b> %s<br>\n", $msg));
562 printf("<b>Template Error:</b> %s<br>\n", $msg);
563 }
564}
565?>