[ Index ]
 

Code source de Phorum 5.1.25

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/include/ -> templates.php (source)

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


Généré le : Thu Nov 29 12:22:27 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics