1<?php 2// 3// +----------------------------------------------------------------------+ 4// | PHP Version 4 | 5// +----------------------------------------------------------------------+ 6// | Copyright (c) 1997-2003 The PHP Group | 7// +----------------------------------------------------------------------+ 8// | This source file is subject to version 2.02 of the PHP license, | 9// | that is bundled with this package in the file LICENSE, and is | 10// | available at through the world-wide-web at | 11// | http://www.php.net/license/2_02.txt. | 12// | If you did not receive a copy of the PHP license and are unable to | 13// | obtain it through the world-wide-web, please send a note to | 14// | license@php.net so we can mail you a copy immediately. | 15// +----------------------------------------------------------------------+ 16// | Author: Alan Knowles <alan@akbkhome.com> 17// +----------------------------------------------------------------------+ 18// 19 20 21/** 22* The Standard Tag filter 23* 24* @abstract 25* does all the clever stuff... 26* 27* Security Notes: 28* Templates should not originate from untrusted sources, 29* - the method(#.....#) could be regarded as insecure. 30* - there is no attempt to protect your from <script / <?php in templates. 31* 32* @package HTML_Template_Flexy 33* 34*/ 35 36 37class HTML_Template_Flexy_Compiler_Regex_SimpleTags 38{ 39 /* 40 * @var object HTML_Template_Flexy the main engine 41 */ 42 var $engine; // the engine (with options) 43 /* 44 * @var string $start the start tag for the template (escaped for regex) 45 */ 46 var $start = '\{'; 47 48 /* 49 * @var string $stop the stopt tag for the template (escaped for regex) 50 */ 51 var $stop = '\}'; 52 /* 53 * @var string $error show/hide the PHP error messages on/off in templates 54 */ 55 var $error = "@"; // change to blank to debug errors. 56 /** 57 * Standard Set Engine 58 * 59 * 60 * @param object HTML_Template_Flexy the main engine 61 * @access private 62 */ 63 function _set_engine(&$engine) { 64 $this->engine = &$engine; 65 if ($this->engine->options['debug']) { 66 $this->error = ""; 67 } 68 } 69 70 71 72 /** 73 * Standard Variable replacement 74 * 75 * 76 * Maps variables 77 * {i.xyz} maps to <?php echo htmlspecialchars($i->xyz)?> 78 * {i.xyz:h} maps to <?php echo $i->xyz?> 79 * {i.xyz:u} maps to <?php echo urlencode($i->xyz)?> 80 * {i.xyz:ru} maps to <?php echo rawurlencode($i->xyz)?> 81 * 82 * {i.xyz:r} maps to <PRE><?php echo print_r($i->xyz)?></PRE> 83 * {i.xyz:n} maps to <?php echo nl2br(htmlspecialchars($i->xyz))?> 84 * 85 * 86 * @param string $input the template 87 * @return string the result of the filtering 88 * @access public 89 */ 90 91 92 93 function variables ($input) { 94 $input = preg_replace( 95 "/".$this->start."([a-z0-9_.]+)".$this->stop."/ie", 96 "'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').')?>'", 97 $input); 98 99 100 $input = preg_replace( 101 "/".$this->start."([a-z0-9_.]+):h".$this->stop."/ie", 102 "'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'?>'", 103 $input); 104 105 $input = preg_replace( 106 "/".$this->start."([a-z0-9_.]+):u".$this->stop."/ie", 107 "'<?php echo urlencode(".$this->error."$'.str_replace('.','->','\\1').')?>'", 108 $input); 109 110 $input = preg_replace( 111 "/".$this->start."([a-z0-9_.]+):ru".$this->stop."/ie", 112 "'<?php echo rawurlencode(".$this->error."$'.str_replace('.','->','\\1').')?>'", 113 $input); 114 115 $input = preg_replace( 116 "/".$this->start."([a-z0-9_.]+):r".$this->stop."/ie", 117 "'<PRE><?php echo print_r($'.str_replace('.','->','\\1').')?></PRE>'", 118 $input); 119 120 $input = preg_replace( 121 "/".$this->start."([a-z0-9_.]+):n".$this->stop."/ie", 122 "'<?php echo nl2br(htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'))?>'", 123 $input); 124 return $input; 125 126 } 127 /** 128 * Urlencoded Variable replacement 129 * 130 * Often when you use a WYSISYG editor, it replaces { in 131 * the href="{somevar}" with the urlencoded version, this bit fixes it. 132 * 133 * Maps variables 134 * %??i.xyz%?? maps to <?php echo htmlspecialchars($i->xyz)?> 135 * %??i.xyz:h%?? maps to <?php echo $i->xyz?> 136 * %??i.xyz:u%?? maps to <?php echo urlencode($i->xyz)?> 137 * %??i.xyz:ru%?? maps to <?php echo urlencode($i->xyz)?> 138 * THIS IS PROBABLY THE ONE TO USE! 139 * 140 * %??i.xyz:uu%?? maps to <?php echo urlencode(urlencode($i->xyz))?> 141 * 142 * 143 * @param string $input the template 144 * @return string the result of the filtering 145 * @access public 146 */ 147 148 function urlencoded_variables ($input) { 149 $input = preg_replace( 150 "/".urlencode(stripslashes($this->start))."([a-z0-9_.]+)".urlencode(stripslashes($this->stop))."/ie", 151 "'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').')?>'", 152 $input); 153 154 155 $input = preg_replace( 156 "/".urlencode(stripslashes($this->start))."([a-z0-9_.]+):h".urlencode(stripslashes($this->stop))."/ie", 157 "'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'?>'", 158 $input); 159 160 $input = preg_replace( 161 "/".urlencode(stripslashes($this->start))."([a-z0-9_.]+):u".urlencode(stripslashes($this->stop))."/ie", 162 "'<?php echo urlencode(".$this->error."$'.str_replace('.','->','\\1').')?>'", 163 $input); 164 165 $input = preg_replace( 166 "/".urlencode(stripslashes($this->start))."([a-z0-9_.]+):uu".urlencode(stripslashes($this->stop))."/ie", 167 "'<?php echo urlencode(urlencode(".$this->error."$'.str_replace('.','->','\\1').'))?>'", 168 $input); 169 return $input; 170 } 171 /** 172 * Calling Methods 173 * 174 * This allows you to call methods of your application 175 * 176 * Maps Methods 177 * {t.xxxx_xxxx()} maps to <?php echo htmlspecialchars($t->xxxx_xxxx())?> 178 * {t.xxxx_xxxx():h} maps to <?php echo $t->xxxx_xxxx()?> 179 * 180 * {t.xxxx_xxxx(sssss.dddd)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx($ssss->dddd))?> 181 * {t.xxxx_xxxx(sssss.dddd):h} maps to <?php echo $t->xxxx_xxxx($ssss->dddd)?> 182 * {t.xxxx_xxxx(sssss.dddd):s} maps to <?php highlight_string($t->xxxx_xxxx($ssss->dddd))?> 183 * 184 * {t.xxxx_xxxx(#XXXXX#)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx('XXXXXX'))?> 185 * {t.xxxx_xxxx(#XXXXX#):h} maps to <?php echo $t->xxxx_xxxx('XXXXXX')?> 186 * 187 * {t.xxxx_xxxx(sss.ddd,sss.ddd)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx($sss->ddd,$sss->ddd))?> 188 * {t.xxxx_xxxx(#aaaa#,sss.ddd)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx("aaaa",$sss->ddd))?> 189 * {t.xxxx_xxxx(sss.ddd,#aaaa#)} maps to <?php echo htmlspecialchars($t->xxxx_xxxx($sss->ddd,"aaaa"))?> 190 * 191 * 192 * 193 * @param string $input the template 194 * @return string the result of the filtering 195 * @access public 196 */ 197 198 199 200 201 202 function methods($input) { 203 204 /* no vars */ 205 $input = preg_replace( 206 "/".$this->start."([a-z0-9_.]+)\(\)".$this->stop."/ie", 207 "'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'())?>'", 208 $input); 209 210 $input = preg_replace( 211 "/".$this->start."([a-z0-9_.]+)\(\):h".$this->stop."/ie", 212 "'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'()?>'", 213 $input); 214 /* single vars */ 215 $input = preg_replace( 216 "/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+)\)".$this->stop."/ie", 217 "'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . '))?>'", 218 $input); 219 220 $input = preg_replace( 221 "/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+)\):h".$this->stop."/ie", 222 "'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . ')?>'", 223 $input); 224 $input = preg_replace( 225 "/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+)\):s".$this->stop."/ie", 226 "'<?php highlight_string($'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . '));?>'", 227 $input); 228 /* double vars */ 229 $input = preg_replace( 230 "/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+),([a-z0-9_.]+)\)".$this->stop."/ie", 231 "'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . ',$' . str_replace('.','->','\\3') . '))?>'", 232 $input); 233 /* double vars:: # #'d ,var */ 234 $input = preg_replace( 235 "/".$this->start."([a-z0-9_.]+)\(\#([^\#]+)\#,([a-z0-9_.]+)\)".$this->stop."/ie", 236 "'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'(\''. str_replace(\"'\",\"\\\'\",'\\2') . '\',$' . str_replace('.','->','\\3') . '))?>'", 237 $input); 238 /* double vars:: var , # #'d */ 239 $input = preg_replace( 240 "/".$this->start."([a-z0-9_.]+)\(([a-z0-9_.]+),\#([^\#]+)\#\)".$this->stop."/ie", 241 "'<?php echo htmlspecialchars(".$this->error."$'.str_replace('.','->','\\1').'($' . str_replace('.','->','\\2') . ',\''. str_replace(\"'\",\"\\\'\",'\\3') . '\'))?>'", 242 $input); 243 244 /*strings or integers */ 245 $input = preg_replace( 246 "/".$this->start."([a-z0-9_.]+)\(\#([^\#]+)\#\)".$this->stop."/ie", 247 "'<?php echo htmlspecialchars(\$'.str_replace('.','->','\\1') . '(\''. str_replace(\"'\",\"\\\'\",'\\2') . '\'))?>'", 248 $input); 249 250 $input = preg_replace( 251 "/".$this->start."([a-z0-9_.]+)\(\#([^\#]+)\#\):h".$this->stop."/ie", 252 "'<?php echo ".$this->error."$'.str_replace('.','->','\\1').'(\"' . str_replace(\"'\",\"\\\'\",'\\2') . '\")?>'", 253 $input); 254 255 return $input; 256 } 257 /** 258 * Looping 259 * 260 * This allows you to do loops on variables (eg. nested/ repeated blocks!) 261 * 262 * Maps Methods 263 * {foreach:t.xyz,zzz} maps to <?php if ($i->xyz) foreach ($t->xyz as $zzz) { ?> 264 * {foreach:t.xyz,xxx,zzz} maps to <?php if ($i->xyz) foreach ($t->xyz as $xxx=>$zzz) { ?> 265 * {end:} maps to <?php }?> 266 * {else:} maps to <?php }else{?> 267 * 268 * 269 * 270 * @param string $input the template 271 * @return string the result of the filtering 272 * @access public 273 */ 274 275 276 function looping($input) { 277 278 279 $input = preg_replace( 280 "/".$this->start."foreach:([a-z0-9_.]+),([a-z0-9_.]+)".$this->stop."/ie", 281 "'<?php if (".$this->error."$' . str_replace('.','->','\\1') . ') foreach( $' . str_replace('.','->','\\1') . ' as $' . str_replace('.','->','\\2') . ') { ?>'", 282 $input); 283 $input = preg_replace( 284 "/".$this->start."foreach:([a-z0-9_.]+),([a-z0-9_.]+),([a-z0-9_.]+)".$this->stop."/ie", 285 "'<?php if (".$this->error."$' . str_replace('.','->','\\1') . ') foreach( $' . str_replace('.','->','\\1') . ' as $' . str_replace('.','->','\\2') . '=>$' . str_replace('.','->','\\3') .') { ?>'", 286 $input); 287 288 $input = str_replace(stripslashes($this->start)."else:".stripslashes($this->stop),'<?php }else{?>', $input); 289 $input = str_replace(stripslashes($this->start)."end:".stripslashes($this->stop),'<?php }?>', $input); 290 return $input; 291 } 292 /** 293 * Conditional inclusion 294 * 295 * This allows you to do conditional inclusion (eg. blocks!) 296 * 297 * Maps conditions 298 * 299 * {if:t.xxxx} => <?php if ($t->xxxx) { ?> 300 * {if:t.x_xxx()} => <?php if ($t->x_xxx()) { ?> 301 * 302 * @param string $input the template 303 * @return string the result of the filtering 304 * @access public 305 */ 306 307 function conditionals($input) { 308 309 $input = preg_replace( 310 "/".$this->start."if:([a-z0-9_.]+)".$this->stop."/ie", 311 "'<?php if (".$this->error."$' . str_replace('.','->','\\1') . ') { ?>'", 312 $input); 313 314 $input = preg_replace( 315 "/".$this->start."if:([a-z0-9_.]+)\(\)".$this->stop."/ie", 316 "'<?php if (".$this->error."$' . str_replace('.','->','\\1') . '()) { ?>'", 317 $input); 318 319 return $input; 320 } 321 /** 322 * sub template inclusion 323 * 324 * This allows you to do include other files (either flat or generated templates.). 325 * 326 * {include:t.abcdef} maps to <?php 327 * if($t->abcdef && file_exists($compileDir . "/". $t->abcdef . "en.php")) 328 * include($compileDir . "/". $t->abcdef . ".en.php"); 329 * ?> 330 * 331 * include abcdef.en.php (Eg. hard coded compiled template 332 * {include:#abcdef#} => <?php 333 * if(file_exists($compileDir . "/abcdef.en.php")) 334 * include($compileDir . "/abcdef.en.php"); 335 * ?> 336 * 337 * include raw 338 * {t_include:#abcdef.html#} => <?php 339 * if(file_exists($templateDir . "/abcdef.html")) 340 * include($compileDir . "/abcdef.html"); 341 * ?> 342 * Compile and include 343 * {q_include:#abcdef.html#} => <?php 344 * HTML_Template_Flexy::staticQuickTemplate('abcedef.html',$t); 345 * ?> 346 * 347 * 348 * @param string $input the template 349 * @return string the result of the filtering 350 * @access public 351 */ 352 353 function include_template($input) { 354 355 // array not supported for this type of template. 356 if (is_array($this->engine->options['templateDir'])) { 357 return $input; 358 } 359 360 $input = preg_replace( 361 "/".$this->start."include:([a-z0-9_.]+)".$this->stop."/ie", 362 "'<?php 363 if ((".$this->error."$' . str_replace('.','->','\\1') . ') && 364 file_exists(\"" . $this->engine->options['compileDir'] . 365 "/\{$' . str_replace('.','->','\\1') . '}.en.php\")) 366 include(\"" . $this->engine->options['compileDir'] . 367 "/\{$' . str_replace('.','->','\\1') . '}.en.php\");?>'", 368 $input); 369 370 $input = preg_replace( 371 "/".$this->start."include:#([a-z0-9_.]+)#".$this->stop."/ie", 372 "'<?php if (file_exists(\"" . $this->engine->options['compileDir'] . "/\\1.en.php\")) include(\"" . 373 $this->engine->options['compileDir'] . "/\\1.en.php\");?>'", 374 $input); 375 376 $input = preg_replace( 377 "/".$this->start."t_include:#([a-z0-9_.]+)#".$this->stop."/ie", 378 "'<?php if (file_exists(\"" . $this->engine->options['templateDir'] . 379 "/\\1\")) include(\"" . $this->engine->options['templateDir'] . "/\\1\");?>'", 380 $input); 381 382 $input = preg_replace( 383 "/".$this->start."q_include:#([a-z0-9_.]+)#".$this->stop."/ie", 384 "'<?php HTML_Template_Flexy::staticQuickTemplate(\"\\1\",\$t); ?>'", 385 $input); 386 387 return $input; 388 } 389 390 391 392 393 394} 395 396?>