1 |
1535
|
Luisehahne
|
<?php
|
2 |
|
|
//error_reporting(E_ALL ^ E_NOTICE);
|
3 |
|
|
/*~ class.quickskin.php
|
4 |
|
|
.---------------------------------------------------------------------------.
|
5 |
|
|
| Software: QuickSkin Class |
|
6 |
|
|
| Version: 5.0 |
|
7 |
|
|
| Contact: andy.prevost@worxteam.com,andy@codeworx.ca |
|
8 |
|
|
| Info: http://quickskin.sourceforge.net |
|
9 |
|
|
| Support: http://sourceforge.net/projects/quickskin/ |
|
10 |
|
|
| ------------------------------------------------------------------------- |
|
11 |
|
|
| Author: Andy Prevost andy.prevost@worxteam.com (admin) |
|
12 |
|
|
| Author: Manuel 'EndelWar' Dalla Lana endelwar@aregar.it (former admin) |
|
13 |
|
|
| Author: Philipp v. Criegern philipp@criegern.com (original founder) |
|
14 |
|
|
| Copyright (c) 2002-2009, Andy Prevost. All Rights Reserved. |
|
15 |
|
|
| * NOTE: QuickSkin is the SmartTemplate project renamed. SmartTemplate |
|
16 |
|
|
| information and downloads can still be accessed at the |
|
17 |
|
|
| smarttemplate.sourceforge.net site |
|
18 |
|
|
| ------------------------------------------------------------------------- |
|
19 |
|
|
| License: Distributed under the Lesser General Public License (LGPL) |
|
20 |
|
|
| http://www.gnu.org/copyleft/lesser.html |
|
21 |
|
|
| This program is distributed in the hope that it will be useful - WITHOUT |
|
22 |
|
|
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
23 |
|
|
| FITNESS FOR A PARTICULAR PURPOSE. |
|
24 |
|
|
| ------------------------------------------------------------------------- |
|
25 |
|
|
| We offer a number of paid services: |
|
26 |
|
|
| - Web Hosting on highly optimized fast and secure servers |
|
27 |
|
|
| - Technology Consulting |
|
28 |
|
|
| - Oursourcing (highly qualified programmers and graphic designers) |
|
29 |
|
|
'---------------------------------------------------------------------------'
|
30 |
|
|
Last modified: January 01 2009 ~*/
|
31 |
|
|
|
32 |
|
|
/* designed to work with PHP5 - will NOT work with PHP4 */
|
33 |
|
|
|
34 |
|
|
/* PURPOSE: 'Compiles' HTML-Templates to PHP Code
|
35 |
|
|
*
|
36 |
|
|
* Usage Example I:
|
37 |
|
|
*
|
38 |
|
|
* $page = new QuickSkin( "template.html" );
|
39 |
|
|
* $page->assign( 'TITLE', 'TemplateDemo - Userlist' );
|
40 |
|
|
* $page->assign( 'user', DB_read_all( 'select * from ris_user' ) );
|
41 |
|
|
* $page->output();
|
42 |
|
|
*
|
43 |
|
|
* Usage Example II:
|
44 |
|
|
*
|
45 |
|
|
* $data = array(
|
46 |
|
|
* 'TITLE' => 'TemplateDemo - Userlist',
|
47 |
|
|
* 'user' => DB_read_all( 'select * from ris_user' )
|
48 |
|
|
* );
|
49 |
|
|
* $page = new QuickSkin( "template.html" );
|
50 |
|
|
* $page->output( $data );
|
51 |
|
|
*
|
52 |
|
|
*/
|
53 |
|
|
|
54 |
|
|
class QuickSkin {
|
55 |
|
|
|
56 |
|
|
/////////////////////////////////////////////////
|
57 |
|
|
// PROPERTIES, PUBLIC
|
58 |
|
|
/////////////////////////////////////////////////
|
59 |
|
|
|
60 |
|
|
/**
|
61 |
|
|
* Reuse Code
|
62 |
|
|
* Whether to use stored compiled php code or not (for debug purpose)
|
63 |
|
|
* @var bool
|
64 |
|
|
*/
|
65 |
|
|
public $reuse_code = false;
|
66 |
|
|
|
67 |
|
|
/**
|
68 |
|
|
* Template Directory
|
69 |
|
|
* Directory where all templates are stored, can be overwritten by
|
70 |
|
|
* global configuration array $_CONFIG['template_dir']
|
71 |
|
|
* @var string
|
72 |
|
|
*/
|
73 |
|
|
public $template_dir = '_skins/';
|
74 |
|
|
|
75 |
|
|
/**
|
76 |
|
|
* Temp Directory
|
77 |
|
|
* Where to store compiled templates, can be overwritten by
|
78 |
|
|
* global configuration array $_CONFIG['quickskin_compiled']
|
79 |
|
|
* @var string
|
80 |
|
|
*/
|
81 |
|
|
public $temp_dir = '_skins_tmp/';
|
82 |
|
|
|
83 |
|
|
/**
|
84 |
|
|
* Cache Directory
|
85 |
|
|
* Temporary folder for output cache storage, can be overwritten by
|
86 |
|
|
* global configuration array $_CONFIG['quickskin_cache']
|
87 |
|
|
* Note: typically set the same as the Temp Directory, but can be unique
|
88 |
|
|
* @var string
|
89 |
|
|
*/
|
90 |
|
|
public $cache_dir = '_skins_tmp/';
|
91 |
|
|
|
92 |
|
|
/**
|
93 |
|
|
* Cache Lifetime
|
94 |
|
|
* Default Output Cache Lifetime in Seconds, can be overwritten by
|
95 |
|
|
* global configuration array $_CONFIG['cache_lifetime']
|
96 |
|
|
* @var int
|
97 |
|
|
*/
|
98 |
|
|
public $cache_lifetime = 600; // seconds
|
99 |
|
|
|
100 |
|
|
/**
|
101 |
|
|
* Extensions Directory
|
102 |
|
|
* Directory where all extensions are stored
|
103 |
|
|
* @var string
|
104 |
|
|
*/
|
105 |
|
|
public $extensions_dir = '_lib/qx'; /* Directory where all extensions are stored */
|
106 |
|
|
|
107 |
|
|
/**
|
108 |
|
|
* Extension Prefix
|
109 |
|
|
* Filename prefix on all the extensions files
|
110 |
|
|
* @var string
|
111 |
|
|
*/
|
112 |
|
|
public $extension_prefix = 'qx_';
|
113 |
|
|
|
114 |
|
|
/**
|
115 |
|
|
* Left Delimiter
|
116 |
|
|
* Default Left delimiter, can be overwritten by
|
117 |
|
|
* global configuration array $_CONFIG['left_delimiter']
|
118 |
|
|
* @var string
|
119 |
|
|
*/
|
120 |
|
|
public $left_delimiter = '{';
|
121 |
|
|
|
122 |
|
|
/**
|
123 |
|
|
* Right Delimiter
|
124 |
|
|
* Default Right delimiter, can be overwritten by
|
125 |
|
|
* global configuration array $_CONFIG['right_delimiter']
|
126 |
|
|
* @var string
|
127 |
|
|
*/
|
128 |
|
|
public $right_delimiter = '}';
|
129 |
|
|
|
130 |
|
|
/**
|
131 |
|
|
* Extension Tagged
|
132 |
|
|
* List of used QuickSkin Extensions
|
133 |
|
|
* @var array
|
134 |
|
|
*/
|
135 |
|
|
public $extension_tagged = array();
|
136 |
|
|
|
137 |
|
|
/**
|
138 |
|
|
* QuickSkin Version Number
|
139 |
|
|
* List of used QuickSkin Extensions
|
140 |
|
|
* @var string
|
141 |
|
|
*/
|
142 |
|
|
public $version = '5.0';
|
143 |
|
|
|
144 |
|
|
/////////////////////////////////////////////////
|
145 |
|
|
// PROPERTIES, PRIVATE
|
146 |
|
|
/////////////////////////////////////////////////
|
147 |
|
|
|
148 |
|
|
private $cache_filename; /* Temporary file for output cache storage */
|
149 |
|
|
private $tpl_file; /* The template filename */
|
150 |
|
|
private $cpl_file; /* The compiled template filename */
|
151 |
|
|
private $data = array(); /* Template content array */
|
152 |
|
|
private $parser; /* Parser Class */
|
153 |
|
|
private $debugger; /* Debugger Class */
|
154 |
|
|
private $skins_sub_dir; /* temporary variable to hold the subdirectory of the main template */
|
155 |
|
|
private $supp_templates = ''; /* supplementary templates */
|
156 |
|
|
private $supptemplate = ''; /* supplementary template */
|
157 |
|
|
|
158 |
|
|
/* QuickSkin Constructor
|
159 |
|
|
* @access public
|
160 |
|
|
* @param string $template_filename Template Filename
|
161 |
|
|
*/
|
162 |
|
|
function __construct( $template_filename = '' ) {
|
163 |
|
|
global $_CONFIG;
|
164 |
|
|
|
165 |
|
|
if (!empty($_CONFIG['quickskin_compiled'])) {
|
166 |
|
|
$this->temp_dir = $_CONFIG['quickskin_compiled'];
|
167 |
|
|
}
|
168 |
|
|
if (!empty($_CONFIG['quickskin_cache'])) {
|
169 |
|
|
$this->cache_dir = $_CONFIG['quickskin_cache'];
|
170 |
|
|
}
|
171 |
|
|
if (is_numeric($_CONFIG['cache_lifetime'])) {
|
172 |
|
|
$this->cache_lifetime = $_CONFIG['cache_lifetime'];
|
173 |
|
|
}
|
174 |
|
|
if (!empty($_CONFIG['template_dir']) && is_file($_CONFIG['template_dir'] . '/' . $template_filename)) {
|
175 |
|
|
$this->template_dir = $_CONFIG['template_dir'];
|
176 |
|
|
}
|
177 |
|
|
$this->tpl_file = $template_filename;
|
178 |
|
|
if ( dirname($this->tpl_file) != "") {
|
179 |
|
|
$this->skins_sub_dir = dirname($this->tpl_file);
|
180 |
|
|
}
|
181 |
|
|
}
|
182 |
|
|
|
183 |
|
|
/* DEPRECATED METHODS */
|
184 |
|
|
/* Methods used in older parser versions, soon will be removed */
|
185 |
|
|
function set_templatefile ($template_filename) { $this->tpl_file = $template_filename; }
|
186 |
|
|
function add_value ($name, $value ) { $this->assign($name, $value); }
|
187 |
|
|
function add_array ($name, $value ) { $this->append($name, $value); }
|
188 |
|
|
|
189 |
|
|
/* Process file or contents to strip out the <body tag (inclusive)
|
190 |
|
|
* and the </body tag to the end
|
191 |
|
|
*
|
192 |
|
|
* Usage Example:
|
193 |
|
|
* $page->getContents( '', '/contents.htm' );
|
194 |
|
|
* or
|
195 |
|
|
* $page->getContents( 'start of data .... end of data' );
|
196 |
|
|
*
|
197 |
|
|
* @access public
|
198 |
|
|
* @param string $contents Parameter contents
|
199 |
|
|
* @param string $filename Parameter filename (fully qualified)
|
200 |
|
|
* @desc strip out body tags and return only page data
|
201 |
|
|
*/
|
202 |
|
|
function getContents($contents, $filename="") {
|
203 |
|
|
if ( $contents == '' && $filename != '' && file_exists($filename) ) {
|
204 |
|
|
$contents = file_get_contents($filename);
|
205 |
|
|
}
|
206 |
|
|
|
207 |
|
|
// START process any PHP code
|
208 |
|
|
ob_start();
|
209 |
|
|
eval("?>".$contents."<?php ");
|
210 |
|
|
$contents = ob_get_contents();
|
211 |
|
|
ob_end_clean();
|
212 |
|
|
// END process any PHP code
|
213 |
|
|
$lower_contents = strtolower($contents);
|
214 |
|
|
// determine if a <body tag exists and process if necessary
|
215 |
|
|
$bodytag_start = strpos($lower_contents, "<body");
|
216 |
|
|
if ( $bodytag_start !== false ) {
|
217 |
|
|
$bodytag_end = strpos($lower_contents, ">", $bodytag_start) + 1;
|
218 |
|
|
// get contents with <body tag removed
|
219 |
|
|
$contents = substr($contents, $bodytag_end);
|
220 |
|
|
$lower_contents = strtolower($contents);
|
221 |
|
|
// work on </body closing tag
|
222 |
|
|
$end_start = strpos($lower_contents, "</body");
|
223 |
|
|
$end_end = strpos($lower_contents, ">", $bodytag_start) + 1;
|
224 |
|
|
// return stripped out <body and </body tags
|
225 |
|
|
return $this->getExtensions( substr($contents, 0, $end_start) );
|
226 |
|
|
} else {
|
227 |
|
|
// body tags not found, so return data
|
228 |
|
|
return $this->getExtensions( $contents );
|
229 |
|
|
}
|
230 |
|
|
}
|
231 |
|
|
|
232 |
|
|
/* Determine Contents Command from Variable Name
|
233 |
|
|
* {variable} : array( "echo", "variable" ) -> echo $_obj['variable']
|
234 |
|
|
* {variable > new_name} : array( "_obj['new_name']=", "variable" ) -> $_obj['new_name']= $_obj['variable']
|
235 |
|
|
* @param string $tag Variale Name used in Template
|
236 |
|
|
* @return array Array Command, Variable
|
237 |
|
|
* @access private
|
238 |
|
|
* @desc Determine Contents Command from Variable Name
|
239 |
|
|
*/
|
240 |
|
|
function processCmd($tag) {
|
241 |
|
|
if (preg_match('/^(.+) > ([a-zA-Z0-9_.]+)$/', $tag, $tagvar)) {
|
242 |
|
|
$tag = $tagvar[1];
|
243 |
|
|
list($newblock, $newskalar) = $this->var_name($tagvar[2]);
|
244 |
|
|
$cmd = "\$$newblock"."['$newskalar']=";
|
245 |
|
|
} else {
|
246 |
|
|
$cmd = 'echo';
|
247 |
|
|
}
|
248 |
|
|
$ret = array($cmd, $tag);
|
249 |
|
|
return $ret;
|
250 |
|
|
}
|
251 |
|
|
|
252 |
|
|
/* Load and process the Extensions that may be used in the Contents
|
253 |
|
|
*
|
254 |
|
|
* Usage Example:
|
255 |
|
|
* $tcnt = $this->getExtensions( $param );
|
256 |
|
|
*
|
257 |
|
|
* @access public
|
258 |
|
|
* @param string $param (content to process)
|
259 |
|
|
* @return string
|
260 |
|
|
* @desc Load and process the Extensions that may be used in the Contents
|
261 |
|
|
*/
|
262 |
|
|
function getExtensions($contents) {
|
263 |
|
|
$header = '';
|
264 |
|
|
/* Include Extensions */
|
265 |
|
|
if (preg_match_all('/'.$this->left_delimiter.'([a-zA-Z0-9_]+):([^}]*)'.$this->right_delimiter.'/', $contents, $var)) {
|
266 |
|
|
foreach ($var[2] as $cnt => $tag) {
|
267 |
|
|
/* Determine Command (echo / $obj[n]=) */
|
268 |
|
|
list($cmd, $tag) = $this->processCmd($tag);
|
269 |
|
|
|
270 |
|
|
$extension = $var[1][$cnt];
|
271 |
|
|
//if (!isset($this->extension_tagged[$extension])) {
|
272 |
|
|
$header .= 'include_once "'.$this->extensions_dir."/".$this->extension_prefix."$extension.php\";\n";
|
273 |
|
|
// $this->extension_tagged[$extension] = true;
|
274 |
|
|
//}
|
275 |
|
|
if (!strlen($tag)) {
|
276 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension();\n?>\n";
|
277 |
|
|
} elseif (substr($tag, 0, 1) == '"') {
|
278 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension($tag);\n?>\n";
|
279 |
|
|
} elseif (strpos($tag, ',')) {
|
280 |
|
|
list($tag, $addparam) = explode(',', $tag, 2);
|
281 |
|
|
list($block, $skalar) = $this->var_name($tag);
|
282 |
|
|
if (preg_match('/^([a-zA-Z_]+)/', $addparam, $match)) {
|
283 |
|
|
$nexttag = $match[1];
|
284 |
|
|
list($nextblock, $nextskalar) = $this->var_name($nexttag);
|
285 |
|
|
$addparam = substr($addparam, strlen($nexttag));
|
286 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension(\$$block"."['$skalar'],\$$nextblock"."['$nextskalar']"."$addparam);\n?>\n";
|
287 |
|
|
} else {
|
288 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension(\$$block"."['$skalar'],$addparam);\n?>\n";
|
289 |
|
|
}
|
290 |
|
|
} else {
|
291 |
|
|
list($block, $skalar) = $this->var_name($tag);
|
292 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension(\$$block"."['$skalar']);\n?>\n";
|
293 |
|
|
}
|
294 |
|
|
$contents = str_replace($var[0][$cnt], $code, $contents);
|
295 |
|
|
}
|
296 |
|
|
}
|
297 |
|
|
// START process any PHP code
|
298 |
|
|
ob_start();
|
299 |
|
|
eval($header);
|
300 |
|
|
eval("?>".$contents."<?php ");
|
301 |
|
|
$contents = ob_get_contents();
|
302 |
|
|
ob_end_clean();
|
303 |
|
|
// END process any PHP code
|
304 |
|
|
return $contents;
|
305 |
|
|
}
|
306 |
|
|
|
307 |
|
|
/* Assign Supplementary Template
|
308 |
|
|
*
|
309 |
|
|
* Usage Example:
|
310 |
|
|
* $page->addtpl( 'sponsors', 'default/poweredby.htm' );
|
311 |
|
|
*
|
312 |
|
|
* @access public
|
313 |
|
|
* @param string $name Parameter Name
|
314 |
|
|
* @param string $value Parameter Value
|
315 |
|
|
* @desc Assign Supplementary Template
|
316 |
|
|
*/
|
317 |
|
|
function addtpl ( $name, $value = '' ) {
|
318 |
|
|
if (is_array($name)) {
|
319 |
|
|
foreach ($name as $k => $v) {
|
320 |
|
|
$this->supptemplate[$k] = $v;
|
321 |
|
|
}
|
322 |
|
|
} else {
|
323 |
|
|
$this->supptemplate[$name] = $value;
|
324 |
|
|
}
|
325 |
|
|
}
|
326 |
|
|
|
327 |
|
|
/* Assign Template Content
|
328 |
|
|
*
|
329 |
|
|
* Usage Example:
|
330 |
|
|
* $page->assign( 'TITLE', 'My Document Title' );
|
331 |
|
|
* $page->assign( 'userlist', array(
|
332 |
|
|
* array( 'ID' => 123, 'NAME' => 'John Doe' ),
|
333 |
|
|
* array( 'ID' => 124, 'NAME' => 'Jack Doe' ),
|
334 |
|
|
* );
|
335 |
|
|
*
|
336 |
|
|
* @access public
|
337 |
|
|
* @param string $name Parameter Name
|
338 |
|
|
* @param mixed $value Parameter Value
|
339 |
|
|
* @desc Assign Template Content
|
340 |
|
|
*/
|
341 |
|
|
function assign ( $name, $value = '' ) {
|
342 |
|
|
if (is_array($name)) {
|
343 |
|
|
foreach ($name as $k => $v) {
|
344 |
|
|
$this->data[$k] = $v;
|
345 |
|
|
}
|
346 |
|
|
} else {
|
347 |
|
|
$this->data[$name] = $value;
|
348 |
|
|
}
|
349 |
|
|
}
|
350 |
|
|
|
351 |
|
|
/* Assign Template Content
|
352 |
|
|
*
|
353 |
|
|
* Usage Example:
|
354 |
|
|
* $page->append( 'userlist', array( 'ID' => 123, 'NAME' => 'John Doe' ) );
|
355 |
|
|
* $page->append( 'userlist', array( 'ID' => 124, 'NAME' => 'Jack Doe' ) );
|
356 |
|
|
*
|
357 |
|
|
* @access public
|
358 |
|
|
* @param string $name Parameter Name
|
359 |
|
|
* @param mixed $value Parameter Value
|
360 |
|
|
* @desc Assign Template Content
|
361 |
|
|
*/
|
362 |
|
|
function append ( $name, $value ) {
|
363 |
|
|
if (is_array($value)) {
|
364 |
|
|
$this->data[$name][] = $value;
|
365 |
|
|
} elseif (!is_array($this->data[$name])) {
|
366 |
|
|
$this->data[$name] .= $value;
|
367 |
|
|
}
|
368 |
|
|
}
|
369 |
|
|
|
370 |
|
|
/* Parser Wrapper
|
371 |
|
|
* Returns Template Output as a String
|
372 |
|
|
*
|
373 |
|
|
* @access public
|
374 |
|
|
* @param array $_top Content Array
|
375 |
|
|
* @return string Parsed Template
|
376 |
|
|
* @desc Output Buffer Parser Wrapper
|
377 |
|
|
*/
|
378 |
|
|
function result ( $_top = '' ) {
|
379 |
|
|
ob_start();
|
380 |
|
|
$this->output( $_top );
|
381 |
|
|
$result = ob_get_contents();
|
382 |
|
|
ob_end_clean();
|
383 |
|
|
return $result;
|
384 |
|
|
}
|
385 |
|
|
|
386 |
|
|
/* Execute parsed Template
|
387 |
|
|
* Prints Parsing Results to Standard Output
|
388 |
|
|
*
|
389 |
|
|
* @access public
|
390 |
|
|
* @param array $_top Content Array
|
391 |
|
|
* @desc Execute parsed Template
|
392 |
|
|
*/
|
393 |
|
|
function output ( $_top = '' ) {
|
394 |
|
|
global $_top;
|
395 |
|
|
|
396 |
|
|
$data = $this->data;
|
397 |
|
|
/* Process supplementary templates */
|
398 |
|
|
if ( is_array($this->supptemplate) && !empty($this->supptemplate) ) { // passed by addtpl functionality
|
399 |
|
|
foreach ($this->supptemplate as $key => $value) {
|
400 |
|
|
$supp_templates[$key] = file_get_contents($value);
|
401 |
|
|
}
|
402 |
|
|
}
|
403 |
|
|
|
404 |
|
|
/* Make sure that folder names have a trailing '/' */
|
405 |
|
|
if (strlen($this->template_dir) && substr($this->template_dir, -1) != '/') {
|
406 |
|
|
$this->template_dir .= '/';
|
407 |
|
|
}
|
408 |
|
|
if (strlen($this->temp_dir) && substr($this->temp_dir, -1) != '/') {
|
409 |
|
|
$this->temp_dir .= '/';
|
410 |
|
|
}
|
411 |
|
|
|
412 |
|
|
/* Prepare Template Content*/
|
413 |
|
|
if (!is_array($_top)) {
|
414 |
|
|
if (strlen($_top)) {
|
415 |
|
|
$this->tpl_file = $_top;
|
416 |
|
|
}
|
417 |
|
|
$_top = $this->data;
|
418 |
|
|
}
|
419 |
|
|
$_obj = &$_top;
|
420 |
|
|
$_stack_cnt = 0;
|
421 |
|
|
$_stack[$_stack_cnt++] = $_obj;
|
422 |
|
|
|
423 |
|
|
/* Check if template is already compiled */
|
424 |
|
|
$queryString = $_SERVER['QUERY_STRING'];
|
425 |
|
|
$cpl_file_name = preg_replace('/[:\/.\\\\]/', '_', $this->tpl_file . '?' . $queryString);
|
426 |
|
|
if (strlen($cpl_file_name) > 0) {
|
427 |
|
|
$cpl_file_name = 'qs_' . md5($cpl_file_name);
|
428 |
|
|
$this->cpl_file = $this->temp_dir . $cpl_file_name . '.php';
|
429 |
|
|
$compile_template = true;
|
430 |
|
|
if ($this->reuse_code) {
|
431 |
|
|
if (is_file($this->cpl_file)) {
|
432 |
|
|
if ($this->mtime($this->cpl_file) > $this->mtime($this->template_dir . $this->tpl_file)) {
|
433 |
|
|
$compile_template = false;
|
434 |
|
|
}
|
435 |
|
|
}
|
436 |
|
|
}
|
437 |
|
|
if ($compile_template) {
|
438 |
|
|
$this->parser = new QuickSkinParser();
|
439 |
|
|
$this->parser->template_dir = $this->template_dir;
|
440 |
|
|
$this->parser->skins_sub_dir = $this->skins_sub_dir;
|
441 |
|
|
$this->parser->tpl_file = $this->tpl_file;
|
442 |
|
|
$this->parser->left_delimiter = $this->left_delimiter;
|
443 |
|
|
$this->parser->right_delimiter = $this->right_delimiter;
|
444 |
|
|
$this->parser->extensions_dir = $this->extensions_dir;
|
445 |
|
|
$this->parser->extension_prefix = $this->extension_prefix;
|
446 |
|
|
$this->parser->supp_templates = $this->supp_templates;
|
447 |
|
|
|
448 |
|
|
if (!$this->parser->compile($this->cpl_file,$data,$this->supp_templates,$this->extensions_dir)) {
|
449 |
|
|
exit('QuickSkin Parser Error: ' . $this->parser->error);
|
450 |
|
|
}
|
451 |
|
|
}
|
452 |
|
|
/* Execute Compiled Template */
|
453 |
|
|
include($this->cpl_file);
|
454 |
|
|
} else {
|
455 |
|
|
exit('QuickSkin Error: You must set a template file name');
|
456 |
|
|
}
|
457 |
|
|
/* Delete Global Content Array in order to allow multiple use of QuickSkin class in one script */
|
458 |
|
|
unset ($GLOBALS['_top']);
|
459 |
|
|
}
|
460 |
|
|
|
461 |
|
|
/* Debug Template
|
462 |
|
|
*
|
463 |
|
|
* @access public
|
464 |
|
|
* @param array $_top Content Array
|
465 |
|
|
* @desc Debug Template
|
466 |
|
|
*/
|
467 |
|
|
function debug ( $_top = '' ) {
|
468 |
|
|
/* Prepare Template Content */
|
469 |
|
|
if (!$_top) {
|
470 |
|
|
$_top = $this->data;
|
471 |
|
|
}
|
472 |
|
|
if (@include_once('class.quickskindebugger.php')) {
|
473 |
|
|
$this->debugger = new QuickSkinDebugger($this->template_dir . $this->tpl_file, $this->right_delimiter, $this->left_delimiter);
|
474 |
|
|
$this->debugger->start($_top);
|
475 |
|
|
} else {
|
476 |
|
|
exit( 'QuickSkin Error: Cannot find class.quickskindebugger.php; check QuickSkin installation');
|
477 |
|
|
}
|
478 |
|
|
}
|
479 |
|
|
|
480 |
|
|
/* Start Ouput Content Buffering
|
481 |
|
|
*
|
482 |
|
|
* Usage Example:
|
483 |
|
|
* $page = new QuickSkin('template.html');
|
484 |
|
|
* $page->use_cache();
|
485 |
|
|
* ...
|
486 |
|
|
*
|
487 |
|
|
* @access public
|
488 |
|
|
* @desc Output Cache
|
489 |
|
|
*/
|
490 |
|
|
function use_cache ( $key = '' ) {
|
491 |
|
|
if (empty($_POST)) {
|
492 |
|
|
$this->cache_filename = $this->cache_dir . 'cache_' . md5($_SERVER['REQUEST_URI'] . serialize($key)) . '.ser';
|
493 |
|
|
if (($_SERVER['HTTP_CACHE_CONTROL'] != 'no-cache') && ($_SERVER['HTTP_PRAGMA'] != 'no-cache') && @is_file($this->cache_filename)) {
|
494 |
|
|
if ((time() - filemtime($this->cache_filename)) < $this->cache_lifetime) {
|
495 |
|
|
readfile($this->cache_filename);
|
496 |
|
|
exit;
|
497 |
|
|
}
|
498 |
|
|
}
|
499 |
|
|
ob_start( array( &$this, 'cache_callback' ) );
|
500 |
|
|
}
|
501 |
|
|
}
|
502 |
|
|
|
503 |
|
|
/* Output Buffer Callback Function
|
504 |
|
|
*
|
505 |
|
|
* @access private
|
506 |
|
|
* @param string $output
|
507 |
|
|
* @return string $output
|
508 |
|
|
*/
|
509 |
|
|
function cache_callback ( $output ) {
|
510 |
|
|
if ($hd = @fopen($this->cache_filename, 'w')) {
|
511 |
|
|
fwrite($hd, $output);
|
512 |
|
|
fclose($hd);
|
513 |
|
|
} else {
|
514 |
|
|
$output = 'QuickSkin Error: failed to open cache file "' . $this->cache_filename . '"';
|
515 |
|
|
}
|
516 |
|
|
return $output;
|
517 |
|
|
}
|
518 |
|
|
|
519 |
|
|
/* Determine Last Filechange Date (if File exists)
|
520 |
|
|
*
|
521 |
|
|
* @access private
|
522 |
|
|
* @param string $filename
|
523 |
|
|
* @return mixed
|
524 |
|
|
* @desc Determine Last Filechange Date
|
525 |
|
|
*/
|
526 |
|
|
function mtime ( $filename ) {
|
527 |
|
|
if (@is_file($filename)) {
|
528 |
|
|
$ret = filemtime($filename);
|
529 |
|
|
return $ret;
|
530 |
|
|
}
|
531 |
|
|
}
|
532 |
|
|
|
533 |
|
|
/* Set (or reset) Properties (variables)
|
534 |
|
|
*
|
535 |
|
|
* Usage Example:
|
536 |
|
|
* $page->set('reuse_code', true);
|
537 |
|
|
*
|
538 |
|
|
* @access public
|
539 |
|
|
* @param string $name Parameter Name
|
540 |
|
|
* @param mixed $value Parameter Value
|
541 |
|
|
* NOTE: will not work with arrays, there are no arrays to set/reset */
|
542 |
|
|
function set ( $name, $value = '' ) {
|
543 |
|
|
if ( isset($this->$name) ) {
|
544 |
|
|
$this->$name = $value;
|
545 |
|
|
} else {
|
546 |
|
|
exit( 'QuickSkin Error: Attempt to set a non-existant class property: ' . $name);
|
547 |
|
|
}
|
548 |
|
|
}
|
549 |
|
|
|
550 |
|
|
}
|
551 |
|
|
|
552 |
|
|
/*~
|
553 |
|
|
.---------------------------------------------------------------------------.
|
554 |
|
|
| Software: QuickSkinParser Class * Used by QuickSkin Class |
|
555 |
|
|
| Version: 5.0 |
|
556 |
|
|
| Contact: andy.prevost@worxteam.com,andy@codeworx.ca |
|
557 |
|
|
| Info: http://quickskin.sourceforge.net |
|
558 |
|
|
| Support: http://sourceforge.net/projects/quickskin/ |
|
559 |
|
|
| ------------------------------------------------------------------------- |
|
560 |
|
|
| Author: Andy Prevost andy.prevost@worxteam.com (admin) |
|
561 |
|
|
| Author: Manuel 'EndelWar' Dalla Lana endelwar@aregar.it (former admin) |
|
562 |
|
|
| Author: Philipp v. Criegern philipp@criegern.com (original founder) |
|
563 |
|
|
| Copyright (c) 2002-2009, Andy Prevost. All Rights Reserved. |
|
564 |
|
|
| * NOTE: QuickSkin is the SmartTemplate project renamed. SmartTemplate |
|
565 |
|
|
| information and downloads can still be accessed at the |
|
566 |
|
|
| smarttemplate.sourceforge.net site |
|
567 |
|
|
| ------------------------------------------------------------------------- |
|
568 |
|
|
| License: Distributed under the Lesser General Public License (LGPL) |
|
569 |
|
|
| http://www.gnu.org/copyleft/lesser.html |
|
570 |
|
|
| This program is distributed in the hope that it will be useful - WITHOUT |
|
571 |
|
|
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
572 |
|
|
| FITNESS FOR A PARTICULAR PURPOSE. |
|
573 |
|
|
| ------------------------------------------------------------------------- |
|
574 |
|
|
| We offer a number of paid services: |
|
575 |
|
|
| - Web Hosting on highly optimized fast and secure servers |
|
576 |
|
|
| - Technology Consulting |
|
577 |
|
|
| - Oursourcing (highly qualified programmers and graphic designers) |
|
578 |
|
|
'---------------------------------------------------------------------------'
|
579 |
|
|
Last modified: January 01 2009 ~*/
|
580 |
|
|
|
581 |
|
|
class QuickSkinParser {
|
582 |
|
|
|
583 |
|
|
/////////////////////////////////////////////////
|
584 |
|
|
// PROPERTIES, PUBLIC
|
585 |
|
|
/////////////////////////////////////////////////
|
586 |
|
|
|
587 |
|
|
public $error; /* Error messages */
|
588 |
|
|
public $template; /* The template itself */
|
589 |
|
|
public $tpl_file; /* The template filename */
|
590 |
|
|
public $template_dir; /* The template filename used to extract the dirname for subtemplates */
|
591 |
|
|
public $skins_sub_dir; /* The template subdirectory, passed by main class */
|
592 |
|
|
public $extensions_dir; /* The extension directory */
|
593 |
|
|
public $extension_tagged = array(); /* List of used QuickSkin Extensions */
|
594 |
|
|
public $left_delimiter; /* Default Left delimiter */
|
595 |
|
|
public $right_delimiter; /* Default Right delimiter */
|
596 |
|
|
public $supp_templates = ''; /* Contains array or single supplementary template(s) */
|
597 |
|
|
public $extension_prefix; /* filename prefix on all the extensions files */
|
598 |
|
|
|
599 |
|
|
/* QuickSkinParser Constructor */
|
600 |
|
|
/*
|
601 |
|
|
function __construct() {
|
602 |
|
|
}
|
603 |
|
|
*/
|
604 |
|
|
|
605 |
|
|
/* Replace template logical expression in IF..ENDIF (|| or &&) with php logical expression
|
606 |
|
|
* @access private
|
607 |
|
|
* @desc replace template logical expression (|| or &&) with php logical expression
|
608 |
|
|
* @author Bruce Huang (msn: huang_x_c@163.com)
|
609 |
|
|
* @param string $src_page source page intended to be replaced
|
610 |
|
|
*/
|
611 |
|
|
function replace_logic_expression( &$src_page ) {
|
612 |
|
|
/* cannot find '||' or '&&' */
|
613 |
|
|
if(!strpos($src_page, '||') && !strpos($src_page, '&&')) {
|
614 |
|
|
return;
|
615 |
|
|
}
|
616 |
|
|
/* match 'ELSE' and the last sub expression */
|
617 |
|
|
if (preg_match_all('/<!-- (ELSE)?IF \s*(\(*).*[|&]{2}\s*\(*\s*([a-zA-Z0-9_.]+)\s*([!=<>]+)\s*(["]?[^"]*?["]?)\s*(\)*)\s* -->/', $src_page, $var)) {
|
618 |
|
|
foreach ($var[3] as $cnt => $tag) {
|
619 |
|
|
list($parent, $block) = $this->var_name($tag);
|
620 |
|
|
$cmp = $var[4][$cnt];
|
621 |
|
|
$val = $var[5][$cnt];
|
622 |
|
|
$else = ($var[1][$cnt] == 'ELSE') ? '} else' : '';
|
623 |
|
|
if ($cmp == '=') {
|
624 |
|
|
$cmp = '==';
|
625 |
|
|
}
|
626 |
|
|
if (preg_match('/"([^"]*)"/',$val,$matches)) {
|
627 |
|
|
$code_suffix = "\$$parent"."['$block'] $cmp \"".$matches[1].$var[6][$cnt]."\"){\n?>";
|
628 |
|
|
} elseif (preg_match('/([^"]*)/',$val,$matches)) {
|
629 |
|
|
list($parent_right, $block_right) = $this->var_name($matches[1]);
|
630 |
|
|
$code_suffix = "\$$parent"."['$block'] $cmp \$$parent_right"."['$block_right']".$var[6][$cnt]."){\?>";
|
631 |
|
|
}
|
632 |
|
|
|
633 |
|
|
/* match other sub expressions */
|
634 |
|
|
if (preg_match_all('/([a-zA-Z0-9_.]+)\s*([!=<>]+)\s*(["]?[^"]*?["]?)\s*(\)*\s*[|&]{2}\s*\(*)\s*/', $var[0][$cnt], $sub_var)) {
|
635 |
|
|
$code_mid = '';
|
636 |
|
|
foreach($sub_var[1] as $sub_cnt => $sub_tag) {
|
637 |
|
|
list($sub_parent, $sub_block) = $this->var_name($sub_tag);
|
638 |
|
|
$cmp = $sub_var[2][$sub_cnt];
|
639 |
|
|
$val = $sub_var[3][$sub_cnt];
|
640 |
|
|
$logic_exp = $sub_var[4][$sub_cnt];
|
641 |
|
|
if ($cmp == '=') {
|
642 |
|
|
$cmp = '==';
|
643 |
|
|
}
|
644 |
|
|
if (preg_match('/"([^"]*)"/',$val,$matches)) {
|
645 |
|
|
$code_mid = $code_mid."\$$sub_parent"."['$sub_block'] $cmp \"".$matches[1]."\"".$logic_exp;
|
646 |
|
|
} elseif (preg_match('/([^"]*)/',$val,$matches)) {
|
647 |
|
|
list($sub_parent_right, $sub_block_right) = $this->var_name($matches[1]);
|
648 |
|
|
$code_mid = $code_mid."\$$sub_parent"."['$sub_block'] $cmp \$$sub_parent_right"."['$sub_block_right']".$logic_exp;
|
649 |
|
|
}
|
650 |
|
|
}
|
651 |
|
|
}
|
652 |
|
|
$code = "<?php\n".$else.'if ('.$var[2][$cnt].$code_mid.$code_suffix;
|
653 |
|
|
$src_page = str_replace($var[0][$cnt], $code, $src_page);
|
654 |
|
|
}
|
655 |
|
|
}
|
656 |
|
|
}
|
657 |
|
|
|
658 |
|
|
/* Main Template Parser
|
659 |
|
|
* @param string $compiled_template_filename Compiled Template Filename
|
660 |
|
|
* @desc Creates Compiled PHP Template
|
661 |
|
|
*/
|
662 |
|
|
function compile( $compiled_template_filename = '', $data='', $supp_templates='', $extensions_dir='' ) {
|
663 |
|
|
|
664 |
|
|
$this->extension_prefix = preg_quote($this->extension_prefix);
|
665 |
|
|
|
666 |
|
|
/* Load Template */
|
667 |
|
|
$template_filename = $this->template_dir . $this->tpl_file;
|
668 |
|
|
if ($hd = @fopen($template_filename, 'r')) {
|
669 |
|
|
if (filesize($template_filename)) {
|
670 |
|
|
$this->template = fread($hd, filesize($template_filename));
|
671 |
|
|
$this->left_delimiter = preg_quote($this->left_delimiter);
|
672 |
|
|
$this->right_delimiter = preg_quote($this->right_delimiter);
|
673 |
|
|
} else {
|
674 |
|
|
$this->template = 'QuickSkin Parser Error: File size is zero byte: ' .$template_filename;
|
675 |
|
|
}
|
676 |
|
|
fclose($hd);
|
677 |
|
|
} else {
|
678 |
|
|
$this->template = 'QuickSkin Parser Error: File not found: ' .$template_filename;
|
679 |
|
|
}
|
680 |
|
|
|
681 |
|
|
if (empty($this->template)) {
|
682 |
|
|
return;
|
683 |
|
|
}
|
684 |
|
|
|
685 |
|
|
/* Do the variable substitution for paths, urls, subtemplates */
|
686 |
|
|
$this->template = $this->worx_var_swap($this->template, $data, $supp_templates);
|
687 |
|
|
|
688 |
|
|
$header = '';
|
689 |
|
|
|
690 |
|
|
/* Code to allow subtemplates */
|
691 |
|
|
if(eregi("<!-- INCLUDE", $this->template)) {
|
692 |
|
|
while ($this->count_subtemplates() > 0) {
|
693 |
|
|
preg_match_all('/<!-- INCLUDE ([a-zA-Z0-9\-_.]+) -->/', $this->template, $tvar);
|
694 |
|
|
foreach($tvar[1] as $subfile) {
|
695 |
|
|
if(file_exists($this->template_dir . '/' . $this->skins_sub_dir . '/' .$subfile)) {
|
696 |
|
|
$subst = implode('',file($this->template_dir . '/' . $this->skins_sub_dir . '/' .$subfile));
|
697 |
|
|
} else {
|
698 |
|
|
$subst = 'QuickSkin Parser Error: Subtemplate not found: \''.$subfile.'\'';
|
699 |
|
|
}
|
700 |
|
|
$this->template = str_replace("<!-- INCLUDE $subfile -->", $subst, $this->template);
|
701 |
|
|
}
|
702 |
|
|
}
|
703 |
|
|
}
|
704 |
|
|
/* END, ELSE Blocks */
|
705 |
|
|
$page = preg_replace("/<!-- ENDIF.+?-->/", "<?php\n}\n?>", $this->template);
|
706 |
|
|
$page = preg_replace("/<!-- END[ a-zA-Z0-9_.]* -->/", "<?php\n}\n\$_obj=\$_stack[--\$_stack_cnt];}\n?>", $page);
|
707 |
|
|
$page = str_replace("<!-- ELSE -->", "<?php\n} else {\n?>", $page);
|
708 |
|
|
|
709 |
|
|
/* 'BEGIN - END' Blocks */
|
710 |
|
|
if (preg_match_all('/<!-- BEGIN ([a-zA-Z0-9_.]+) -->/', $page, $var)) {
|
711 |
|
|
foreach ($var[1] as $tag) {
|
712 |
|
|
list($parent, $block) = $this->var_name($tag);
|
713 |
|
|
$code = "<?php\n"
|
714 |
|
|
. "if (!empty(\$$parent"."['$block'])){\n"
|
715 |
|
|
. "if (!is_array(\$$parent"."['$block']))\n"
|
716 |
|
|
. "\$$parent"."['$block']=array(array('$block'=>\$$parent"."['$block']));\n"
|
717 |
|
|
. "\$_stack[\$_stack_cnt++]=\$_obj;\n"
|
718 |
|
|
. "\$rowcounter = 0;\n"
|
719 |
|
|
. "foreach (\$$parent"."['$block'] as \$rowcnt=>\$$block) {\n"
|
720 |
|
|
. "\$$block"."['ROWCNT']=(\$rowcounter);\n"
|
721 |
|
|
. "\$$block"."['ALTROW']=\$rowcounter%2;\n"
|
722 |
|
|
. "\$$block"."['ROWBIT']=\$rowcounter%2;\n"
|
723 |
|
|
. "\$rowcounter++;"
|
724 |
|
|
. "\$_obj=&\$$block;\n?>";
|
725 |
|
|
$page = str_replace("<!-- BEGIN $tag -->", $code, $page);
|
726 |
|
|
}
|
727 |
|
|
}
|
728 |
|
|
|
729 |
|
|
/* replace logical operator in [ELSE]IF */
|
730 |
|
|
$this->replace_logic_expression($page);
|
731 |
|
|
|
732 |
|
|
/* 'IF nnn=mmm' Blocks */
|
733 |
|
|
if (preg_match_all('/<!-- (ELSE)?IF ([a-zA-Z0-9_.]+)\s*([!=<>]+)\s*(["]?[^"]*["]?) -->/', $page, $var)) {
|
734 |
|
|
foreach ($var[2] as $cnt => $tag) {
|
735 |
|
|
list($parent, $block) = $this->var_name($tag);
|
736 |
|
|
$cmp = $var[3][$cnt];
|
737 |
|
|
$val = $var[4][$cnt];
|
738 |
|
|
$else = ($var[1][$cnt] == 'ELSE') ? '} else' : '';
|
739 |
|
|
if ($cmp == '=') {
|
740 |
|
|
$cmp = '==';
|
741 |
|
|
}
|
742 |
|
|
|
743 |
|
|
if (preg_match('/"([^"]*)"/',$val,$matches)) {
|
744 |
|
|
$code = "<?php\n$else"."if (\$$parent"."['$block'] $cmp \"".$matches[1]."\"){\n?>";
|
745 |
|
|
} elseif (preg_match('/([^"]*)/',$val,$matches)) {
|
746 |
|
|
list($parent_right, $block_right) = $this->var_name($matches[1]);
|
747 |
|
|
$code = "<?php\n$else"."if (\$$parent"."['$block'] $cmp \$$parent_right"."['$block_right']){\n?>";
|
748 |
|
|
}
|
749 |
|
|
|
750 |
|
|
$page = str_replace($var[0][$cnt], $code, $page);
|
751 |
|
|
}
|
752 |
|
|
}
|
753 |
|
|
|
754 |
|
|
/* 'IF nnn' Blocks */
|
755 |
|
|
if (preg_match_all('/<!-- (ELSE)?IF ([a-zA-Z0-9_.]+) -->/', $page, $var)) {
|
756 |
|
|
foreach ($var[2] as $cnt => $tag) {
|
757 |
|
|
$else = ($var[1][$cnt] == 'ELSE') ? '} else' : '';
|
758 |
|
|
list($parent, $block) = $this->var_name($tag);
|
759 |
|
|
$code = "<?php\n$else"."if (!empty(\$$parent"."['$block'])){\n?>";
|
760 |
|
|
$page = str_replace($var[0][$cnt], $code, $page);
|
761 |
|
|
}
|
762 |
|
|
}
|
763 |
|
|
|
764 |
|
|
/* 'IF {extension:variable}'=mmm Blocks
|
765 |
|
|
* e.g.
|
766 |
|
|
* <!-- IF {count:list} > 0 -->
|
767 |
|
|
* List populated
|
768 |
|
|
* <!-- ELSE -->
|
769 |
|
|
* List is empty
|
770 |
|
|
* <!-- ENDIF -->
|
771 |
|
|
* thanks to Khary Sharpe (ksharpe [at] kharysharpe [dot] com) for the initial code
|
772 |
|
|
*/
|
773 |
|
|
if (preg_match_all('/<!-- (ELSE)?IF {([a-zA-Z0-9_]+):([^}]*)}\s*([!=<>]+)\s*(["]?[^"]*["]?) -->/', $page, $var)) {
|
774 |
|
|
foreach ($var[2] as $cnt => $tag) {
|
775 |
|
|
list($parent, $block) = $this->var_name($tag);
|
776 |
|
|
$cmp = $var[4][$cnt];
|
777 |
|
|
$val = $var[5][$cnt];
|
778 |
|
|
$else = ($var[1][$cnt] == 'ELSE') ? '} else' : '';
|
779 |
|
|
if ($cmp == '=') {
|
780 |
|
|
$cmp = '==';
|
781 |
|
|
}
|
782 |
|
|
|
783 |
|
|
$extension = $var[2][$cnt];
|
784 |
|
|
$extension_var = $var[3][$cnt];
|
785 |
|
|
if (!isset($this->extension_tagged[$extension])) {
|
786 |
|
|
$header .= 'include_once "'.$this->extensions_dir."/".$this->extension_prefix."$extension.php\";\n";
|
787 |
|
|
$this->extension_tagged[$extension] = true;
|
788 |
|
|
}
|
789 |
|
|
if (!strlen($extension_var)) {
|
790 |
|
|
$code = "<?php\n$else"."if (".$this->extension_prefix."$extension() $cmp $val) {\n?>\n";
|
791 |
|
|
} elseif (substr($extension_var, 0, 1) == '"') {
|
792 |
|
|
$code = "<?php\n$else"."if (".$this->extension_prefix."$extension($extension_var) $cmp $val) {\n?>\n";
|
793 |
|
|
} elseif (strpos($extension_var, ',')) {
|
794 |
|
|
list($tag, $addparam) = explode(',', $extension_var, 2);
|
795 |
|
|
list($block, $skalar) = $this->var_name($extension_var);
|
796 |
|
|
if (preg_match('/^([a-zA-Z_]+)/', $addparam, $match)) {
|
797 |
|
|
$nexttag = $match[1];
|
798 |
|
|
list($nextblock, $nextskalar) = $this->var_name($nexttag);
|
799 |
|
|
$addparam = substr($addparam, strlen($nexttag));
|
800 |
|
|
$code = "<?php\n$else"."if (".$this->extension_prefix."$extension(\$$block"."['$skalar'],\$$nextblock"."['$nextskalar']"."$addparam) $cmp $val) {\n?>\n";
|
801 |
|
|
} else {
|
802 |
|
|
$code = "<?php\n$else"."if (".$this->extension_prefix."$extension(\$$block"."['$skalar'],$addparam) $cmp $val) {\n?>\n";
|
803 |
|
|
}
|
804 |
|
|
} else {
|
805 |
|
|
list($block, $skalar) = $this->var_name($extension_var);
|
806 |
|
|
$code = "<?php\n$else"."if (".$this->extension_prefix."$extension(\$$block"."['$skalar']) $cmp $val) {\n?>\n";
|
807 |
|
|
}
|
808 |
|
|
$page = str_replace($var[0][$cnt], $code, $page);
|
809 |
|
|
}
|
810 |
|
|
}
|
811 |
|
|
|
812 |
|
|
/* Replace Scalars */
|
813 |
|
|
if (preg_match_all('/'.$this->left_delimiter.'([a-zA-Z0-9_. >]+)'.$this->right_delimiter.'/', $page, $var)) {
|
814 |
|
|
foreach ($var[1] as $fulltag) {
|
815 |
|
|
/* Determine Command (echo / $obj[n]=) */
|
816 |
|
|
list($cmd, $tag) = $this->cmd_name($fulltag);
|
817 |
|
|
list($block, $skalar) = $this->var_name($tag);
|
818 |
|
|
$code = "<?php\n$cmd \$$block"."['$skalar'];\n?>\n";
|
819 |
|
|
$page = str_replace(stripslashes($this->left_delimiter).$fulltag.stripslashes($this->right_delimiter), $code, $page);
|
820 |
|
|
}
|
821 |
|
|
}
|
822 |
|
|
|
823 |
|
|
/* Replace Translations */
|
824 |
|
|
if (preg_match_all('/<"([a-zA-Z0-9_.]+)">/', $page, $var)) {
|
825 |
|
|
foreach ($var[1] as $tag) {
|
826 |
|
|
list($block, $skalar) = $this->var_name($tag);
|
827 |
|
|
$code = "<?php\necho gettext('$skalar');\n?>\n";
|
828 |
|
|
$page = str_replace('<"'.$tag.'">', $code, $page);
|
829 |
|
|
}
|
830 |
|
|
}
|
831 |
|
|
|
832 |
|
|
/* Include Extensions */
|
833 |
|
|
if (preg_match_all('/'.$this->left_delimiter.'([a-zA-Z0-9_]+):([^}]*)'.$this->right_delimiter.'/', $page, $var)) {
|
834 |
|
|
foreach ($var[2] as $cnt => $tag) {
|
835 |
|
|
/* Determine Command (echo / $obj[n]=) */
|
836 |
|
|
list($cmd, $tag) = $this->cmd_name($tag);
|
837 |
|
|
|
838 |
|
|
$extension = $var[1][$cnt];
|
839 |
|
|
if (!isset($this->extension_tagged[$extension])) {
|
840 |
|
|
$header .= 'include_once "'.$this->extensions_dir."/".$this->extension_prefix."$extension.php\";\n";
|
841 |
|
|
$this->extension_tagged[$extension] = true;
|
842 |
|
|
}
|
843 |
|
|
if (!strlen($tag)) {
|
844 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension();\n?>\n";
|
845 |
|
|
} elseif (substr($tag, 0, 1) == '"') {
|
846 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension($tag);\n?>\n";
|
847 |
|
|
} elseif (strpos($tag, ',')) {
|
848 |
|
|
list($tag, $addparam) = explode(',', $tag, 2);
|
849 |
|
|
list($block, $skalar) = $this->var_name($tag);
|
850 |
|
|
if (preg_match('/^([a-zA-Z_]+)/', $addparam, $match)) {
|
851 |
|
|
$nexttag = $match[1];
|
852 |
|
|
list($nextblock, $nextskalar) = $this->var_name($nexttag);
|
853 |
|
|
$addparam = substr($addparam, strlen($nexttag));
|
854 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension(\$$block"."['$skalar'],\$$nextblock"."['$nextskalar']"."$addparam);\n?>\n";
|
855 |
|
|
} else {
|
856 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension(\$$block"."['$skalar'],$addparam);\n?>\n";
|
857 |
|
|
}
|
858 |
|
|
} else {
|
859 |
|
|
list($block, $skalar) = $this->var_name($tag);
|
860 |
|
|
$code = "<?php\n$cmd ".$this->extension_prefix."$extension(\$$block"."['$skalar']);\n?>\n";
|
861 |
|
|
}
|
862 |
|
|
$page = str_replace($var[0][$cnt], $code, $page);
|
863 |
|
|
}
|
864 |
|
|
}
|
865 |
|
|
|
866 |
|
|
/* Add Include Header */
|
867 |
|
|
if (isset($header) && !empty($header)) {
|
868 |
|
|
$page = "<?php\n$header\n?>$page";
|
869 |
|
|
}
|
870 |
|
|
|
871 |
|
|
/* do substitutions on included supplementary templates */
|
872 |
|
|
$page = $this->worx_tpl_swap($page, $data, $supp_templates);
|
873 |
|
|
|
874 |
|
|
/* Store Code to Temp Dir */
|
875 |
|
|
if (strlen($compiled_template_filename)) {
|
876 |
|
|
if ($hd = fopen($compiled_template_filename, 'w')) {
|
877 |
|
|
fwrite($hd, $page);
|
878 |
|
|
fclose($hd);
|
879 |
|
|
return true;
|
880 |
|
|
} else {
|
881 |
|
|
$this->error = 'Could not write compiled file.';
|
882 |
|
|
return false;
|
883 |
|
|
}
|
884 |
|
|
} else {
|
885 |
|
|
return $page;
|
886 |
|
|
}
|
887 |
|
|
}
|
888 |
|
|
|
889 |
|
|
/* Splits Template-Style Variable Names into an Array-Name/Key-Name Components
|
890 |
|
|
* {example} : array( "_obj", "example" ) -> $_obj['example']
|
891 |
|
|
* {example.value} : array( "_obj['example']", "value" ) -> $_obj['example']['value']
|
892 |
|
|
* {example.0.value} : array( "_obj['example'][0]", "value" ) -> $_obj['example'][0]['value']
|
893 |
|
|
* {top.example} : array( "_stack[0]", "example" ) -> $_stack[0]['example']
|
894 |
|
|
* {parent.example} : array( "_stack[$_stack_cnt-1]", "example" ) -> $_stack[$_stack_cnt-1]['example']
|
895 |
|
|
* {parent.parent.example} : array( "_stack[$_stack_cnt-2]", "example" ) -> $_stack[$_stack_cnt-2]['example']
|
896 |
|
|
* @param string $tag Variale Name used in Template
|
897 |
|
|
* @return array Array Name, Key Name
|
898 |
|
|
* @access private
|
899 |
|
|
* @desc Splits Template-Style Variable Names into an Array-Name/Key-Name Components
|
900 |
|
|
*/
|
901 |
|
|
function var_name($tag) {
|
902 |
|
|
$parent_level = 0;
|
903 |
|
|
while (substr($tag, 0, 7) == 'parent.') {
|
904 |
|
|
$tag = substr($tag, 7);
|
905 |
|
|
$parent_level++;
|
906 |
|
|
}
|
907 |
|
|
if (substr($tag, 0, 4) == 'top.') {
|
908 |
|
|
$obj = '_stack[0]';
|
909 |
|
|
$tag = substr($tag,4);
|
910 |
|
|
} elseif ($parent_level) {
|
911 |
|
|
$obj = '_stack[$_stack_cnt-'.$parent_level.']';
|
912 |
|
|
} else {
|
913 |
|
|
$obj = '_obj';
|
914 |
|
|
}
|
915 |
|
|
while (is_int(strpos($tag, '.'))) {
|
916 |
|
|
list($parent, $tag) = explode('.', $tag, 2);
|
917 |
|
|
if (is_numeric($parent)) {
|
918 |
|
|
$obj .= "[" . $parent . "]";
|
919 |
|
|
} else {
|
920 |
|
|
$obj .= "['" . $parent . "']";
|
921 |
|
|
}
|
922 |
|
|
}
|
923 |
|
|
$ret = array($obj, $tag);
|
924 |
|
|
return $ret;
|
925 |
|
|
}
|
926 |
|
|
|
927 |
|
|
/* Determine Template Command from Variable Name
|
928 |
|
|
* {variable} : array( "echo", "variable" ) -> echo $_obj['variable']
|
929 |
|
|
* {variable > new_name} : array( "_obj['new_name']=", "variable" ) -> $_obj['new_name']= $_obj['variable']
|
930 |
|
|
* @param string $tag Variale Name used in Template
|
931 |
|
|
* @return array Array Command, Variable
|
932 |
|
|
* @access private
|
933 |
|
|
* @desc Determine Template Command from Variable Name
|
934 |
|
|
*/
|
935 |
|
|
function cmd_name($tag) {
|
936 |
|
|
if (preg_match('/^(.+) > ([a-zA-Z0-9_.]+)$/', $tag, $tagvar)) {
|
937 |
|
|
$tag = $tagvar[1];
|
938 |
|
|
list($newblock, $newskalar) = $this->var_name($tagvar[2]);
|
939 |
|
|
$cmd = "\$$newblock"."['$newskalar']=";
|
940 |
|
|
} else {
|
941 |
|
|
$cmd = 'echo';
|
942 |
|
|
}
|
943 |
|
|
$ret = array($cmd, $tag);
|
944 |
|
|
return $ret;
|
945 |
|
|
}
|
946 |
|
|
|
947 |
|
|
/* @return int Number of subtemplate included
|
948 |
|
|
* @access private
|
949 |
|
|
* @desc Count number of subtemplates included in current template
|
950 |
|
|
*/
|
951 |
|
|
function count_subtemplates() {
|
952 |
|
|
$ret = preg_match_all('/<!-- INCLUDE ([a-zA-Z0-9_.]+) -->/', $this->template, $tvar);
|
953 |
|
|
unset($tvar);
|
954 |
|
|
return $ret;
|
955 |
|
|
}
|
956 |
|
|
|
957 |
|
|
function worx_var_swap($tpldata, $data, $supp_templates) { /* do the substitution of the variables here */
|
958 |
|
|
|
959 |
|
|
/* replace all the template elements (sub templates) */
|
960 |
|
|
if ( is_array($supp_templates) && !empty($supp_templates) ) {
|
961 |
|
|
foreach ($supp_templates as $key => $val) {
|
962 |
|
|
$tpldata = str_replace("\{$key}", $val, $tpldata);
|
963 |
|
|
}
|
964 |
|
|
}
|
965 |
|
|
/* do the substitution of the directory names here */
|
966 |
|
|
|
967 |
|
|
return $tpldata;
|
968 |
|
|
|
969 |
|
|
}
|
970 |
|
|
|
971 |
|
|
function worx_tpl_swap($tpldata, $data, $supp_templates) { /* do the substitution of the sub templates here */
|
972 |
|
|
|
973 |
|
|
/* do the substitution of the directory names here */
|
974 |
|
|
|
975 |
|
|
/* do image link substitution */
|
976 |
|
|
if ( $data['tpl_img'] != '' && $data['url_img'] != '' ) {
|
977 |
|
|
$tpldata = str_replace($data['tpl_img'],$data['url_img'],$tpldata);
|
978 |
|
|
unset($data['tpl_img']);
|
979 |
|
|
unset($data['url_img']);
|
980 |
|
|
} elseif (defined(_URL_USRIMG)) {
|
981 |
|
|
$tpldata = str_replace('tplimgs/',_URL_USRIMG,$tpldata);
|
982 |
|
|
}
|
983 |
|
|
|
984 |
|
|
/* do javascript link substitution */
|
985 |
|
|
if ( $data['tpl_js'] != '' && $data['url_js'] != '' ) {
|
986 |
|
|
$tpldata = str_replace($data['tpl_js'],$data['url_js'],$tpldata);
|
987 |
|
|
unset($data['img_tpl']);
|
988 |
|
|
unset($data['url_js']);
|
989 |
|
|
} elseif (defined(_URL_USRJS)) {
|
990 |
|
|
$tpldata = str_replace('tpljs/',_URL_USRJS,$tpldata);
|
991 |
|
|
}
|
992 |
|
|
|
993 |
|
|
/* do css link substitution */
|
994 |
|
|
if ( $data['tpl_css'] != '' && $data['url_css'] != '' ) {
|
995 |
|
|
$tpldata = str_replace($data['tpl_css'],$data['url_css'],$tpldata);
|
996 |
|
|
unset($data['tpl_css']);
|
997 |
|
|
unset($data['url_css']);
|
998 |
|
|
} elseif (defined(_URL_USRCSS)) {
|
999 |
|
|
$tpldata = str_replace('url_css/',_URL_USRCSS,$tpldata);
|
1000 |
|
|
}
|
1001 |
|
|
|
1002 |
|
|
return $tpldata;
|
1003 |
|
|
|
1004 |
|
|
}
|
1005 |
|
|
|
1006 |
|
|
}
|
1007 |
|
|
|
1008 |
|
|
?>
|