| [ Index ] |
|
Code source de Phorum 5.1.25 |
1 <?php 2 3 //////////////////////////////////////////////////////////////////////////////// 4 // // 5 // Copyright (C) 2006 Phorum Development Team // 6 // http://www.phorum.org // 7 // // 8 // This program is free software. You can redistribute it and/or modify // 9 // it under the terms of either the current Phorum License (viewable at // 10 // phorum.org) or the Phorum License that was distributed with this file // 11 // // 12 // This program is distributed in the hope that it will be useful, // 13 // but WITHOUT ANY WARRANTY, without even the implied warranty of // 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // 15 // // 16 // You should have received a copy of the Phorum License // 17 // along with this program. // 18 //////////////////////////////////////////////////////////////////////////////// 19 20 if(!defined("PHORUM")) return; 21 22 // For keeping track of include dependancies, which 23 // are used to let templates automatically rebuild 24 // in case an included subtemplate has been changed. 25 $include_level = 0; 26 $include_deps = array(); 27 28 function phorum_import_template($tplfile, $outfile, $tplname = NULL) 29 { 30 global $include_level, $include_deps; 31 $include_level++; 32 33 // Remember that we used this template. 34 $filemtime = @filemtime($tplfile); 35 if ($filemtime === false) $filemtime = 0; 36 $include_deps[$tplfile] = array( $outfile, $filemtime ); 37 38 // Check if the file exists. 39 if (! file_exists($tplfile)) die( 40 "Template problem: file \"" . htmlspecialchars($tplfile) . "\" " . 41 "does not exist"); 42 43 // In case we're handling 0 byte large files, we set $page 44 // directly. Running fread($fp, 0) gives a PHP warning. 45 if (filesize($tplfile)) { 46 $fp=fopen($tplfile, "r"); 47 if (! $fp) die( 48 "Template problem: file \"" . htmlspecialchars($tplfile) . "\" " . 49 "cannot be read."); 50 $page=fread($fp, filesize($tplfile)); 51 fclose($fp); 52 } else { 53 die("Template problem: cannot stat file " . 54 "\"" . htmlspecialchars($tplfile) . "\""); 55 } 56 57 preg_match_all("/\{[\!\/A-Za-z].+?\}/s", $page, $matches); 58 59 settype($oldloopvar, "string"); 60 settype($loopvar, "string"); 61 settype($olddatavar, "string"); 62 settype($datavar, "string"); 63 $loopvars = array(); 64 65 foreach($matches[0] as $match){ 66 unset($parts); 67 68 $string=substr($match, 1, -1); 69 70 $string = trim($string); 71 72 // pre-parse pointer variables 73 if(strstr($string, "->")){ 74 $string=str_replace("->", "']['", $string); 75 } 76 77 $parts=explode(" ", $string); 78 79 switch(strtolower($parts[0])){ 80 81 // Comment 82 case "!": 83 84 $repl="<?php // ".implode(" ", $parts)." ?>"; 85 break; 86 87 88 case "include": 89 90 $repl = file_get_contents(phorum_get_template($parts[1],1)); 91 break; 92 93 case "include_once": 94 95 $repl="<?php include_once phorum_get_template('$parts[1]'); ?>"; 96 break; 97 98 case "include_var": // include a file given by a variable 99 100 $repl="<?php include_once phorum_get_template( \$PHORUM[\"DATA\"]['$parts[1]']); ?>"; 101 break; 102 103 // A define is used to create vars for the engine to use. 104 case "define": 105 106 $repl="<?php \$PHORUM[\"TMP\"]['$parts[1]']='"; 107 array_shift($parts); 108 array_shift($parts); 109 foreach($parts as $part){ 110 $repl.=str_replace("'", "\\'", $part)." "; 111 } 112 $repl=trim($repl)."'; ?>"; 113 break; 114 115 116 // A var is used to create vars for the template. 117 case "var": 118 119 $repl="<?php \$PHORUM[\"DATA\"]['$parts[1]']='"; 120 array_shift($parts); 121 array_shift($parts); 122 foreach($parts as $part){ 123 $repl.=str_replace("'", "\\'", $part)." "; 124 } 125 $repl=trim($repl)."'; ?>"; 126 break; 127 128 // Run a Phorum hook. The first parameter is the name of the 129 // hook. Other parameters will be passed on as arguments for 130 // the hook function. On argument will be passed directly to 131 // the hook. Multiple arguments will be passed in an array. 132 case "hook": 133 134 // Setup hook arguments. 135 $hookargs = array(); 136 for($i = 2; !empty($parts[$i]); $i++) { 137 // For supporting the following construct, where the 138 // loopvar is passed to the hook in full: 139 // {LOOP SOMELIST} 140 // {HOOK some_hook SOMELIST} 141 // {/LOOP SOMELIST} 142 if (isset($loopvars[$parts[$i]])) { 143 $hookargs[] = "\$PHORUM['TMP']['".addslashes($parts[$i])."']"; 144 } else { 145 $index = phorum_determine_index($loopvars, $parts[$i]); 146 $hookargs[] = "\$PHORUM['$index']['".addslashes($parts[$i])."']"; 147 } 148 } 149 150 // Build the replacement string. 151 $repl = "<?php if(isset(\$PHORUM['hooks']['".addslashes($parts[1])."'])) phorum_hook('".addslashes($parts[1])."'"; 152 if (count($hookargs) == 1) { 153 $repl .= "," . $hookargs[0]; 154 } elseif (count($hookargs) > 1) { 155 $repl .= ",array(" . implode(",", $hookargs) . ")"; 156 } 157 $repl .= ");?>"; 158 break; 159 160 // starts a loop 161 case "loop": 162 163 $loopvars[$parts[1]]=true; 164 $index=phorum_determine_index($loopvars, $parts[1]); 165 $repl="<?php \$phorum_loopstack[] = isset(\$PHORUM['TMP']['$parts[1]']) ? \$PHORUM['TMP']['$parts[1]']:NULL; if(isset(\$PHORUM['$index']['$parts[1]']) && is_array(\$PHORUM['$index']['$parts[1]'])) foreach(\$PHORUM['$index']['$parts[1]'] as \$PHORUM['TMP']['$parts[1]']){ ?>"; 166 break; 167 168 169 // ends a loop 170 case "/loop": 171 172 if (!isset($parts[1])) print "<h3>Template warning: Missing argument for /loop statement in file '" . htmlspecialchars($tplfile) . "'</h3>"; 173 $repl="<?php } if(isset(\$PHORUM['TMP']) && isset(\$PHORUM['TMP']['$parts[1]'])) unset(\$PHORUM['TMP']['$parts[1]']); \$phorum_loopstackitem=array_pop(\$phorum_loopstack); if (isset(\$phorum_loopstackitem)) \$PHORUM['TMP']['$parts[1]'] = \$phorum_loopstackitem;?>"; 174 unset($loopvars[$parts[1]]); 175 break; 176 177 178 // if and elseif are the same accept how the line starts 179 case "if": 180 case "elseif": 181 182 // determine if or elseif 183 $prefix = (strtolower($parts[0])=="if") ? "if" : "} elseif"; 184 185 // are we wanting == or != 186 if(strtolower($parts[1])=="not"){ 187 $operator="!="; 188 $parts[1]=$parts[2]; 189 if(isset($parts[3])){ 190 $parts[2]=$parts[3]; 191 unset($parts[3]); 192 } else { 193 unset($parts[2]); 194 } 195 } else { 196 $operator="=="; 197 } 198 199 $index=phorum_determine_index($loopvars, $parts[1]); 200 201 // if there is no part 2, check that the value is set and not empty 202 if(!isset($parts[2])){ 203 if($operator=="=="){ 204 $repl="<?php $prefix(isset(\$PHORUM['$index']['$parts[1]']) && !empty(\$PHORUM['$index']['$parts[1]'])){ ?>"; 205 } else { 206 $repl="<?php $prefix(!isset(\$PHORUM['$index']['$parts[1]']) || empty(\$PHORUM['$index']['$parts[1]'])){ ?>"; 207 } 208 209 // if it is numeric, a constant or a string, simply set it as is 210 } elseif(is_numeric($parts[2]) || defined($parts[2]) || preg_match('!"[^"]*"!', $parts[2])) { 211 $repl="<?php $prefix(isset(\$PHORUM['$index']['$parts[1]']) && \$PHORUM['$index']['$parts[1]']$operator$parts[2]){ ?>"; 212 213 // we must have a template var 214 } else { 215 216 $index_part2=phorum_determine_index($loopvars, $parts[2]); 217 218 // this is a really complicated IF we are building. 219 220 $repl="<?php $prefix(isset(\$PHORUM['$index']['$parts[1]']) && isset(\$PHORUM['$index_part2']['$parts[2]']) && \$PHORUM['$index']['$parts[1]']$operator\$PHORUM['$index_part2']['$parts[2]']) { ?>"; 221 222 } 223 224 // reset $prefix 225 $prefix=""; 226 break; 227 228 229 // create an else 230 case "else": 231 232 $repl="<?php } else { ?>"; 233 break; 234 235 236 // close an if 237 case "/if": 238 239 $repl="<?php } ?>"; 240 break; 241 242 case "assign": 243 if(defined($parts[2]) || is_numeric($parts[2])){ 244 $repl="<?php \$PHORUM[\"DATA\"]['$parts[1]']=$parts[2]; ?>"; 245 } else { 246 $index=phorum_determine_index($loopvars, $parts[2]); 247 248 $repl="<?php \$PHORUM[\"DATA\"]['$parts[1]']=\$PHORUM['$index']['$parts[2]']; ?>"; 249 } 250 break; 251 252 253 // this is just for echoing vars from DATA or TMP if it is a loopvar 254 default: 255 256 if(defined($parts[0])){ 257 $repl="<?php echo $parts[0]; ?>"; 258 } else { 259 260 $index=phorum_determine_index($loopvars, $parts[0]); 261 262 $repl="<?php echo \$PHORUM['$index']['$parts[0]']; ?>"; 263 } 264 } 265 266 $page=str_replace($match, $repl, $page); 267 } 268 269 $include_level--; 270 271 // Did we finish processing our top level template? Then write out 272 // the compiled template to the cache. 273 // 274 // For storing the compiled template, we use two files. The first one 275 // has some code for checking if one of the dependant files has been 276 // updated and for rebuilding the template if this is the case. 277 // This one loads the second file, which is the template itself. 278 // 279 // This two-stage loading is needed to make sure that syntax 280 // errors in a template file won't break the depancy checking process. 281 // If both were in the same file, the complete file would not be run 282 // at all and the user would have to clean out the template cache to 283 // reload the template once it was fixed. This way user intervention 284 // is never needed. 285 if ($include_level == 0) 286 { 287 // Find the template name for the top level template. 288 $pathparts = preg_split('[\\/]', $outfile); 289 $fileparts = explode('-', preg_replace('/^.*\//', '', $pathparts[count($pathparts)-1])); 290 $this_template = addslashes($fileparts[2]); 291 292 // Determine first and second stage cache filenames. 293 $stage1_file = $outfile; 294 $fileparts[3] = "toplevel_stage2"; 295 unset($pathparts[count($pathparts)-1]); 296 $stage2_file = implode('/', $pathparts) . '/' . implode('-', $fileparts); 297 298 // Create code for automatic rebuilding of rendered templates 299 // in case of changes. This is done by checking if one of the 300 // templates in the dependancy list has been updated. If this 301 // is the case, all dependant rendered subtemplates are deleted. 302 // After that phorum_get_template() is called on the top level 303 // template to rebuild all needed templates. 304 305 $check_deps = 306 "<?php\n" . 307 "\$need_update = (\n" . 308 " !file_exists(\"".addslashes($stage2_file)."\") ||\n"; 309 310 foreach ($include_deps as $tpl => $info) { 311 list ($out, $mtime) = $info; 312 $qtpl = addslashes($tpl); 313 $check_deps .= " @filemtime(\"$qtpl\") != $mtime ||\n"; 314 } 315 $check_deps = substr($check_deps, 0, -4); // strip trailing " ||\n" 316 $check_deps .= 317 "\n" . 318 ");\n" . 319 "if (\$need_update) {\n"; 320 foreach ($include_deps as $tpl => $info) { 321 list ($out, $mtime) = $info; 322 $qout = addslashes($out); 323 $check_deps .= " @unlink(\"$qout\");\n"; 324 } 325 $use_template = $tplname == NULL ? $this_template : $tplname; 326 $check_deps .= 327 " \$tplfile = phorum_get_template(\"$use_template\");\n" . 328 "}\n" . 329 "include(\"" . addslashes($stage2_file) . "\");\n" . 330 "?>\n"; 331 332 // Reset dependancy list for the next phorum_import_template() call. 333 $include_deps = array(); 334 335 // Write out data to the cache. 336 phorum_write_templatefile($stage1_file, $check_deps); 337 phorum_write_templatefile($stage2_file, $page, true); 338 } 339 else 340 { 341 // Write out subtemplate to the cache. 342 phorum_write_templatefile($outfile, $page); 343 } 344 345 346 } 347 348 function phorum_write_templatefile($filename, $content, $is_toplevel = false) 349 { 350 if($fp=fopen($filename, "w")) { 351 fputs($fp, "<?php if(!defined(\"PHORUM\")) return; ?>\n"); 352 if ($is_toplevel) { 353 fputs($fp, "<?php \$phorum_loopstack = array() ?>\n"); 354 } 355 fputs($fp, $content); 356 if (! fclose($fp)) { 357 die("Error on closing $filename. Is your disk full?"); 358 } 359 // Some very unusual thing might happen. On Windows2000 we have seen 360 // that the webserver can write a message to the cache directory, 361 // but that it cannot read it afterwards. Probably due to 362 // specific NTFS file permission settings. So here we have to make 363 // sure that we can open the file that we just wrote. 364 $checkfp = fopen($filename, "r"); 365 if (! $checkfp) { 366 die("Failed to write a usable compiled template to $filename. " . 367 "The file was was created successfully, but it could not " . 368 "be read by the webserver afterwards. This is probably " . 369 "caused by the file permissions on your cache directory."); 370 } 371 fclose($checkfp); 372 } else { 373 die("Failed to write a compiled template to $filename. This is " . 374 "probably caused by the file permissions on your cache " . 375 "directory."); 376 } 377 } 378 379 function phorum_determine_index($loopvars, $varname) 380 { 381 if(isset($loopvars) && count($loopvars)){ 382 while(strstr($varname, "]")){ 383 $varname=substr($varname, 0, strrpos($varname, "]")-1); 384 if(isset($loopvars[$varname])){ 385 return "TMP"; 386 break; 387 } 388 } 389 } 390 391 return "DATA"; 392 } 393 394 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Thu Nov 29 12:22:27 2007 | par Balluche grâce à PHPXref 0.7 |
|