ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
IT.php
Go to the documentation of this file.
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 include_once("./Services/UICore/lib/html-it/exceptions/class.ilTemplateException.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);
125 {
132  public $err = array();
133 
138  public $clearCache = false;
139 
146  public $openingDelimiter = '{';
147 
154  public $closingDelimiter = '}';
155 
164  public $blocknameRegExp = '[\.0-9A-Za-z_-]+';
165 
174  public $variablenameRegExp = '[\.0-9A-Za-z_-]+';
175 
182  public $variablesRegExp = '';
183 
189 
195  public $removeUnknownVariables = true;
196 
202  public $removeEmptyBlocks = true;
203 
209  public $blockRegExp = '';
210 
215  public $currentBlock = '__global__';
216 
221  public $template = '';
222 
229  public $blocklist = array();
230 
236  public $blockdata = array();
237 
242  public $blockvariables = array();
243 
244  public $blockparents = array();
245 
250  public $blockinner = array();
251 
277  public $touchedBlocks = array();
278 
284  public $_hiddenBlocks = array();
285 
296  public $variableCache = array();
297 
307  public $clearCacheOnParse = false;
308 
315  public $fileRoot = '';
316 
321  public $flagBlocktrouble = false;
322 
327  public $flagGlobalParsed = false;
328 
341  public $flagCacheTemplatefile = true;
342 
346  public $lastTemplatefile = '';
347 
356  public $_options = array(
357  'preserve_data' => false,
358  'use_preg' => true
359  );
360 
372  public function __construct($root = '', $options = null)
373  {
374  if (!is_null($options)) {
375  $this->setOptions($options);
376  }
377  $this->variablesRegExp = '@' . $this->openingDelimiter .
378  '(' . $this->variablenameRegExp . ')' .
379  $this->closingDelimiter . '@sm';
380  $this->removeVariablesRegExp = '@' . $this->openingDelimiter .
381  "\s*(" . $this->variablenameRegExp .
382  ")\s*" . $this->closingDelimiter . '@sm';
383 
384  $this->blockRegExp = '@<!--\s+BEGIN\s+(' . $this->blocknameRegExp .
385  ')\s+-->(.*)<!--\s+END\s+\1\s+-->@sm';
386 
387  $this->setRoot($root);
388  } // end constructor
389 
390 
399  public function setOption($option, $value)
400  {
401  if (array_key_exists($option, $this->_options)) {
402  $this->_options[$option] = $value;
403  return IT_OK;
404  }
405  throw (new ilTemplateException($this->errorMessage(IT_UNKNOWN_OPTION) . ": '{$option}'"));
406  }
407 
420  public function setOptions($options)
421  {
422  if (is_array($options)) {
423  foreach ($options as $option => $value) {
424  $error = $this->setOption($option, $value);
425  }
426  }
427 
428  return IT_OK;
429  }
430 
435  public function show($block = '__global__')
436  {
437  print $this->get($block);
438  } // end func show
439 
449  public function get($block = '__global__')
450  {
451  if ($block == '__global__' && !$this->flagGlobalParsed) {
452  $this->parse('__global__');
453  }
454 
455  if (!isset($this->blocklist[$block])) {
457  '"' . $block . "'"));
458  }
459 
460  if (isset($this->blockdata[$block])) {
461  $ret = $this->blockdata[$block];
462  if ($this->clearCache) {
463  unset($this->blockdata[$block]);
464  }
465  if ($this->_options['preserve_data']) {
466  $ret = str_replace(
467  $this->openingDelimiter .
468  '%preserved%' . $this->closingDelimiter,
469  $this->openingDelimiter,
470  $ret
471  );
472  }
473  return $ret;
474  }
475 
476  return '';
477  } // end func get()
478 
487  public function parse($block = '__global__', $flag_recursion = false)
488  {
489  static $regs, $values;
490 
491  if (!isset($this->blocklist[$block])) {
493  '"' . $block . "'"));
494  }
495 
496  if ($block == '__global__') {
497  $this->flagGlobalParsed = true;
498  }
499 
500  if (!$flag_recursion) {
501  $regs = array();
502  $values = array();
503  }
504  $outer = $this->blocklist[$block];
505  $empty = true;
506 
507  if ($this->clearCacheOnParse) {
508  foreach ($this->variableCache as $name => $value) {
509  $regs[] = $this->openingDelimiter .
511  $values[] = $value;
512  $empty = false;
513  }
514  $this->variableCache = array();
515  } else {
516  foreach ($this->blockvariables[$block] as $allowedvar => $v) {
517  if (isset($this->variableCache[$allowedvar])) {
518  $regs[] = $this->openingDelimiter .
519  $allowedvar . $this->closingDelimiter;
520  $values[] = $this->variableCache[$allowedvar];
521  unset($this->variableCache[$allowedvar]);
522  $empty = false;
523  }
524  }
525  }
526 
527  if (isset($this->blockinner[$block])) {
528  foreach ($this->blockinner[$block] as $k => $innerblock) {
529  $this->parse($innerblock, true);
530  if ($this->blockdata[$innerblock] != '') {
531  $empty = false;
532  }
533 
534  $placeholder = $this->openingDelimiter . "__" .
535  $innerblock . "__" . $this->closingDelimiter;
536  $outer = str_replace(
537  $placeholder,
538  $this->blockdata[$innerblock],
539  $outer
540  );
541  $this->blockdata[$innerblock] = "";
542  }
543  }
544 
545  if (!$flag_recursion && 0 != count($values)) {
546  if ($this->_options['use_preg']) {
547  $regs = array_map(
548  array(
549  &$this, '_addPregDelimiters'),
550  $regs
551  );
552  $funcReplace = 'preg_replace';
553  } else {
554  $funcReplace = 'str_replace';
555  }
556 
557  if ($this->_options['preserve_data']) {
558  $values = array_map(
559  array(&$this, '_preserveOpeningDelimiter'),
560  $values
561  );
562  }
563 
564  $outer = $funcReplace($regs, $values, $outer);
565 
566  if ($this->removeUnknownVariables) {
567  $outer = preg_replace($this->removeVariablesRegExp, "", $outer);
568  }
569  }
570 
571  if ($empty) {
572  if (!$this->removeEmptyBlocks) {
573  $this->blockdata[$block ] .= $outer;
574  } else {
575  if (isset($this->touchedBlocks[$block])) {
576  $this->blockdata[$block] .= $outer;
577  unset($this->touchedBlocks[$block]);
578  }
579  }
580  } else {
581  if (empty($this->blockdata[$block])) {
582  $this->blockdata[$block] = $outer;
583  } else {
584  $this->blockdata[$block] .= $outer;
585  }
586  }
587 
588  return $empty;
589  } // end func parse
590 
596  public function parseCurrentBlock()
597  {
598  return $this->parse($this->currentBlock);
599  } // end func parseCurrentBlock
600 
615  public function setVariable($variable, $value = '')
616  {
617  if (is_array($variable)) {
618  $this->variableCache = array_merge(
619  $this->variableCache,
620  $variable
621  );
622  } else {
623  $this->variableCache[$variable] = $value;
624  }
625  } // end func setVariable
626 
636  public function setCurrentBlock($block = '__global__')
637  {
638  if (!isset($this->blocklist[$block])) {
640  '"' . $block . "'"));
641  }
642 
643  $this->currentBlock = $block;
644 
645  return true;
646  } // end func setCurrentBlock
647 
657  public function touchBlock($block)
658  {
659  if (!isset($this->blocklist[$block])) {
661  '"' . $block . "'"));
662  }
663 
664  $this->touchedBlocks[$block] = true;
665 
666  return true;
667  } // end func touchBlock
668 
679  protected function init()
680  {
681  $this->free();
682  require_once('./Services/GlobalCache/classes/class.ilGlobalCache.php');
684 
685  if ($blockdata = $blocks->get($this->real_filename)) {
686  $this->blockdata = $blockdata['blockdata'];
687  $this->blocklist = $blockdata['blocklist'];
688  } else {
690  $this->findBlocks($this->template);
691  $blockdata['blockdata'] = $this->blockdata;
692  $blockdata['blocklist'] = $this->blocklist;
693  $blocks->set($this->real_filename, $blockdata, 60);
694  }
695 
696  // we don't need it any more
697  $this->template = '';
698 
700  if ($blockvariables = $variables->get($this->real_filename)) {
701  $this->blockvariables = $blockvariables;
702  } else {
703  $this->buildBlockvariablelist();
704  $variables->set($this->real_filename, $this->blockvariables, 60);
705  }
706  } // end func init
707 
716  public function free()
717  {
718  $this->err = array();
719 
720  $this->currentBlock = '__global__';
721 
722  $this->variableCache = array();
723  $this->blocklist = array();
724  $this->touchedBlocks = array();
725 
726  $this->flagBlocktrouble = false;
727  $this->flagGlobalParsed = false;
728  } // end func free
729 
743  public function setTemplate(
744  $template,
746  $removeEmptyBlocks = true
747  ) {
748  $this->removeUnknownVariables = $removeUnknownVariables;
749  $this->removeEmptyBlocks = $removeEmptyBlocks;
750 
751  if ($template == '' && $this->flagCacheTemplatefile) {
752  $this->variableCache = array();
753  $this->blockdata = array();
754  $this->touchedBlocks = array();
755  $this->currentBlock = '__global__';
756  } else {
757  $this->template = '<!-- BEGIN __global__ -->' . $template .
758  '<!-- END __global__ -->';
759  $this->init();
760  }
761 
762  if ($this->flagBlocktrouble) {
763  return false;
764  }
765 
766  return true;
767  } // end func setTemplate
768 
780  public function loadTemplatefile(
781  $filename,
783  $removeEmptyBlocks = true
784  ) {
785  $template = '';
786  if (!$this->flagCacheTemplatefile ||
787  $this->lastTemplatefile != $filename
788  ) {
789  $template = $this->getFile($filename);
790  }
791  $this->lastTemplatefile = $filename;
792 
793  return $template != '' ?
794  $this->setTemplate(
795  $template,
798  ) : false;
799  } // end func LoadTemplatefile
800 
812  public function setRoot($root)
813  {
814  if ($root != '' && substr($root, -1) != '/') {
815  $root .= '/';
816  }
817 
818  $this->fileRoot = $root;
819  } // end func setRoot
820 
824  public function buildBlockvariablelist()
825  {
826  foreach ($this->blocklist as $name => $content) {
827  preg_match_all($this->variablesRegExp, $content, $regs);
828 
829  if (count($regs[1]) != 0) {
830  foreach ($regs[1] as $k => $var) {
831  $this->blockvariables[$name][$var] = true;
832  }
833  } else {
834  $this->blockvariables[$name] = array();
835  }
836  }
837  } // end func buildBlockvariablelist
838 
842  public function getGlobalvariables()
843  {
844  $regs = array();
845  $values = array();
846 
847  foreach ($this->blockvariables['__global__'] as $allowedvar => $v) {
848  if (isset($this->variableCache[$allowedvar])) {
849  $regs[] = '@' . $this->openingDelimiter .
850  $allowedvar . $this->closingDelimiter . '@';
851  $values[] = $this->variableCache[$allowedvar];
852  unset($this->variableCache[$allowedvar]);
853  }
854  }
855 
856  return array($regs, $values);
857  } // end func getGlobalvariables
858 
865  public function findBlocks($string)
866  {
867  $blocklist = array();
868  if (preg_match_all($this->blockRegExp, $string, $regs, PREG_SET_ORDER)) {
869  foreach ($regs as $k => $match) {
870  $blockname = $match[1];
871  $blockcontent = $match[2];
872 
873  if (isset($this->blocklist[$blockname])) {
874  throw (new ilTemplateException($this->errorMessage(
876  $blockname
877  )));
878  }
879 
880  $this->blocklist[$blockname] = $blockcontent;
881  $this->blockdata[$blockname] = "";
882 
883  $blocklist[] = $blockname;
884 
885  $inner = $this->findBlocks($blockcontent);
886  foreach ($inner as $k => $name) {
887  $pattern = sprintf(
888  '@<!--\s+BEGIN\s+%s\s+-->(.*)<!--\s+END\s+%s\s+-->@sm',
889  $name,
890  $name
891  );
892 
893  $this->blocklist[$blockname] = preg_replace(
894  $pattern,
895  $this->openingDelimiter .
896  '__' . $name . '__' .
897  $this->closingDelimiter,
898  $this->blocklist[$blockname]
899  );
900  $this->blockinner[$blockname][] = $name;
901  $this->blockparents[$name] = $blockname;
902  }
903  }
904  }
905 
906  return $blocklist;
907  } // end func findBlocks
908 
914  public function getFile($filename)
915  {
916  if ($filename[0] == '/' && substr($this->fileRoot, -1) == '/') {
917  $filename = substr($filename, 1);
918  }
919 
920  $filename = $this->fileRoot . $filename;
921 
922  require_once('./Services/GlobalCache/classes/class.ilGlobalCache.php');
923  $this->real_filename = $filename;
925  if (!$content = $ilGlobalCache->get($filename)) {
926  if (!($fh = @fopen($filename, 'r'))) {
928  ': "' . $filename . '"'));
929  }
930 
931  $fsize = filesize($filename);
932  if ($fsize < 1) {
933  fclose($fh);
934  return '';
935  }
936 
937  $content = fread($fh, $fsize);
938  $ilGlobalCache->set($filename, $content, 60);
939  fclose($fh);
940  }
941 
942 
943  /* performance patch, 6.4.2017
944  return preg_replace_callback(
945  "#<!-- INCLUDE (.*) -->#im",
946  function ($hit) {
947  return $this->getFile($hit[1]);
948  },
949  $content
950  );*/
951 
952  return $content;
953  } // end func getFile
954 
962  public function _addPregDelimiters($str)
963  {
964  return '@' . $str . '@';
965  }
966 
973  public function _preserveOpeningDelimiter($str)
974  {
975  return (false === strpos($str, $this->openingDelimiter))?
976  $str:
977  str_replace(
978  $this->openingDelimiter,
979  $this->openingDelimiter .
980  '%preserved%' . $this->closingDelimiter,
981  $str
982  );
983  }
984 
993  public function errorMessage($value, $blockname = '')
994  {
995  static $errorMessages;
996  if (!isset($errorMessages)) {
997  $errorMessages = array(
998  IT_OK => '',
999  IT_ERROR => 'unknown error',
1000  IT_TPL_NOT_FOUND => 'Cannot read the template file',
1001  IT_BLOCK_NOT_FOUND => 'Cannot find this block',
1002  IT_BLOCK_DUPLICATE => 'The name of a block must be' .
1003  ' uniquewithin a template.' .
1004  ' Found "' . $blockname . '" twice.' .
1005  'Unpredictable results ' .
1006  'may appear.',
1007  IT_UNKNOWN_OPTION => 'Unknown option'
1008  );
1009  }
1010 
1011  return isset($errorMessages[$value]) ?
1012  $errorMessages[$value] : $errorMessages[IT_ERROR];
1013  }
1014 } // end class IntegratedTemplate
loadTemplatefile( $filename, $removeUnknownVariables=true, $removeEmptyBlocks=true)
Reads a template file from the disk.
Definition: IT.php:780
touchBlock($block)
Preserves an empty block even if removeEmptyBlocks is true.
Definition: IT.php:657
show($block='__global__')
Print a certain block with all replacements done.
Definition: IT.php:435
_addPregDelimiters($str)
Adds delimiters to a string, so it can be used as a pattern in preg_* functions.
Definition: IT.php:962
$removeVariablesRegExp
RegExp used to strip unused variable placeholder.
Definition: IT.php:188
$variablenameRegExp
Definition: IT.php:174
getGlobalvariables()
Returns a list of all global variables.
Definition: IT.php:842
static getInstance($component)
const IT_OK
Definition: IT.php:23
errorMessage($value, $blockname='')
Return a textual error message for a IT error code.
Definition: IT.php:993
$removeUnknownVariables
Definition: IT.php:195
setCurrentBlock($block='__global__')
Sets the name of the current block that is the block where variables are added.
Definition: IT.php:636
setOptions($options)
Sets the options for the template class.
Definition: IT.php:420
free()
Clears all datafields of the object.
Definition: IT.php:716
if($format !==null) $name
Definition: metadata.php:230
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:615
setRoot($root)
Sets the file root.
Definition: IT.php:812
const IT_UNKNOWN_OPTION
Definition: IT.php:28
const IT_BLOCK_NOT_FOUND
Definition: IT.php:26
$flagCacheTemplatefile
Definition: IT.php:341
$_options
$_options[&#39;preserve_data&#39;] Whether to substitute variables and remove empty placeholders in data pass...
Definition: IT.php:356
parse($block='__global__', $flag_recursion=false)
Parses the given block.
Definition: IT.php:487
$filename
Definition: buildRTE.php:89
parseCurrentBlock()
Parses the current block.
Definition: IT.php:596
buildBlockvariablelist()
Build a list of all variables within of a block.
Definition: IT.php:824
static log($message, $log_level)
$_hiddenBlocks
List of blocks which should not be shown even if not "empty".
Definition: IT.php:284
__construct($root='', $options=null)
Builds some complex regular expressions and optinally sets the file root directory.
Definition: IT.php:372
$clearCacheOnParse
Definition: IT.php:307
$removeEmptyBlocks
Definition: IT.php:202
setTemplate( $template, $removeUnknownVariables=true, $removeEmptyBlocks=true)
Sets the template.
Definition: IT.php:743
$touchedBlocks
List of blocks to preverse even if they are "empty".
Definition: IT.php:277
_preserveOpeningDelimiter($str)
Replaces an opening delimiter by a special string.
Definition: IT.php:973
$ret
Definition: parser.php:6
init()
Clears all datafields of the object and rebuild the internal blocklist.
Definition: IT.php:679
setOption($option, $value)
Sets the option for the template class.
Definition: IT.php:399
const IT_BLOCK_DUPLICATE
Definition: IT.php:27
findBlocks($string)
Recusively builds a list of all blocks within the template.
Definition: IT.php:865
$lastTemplatefile
EXPERIMENTAL! FIXME!
Definition: IT.php:346
const IT_ERROR
Definition: IT.php:24
const IT_TPL_NOT_FOUND
Definition: IT.php:25
getFile($filename)
Reads a file from disk and returns its content.
Definition: IT.php:914
Integrated Template - IT.