Project

General

Profile

1
<?php
2

    
3
// $Id: template.inc 1091 2009-07-23 20:33:29Z Ruebenwurzel $
4

    
5
/*
6
 * Session Management for PHP3
7
 *
8
 * (C) Copyright 1999-2000 NetUSE GmbH
9
 *                    Kristian Koehntopp
10
 *
11
 * $Id: template.inc 1091 2009-07-23 20:33:29Z Ruebenwurzel $
12
 *
13
 */
14

    
15
/*
16
 * Change log since version 7.2c
17
 *
18
 * Bug fixes to version 7.2c compiled by Richard Archer <rha@juggernaut.com.au>:
19
 * (credits given to first person to post a diff to phplib mailing list)
20
 *
21
 * Normalised all comments and whitespace (rha)
22
 * replaced "$handle" with "$varname" and "$h" with "$v" throughout (from phplib-devel)
23
 * added braces around all one-line if statements in: get_undefined, loadfile and halt (rha)
24
 * set_var was missing two sets of braces (rha)
25
 * added a couple of "return true" statements (rha)
26
 * set_unknowns had "keep" as default instead of "remove" (from phplib-devel)
27
 * set_file failed to check for empty strings if passed an array of filenames (phplib-devel)
28
 * remove @ from call to preg_replace in subst -- report errors if there are any (NickM)
29
 * set_block unnecessarily required a newline in the template file (Marc Tardif)
30
 * pparse now calls this->finish to replace undefined vars (Layne Weathers)
31
 * get_var now checks for unset varnames (NickM & rha)
32
 * get_var when passed an array used the array key instead of the value (rha)
33
 * get_vars now uses a call to get_var rather than this->varvals to prevent undefined var warning (rha)
34
 * in finish, the replacement string referenced an unset variable (rha)
35
 * loadfile would try to load a file if the varval had been set to "" (rha)
36
 * in get_undefined, only match non-whitespace in variable tags as in finish (Layne Weathers & rha)
37
 * more elegant fix to the problem of subst stripping '$n', '\n' and '\\' strings (rha)
38
 * parse uses get_var to obtain return value (Jordi via SF)
39
 * set_block reports an error if the block could not be extracted (rha)
40
 * filename is now windows-pathname aware (krabu @ SF)
41
 *
42
 *
43
 * Changes in functionality which go beyond bug fixes:
44
 *
45
 * added ability for filename comments to be output (from phplib-users layne)
46
 * changed debug handling so set, get and internals can be tracked separately (rha)
47
 * added debug statements throughout to track most function calls (rha)
48
 * debug output contained raw HTML -- is now escaped with htmlentities (rha)
49
 * Alter regex in set_block to remove more whitespace around BEGIN/END tags to improve HTML layout (rha)
50
 * Add "append" option to set_var, works just like append in parse (dale at linuxwebpro.com, rha)
51
 * Altered parse so that append is honored if passed an array (Brian)
52
 * Converted comments and documentation to phpdoc style (rha)
53
 * Added clear_var to set the value of variables to "" (rha)
54
 * Added unset_var to usset variables (rha)
55
 *
56
 */
57

    
58
/**
59
 * The template class allows you to keep your HTML code in some external files
60
 * which are completely free of PHP code, but contain replacement fields.
61
 * The class provides you with functions which can fill in the replacement fields
62
 * with arbitrary strings. These strings can become very large, e.g. entire tables.
63
 *
64
 * Note: If you think that this is like FastTemplates, read carefully. It isn't.
65
 *
66
 */
