[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/HTML/Template/ -> IT.php (source)

   1  <?php
   2  //
   3  // +----------------------------------------------------------------------+
   4  // | Copyright (c) 1997-2005 Ulf Wendel, Pierre-Alain Joye                |
   5  // +----------------------------------------------------------------------+
   6  // | This source file is subject to the New BSD license, That is bundled  |
   7  // | with this package in the file LICENSE, and is available through      |
   8  // | the world-wide-web at                                                |
   9  // | http://www.opensource.org/licenses/bsd-license.php                   |
  10  // | If you did not receive a copy of the new BSDlicense and are unable   |
  11  // | to obtain it through the world-wide-web, please send a note to       |
  12  // | pajoye@php.net so we can mail you a copy immediately.                |
  13  // +----------------------------------------------------------------------+
  14  // | Author: Ulf Wendel <ulf.wendel@phpdoc.de>                            |
  15  // |         Pierre-Alain Joye <pajoye@php.net>                           |
  16  // +----------------------------------------------------------------------+
  17  //
  18  // $Id: IT.php,v 1.20 2006/08/17 15:47:22 dsp Exp $
  19  //
  20  
  21  require_once  'PEAR.php';
  22  
  23  define('IT_OK',                         1);
  24  define('IT_ERROR',                     -1);
  25  define('IT_TPL_NOT_FOUND',             -2);
  26  define('IT_BLOCK_NOT_FOUND',           -3);
  27  define('IT_BLOCK_DUPLICATE',           -4);
  28  define('IT_UNKNOWN_OPTION',            -6);
  29  /**
  30   * Integrated Template - IT
  31   *
  32   * Well there's not much to say about it. I needed a template class that
  33   * supports a single template file with multiple (nested) blocks inside and
  34   * a simple block API.
  35   *
  36   * The Isotemplate API is somewhat tricky for a beginner although it is the best
  37   * one you can build. template::parse() [phplib template = Isotemplate] requests
  38   * you to name a source and a target where the current block gets parsed into.
  39   * Source and target can be block names or even handler names. This API gives you
  40   * a maximum of fexibility but you always have to know what you do which is
  41   * quite unusual for php skripter like me.
  42   *
  43   * I noticed that I do not any control on which block gets parsed into which one.
  44   * If all blocks are within one file, the script knows how they are nested and in
  45   * which way you have to parse them. IT knows that inner1 is a child of block2, there's
  46   * no need to tell him about this.
  47   *
  48   * <table border>
  49   *   <tr>
  50   *     <td colspan=2>
  51   *       __global__
  52   *       <p>
  53   *       (hidden and automatically added)
  54   *     </td>
  55   *   </tr>
  56   *   <tr>
  57   *     <td>block1</td>
  58   *     <td>
  59   *       <table border>
  60   *         <tr>
  61   *           <td colspan=2>block2</td>
  62   *         </tr>
  63   *         <tr>
  64   *           <td>inner1</td>
  65   *           <td>inner2</td>
  66   *         </tr>
  67   *       </table>
  68   *     </td>
  69   *   </tr>
  70   * </table>
  71   *
  72   * To add content to block1 you simply type:
  73   * <code>$tpl->setCurrentBlock("block1");</code>
  74   * and repeat this as often as needed:
  75   * <code>
  76   *   $tpl->setVariable(...);
  77   *   $tpl->parseCurrentBlock();
  78   * </code>
  79   *
  80   * To add content to block2 you would type something like:
  81   * <code>
  82   * $tpl->setCurrentBlock("inner1");
  83   * $tpl->setVariable(...);
  84   * $tpl->parseCurrentBlock();
  85   *
  86   * $tpl->setVariable(...);
  87   * $tpl->parseCurrentBlock();
  88   *
  89   * $tpl->parse("block1");
  90   * </code>
  91   *
  92   * This will result in one repition of block1 which contains two repitions
  93   * of inner1. inner2 will be removed if $removeEmptyBlock is set to true which is the default.
  94   *
  95   * Usage:
  96   * <code>
  97   * $tpl = new HTML_Template_IT( [string filerootdir] );
  98   *
  99   * // load a template or set it with setTemplate()
 100   * $tpl->loadTemplatefile( string filename [, boolean removeUnknownVariables, boolean removeEmptyBlocks] )
 101   *
 102   * // set "global" Variables meaning variables not beeing within a (inner) block
 103   * $tpl->setVariable( string variablename, mixed value );
 104   *
 105   * // like with the Isotemplates there's a second way to use setVariable()
 106   * $tpl->setVariable( array ( string varname => mixed value ) );
 107   *
 108   * // Let's use any block, even a deeply nested one
 109   * $tpl->setCurrentBlock( string blockname );
 110   *
 111   * // repeat this as often as you need it.
 112   * $tpl->setVariable( array ( string varname => mixed value ) );
 113   * $tpl->parseCurrentBlock();
 114   *
 115   * // get the parsed template or print it: $tpl->show()
 116   * $tpl->get();
 117   * </code>
 118   *
 119   * @author   Ulf Wendel <uw@netuse.de>
 120   * @version  $Id: IT.php,v 1.20 2006/08/17 15:47:22 dsp Exp $
 121   * @access   public
 122   * @package  HTML_Template_IT
 123   */
 124  class HTML_Template_IT
 125  {
 126      /**
 127       * Contains the error objects
 128       * @var      array
 129       * @access   public
 130       * @see      halt(), $printError, $haltOnError
 131       */
 132      var $err = array();
 133  
 134      /**
 135       * Clear cache on get()?
 136       * @var      boolean
 137       */
 138      var $clearCache = false;
 139  
 140      /**
 141       * First character of a variable placeholder ( _{_VARIABLE} ).
 142       * @var      string
 143       * @access   public
 144       * @see      $closingDelimiter, $blocknameRegExp, $variablenameRegExp
 145       */
 146      var $openingDelimiter = '{';
 147  
 148      /**
 149       * Last character of a variable placeholder ( {VARIABLE_}_ ).
 150       * @var      string
 151       * @access   public
 152       * @see      $openingDelimiter, $blocknameRegExp, $variablenameRegExp
 153       */
 154      var $closingDelimiter     = '}';
 155  
 156      /**
 157       * RegExp matching a block in the template.
 158       * Per default "sm" is used as the regexp modifier, "i" is missing.
 159       * That means a case sensitive search is done.
 160       * @var      string
 161       * @access   public
 162       * @see      $variablenameRegExp, $openingDelimiter, $closingDelimiter
 163       */
 164      var $blocknameRegExp    = '[\.0-9A-Za-z_-]+';
 165  
 166      /**
 167       * RegExp matching a variable placeholder in the template.
 168       * Per default "sm" is used as the regexp modifier, "i" is missing.
 169       * That means a case sensitive search is done.
 170       * @var      string
 171       * @access   public
 172       * @see      $blocknameRegExp, $openingDelimiter, $closingDelimiter
 173       */
 174      var $variablenameRegExp    = '[\.0-9A-Za-z_-]+';
 175  
 176      /**
 177       * RegExp used to find variable placeholder, filled by the constructor.
 178       * @var      string    Looks somewhat like @(delimiter varname delimiter)@
 179       * @access   public
 180       * @see      IntegratedTemplate()
 181       */
 182      var $variablesRegExp = '';
 183  
 184      /**
 185       * RegExp used to strip unused variable placeholder.
 186       * @brother  $variablesRegExp
 187       */
 188      var $removeVariablesRegExp = '';
 189  
 190      /**
 191       * Controls the handling of unknown variables, default is remove.
 192       * @var      boolean
 193       * @access   public
 194       */
 195      var $removeUnknownVariables = true;
 196  
 197      /**
 198       * Controls the handling of empty blocks, default is remove.
 199       * @var      boolean
 200       * @access   public
 201       */
 202      var $removeEmptyBlocks = true;
 203  
 204      /**
 205       * RegExp used to find blocks an their content, filled by the constructor.
 206       * @var      string
 207       * @see      IntegratedTemplate()
 208       */
 209      var $blockRegExp = '';
 210  
 211      /**
 212       * Name of the current block.
 213       * @var      string
 214       */
 215      var $currentBlock = '__global__';
 216  
 217      /**
 218       * Content of the template.
 219       * @var      string
 220       */
 221      var $template = '';
 222  
 223      /**
 224       * Array of all blocks and their content.
 225       *
 226       * @var      array
 227       * @see      findBlocks()
 228       */
 229      var $blocklist = array();
 230  
 231      /**
 232       * Array with the parsed content of a block.
 233       *
 234       * @var      array
 235       */
 236      var $blockdata = array();
 237  
 238      /**
 239       * Array of variables in a block.
 240       * @var      array
 241       */
 242      var $blockvariables = array();
 243  
 244      /**
 245       * Array of inner blocks of a block.
 246       * @var      array
 247       */
 248      var $blockinner = array();
 249  
 250      /**
 251       * List of blocks to preverse even if they are "empty".
 252       *
 253       * This is something special. Sometimes you have blocks that
 254       * should be preserved although they are empty (no placeholder replaced).
 255       * Think of a shopping basket. If it's empty you have to drop a message to
 256       * the user. If it's filled you have to show the contents of
 257       * the shopping baseket. Now where do you place the message that the basket
 258       * is empty? It's no good idea to place it in you applications as customers
 259       * tend to like unecessary minor text changes. Having another template file
 260       * for an empty basket means that it's very likely that one fine day
 261       * the filled and empty basket templates have different layout. I decided
 262       * to introduce blocks that to not contain any placeholder but only
 263       * text such as the message "Your shopping basked is empty".
 264       *
 265       * Now if there is no replacement done in such a block the block will
 266       * be recognized as "empty" and by default ($removeEmptyBlocks = true) be
 267       * stripped off. To avoid thisyou can now call touchBlock() to avoid this.
 268       *
 269       * The array $touchedBlocks stores a list of touched block which must not
 270       * be removed even if they are empty.
 271       *
 272       * @var  array    $touchedBlocks
 273       * @see  touchBlock(), $removeEmptyBlocks
 274       */
 275       var $touchedBlocks = array();
 276  
 277      /**
 278       * List of blocks which should not be shown even if not "empty"
 279       * @var  array    $_hiddenBlocks
 280       * @see  hideBlock(), $removeEmptyBlocks
 281       */
 282      var $_hiddenBlocks = array();
 283  
 284      /**
 285       * Variable cache.
 286       *
 287       * Variables get cached before any replacement is done.
 288       * Advantage: empty blocks can be removed automatically.
 289       * Disadvantage: might take some more memory
 290       *
 291       * @var    array
 292       * @see    setVariable(), $clearCacheOnParse
 293       */
 294      var $variableCache = array();
 295  
 296      /**
 297       * Clear the variable cache on parse?
 298       *
 299       * If you're not an expert just leave the default false.
 300       * True reduces memory consumption somewhat if you tend to
 301       * add lots of values for unknown placeholder.
 302       *
 303       * @var    boolean
 304       */
 305      var $clearCacheOnParse = false;
 306  
 307      /**
 308       * Root directory for all file operations.
 309       * The string gets prefixed to all filenames given.
 310       * @var    string
 311       * @see    HTML_Template_IT(), setRoot()
 312       */
 313      var $fileRoot = '';
 314  
 315      /**
 316       * Internal flag indicating that a blockname was used multiple times.
 317       * @var    boolean
 318       */
 319      var $flagBlocktrouble = false;
 320  
 321      /**
 322       * Flag indicating that the global block was parsed.
 323       * @var    boolean
 324       */
 325      var $flagGlobalParsed = false;
 326  
 327      /**
 328       * EXPERIMENTAL! FIXME!
 329       * Flag indication that a template gets cached.
 330       *
 331       * Complex templates require some times to be preparsed
 332       * before the replacement can take place. Often I use
 333       * one template file over and over again but I don't know
 334       * before that I will use the same template file again.
 335       * Now IT could notice this and skip the preparse.
 336       *
 337       * @var    boolean
 338       */
 339      var $flagCacheTemplatefile = true;
 340  
 341      /**
 342       * EXPERIMENTAL! FIXME!
 343       */
 344      var $lastTemplatefile = '';
 345  
 346      /**
 347       * $_options['preserve_data'] Whether to substitute variables and remove
 348       * empty placeholders in data passed through setVariable
 349       * (see also bugs #20199, #21951).
 350       * $_options['use_preg'] Whether to use preg_replace instead of
 351       * str_replace in parse()
 352       * (this is a backwards compatibility feature, see also bugs #21951, #20392)
 353       */
 354      var $_options = array(
 355          'preserve_data' => false,
 356          'use_preg'      => true
 357      );
 358  
 359      /**
 360       * Builds some complex regular expressions and optinally sets the
 361       * file root directory.
 362       *
 363       * Make sure that you call this constructor if you derive your template
 364       * class from this one.
 365       *
 366       * @param    string    File root directory, prefix for all filenames
 367       *                     given to the object.
 368       * @see      setRoot()
 369       */
 370      function HTML_Template_IT($root = '', $options = null)
 371      {
 372          if (!is_null($options)) {
 373              $this->setOptions($options);
 374          }
 375          $this->variablesRegExp = '@' . $this->openingDelimiter .
 376                                   '(' . $this->variablenameRegExp . ')' .
 377                                   $this->closingDelimiter . '@sm';
 378          $this->removeVariablesRegExp = '@' . $this->openingDelimiter .
 379                                         "\s*(" . $this->variablenameRegExp .
 380                                         ")\s*" . $this->closingDelimiter .'@sm';
 381  
 382          $this->blockRegExp = '@<!--\s+BEGIN\s+(' . $this->blocknameRegExp .
 383                               ')\s+-->(.*)<!--\s+END\s+\1\s+-->@sm';
 384  
 385          $this->setRoot($root);
 386      } // end constructor
 387  
 388  
 389      /**
 390       * Sets the option for the template class
 391       *
 392       * @access public
 393       * @param  string  option name
 394       * @param  mixed   option value
 395       * @return mixed   IT_OK on success, error object on failure
 396       */
 397      function setOption($option, $value)
 398      {
 399          if (array_key_exists($option, $this->_options)) {
 400              $this->_options[$option] = $value;
 401              return IT_OK;
 402          }
 403  
 404          return PEAR::raiseError(
 405                  $this->errorMessage(IT_UNKNOWN_OPTION) . ": '{$option}'",
 406                  IT_UNKNOWN_OPTION
 407              );
 408      }
 409  
 410      /**
 411       * Sets the options for the template class
 412       *
 413       * @access public
 414       * @param  string  options array of options
 415       *                 default value:
 416       *                   'preserve_data' => false,
 417       *                   'use_preg'      => true
 418       * @param  mixed   option value
 419       * @return mixed   IT_OK on success, error object on failure
 420       * @see $options
 421       */
 422      function setOptions($options)
 423      {
 424          if (is_array($options)) {
 425              foreach ($options as $option => $value) {
 426                  $error = $this->setOption($option, $value);
 427                  if (PEAR::isError($error)) {
 428                      return $error;
 429                  }
 430              }
 431          }
 432  
 433          return IT_OK;
 434      }
 435  
 436      /**
 437       * Print a certain block with all replacements done.
 438       * @brother get()
 439       */
 440      function show($block = '__global__')
 441      {
 442          print $this->get($block);
 443      } // end func show
 444  
 445      /**
 446       * Returns a block with all replacements done.
 447       *
 448       * @param    string     name of the block
 449       * @return   string
 450       * @throws   PEAR_Error
 451       * @access   public
 452       * @see      show()
 453       */
 454      function get($block = '__global__')
 455      {
 456          if ($block == '__global__'  && !$this->flagGlobalParsed) {
 457              $this->parse('__global__');
 458          }
 459  
 460          if (!isset($this->blocklist[$block])) {
 461              $this->err[] = PEAR::raiseError(
 462                              $this->errorMessage(IT_BLOCK_NOT_FOUND) .
 463                              '"' . $block . "'",
 464                              IT_BLOCK_NOT_FOUND
 465                          );
 466              return '';
 467          }
 468  
 469          if (isset($this->blockdata[$block])) {
 470              $ret = $this->blockdata[$block];
 471              if ($this->clearCache) {
 472                  unset($this->blockdata[$block]);
 473              }
 474              if ($this->_options['preserve_data']) {
 475                  $ret = str_replace(
 476                          $this->openingDelimiter .
 477                          '%preserved%' . $this->closingDelimiter,
 478                          $this->openingDelimiter,
 479                          $ret
 480                      );
 481              }
 482              return $ret;
 483          }
 484  
 485          return '';
 486      } // end func get()
 487  
 488      /**
 489       * Parses the given block.
 490       *
 491       * @param    string    name of the block to be parsed
 492       * @access   public
 493       * @see      parseCurrentBlock()
 494       * @throws   PEAR_Error
 495       */
 496      function parse($block = '__global__', $flag_recursion = false)
 497      {
 498          static $regs, $values;
 499  
 500          if (!isset($this->blocklist[$block])) {
 501              return PEAR::raiseError(
 502                  $this->errorMessage( IT_BLOCK_NOT_FOUND ) . '"' . $block . "'",
 503                          IT_BLOCK_NOT_FOUND
 504                  );
 505          }
 506  
 507          if ($block == '__global__') {
 508              $this->flagGlobalParsed = true;
 509          }
 510  
 511          if (!$flag_recursion) {
 512              $regs   = array();
 513              $values = array();
 514          }
 515          $outer = $this->blocklist[$block];
 516          $empty = true;
 517  
 518          if ($this->clearCacheOnParse) {
 519              foreach ($this->variableCache as $name => $value) {
 520                  $regs[] = $this->openingDelimiter .
 521                            $name . $this->closingDelimiter;
 522                  $values[] = $value;
 523                  $empty = false;
 524              }
 525              $this->variableCache = array();
 526          } else {
 527              foreach ($this->blockvariables[$block] as $allowedvar => $v) {
 528  
 529                  if (isset($this->variableCache[$allowedvar])) {
 530                     $regs[]   = $this->openingDelimiter .
 531                                 $allowedvar . $this->closingDelimiter;
 532                     $values[] = $this->variableCache[$allowedvar];
 533                     unset($this->variableCache[$allowedvar]);
 534                     $empty = false;
 535                  }
 536              }
 537          }
 538  
 539          if (isset($this->blockinner[$block])) {
 540              foreach ($this->blockinner[$block] as $k => $innerblock) {
 541  
 542                  $this->parse($innerblock, true);
 543                  if ($this->blockdata[$innerblock] != '') {
 544                      $empty = false;
 545                  }
 546  
 547                  $placeholder = $this->openingDelimiter . "__" .
 548                                  $innerblock . "__" . $this->closingDelimiter;
 549                  $outer = str_replace(
 550                                      $placeholder,
 551                                      $this->blockdata[$innerblock], $outer
 552                          );
 553                  $this->blockdata[$innerblock] = "";
 554              }
 555  
 556          }
 557  
 558          if (!$flag_recursion && 0 != count($values)) {
 559              if ($this->_options['use_preg']) {
 560                  $regs        = array_map(array(
 561                                      &$this, '_addPregDelimiters'),
 562                                      $regs
 563                                  );
 564                  $funcReplace = 'preg_replace';
 565              } else {
 566                  $funcReplace = 'str_replace';
 567              }
 568  
 569              if ($this->_options['preserve_data']) {
 570                  $values = array_map(
 571                              array(&$this, '_preserveOpeningDelimiter'), $values
 572                          );
 573              }
 574  
 575              $outer = $funcReplace($regs, $values, $outer);
 576  
 577              if ($this->removeUnknownVariables) {
 578                  $outer = preg_replace($this->removeVariablesRegExp, "", $outer);
 579              }
 580          }
 581  
 582          if ($empty) {
 583              if (!$this->removeEmptyBlocks) {
 584                  $this->blockdata[$block ].= $outer;
 585              } else {
 586                  if (isset($this->touchedBlocks[$block])) {
 587                      $this->blockdata[$block] .= $outer;
 588                      unset($this->touchedBlocks[$block]);
 589                  }
 590              }
 591          } else {
 592              if (empty($this->blockdata[$block])) {
 593                  $this->blockdata[$block] = $outer;
 594              } else {
 595                  $this->blockdata[$block] .= $outer;
 596              }
 597          }
 598  
 599          return $empty;
 600      } // end func parse
 601  
 602      /**
 603       * Parses the current block
 604       * @see      parse(), setCurrentBlock(), $currentBlock
 605       * @access   public
 606       */
 607      function parseCurrentBlock()
 608      {
 609          return $this->parse($this->currentBlock);
 610      } // end func parseCurrentBlock
 611  
 612      /**
 613       * Sets a variable value.
 614       *
 615       * The function can be used eighter like setVariable( "varname", "value")
 616       * or with one array $variables["varname"] = "value"
 617       * given setVariable($variables) quite like phplib templates set_var().
 618       *
 619       * @param    mixed     string with the variable name or an array
 620       *                     %variables["varname"] = "value"
 621       * @param    string    value of the variable or empty if $variable
 622       *                     is an array.
 623       * @param    string    prefix for variable names
 624       * @access   public
 625       */
 626      function setVariable($variable, $value = '')
 627      {
 628          if (is_array($variable)) {
 629              $this->variableCache = array_merge(
 630                                              $this->variableCache, $variable
 631                                      );
 632          } else {
 633              $this->variableCache[$variable] = $value;
 634          }
 635      } // end func setVariable
 636  
 637      /**
 638       * Sets the name of the current block that is the block where variables
 639       * are added.
 640       *
 641       * @param    string      name of the block
 642       * @return   boolean     false on failure, otherwise true
 643       * @throws   PEAR_Error
 644       * @access   public
 645       */
 646      function setCurrentBlock($block = '__global__')
 647      {
 648  
 649          if (!isset($this->blocklist[$block])) {
 650              return PEAR::raiseError(
 651                  $this->errorMessage( IT_BLOCK_NOT_FOUND ) .
 652                  '"' . $block . "'", IT_BLOCK_NOT_FOUND
 653              );
 654          }
 655  
 656          $this->currentBlock = $block;
 657  
 658          return true;
 659      } // end func setCurrentBlock
 660  
 661      /**
 662       * Preserves an empty block even if removeEmptyBlocks is true.
 663       *
 664       * @param    string      name of the block
 665       * @return   boolean     false on false, otherwise true
 666       * @throws   PEAR_Error
 667       * @access   public
 668       * @see      $removeEmptyBlocks
 669       */
 670      function touchBlock($block)
 671      {
 672          if (!isset($this->blocklist[$block])) {
 673              return PEAR::raiseError(
 674                  $this->errorMessage(IT_BLOCK_NOT_FOUND) .
 675                  '"' . $block . "'", IT_BLOCK_NOT_FOUND);
 676          }
 677  
 678          $this->touchedBlocks[$block] = true;
 679  
 680          return true;
 681      } // end func touchBlock
 682  
 683      /**
 684       * Clears all datafields of the object and rebuild the internal blocklist
 685       *
 686       * LoadTemplatefile() and setTemplate() automatically call this function
 687       * when a new template is given. Don't use this function
 688       * unless you know what you're doing.
 689       *
 690       * @access   public
 691       * @see      free()
 692       */
 693      function init()
 694      {
 695          $this->free();
 696          $this->findBlocks($this->template);
 697          // we don't need it any more
 698          $this->template = '';
 699          $this->buildBlockvariablelist();
 700      } // end func init
 701  
 702      /**
 703       * Clears all datafields of the object.
 704       *
 705       * Don't use this function unless you know what you're doing.
 706       *
 707       * @access   public
 708       * @see      init()
 709       */
 710      function free()
 711      {
 712          $this->err = array();
 713  
 714          $this->currentBlock = '__global__';
 715  
 716          $this->variableCache    = array();
 717          $this->blocklist        = array();
 718          $this->touchedBlocks    = array();
 719  
 720          $this->flagBlocktrouble = false;
 721          $this->flagGlobalParsed = false;
 722      } // end func free
 723  
 724      /**
 725       * Sets the template.
 726       *
 727       * You can eighter load a template file from disk with
 728       * LoadTemplatefile() or set the template manually using this function.
 729       *
 730       * @param        string      template content
 731       * @param        boolean     remove unknown/unused variables?
 732       * @param        boolean     remove empty blocks?
 733       * @see          LoadTemplatefile(), $template
 734       * @access       public
 735       * @return       boolean
 736       */
 737      function setTemplate( $template, $removeUnknownVariables = true,
 738                            $removeEmptyBlocks = true)
 739      {
 740          $this->removeUnknownVariables = $removeUnknownVariables;
 741          $this->removeEmptyBlocks = $removeEmptyBlocks;
 742  
 743          if ($template == '' && $this->flagCacheTemplatefile) {
 744              $this->variableCache = array();
 745              $this->blockdata = array();
 746              $this->touchedBlocks = array();
 747              $this->currentBlock = '__global__';
 748          } else {
 749              $this->template = '<!-- BEGIN __global__ -->' . $template .
 750                                '<!-- END __global__ -->';
 751              $this->init();
 752          }
 753  
 754          if ($this->flagBlocktrouble) {
 755              return false;
 756          }
 757  
 758          return true;
 759      } // end func setTemplate
 760  
 761      /**
 762       * Reads a template file from the disk.
 763       *
 764       * @param    string      name of the template file
 765       * @param    bool        how to handle unknown variables.
 766       * @param    bool        how to handle empty blocks.
 767       * @access   public
 768       * @return   boolean    false on failure, otherwise true
 769       * @see      $template, setTemplate(), $removeUnknownVariables,
 770       *           $removeEmptyBlocks
 771       */
 772      function loadTemplatefile( $filename,
 773                                 $removeUnknownVariables = true,
 774                                 $removeEmptyBlocks = true )
 775      {
 776          $template = '';
 777          if (!$this->flagCacheTemplatefile ||
 778              $this->lastTemplatefile != $filename
 779          ) {
 780              $template = $this->getFile($filename);
 781          }
 782          $this->lastTemplatefile = $filename;
 783  
 784          return $template != '' ?
 785                  $this->setTemplate(
 786                          $template,$removeUnknownVariables, $removeEmptyBlocks
 787                      ) : false;
 788      } // end func LoadTemplatefile
 789  
 790      /**
 791       * Sets the file root. The file root gets prefixed to all filenames passed
 792       * to the object.
 793       *
 794       * Make sure that you override this function when using the class
 795       * on windows.
 796       *
 797       * @param    string
 798       * @see      HTML_Template_IT()
 799       * @access   public
 800       */
 801      function setRoot($root)
 802      {
 803          if ($root != '' && substr($root, -1) != '/') {
 804              $root .= '/';
 805          }
 806  
 807          $this->fileRoot = $root;
 808      } // end func setRoot
 809  
 810      /**
 811       * Build a list of all variables within of a block
 812       */
 813      function buildBlockvariablelist()
 814      {
 815          foreach ($this->blocklist as $name => $content) {
 816              preg_match_all($this->variablesRegExp, $content, $regs);
 817  
 818              if (count($regs[1]) != 0) {
 819                  foreach ($regs[1] as $k => $var) {
 820                      $this->blockvariables[$name][$var] = true;
 821                  }
 822              } else {
 823                  $this->blockvariables[$name] = array();
 824              }
 825          }
 826      } // end func buildBlockvariablelist
 827  
 828      /**
 829       * Returns a list of all global variables
 830       */
 831      function getGlobalvariables()
 832      {
 833          $regs   = array();
 834          $values = array();
 835  
 836          foreach ($this->blockvariables['__global__'] as $allowedvar => $v) {
 837              if (isset($this->variableCache[$allowedvar])) {
 838                  $regs[]   = '@' . $this->openingDelimiter .
 839                              $allowedvar . $this->closingDelimiter . '@';
 840                  $values[] = $this->variableCache[$allowedvar];
 841                  unset($this->variableCache[$allowedvar]);
 842              }
 843          }
 844  
 845          return array($regs, $values);
 846      } // end func getGlobalvariables
 847  
 848      /**
 849       * Recusively builds a list of all blocks within the template.
 850       *
 851       * @param    string    string that gets scanned
 852       * @see      $blocklist
 853       */
 854      function findBlocks($string)
 855      {
 856          $blocklist = array();
 857  
 858          if (preg_match_all($this->blockRegExp, $string, $regs, PREG_SET_ORDER)) {
 859              foreach ($regs as $k => $match) {
 860                  $blockname         = $match[1];
 861                  $blockcontent = $match[2];
 862  
 863                  if (isset($this->blocklist[$blockname])) {
 864                      $this->err[] = PEAR::raiseError(
 865                                              $this->errorMessage(
 866                                              IT_BLOCK_DUPLICATE, $blockname),
 867                                              IT_BLOCK_DUPLICATE
 868                                      );
 869                      $this->flagBlocktrouble = true;
 870                  }
 871  
 872                  $this->blocklist[$blockname] = $blockcontent;
 873                  $this->blockdata[$blockname] = "";
 874  
 875                  $blocklist[] = $blockname;
 876  
 877                  $inner = $this->findBlocks($blockcontent);
 878                  foreach ($inner as $k => $name) {
 879                      $pattern = sprintf(
 880                          '@<!--\s+BEGIN\s+%s\s+-->(.*)<!--\s+END\s+%s\s+-->@sm',
 881                          $name,
 882                          $name
 883                      );
 884  
 885                      $this->blocklist[$blockname] = preg_replace(
 886                                          $pattern,
 887                                          $this->openingDelimiter .
 888                                          '__' . $name . '__' .
 889                                          $this->closingDelimiter,
 890                                          $this->blocklist[$blockname]
 891                                 );
 892                      $this->blockinner[$blockname][] = $name;
 893                      $this->blockparents[$name] = $blockname;
 894                  }
 895              }
 896          }
 897  
 898          return $blocklist;
 899      } // end func findBlocks
 900  
 901      /**
 902       * Reads a file from disk and returns its content.
 903       * @param    string    Filename
 904       * @return   string    Filecontent
 905       */
 906      function getFile($filename)
 907      {
 908          if ($filename{0} == '/' && substr($this->fileRoot, -1) == '/') {
 909              $filename = substr($filename, 1);
 910          }
 911  
 912          $filename = $this->fileRoot . $filename;
 913  
 914          if (!($fh = @fopen($filename, 'r'))) {
 915              $this->err[] = PEAR::raiseError(
 916                          $this->errorMessage(IT_TPL_NOT_FOUND) .
 917                          ': "' .$filename .'"',
 918                          IT_TPL_NOT_FOUND
 919                      );
 920              return "";
 921          }
 922  
 923          $fsize = filesize($filename);
 924          if ($fsize < 1) {
 925              fclose($fh);
 926              return '';
 927          }
 928  
 929          $content = fread($fh, $fsize);
 930          fclose($fh);
 931  
 932          return preg_replace(
 933              "#<!-- INCLUDE (.*) -->#ime", "\$this->getFile('\\1')", $content
 934          );
 935      } // end func getFile
 936  
 937      /**
 938       * Adds delimiters to a string, so it can be used as a pattern
 939       * in preg_* functions
 940       *
 941       * @param string
 942       * @return string
 943       */
 944      function _addPregDelimiters($str)
 945      {
 946          return '@' . $str . '@';
 947      }
 948  
 949     /**
 950      * Replaces an opening delimiter by a special string
 951      *
 952      * @param  string
 953      * @return string
 954      */
 955      function _preserveOpeningDelimiter($str)
 956      {
 957          return (false === strpos($str, $this->openingDelimiter))?
 958                  $str:
 959                  str_replace(
 960                      $this->openingDelimiter,
 961                      $this->openingDelimiter .
 962                      '%preserved%' . $this->closingDelimiter,
 963                      $str
 964                  );
 965      }
 966  
 967      /**
 968       * Return a textual error message for a IT error code
 969       *
 970       * @param integer $value error code
 971       *
 972       * @return string error message, or false if the error code was
 973       * not recognized
 974       */
 975      function errorMessage($value, $blockname = '')
 976      {
 977          static $errorMessages;
 978          if (!isset($errorMessages)) {
 979              $errorMessages = array(
 980                  IT_OK                       => '',
 981                  IT_ERROR                    => 'unknown error',
 982                  IT_TPL_NOT_FOUND            => 'Cannot read the template file',
 983                  IT_BLOCK_NOT_FOUND          => 'Cannot find this block',
 984                  IT_BLOCK_DUPLICATE          => 'The name of a block must be'.
 985                                                 ' uniquewithin a template.'.
 986                                                 ' Found "' . $blockname . '" twice.'.
 987                                                 'Unpredictable results '.
 988                                                 'may appear.',
 989                  IT_UNKNOWN_OPTION           => 'Unknown option'
 990              );
 991          }
 992  
 993          if (PEAR::isError($value)) {
 994              $value = $value->getCode();
 995          }
 996  
 997          return isset($errorMessages[$value]) ?
 998                  $errorMessages[$value] : $errorMessages[IT_ERROR];
 999      }
1000  } // end class IntegratedTemplate
1001  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7