XTemplate::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1
Metric Value
cc 1
eloc 5
nc 1
nop 3
dl 0
loc 8
ccs 6
cts 6
cp 1
crap 1
rs 9.4285
1
<?php
2
3
/*
4
5
Modification information for LGPL compliance
6
Stas 2010-12-20 Added 'VERSION_MARK' to templates
7
8
r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync
9
10
r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
11
12
r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
13
14
r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3  tags and updated the build system
15
16
r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
17
18
r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
19
20
r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm
21
22
r36874 - 2008-06-19 12:09:05 -0700 (Thu, 19 Jun 2008) - roger - bug 22568: use md5 of unique key and version for js key.
23
24
r32524 - 2008-03-06 15:51:02 -0800 (Thu, 06 Mar 2008) - dwong - Fix incorrect encoding on source code caused by IDE, e.g.
25
utils.php r3048
26
InboundEmail.php r17199
27
header.php r13729
28
29
r30876 - 2008-01-09 19:01:57 -0800 (Wed, 09 Jan 2008) - majed - initial check in for instances
30
31
r29571 - 2007-11-13 10:49:09 -0800 (Tue, 13 Nov 2007) - eddy - Bug 17113
32
Added check for array element prior to accessing it.
33
XTemplate/xtpl.php
34
35
r26822 - 2007-09-18 10:20:27 -0700 (Tue, 18 Sep 2007) - tswicegood - Refactor a bunch of the loops and such.
36
This code doesn't have a future in Sugar, but there are some legacy
37
areas that still rely on it.  Refactoring these few areas cuts its impact
38
on Sugar's main page by 40% (6.14% to 3.72%).
39
40
r26819 - 2007-09-18 10:07:01 -0700 (Tue, 18 Sep 2007) - tswicegood - Reduces this execution time relatively by 25%
41
42
r25238 - 2007-08-07 15:40:32 -0700 (Tue, 07 Aug 2007) - dwheeler - Bug 14129. Removed field from vardefs as it is no longer used, and should not be visible from mass update.
43
44
r18355 - 2006-12-05 17:00:55 -0800 (Tue, 05 Dec 2006) - jenny - Bug 10292 - checking to see if we actually have an array before setting the array values.
45
46
r13627 - 2006-05-31 11:01:53 -0700 (Wed, 31 May 2006) - majed - name change
47
48
r12024 - 2006-03-09 23:42:27 -0800 (Thu, 09 Mar 2006) - majed - fixes bugs 4449 5050 4063 4976 4770
49
50
r11291 - 2006-01-22 10:41:45 -0800 (Sun, 22 Jan 2006) - andrew - Removed the 'Log' CVS keyword.
51
52
r10797 - 2005-12-21 18:10:38 -0800 (Wed, 21 Dec 2005) - wayne - sugar_version and js_custom_version xtpl assignment now in xtpl.php
53
54
r9351 - 2005-11-15 15:39:37 -0800 (Tue, 15 Nov 2005) - andrew - Added another check for the $focus that needs to be in for PHP 5.0.3.
55
56
r9270 - 2005-11-11 15:08:19 -0800 (Fri, 11 Nov 2005) - majed - Adds support for emails email marketing and email templates
57
58
r8555 - 2005-10-19 12:26:13 -0700 (Wed, 19 Oct 2005) - majed - adds initial acl support
59
60
r8508 - 2005-10-17 17:23:04 -0700 (Mon, 17 Oct 2005) - majed - adds initial acl support
61
62
r5820 - 2005-06-21 14:22:24 -0700 (Tue, 21 Jun 2005) - majed - fixes issues with nusoap and with custom fields
63
64
r4920 - 2005-04-29 00:38:19 -0700 (Fri, 29 Apr 2005) - jacob - Preventing conversion of array to string.
65
66
r4743 - 2005-04-27 00:57:27 -0700 (Wed, 27 Apr 2005) - jacob - Adding support for "parsing" sections that do not exist in HTML.  This provides backwards compatibility for old HTML files with new PHP files.
67
68
r2016 - 2004-12-28 15:19:29 -0800 (Tue, 28 Dec 2004) - majed - added a function to scan through a block checking for a given variable
69
70
r1228 - 2004-10-20 02:09:09 -0700 (Wed, 20 Oct 2004) - lam - update
71
72
r1211 - 2004-10-19 21:55:03 -0700 (Tue, 19 Oct 2004) - lam - update
73
74
r730 - 2004-09-09 20:14:02 -0700 (Thu, 09 Sep 2004) - sugarjacob - Cleaning up blanks
75
76
r462 - 2004-08-25 17:43:37 -0700 (Wed, 25 Aug 2004) - sugarmsi - added an exists method to check if a block exists in a template
77
78
r397 - 2004-08-08 02:28:36 -0700 (Sun, 08 Aug 2004) - sugarjacob - Fix: XTemplate changed to use <?php script declarations
79
80
r297 - 2004-07-31 15:13:23 -0700 (Sat, 31 Jul 2004) - sugarjacob - Removing default setting of template language arrays.
81
82
r295 - 2004-07-31 14:37:38 -0700 (Sat, 31 Jul 2004) - sugarjacob - Adding code to automatically assign the language strings to every template created.
83
84
r268 - 2004-07-16 01:21:57 -0700 (Fri, 16 Jul 2004) - sugarjacob - Changing the XTemplate replacement mechanism to allow for '$' in the text being substituted.
85
86
r80 - 2004-06-11 16:39:47 -0700 (Fri, 11 Jun 2004) - sugarjacob - Fixing issue with a variable not being an array in some cases.
87
88
r78 - 2004-06-11 16:34:17 -0700 (Fri, 11 Jun 2004) - sugarjacob - Removing errors or notices about invalid indexs.
89
90
r3 - 2004-05-26 22:30:56 -0700 (Wed, 26 May 2004) - sugarjacob - Moving project to SourceForge.
91
92
93
*/
94
95
96
97
class XTemplate {
98
99
/*
100
	xtemplate class 0.2.4-3
101
	html generation with templates - fast & easy
102
	copyright (c) 2000 barnabás debreceni [[email protected]]
103
	code optimization by Ivar Smolin <[email protected]> 14-march-2001
104
	latest stable & CVS version always available @ http://sourceforge.net/projects/xtpl
105
106
	tested with php 3.0.11 and 4.0.4pl1
107
108
	This program is free software; you can redistribute it and/or
109
	modify it under the terms of the GNU Lesser General Public License
110
	version 2.1 as published by the Free Software Foundation.
111
112
	This library is distributed in the hope that it will be useful,
113
	but WITHOUT ANY WARRANTY; without even the implied warranty of
114
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
115
	GNU Lesser General Public License for more details at
116
	http://www.gnu.org/copyleft/lgpl.html
117
118
	You should have received a copy of the GNU General Public License
119
	along with this program; if not, write to the Free Software
120
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
121
122
123
*/
124
125
/***[ variables ]***********************************************************/
126
127
var $filecontents="";								/* raw contents of template file */
128
var $blocks=array();								/* unparsed blocks */
129
var $parsed_blocks=array();					/* parsed blocks */
130
var $block_parse_order=array();			/* block parsing order for recursive parsing (sometimes reverse:) */
131
var $sub_blocks=array();						/* store sub-block names for fast resetting */
132
var $VARS=array();									/* variables array */
133
var $alternate_include_directory = "";
134
135
var $file_delim="/\{FILE\s*\"([^\"]+)\"\s*\}/m";  /* regexp for file includes */
136
var $block_start_delim="<!-- ";			/* block start delimiter */
137
var $block_end_delim="-->";					/* block end delimiter */
138
var $block_start_word="BEGIN:";			/* block start word */
139
var $block_end_word="END:";					/* block end word */
140
141
/* this makes the delimiters look like: <!-- BEGIN: block_name --> if you use my syntax. */
142
143
var $NULL_STRING=array(""=>"");				/* null string for unassigned vars */
144
var $NULL_BLOCK=array(""=>"");	/* null string for unassigned blocks */
145
var $mainblock="";
146
var $ERROR="";
147
var $AUTORESET=1;										/* auto-reset sub blocks */
148
149
/***[ constructor ]*********************************************************/
150
151 2
function __construct ($file, $alt_include = "", $mainblock="main") {
152 2
	$this->alternate_include_directory = $alt_include;
153 2
	$this->mainblock=$mainblock;
154 2
	$this->filecontents=$this->r_getfile($file);	/* read in template file */
155
	//if(substr_count($file, 'backup') == 1)_ppd($this->filecontents);
156 2
	$this->blocks=$this->maketree($this->filecontents,$mainblock);	/* preprocess some stuff */
157
	//$this->scan_globals();
158 2
}
159
160
    /**
161
     * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead
162
     */
163
    function XTemplate($file, $alt_include = "", $mainblock="main"){
164
        $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
165
        if(isset($GLOBALS['log'])) {
166
            $GLOBALS['log']->deprecated($deprecatedMessage);
167
        }
168
        else {
169
            trigger_error($deprecatedMessage, E_USER_DEPRECATED);
170
        }
171
        self::__construct($file, $alt_include, $mainblock);
172
    }
173
174
175
176
/***************************************************************************/
177
/***[ public stuff ]********************************************************/
178
/***************************************************************************/
179
180
181
/***[ assign ]**************************************************************/
182
/*
183
	assign a variable
184
*/
185
186 2
function assign ($name,$val="") {
187 2
	if (is_array($name)) {
188
		foreach ($name as $k => $v) {
189
			$this->VARS[$k] = $v;
190
		}
191
	} else {
192 2
		$this->VARS[$name]=$val;
193
	}
194 2
}
195
196
function append ($varname, $name,$val="") {
197
	if(!isset($this->VARS[$varname])){
198
		$this->VARS[$varname] = array();
199
	}
200
   if(is_array($this->VARS[$varname])){
201
       $this->VARS[$varname][$name] = $val;
202
    }
203
}
204
205
/***[ parse ]***************************************************************/
206
/*
207
	parse a block
208
*/
209
210 2
function parse ($bname) {
211 2
	global $sugar_version, $sugar_config;
212
213 2
	$this->assign('SUGAR_VERSION', $GLOBALS['js_version_key']);
214 2
	$this->assign('JS_CUSTOM_VERSION', $sugar_config['js_custom_version']);
215 2
    $this->assign('VERSION_MARK', getVersionedPath(''));
216
217 2
	if(empty($this->blocks[$bname]))
218
		return;
219
220 2
	$copy=$this->blocks[$bname];
221 2
	if (!isset($this->blocks[$bname]))
222
		$this->set_error ("parse: blockname [$bname] does not exist");
223 2
	preg_match_all("/\{([A-Za-z0-9\._]+?)}/",$this->blocks[$bname],$var_array);
224 2
	$var_array=$var_array[1];
225 2
	foreach ($var_array as $k => $v) {
226 2
		$sub=explode(".",$v);
227 2
		if ($sub[0]=="_BLOCK_") {
228 2
			unset($sub[0]);
229 2
			$bname2=implode(".",$sub);
230
231 2
			if(isset($this->parsed_blocks[$bname2]))
232
			{
233
				$var=$this->parsed_blocks[$bname2];
234
			}
235
			else
236
			{
237 2
				$var = null;
238
			}
239
240 2
			$nul=(!isset($this->NULL_BLOCK[$bname2])) ? $this->NULL_BLOCK[""] : $this->NULL_BLOCK[$bname2];
241 2
			$var=(empty($var))?$nul:trim($var);
242
			// Commented out due to regular expression issue with '$' in replacement string.
243
			//$copy=preg_replace("/\{".$v."\}/","$var",$copy);
244
			// This should be faster and work better for '$'
245 2
			$copy=str_replace("{".$v."}",$var,$copy);
246
		} else {
247 2
			$var=$this->VARS;
248
249 2
			foreach ($sub as $k1 => $v1)
250
			{
251 2
				if(is_array($var) && isset($var[$v1]))
252
				{
253 2
					$var=$var[$v1];
254
				}
255
				else
256
				{
257 2
					$var = null;
258
				}
259
			}
260
261 2
			$nul=(!isset($this->NULL_STRING[$v])) ? ($this->NULL_STRING[""]) : ($this->NULL_STRING[$v]);
262 2
			$var=(!isset($var))?$nul:$var;
263
			// Commented out due to regular expression issue with '$' in replacement string.
264
			//$copy=preg_replace("/\{$v\}/","$var",$copy);
265
			// This should be faster and work better for '$'
266
267
			// this was periodically returning an array to string conversion error....
268 2
			if(!is_array($var))
269
			{
270 2
				$copy=str_replace("{".$v."}",$var,$copy);
271
			}
272
		}
273
	}
274
275 2
	if(isset($this->parsed_blocks[$bname]))
276
	{
277
		$this->parsed_blocks[$bname].=$copy;
278
	}
279
	else
280
	{
281 2
		$this->parsed_blocks[$bname]=$copy;
282
	}
283
284
	// reset sub-blocks
285 2
	if ($this->AUTORESET && (!empty($this->sub_blocks[$bname]))) {
286 2
		reset($this->sub_blocks[$bname]);
287 2
		foreach ($this->sub_blocks[$bname] as $v)
288 2
			$this->reset($v);
289
	}
290 2
}
291
292
/***[ exists ]**************************************************************/
293
/*
294
	returns true if a block exists otherwise returns false.
295
*/
296
function exists($bname){
297
	return (!empty($this->parsed_blocks[$bname])) || (!empty($this->blocks[$bname]));
298
}
299
300
301
/***[ var_exists ]**************************************************************/
302
/*
303
	returns true if a block exists otherwise returns false.
304
*/
305
function var_exists($bname,$vname){
306
	if(!empty($this->blocks[$bname])){
307
		return substr_count($this->blocks[$bname], '{'. $vname . '}') >0;
308
	}
309
	return false;
310
}
311
312
313
/***[ rparse ]**************************************************************/
314
/*
315
	returns the parsed text for a block, including all sub-blocks.
316
*/
317
318
function rparse($bname) {
319
	if (!empty($this->sub_blocks[$bname])) {
320
		reset($this->sub_blocks[$bname]);
321
		while (list($k,$v)=each($this->sub_blocks[$bname]))
0 ignored issues
show
Unused Code introduced by
The assignment to $k is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
322
			if (!empty($v))
323
				$this->rparse($v,$indent."\t");
0 ignored issues
show
Unused Code introduced by
The call to XTemplate::rparse() has too many arguments starting with $indent . ' '.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
324
	}
325
	$this->parse($bname);
326
}
327
328
/***[ insert_loop ]*********************************************************/
329
/*
330
	inserts a loop ( call assign & parse )
331
*/
332
333
function insert_loop($bname,$var,$value="") {
334
	$this->assign($var,$value);
335
	$this->parse($bname);
336
}
337
338
/***[ text ]****************************************************************/
339
/*
340
	returns the parsed text for a block
341
*/
342
343 2
function text($bname) {
344
345 2
    if(!empty($this->parsed_blocks)){
346 2
	   return $this->parsed_blocks[isset($bname) ? $bname :$this->mainblock];
347
    }else{
348
        return '';
349
    }
350
}
351
352
/***[ out ]*****************************************************************/
353
/*
354
	prints the parsed text
355
*/
356
357
function out ($bname) {
358
	global $focus;
359
360
	if(isset($focus)){
361
		global $action;
362
363
		if($focus && is_subclass_of($focus, 'SugarBean') && !$focus->ACLAccess($action)){
364
365
			ACLController::displayNoAccess(true);
366
367
			sugar_die('');
368
			return;
369
	}}
370
371
	echo $this->text($bname);
372
}
373
374
/***[ reset ]***************************************************************/
375
/*
376
	resets the parsed text
377
*/
378
379 2
function reset ($bname) {
380 2
	$this->parsed_blocks[$bname]="";
381 2
}
382
383
/***[ parsed ]**************************************************************/
384
/*
385
	returns true if block was parsed, false if not
386
*/
387
388
function parsed ($bname) {
389
	return (!empty($this->parsed_blocks[$bname]));
390
}
391
392
/***[ SetNullString ]*******************************************************/
393
/*
394
	sets the string to replace in case the var was not assigned
395
*/
396
397
function SetNullString($str,$varname="") {
398
	$this->NULL_STRING[$varname]=$str;
399
}
400
401
/***[ SetNullBlock ]********************************************************/
402
/*
403
	sets the string to replace in case the block was not parsed
404
*/
405
406
function SetNullBlock($str,$bname="") {
407
	$this->NULL_BLOCK[$bname]=$str;
408
}
409
410
/***[ set_autoreset ]*******************************************************/
411
/*
412
	sets AUTORESET to 1. (default is 1)
413
	if set to 1, parse() automatically resets the parsed blocks' sub blocks
414
	(for multiple level blocks)
415
*/
416
417
function set_autoreset() {
418
	$this->AUTORESET=1;
419
}
420
421
/***[ clear_autoreset ]*****************************************************/
422
/*
423
	sets AUTORESET to 0. (default is 1)
424
	if set to 1, parse() automatically resets the parsed blocks' sub blocks
425
	(for multiple level blocks)
426
*/
427
428
function clear_autoreset() {
429
	$this->AUTORESET=0;
430
}
431
432
/***[ scan_globals ]********************************************************/
433
/*
434
	scans global variables
435
*/
436
437
function scan_globals() {
438
	reset($GLOBALS);
439
	while (list($k,$v)=each($GLOBALS))
440
		$GLOB[$k]=$v;
441
	$this->assign("PHP",$GLOB);	/* access global variables as {PHP.HTTP_HOST} in your template! */
442
}
443
444
/******
445
446
		WARNING
447
		PUBLIC FUNCTIONS BELOW THIS LINE DIDN'T GET TESTED
448
449
******/
450
451
452
/***************************************************************************/
453
/***[ private stuff ]*******************************************************/
454
/***************************************************************************/
455
456
/***[ maketree ]************************************************************/
457
/*
458
	generates the array containing to-be-parsed stuff:
459
  $blocks["main"],$blocks["main.table"],$blocks["main.table.row"], etc.
460
	also builds the reverse parse order.
461
*/
462
463
464 2
function maketree($con,$block) {
465 2
	$con2=explode($this->block_start_delim,$con);
466 2
	$level=0;
467 2
	$block_names=array();
468 2
	$blocks=array();
469 2
	reset($con2);
470 2
	while(list($k,$v)=each($con2)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $k is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
471 2
		$patt="($this->block_start_word|$this->block_end_word)\s*(\w+)\s*$this->block_end_delim(.*)";
472 2
		if (preg_match_all("/$patt/ims",$v,$res, PREG_SET_ORDER)) {
473
			// $res[0][1] = BEGIN or END
474
			// $res[0][2] = block name
475
			// $res[0][3] = kinda content
476 2
			if ($res[0][1]==$this->block_start_word) {
477 2
				$parent_name=implode(".",$block_names);
478 2
				$block_names[++$level]=$res[0][2];							/* add one level - array("main","table","row")*/
479 2
				$cur_block_name=implode(".",$block_names);	/* make block name (main.table.row) */
480 2
				$this->block_parse_order[]=$cur_block_name;	/* build block parsing order (reverse) */
481
482 2
				if(array_key_exists($cur_block_name, $blocks))
483
				{
484
					$blocks[$cur_block_name].=$res[0][3];				/* add contents */
485
				}
486
				else
487
				{
488 2
					$blocks[$cur_block_name]=$res[0][3];				/* add contents */
489
				}
490
491
				/* add {_BLOCK_.blockname} string to parent block */
492 2
				if(array_key_exists($parent_name, $blocks))
493
				{
494 2
					$blocks[$parent_name].="{_BLOCK_.$cur_block_name}";
495
				}
496
				else
497
				{
498 2
					$blocks[$parent_name]="{_BLOCK_.$cur_block_name}";
499
				}
500
501 2
				$this->sub_blocks[$parent_name][]=$cur_block_name;		/* store sub block names for autoresetting and recursive parsing */
502 2
				$this->sub_blocks[$cur_block_name][]="";		/* store sub block names for autoresetting */
503 2
			} else if ($res[0][1]==$this->block_end_word) {
504 2
				unset($block_names[$level--]);
505 2
				$parent_name=implode(".",$block_names);
506 2
				$blocks[$parent_name].=$res[0][3];	/* add rest of block to parent block */
507
  			}
508
		} else { /* no block delimiters found */
509 2
			$index = implode(".",$block_names);
510 2
			if(array_key_exists($index, $blocks))
511
			{
512
				$blocks[].=$this->block_start_delim.$v;
513
			}
514
			else
515
			{
516 2
				$blocks[]=$this->block_start_delim.$v;
517
			}
518
		}
519
	}
520 2
	return $blocks;
521
}
522
523
524
525
/***[ error stuff ]*********************************************************/
526
/*
527
	sets and gets error
528
*/
529
530
function get_error()	{
531
	return ($this->ERROR=="")?0:$this->ERROR;
532
}
533
534
535
function set_error($str)	{
536
	$this->ERROR=$str;
537
}
538
539
/***[ getfile ]*************************************************************/
540
/*
541
	returns the contents of a file
542
*/
543
544 2
function getfile($file) {
545 2
	if (!isset($file)) {
546
		$this->set_error("!isset file name!");
547
		return "";
548
	}
549
550
	// Pick which folder we should include from
551
	// Prefer the local directory, then try the theme directory.
552 2
	if (!is_file($file))
553
		$file = $this->alternate_include_directory.$file;
554
555 2
	if(is_file($file))
556
	{
557 2
		$file_text=file_get_contents($file);
558
559
	} else {
560
		$this->set_error("[$file] does not exist");
561
		$file_text="<b>__XTemplate fatal error: file [$file] does not exist__</b>";
562
	}
563
564 2
	return $file_text;
565
}
566
567
/***[ r_getfile ]***********************************************************/
568
/*
569
	recursively gets the content of a file with {FILE "filename.tpl"} directives
570
*/
571
572
573 2
function r_getfile($file) {
574 2
	$text=$this->getfile($file);
575 2
	while (preg_match($this->file_delim,$text,$res)) {
576
		$text2=$this->getfile($res[1]);
577
		$text=str_replace($res[0], $text2, $text);
578
	}
579 2
	return $text;
580
}
581
582
} /* end of XTemplate class. */
583
584
?>
585