| 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 |
|
|
?>
|