67

    
68
class Template
69
{
70
 /**
71
  * Serialization helper, the name of this class.
72
  *
73
  * @var       string
74
  * @access    public
75
  */
76
  var $classname = "Template";
77

    
78
 /**
79
  * Determines how much debugging output Template will produce.
80
  * This is a bitwise mask of available debug levels:
81
  * 0 = no debugging
82
  * 1 = debug variable assignments
83
  * 2 = debug calls to get variable
84
  * 4 = debug internals (outputs all function calls with parameters).
85
  *
86
  * Note: setting $this->debug = true will enable debugging of variable
87
  * assignments only which is the same behaviour as versions up to release 7.2d.
88
  *
89
  * @var       int
90
  * @access    public
91
  */
92
  var $debug    = false;
93

    
94
 /**
95
  * Determines whether Template outputs filename comments.
96
  * false = no filename outputs
97
  * true = HTML comments (e.g. <!-- START FILE $filename -->) placed in output
98
  *
99
  * @var       int
100
  * @access    public
101
  */
102
  var $filename_comments = false;
103

    
104
 /**
105
  * Determines the regular expression used to find unknown variable tags.
106
  * "loose"  = traditional match all curly braces with no whitespace between
107
  * "strict" = adopts PHP's variable naming rules
108
  *              ("loose" has a nasty habit of deleting JavaScript RegEx components)
109
  *              (should future major version releases of PHPLib default this "strict"?)
110
  *
111
  * @var       string
112
  * @access    public
113
  */
114
  var $unknown_regexp = "loose";
115

    
116
 /**
117
  * The base directory from which template files are loaded.
118
  *
119
  * @var       string
120
  * @access    private
121
  * @see       set_root
122
  */
123
  var $root     = ".";
124

    
125
 /**
126
  * A hash of strings forming a translation table which translates variable names
127
  * into names of files containing the variable content.
128
  * $file[varname] = "filename";
129
  *
130
  * @var       array
131
  * @access    private
132
  * @see       set_file
133
  */
134
  var $file     = array();
135

    
136
 /**
137
  * A hash of strings forming a translation table which translates variable names
138
  * into regular expressions for themselves.
139
  * $varkeys[varname] = "/varname/"
140
  *
141
  * @var       array
142
  * @access    private
143
  * @see       set_var
144
  */
145
  var $varkeys  = array();
146

    
147
 /**
148
  * A hash of strings forming a translation table which translates variable names
149
  * into values for their respective varkeys.
150
  * $varvals[varname] = "value"
151
  *
152
  * @var       array
153
  * @access    private
154
  * @see       set_var
155
  */
156
  var $varvals  = array();
157

    
158
 /**
159
  * Determines how to output variable tags with no assigned value in templates.
160
  *
161
  * @var       string
162
  * @access    private
163
  * @see       set_unknowns
164
  */
165
  var $unknowns = "remove";
166

    
167
 /**
168
  * Determines how Template handles error conditions.
169
  * "yes"      = the error is reported, then execution is halted
170
  * "report"   = the error is reported, then execution continues by returning "false"
171
  * "no"       = errors are silently ignored, and execution resumes reporting "false"
172
  *
173
  * @var       string
174
  * @access    public
175
  * @see       halt
176
  */
177
  var $halt_on_error  = "yes";
178

    
179
 /**
180
  * The last error message is retained in this variable.
181
  *
182
  * @var       string
183
  * @access    public
184
  * @see       halt
185
  */
186
  var $last_error     = "";
187

    
188
 /******************************************************************************
189
  * Class constructor. May be called with two optional parameters.
190
  * The first parameter sets the template directory the second parameter
191
  * sets the policy regarding handling of unknown variables.
192
  *
193
  * usage: Template([string $root = "."], [string $unknowns = "remove"])
194
  *
195
  * @param     $root        path to template directory
196
  * @param     $string      what to do with undefined variables
197
  * @see       set_root
198
  * @see       set_unknowns
199
  * @access    public
200
  * @return    void
201
  */
202
  function Template($root = ".", $unknowns = "remove") {
203
    if ($this->debug & 4) {
204
      echo "<p><b>Template:</b> root = $root, unknowns = $unknowns</p>\n";
205
    }
206
    $this->set_root($root);
207
    $this->set_unknowns($unknowns);
208
  }
209

    
210

    
211
 /******************************************************************************
212
  * Checks that $root is a valid directory and if so sets this directory as the
213
  * base directory from which templates are loaded by storing the value in
214
  * $this->root. Relative filenames are prepended with the path in $this->root.
215
  *
216
  * Returns true on success, false on error.
217
  *
218
  * usage: set_root(string $root)
219
  *
220
  * @param     $root         string containing new template directory
221
  * @see       root
222
  * @access    public
223
  * @return    boolean
224
  */
225
  function set_root($root) {
226
    if(ereg('/$', $root)) {
227
      $root = substr($root, 0, -1);
228
    }
229
    if ($this->debug & 4) {
230
      echo "<p><b>set_root:</b> root = $root</p>\n";
231
    }
232
    if (!is_dir($root)) {
233
      $this->halt("set_root: $root is not a directory.");
234
      return false;
235
    }
236

    
237
    $this->root = $root;
238
    return true;
239
  }
240

    
241

    
242
 /******************************************************************************
243
  * Sets the policy for dealing with unresolved variable names.
244
  *
245
  * unknowns defines what to do with undefined template variables
246
  * "remove"   = remove undefined variables
247
  * "comment"  = replace undefined variables with comments
248
  * "keep"     = keep undefined variables
249
  *
250
  * Note: "comment" can cause unexpected results when the variable tag is embedded
251
  * inside an HTML tag, for example a tag which is expected to be replaced with a URL.
252
  *
253
  * usage: set_unknowns(string $unknowns)
254
  *
255
  * @param     $unknowns         new value for unknowns
256
  * @see       unknowns
257
  * @access    public
258
  * @return    void
259
  */
260
  function set_unknowns($unknowns = "remove") {
261
    if ($this->debug & 4) {
262
      echo "<p><b>unknowns:</b> unknowns = $unknowns</p>\n";
263
    }
264
    $this->unknowns = $unknowns;
265
  }
266

    
267

    
268
 /******************************************************************************
269
  * Defines a filename for the initial value of a variable.
270
  *
271
  * It may be passed either a varname and a file name as two strings or
272
  * a hash of strings with the key being the varname and the value
273
  * being the file name.
274
  *
275
  * The new mappings are stored in the array $this->file.
276
  * The files are not loaded yet, but only when needed.
277
  *
278
  * Returns true on success, false on error.
279
  *
280
  * usage: set_file(array $filelist = (string $varname => string $filename))
281
  * or
282
  * usage: set_file(string $varname, string $filename)
283
  *
284
  * @param     $varname      either a string containing a varname or a hash of varname/file name pairs.
285
  * @param     $filename     if varname is a string this is the filename otherwise filename is not required
286
  * @access    public
287
  * @return    boolean
288
  */
289
  function set_file($varname, $filename = "") {
290
    if (!is_array($varname)) {
291
      if ($this->debug & 4) {
292
        echo "<p><b>set_file:</b> (with scalar) varname = $varname, filename = $filename</p>\n";
293
      }
294
      if ($filename == "") {
295
        $this->halt("set_file: For varname $varname filename is empty.");
296
        return false;
297
      }
298
      $this->file[$varname] = $this->filename($filename);
299
    } else {
300
      reset($varname);
301
      while (list($v, $f) = each($varname)) {
302
        if ($this->debug & 4) {
303
          echo "<p><b>set_file:</b> (with array) varname = $v, filename = $f</p>\n";
304
        }
305
        if ($f == "") {
306
          $this->halt("set_file: For varname $v filename is empty.");
307
          return false;
308
        }
309
        $this->file[$v] = $this->filename($f);
310
      }
311
    }
312
    return true;
313
  }
314

    
315

    
316
 /******************************************************************************
317
  * A variable $parent may contain a variable block defined by:
318
  * &lt;!-- BEGIN $varname --&gt; content &lt;!-- END $varname --&gt;. This function removes
319
  * that block from $parent and replaces it with a variable reference named $name.
320
  * The block is inserted into the varkeys and varvals hashes. If $name is
321
  * omitted, it is assumed to be the same as $varname.
322
  *
323
  * Blocks may be nested but care must be taken to extract the blocks in order
324
  * from the innermost block to the outermost block.
325
  *
326
  * Returns true on success, false on error.
327
  *
328
  * usage: set_block(string $parent, string $varname, [string $name = ""])
329
  *
330
  * @param     $parent       a string containing the name of the parent variable
331
  * @param     $varname      a string containing the name of the block to be extracted
332
  * @param     $name         the name of the variable in which to store the block
333
  * @access    public
334
  * @return    boolean
335
  */
336
  function set_block($parent, $varname, $name = "") {
337
    if ($this->debug & 4) {
338
      echo "<p><b>set_block:</b> parent = $parent, varname = $varname, name = $name</p>\n";
339
    }
340
    if (!$this->loadfile($parent)) {
341
      $this->halt("set_block: unable to load $parent.");
342
      return false;
343
    }
344
    if ($name == "") {
345
      $name = $varname;
346
    }
347

    
348
    $str = $this->get_var($parent);
349
    $reg = "/[ \t]*<!--\s+BEGIN $varname\s+-->\s*?\n?(\s*.*?\n?)\s*<!--\s+END $varname\s+-->\s*?\n?/sm";
350
    preg_match_all($reg, $str, $m);
351
/* workaround to avoid problems with some WB files/modules (e.g. massmail)
352
    if (!isset($m[1][0])) {
353
      $this->halt("set_block: unable to set block $varname.");
354
      return false;
355
    }
356
*/
357
    $str = preg_replace($reg, "{" . $name . "}", $str);
358
    @$this->set_var($varname, $m[1][0]);
359
    $this->set_var($parent, $str);
360
    return true;
361
  }
362

    
363

    
364
 /******************************************************************************
365
  * This functions sets the value of a variable.
366
  *
367
  * It may be called with either a varname and a value as two strings or an
368
  * an associative array with the key being the varname and the value being
369
  * the new variable value.
370
  *
371
  * The function inserts the new value of the variable into the $varkeys and
372
  * $varvals hashes. It is not necessary for a variable to exist in these hashes
373
  * before calling this function.
374
  *
375
  * An optional third parameter allows the value for each varname to be appended
376
  * to the existing variable instead of replacing it. The default is to replace.
377
  * This feature was introduced after the 7.2d release.
378
  *
379
  *
380
  * usage: set_var(string $varname, [string $value = ""], [boolean $append = false])
381
  * or
382
  * usage: set_var(array $varname = (string $varname => string $value), [mixed $dummy_var], [boolean $append = false])
383
  *
384
  * @param     $varname      either a string containing a varname or a hash of varname/value pairs.
385
  * @param     $value        if $varname is a string this contains the new value for the variable otherwise this parameter is ignored
386
  * @param     $append       if true, the value is appended to the variable's existing value
387
  * @access    public
388
  * @return    void
389
  */
390
  function set_var($varname, $value = "", $append = false) {
391
    if (!is_array($varname)) {
392
      if (!empty($varname)) {
393
        if ($this->debug & 1) {
394
          printf("<b>set_var:</b> (with scalar) <b>%s</b> = '%s'<br>\n", $varname, htmlentities($value));
395
        }
396
        $this->varkeys[$varname] = "/".$this->varname($varname)."/";
397
        if ($append && isset($this->varvals[$varname])) {
398
          $this->varvals[$varname] .= $value;
399
        } else {
400
          $this->varvals[$varname] = $value;
401
        }
402
      }
403
    } else {
404
      reset($varname);
405
      while (list($k, $v) = each($varname)) {
406
        if (!empty($k)) {
407
          if ($this->debug & 1) {
408
            printf("<b>set_var:</b> (with array) <b>%s</b> = '%s'<br>\n", $k, htmlentities($v));
409
          }
410
          $this->varkeys[$k] = "/".$this->varname($k)."/";
411
          if ($append && isset($this->varvals[$k])) {
412
            $this->varvals[$k] .= $v;
413
          } else {
414
            $this->varvals[$k] = $v;
415
          }
416
        }
417
      }
418
    }
419
  }
420

    
421

    
422
 /******************************************************************************
423
  * This functions clears the value of a variable.
424
  *
425
  * It may be called with either a varname as a string or an array with the 
426
  * values being the varnames to be cleared.
427
  *
428
  * The function sets the value of the variable in the $varkeys and $varvals 
429
  * hashes to "". It is not necessary for a variable to exist in these hashes
430
  * before calling this function.
431
  *
432
  *
433
  * usage: clear_var(string $varname)
434
  * or
435
  * usage: clear_var(array $varname = (string $varname))
436
  *
437
  * @param     $varname      either a string containing a varname or an array of varnames.
438
  * @access    public
439
  * @return    void
440
  */
441
  function clear_var($varname) {
442
    if (!is_array($varname)) {
443
      if (!empty($varname)) {
444
        if ($this->debug & 1) {
445
          printf("<b>clear_var:</b> (with scalar) <b>%s</b><br>\n", $varname);
446
        }
447
        $this->set_var($varname, "");
448
      }
449
    } else {
450
      reset($varname);
451
      while (list($k, $v) = each($varname)) {
452
        if (!empty($v)) {
453
          if ($this->debug & 1) {
454
            printf("<b>clear_var:</b> (with array) <b>%s</b><br>\n", $v);
455
          }
456
          $this->set_var($v, "");
457
        }
458
      }
459
    }
460
  }
461

    
462

    
463
 /******************************************************************************
464
  * This functions unsets a variable completely.
465
  *
466
  * It may be called with either a varname as a string or an array with the 
467
  * values being the varnames to be cleared.
468
  *
469
  * The function removes the variable from the $varkeys and $varvals hashes.
470
  * It is not necessary for a variable to exist in these hashes before calling
471
  * this function.
472
  *
473
  *
474
  * usage: unset_var(string $varname)
475
  * or
476
  * usage: unset_var(array $varname = (string $varname))
477
  *
478
  * @param     $varname      either a string containing a varname or an array of varnames.
479
  * @access    public
480
  * @return    void
481
  */
482
  function unset_var($varname) {
483
    if (!is_array($varname)) {
484
      if (!empty($varname)) {
485
        if ($this->debug & 1) {
486
          printf("<b>unset_var:</b> (with scalar) <b>%s</b><br>\n", $varname);
487
        }
488
        unset($this->varkeys[$varname]);
489
        unset($this->varvals[$varname]);
490
      }
491
    } else {
492
      reset($varname);
493
      while (list($k, $v) = each($varname)) {
494
        if (!empty($v)) {
495
          if ($this->debug & 1) {
496
            printf("<b>unset_var:</b> (with array) <b>%s</b><br>\n", $v);
497
          }
498
          unset($this->varkeys[$v]);
499
          unset($this->varvals[$v]);
500
        }
501
      }
502
    }
503
  }
504

    
505

    
506
 /******************************************************************************
507
  * This function fills in all the variables contained within the variable named
508
  * $varname. The resulting value is returned as the function result and the
509
  * original value of the variable varname is not changed. The resulting string
510
  * is not "finished", that is, the unresolved variable name policy has not been
511
  * applied yet.
512
  *
513
  * Returns: the value of the variable $varname with all variables substituted.
514
  *
515
  * usage: subst(string $varname)
516
  *
517
  * @param     $varname      the name of the variable within which variables are to be substituted
518
  * @access    public
519
  * @return    string
520
  */
521
  function subst($varname) {
522
    $varvals_quoted = array();
523
    if ($this->debug & 4) {
524
      echo "<p><b>subst:</b> varname = $varname</p>\n";
525
    }
526
    if (!$this->loadfile($varname)) {
527
      $this->halt("subst: unable to load $varname.");
528
      return false;
529
    }
530

    
531
    // quote the replacement strings to prevent bogus stripping of special chars
532
    reset($this->varvals);
533
    while (list($k, $v) = each($this->varvals)) {
534
      $varvals_quoted[$k] = preg_replace(array('/\\\\/', '/\$/'), array('\\\\\\\\', '\\\\$'), $v);
535
    }
536

    
537
    $str = $this->get_var($varname);
538
    $str = preg_replace($this->varkeys, $varvals_quoted, $str);
539
    return $str;
540
  }
541

    
542

    
543
 /******************************************************************************
544
  * This is shorthand for print $this->subst($varname). See subst for further
545
  * details.
546
  *
547
  * Returns: always returns false.
548
  *
549
  * usage: psubst(string $varname)
550
  *
551
  * @param     $varname      the name of the variable within which variables are to be substituted
552
  * @access    public
553
  * @return    false
554
  * @see       subst
555
  */
556
  function psubst($varname) {
557
    if ($this->debug & 4) {
558
      echo "<p><b>psubst:</b> varname = $varname</p>\n";
559
    }
560
    print $this->subst($varname);
561

    
562
    return false;
563
  }
564

    
565

    
566
 /******************************************************************************
567
  * The function substitutes the values of all defined variables in the variable
568
  * named $varname and stores or appends the result in the variable named $target.
569
  *
570
  * It may be called with either a target and a varname as two strings or a
571
  * target as a string and an array of variable names in varname.
572
  *
573
  * The function inserts the new value of the variable into the $varkeys and
574
  * $varvals hashes. It is not necessary for a variable to exist in these hashes
575
  * before calling this function.
576
  *
577
  * An optional third parameter allows the value for each varname to be appended
578
  * to the existing target variable instead of replacing it. The default is to
579
  * replace.
580
  *
581
  * If $target and $varname are both strings, the substituted value of the
582
  * variable $varname is inserted into or appended to $target.
583
  *
584
  * If $handle is an array of variable names the variables named by $handle are
585
  * sequentially substituted and the result of each substitution step is
586
  * inserted into or appended to in $target. The resulting substitution is
587
  * available in the variable named by $target, as is each intermediate step
588
  * for the next $varname in sequence. Note that while it is possible, it
589
  * is only rarely desirable to call this function with an array of varnames
590
  * and with $append = true. This append feature was introduced after the 7.2d
591
  * release.
592
  *
593
  * Returns: the last value assigned to $target.
594
  *
595
  * usage: parse(string $target, string $varname, [boolean $append])
596
  * or
597
  * usage: parse(string $target, array $varname = (string $varname), [boolean $append])
598
  *
599
  * @param     $target      a string containing the name of the variable into which substituted $varnames are to be stored
600
  * @param     $varname     if a string, the name the name of the variable to substitute or if an array a list of variables to be substituted
601
  * @param     $append      if true, the substituted variables are appended to $target otherwise the existing value of $target is replaced
602
  * @access    public
603
  * @return    string
604
  * @see       subst
605
  */
606
  function parse($target, $varname, $append = false) {
607
    if (!is_array($varname)) {
608
      if ($this->debug & 4) {
609
        echo "<p><b>parse:</b> (with scalar) target = $target, varname = $varname, append = $append</p>\n";
610
      }
611
      $str = $this->subst($varname);
612
      if ($append) {
613
        $this->set_var($target, $this->get_var($target) . $str);
614
      } else {
615
        $this->set_var($target, $str);
616
      }
617
    } else {
618
      reset($varname);
619
      while (list($i, $v) = each($varname)) {
620
        if ($this->debug & 4) {
621
          echo "<p><b>parse:</b> (with array) target = $target, i = $i, varname = $v, append = $append</p>\n";
622
        }
623
        $str = $this->subst($v);
624
        if ($append) {
625
          $this->set_var($target, $this->get_var($target) . $str);
626
        } else {
627
          $this->set_var($target, $str);
628
        }
629
      }
630
    }
631

    
632
    if ($this->debug & 4) {
633
      echo "<p><b>parse:</b> completed</p>\n";
634
    }
635
    return $this->get_var($target);
636
  }
637

    
638

    
639
 /******************************************************************************
640
  * This is shorthand for print $this->parse(...) and is functionally identical.
641
  * See parse for further details.
642
  *
643
  * Returns: always returns false.
644
  *
645
  * usage: pparse(string $target, string $varname, [boolean $append])
646
  * or
647
  * usage: pparse(string $target, array $varname = (string $varname), [boolean $append])
648
  *
649
  * @param     $target      a string containing the name of the variable into which substituted $varnames are to be stored
650
  * @param     $varname     if a string, the name the name of the variable to substitute or if an array a list of variables to be substituted
651
  * @param     $append      if true, the substituted variables are appended to $target otherwise the existing value of $target is replaced
652
  * @access    public
653
  * @return    false
654
  * @see       parse
655
  */
656
  function pparse($target, $varname, $append = false, $clear = true) { // added $clear: whether to delete undefined vars or not (needed for wb-module code) - thorn
657
    if ($this->debug & 4) {
658
      echo "<p><b>pparse:</b> passing parameters to parse...</p>\n";
659
    }
660
		if(!$clear) {
661
			$unknowns = $this->unknowns;
662
			$this->set_unknowns('keep');
663
			print $this->finish($this->parse($target, $varname, $append));
664
			$this->set_unknowns($unknowns);
665
		} else {
666
			print $this->finish($this->parse($target, $varname, $append));
667
		}
668
		return false;
669
  }
670

    
671

    
672
 /******************************************************************************
673
  * This function returns an associative array of all defined variables with the
674
  * name as the key and the value of the variable as the value.
675
  *
676
  * This is mostly useful for debugging. Also note that $this->debug can be used
677
  * to echo all variable assignments as they occur and to trace execution.
678
  *
679
  * Returns: a hash of all defined variable values keyed by their names.
680
  *
681
  * usage: get_vars()
682
  *
683
  * @access    public
684
  * @return    array
685
  * @see       $debug
686
  */
687
  function get_vars() {
688
    if ($this->debug & 4) {
689
      echo "<p><b>get_vars:</b> constructing array of vars...</p>\n";
690
    }
691
    reset($this->varkeys);
692
    while (list($k, $v) = each($this->varkeys)) {
693
      $result[$k] = $this->get_var($k);
694
    }
695
    return $result;
696
  }
697

    
698

    
699
 /******************************************************************************
700
  * This function returns the value of the variable named by $varname.
701
  * If $varname references a file and that file has not been loaded yet, the
702
  * variable will be reported as empty.
703
  *
704
  * When called with an array of variable names this function will return a a
705
  * hash of variable values keyed by their names.
706
  *
707
  * Returns: a string or an array containing the value of $varname.
708
  *
709
  * usage: get_var(string $varname)
710
  * or
711
  * usage: get_var(array $varname)
712
  *
713
  * @param     $varname     if a string, the name the name of the variable to get the value of, or if an array a list of variables to return the value of
714
  * @access    public
715
  * @return    string or array
716
  */
717
  function get_var($varname) {
718
    if (!is_array($varname)) {
719
      if (isset($this->varvals[$varname])) {
720
        $str = $this->varvals[$varname];
721
      } else {
722
        $str = "";
723
      }
724
      if ($this->debug & 2) {
725
        printf ("<b>get_var</b> (with scalar) <b>%s</b> = '%s'<br>\n", $varname, htmlentities($str));
726
      }
727
      return $str;
728
    } else {
729
      reset($varname);
730
      while (list($k, $v) = each($varname)) {
731
        if (isset($this->varvals[$v])) {
732
          $str = $this->varvals[$v];
733
        } else {
734
          $str = "";
735
        }
736
        if ($this->debug & 2) {
737
          printf ("<b>get_var:</b> (with array) <b>%s</b> = '%s'<br>\n", $v, htmlentities($str));
738
        }
739
        $result[$v] = $str;
740
      }
741
      return $result;
742
    }
743
  }
744

    
745

    
746
 /******************************************************************************
747
  * This function returns a hash of unresolved variable names in $varname, keyed
748
  * by their names (that is, the hash has the form $a[$name] = $name).
749
  *
750
  * Returns: a hash of varname/varname pairs or false on error.
751
  *
752
  * usage: get_undefined(string $varname)
753
  *
754
  * @param     $varname     a string containing the name the name of the variable to scan for unresolved variables
755
  * @access    public
756
  * @return    array
757
  */
758
  function get_undefined($varname) {
759
    if ($this->debug & 4) {
760
      echo "<p><b>get_undefined:</b> varname = $varname</p>\n";
761
    }
762
    if (!$this->loadfile($varname)) {
763
      $this->halt("get_undefined: unable to load $varname.");
764
      return false;
765
    }
766

    
767
    preg_match_all(
768
        (("loose" == $this->unknown_regexp) ? "/{([^ \t\r\n}]+)}/" : "/{([_a-zA-Z]\\w+)}/"),
769
        $this->get_var($varname),
770
        $m);
771
    $m = $m[1];
772
    if (!is_array($m)) {
773
      return false;
774
    }
775

    
776
    reset($m);
777
    while (list($k, $v) = each($m)) {
778
      if (!isset($this->varkeys[$v])) {
779
        if ($this->debug & 4) {
780
         echo "<p><b>get_undefined:</b> undefined: $v</p>\n";
781
        }
782
        $result[$v] = $v;
783
      }
784
    }
785

    
786
    if (count($result)) {
787
      return $result;
788
    } else {
789
      return false;
790
    }
791
  }
792

    
793

    
794
 /******************************************************************************
795
  * This function returns the finished version of $str. That is, the policy
796
  * regarding unresolved variable names will be applied to $str.
797
  *
798
  * Returns: a finished string derived from $str and $this->unknowns.
799
  *
800
  * usage: finish(string $str)
801
  *
802
  * @param     $str         a string to which to apply the unresolved variable policy
803
  * @access    public
804
  * @return    string
805
  * @see       set_unknowns
806
  */
807
  function finish($str) {
808
    switch ($this->unknowns) {
809
      case "keep":
810
      break;
811

    
812
      case "remove":
813
        $str = preg_replace(
814
            (("loose" == $this->unknown_regexp) ? "/{([^ \t\r\n}]+)}/" : "/{([_a-zA-Z]\\w+)}/"),
815
            "",
816
            $str);
817
      break;
818

    
819
      case "comment":
820
        $str = preg_replace(
821
             (("loose" == $this->unknown_regexp) ? "/{([^ \t\r\n}]+)}/" : "/{([_a-zA-Z]\\w+)}/"),
822
            "<!-- Template variable \\1 undefined -->",
823
            $str);
824
      break;
825
    }
826

    
827
    return $str;
828
  }
829

    
830

    
831
 /******************************************************************************
832
  * This function prints the finished version of the value of the variable named
833
  * by $varname. That is, the policy regarding unresolved variable names will be
834
  * applied to the variable $varname then it will be printed.
835
  *
836
  * usage: p(string $varname)
837
  *
838
  * @param     $varname     a string containing the name of the variable to finish and print
839
  * @access    public
840
  * @return    void
841
  * @see       set_unknowns
842
  * @see       finish
843
  */
844
  function p($varname) {
845
    print $this->finish($this->get_var($varname));
846
  }
847

    
848

    
849
 /******************************************************************************
850
  * This function returns the finished version of the value of the variable named
851
  * by $varname. That is, the policy regarding unresolved variable names will be
852
  * applied to the variable $varname and the result returned.
853
  *
854
  * Returns: a finished string derived from the variable $varname.
855
  *
856
  * usage: get(string $varname)
857
  *
858
  * @param     $varname     a string containing the name of the variable to finish
859
  * @access    public
860
  * @return    void
861
  * @see       set_unknowns
862
  * @see       finish
863
  */
864
  function get($varname) {
865
    return $this->finish($this->get_var($varname));
866
  }
867

    
868

    
869
 /******************************************************************************
870
  * When called with a relative pathname, this function will return the pathname
871
  * with $this->root prepended. Absolute pathnames are returned unchanged.
872
  *
873
  * Returns: a string containing an absolute pathname.
874
  *
875
  * usage: filename(string $filename)
876
  *
877
  * @param     $filename    a string containing a filename
878
  * @access    private
879
  * @return    string
880
  * @see       set_root
881
  */
882
  function filename($filename) {
883
    if ($this->debug & 4) {
884
      echo "<p><b>filename:</b> filename = $filename</p>\n";
885
    }
886
    if (substr($filename, 0, 1) != "/" 
887
       && substr($filename, 0, 1) != "\\"
888
       && substr($filename, 1, 2) != ":\\"
889
       && substr($filename, 1, 2) != ":/"
890
    ) {
891
      $filename = $this->root."/".$filename;
892
    }
893

    
894
    if (!file_exists($filename)) {
895
      $this->halt("filename: file $filename does not exist.");
896
    }
897
    return $filename;
898
  }
899

    
900

    
901
 /******************************************************************************
902
  * This function will construct a regexp for a given variable name with any
903
  * special chars quoted.
904
  *
905
  * Returns: a string containing an escaped variable name.
906
  *
907
  * usage: varname(string $varname)
908
  *
909
  * @param     $varname    a string containing a variable name
910
  * @access    private
911
  * @return    string
912
  */
913
  function varname($varname) {
914
    return preg_quote("{" . $varname . "}");
915
  }
916

    
917

    
918
 /******************************************************************************
919
  * If a variable's value is undefined and the variable has a filename stored in
920
  * $this->file[$varname] then the backing file will be loaded and the file's
921
  * contents will be assigned as the variable's value.
922
  *
923
  * Note that the behaviour of this function changed slightly after the 7.2d
924
  * release. Where previously a variable was reloaded from file if the value
925
  * was empty, now this is not done. This allows a variable to be loaded then
926
  * set to "", and also prevents attempts to load empty variables. Files are
927
  * now only loaded if $this->varvals[$varname] is unset.
928
  *
929
  * Returns: true on success, false on error.
930
  *
931
  * usage: loadfile(string $varname)
932
  *
933
  * @param     $varname    a string containing the name of a variable to load
934
  * @access    private
935
  * @return    boolean
936
  * @see       set_file
937
  */
938
  function loadfile($varname) {
939
    if ($this->debug & 4) {
940
      echo "<p><b>loadfile:</b> varname = $varname</p>\n";
941
    }
942

    
943
    if (!isset($this->file[$varname])) {
944
      // $varname does not reference a file so return
945
      if ($this->debug & 4) {
946
        echo "<p><b>loadfile:</b> varname $varname does not reference a file</p>\n";
947
      }
948
      return true;
949
    }
950

    
951
    if (isset($this->varvals[$varname])) {
952
      // will only be unset if varname was created with set_file and has never been loaded
953
      // $varname has already been loaded so return
954
      if ($this->debug & 4) {
955
        echo "<p><b>loadfile:</b> varname $varname is already loaded</p>\n";
956
      }
957
      return true;
958
    }
959
    $filename = $this->file[$varname];
960

    
961
    /* use @file here to avoid leaking filesystem information if there is an error */
962
    $str = implode("", @file($filename));
963
    if (empty($str)) {
964
      $this->halt("loadfile: While loading $varname, $filename does not exist or is empty.");
965
      return false;
966
    }
967

    
968
    if ($this->filename_comments) {
969
      $str = "<!-- START FILE $filename -->\n$str<!-- END FILE $filename -->\n";
970
    }
971
    if ($this->debug & 4) {
972
      printf("<b>loadfile:</b> loaded $filename into $varname<br>\n");
973
    }
974
    $this->set_var($varname, $str);
975

    
976
    return true;
977
  }
978

    
979

    
980
 /******************************************************************************
981
  * This function is called whenever an error occurs and will handle the error
982
  * according to the policy defined in $this->halt_on_error. Additionally the
983
  * error message will be saved in $this->last_error.
984
  *
985
  * Returns: always returns false.
986
  *
987
  * usage: halt(string $msg)
988
  *
989
  * @param     $msg         a string containing an error message
990
  * @access    private
991
  * @return    void
992
  * @see       $halt_on_error
993
  */
994
  function halt($msg) {
995
    $this->last_error = $msg;
996

    
997
    if ($this->halt_on_error != "no") {
998
      $this->haltmsg($msg);
999
    }
1000

    
1001
    if ($this->halt_on_error == "yes") {
1002
      die("<b>Halted.</b>");
1003
    }
1004

    
1005
    return false;
1006
  }
1007

    
1008

    
1009
 /******************************************************************************
1010
  * This function prints an error message.
1011
  * It can be overridden by your subclass of Template. It will be called with an
1012
  * error message to display.
1013
  *
1014
  * usage: haltmsg(string $msg)
1015
  *
1016
  * @param     $msg         a string containing the error message to display
1017
  * @access    public
1018
  * @return    void
1019
  * @see       halt
1020
  */
1021
  function haltmsg($msg) {
1022
    printf("<b>Template Error:</b> %s<br>\n", $msg);
1023
  }
1024

    
1025
}
1026
?>
(2-2/2)