ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 
248  public $blockinner = array();
249 
275  public $touchedBlocks = array();
276 
282  public $_hiddenBlocks = array();
283 
294  public $variableCache = array();
295 
305  public $clearCacheOnParse = false;
306 
313  public $fileRoot = '';
314 
319  public $flagBlocktrouble = false;
320 
325  public $flagGlobalParsed = false;
326 
339  public $flagCacheTemplatefile = true;
340 
344  public $lastTemplatefile = '';
345 
354  public $_options = array(
355  'preserve_data' => false,
356  'use_preg' => true
357  );
358 
370  public function __construct($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 
397  public function setOption($option, $value)
398  {
399  if (array_key_exists($option, $this->_options)) {
400  $this->_options[$option] = $value;
401  return IT_OK;
402  }
403  throw (new ilTemplateException($this->errorMessage(IT_UNKNOWN_OPTION) . ": '{$option}'"));
404  }
405 
418  public function setOptions($options)
419  {
420  if (is_array($options)) {
421  foreach ($options as $option => $value) {
422  $error = $this->setOption($option, $value);
423  }
424  }
425 
426  return IT_OK;
427  }
428 
433  public function show($block = '__global__')
434  {
435  print $this->get($block);
436  } // end func show
437 
447  public function get($block = '__global__')
448  {
449  if ($block == '__global__' && !$this->flagGlobalParsed) {
450  $this->parse('__global__');
451  }
452 
453  if (!isset($this->blocklist[$block])) {
455  '"' . $block . "'"));
456  }
457 
458  if (isset($this->blockdata[$block])) {
459  $ret = $this->blockdata[$block];
460  if ($this->clearCache) {
461  unset($this->blockdata[$block]);
462  }
463  if ($this->_options['preserve_data']) {
464  $ret = str_replace(
465  $this->openingDelimiter .
466  '%preserved%' . $this->closingDelimiter,
467  $this->openingDelimiter,
468  $ret
469  );
470  }
471  return $ret;
472  }
473 
474  return '';
475  } // end func get()
476 
485  public function parse($block = '__global__', $flag_recursion = false)
486  {
487  static $regs, $values;
488 
489  if (!isset($this->blocklist[$block])) {
491  '"' . $block . "'"));
492  }
493 
494  if ($block == '__global__') {
495  $this->flagGlobalParsed = true;
496  }
497 
498  if (!$flag_recursion) {
499  $regs = array();
500  $values = array();
501  }
502  $outer = $this->blocklist[$block];
503  $empty = true;
504 
505  if ($this->clearCacheOnParse) {
506  foreach ($this->variableCache as $name => $value) {
507  $regs[] = $this->openingDelimiter .
509  $values[] = $value;
510  $empty = false;
511  }
512  $this->variableCache = array();
513  } else {
514  foreach ($this->blockvariables[$block] as $allowedvar => $v) {
515  if (isset($this->variableCache[$allowedvar])) {
516  $regs[] = $this->openingDelimiter .
517  $allowedvar . $this->closingDelimiter;
518  $values[] = $this->variableCache[$allowedvar];
519  unset($this->variableCache[$allowedvar]);
520  $empty = false;
521  }
522  }
523  }
524 
525  if (isset($this->blockinner[$block])) {
526  foreach ($this->blockinner[$block] as $k => $innerblock) {
527  $this->parse($innerblock, true);
528  if ($this->blockdata[$innerblock] != '') {
529  $empty = false;
530  }
531 
532  $placeholder = $this->openingDelimiter . "__" .
533  $innerblock . "__" . $this->closingDelimiter;
534  $outer = str_replace(
535  $placeholder,
536  $this->blockdata[$innerblock],
537  $outer
538  );
539  $this->blockdata[$innerblock] = "";
540  }
541  }
542 
543  if (!$flag_recursion && 0 != count($values)) {
544  if ($this->_options['use_preg']) {
545  $regs = array_map(
546  array(
547  &$this, '_addPregDelimiters'),
548  $regs
549  );
550  $funcReplace = 'preg_replace';
551  } else {
552  $funcReplace = 'str_replace';
553  }
554 
555  if ($this->_options['preserve_data']) {
556  $values = array_map(
557  array(&$this, '_preserveOpeningDelimiter'),
558  $values
559  );
560  }
561 
562  $outer = $funcReplace($regs, $values, $outer);
563 
564  if ($this->removeUnknownVariables) {
565  $outer = preg_replace($this->removeVariablesRegExp, "", $outer);
566  }
567  }
568 
569  if ($empty) {
570  if (!$this->removeEmptyBlocks) {
571  $this->blockdata[$block ] .= $outer;
572  } else {
573  if (isset($this->touchedBlocks[$block])) {
574  $this->blockdata[$block] .= $outer;
575  unset($this->touchedBlocks[$block]);
576  }
577  }
578  } else {
579  if (empty($this->blockdata[$block])) {
580  $this->blockdata[$block] = $outer;
581  } else {
582  $this->blockdata[$block] .= $outer;
583  }
584  }
585 
586  return $empty;
587  } // end func parse
588 
594  public function parseCurrentBlock()
595  {
596  return $this->parse($this->currentBlock);
597  } // end func parseCurrentBlock
598 
613  public function setVariable($variable, $value = '')
614  {
615  if (is_array($variable)) {
616  $this->variableCache = array_merge(
617  $this->variableCache,
618  $variable
619  );
620  } else {
621  $this->variableCache[$variable] = $value;
622  }
623  } // end func setVariable
624 
634  public function setCurrentBlock($block = '__global__')
635  {
636  if (!isset($this->blocklist[$block])) {
638  '"' . $block . "'"));
639  }
640 
641  $this->currentBlock = $block;
642 
643  return true;
644  } // end func setCurrentBlock
645 
655  public function touchBlock($block)
656  {
657  if (!isset($this->blocklist[$block])) {
659  '"' . $block . "'"));
660  }
661 
662  $this->touchedBlocks[$block] = true;
663 
664  return true;
665  } // end func touchBlock
666 
677  public function init()
678  {
679  $this->free();
680  require_once('./Services/GlobalCache/classes/class.ilGlobalCache.php');
682 
683  if ($blockdata = $blocks->get($this->real_filename)) {
684  $this->blockdata = $blockdata['blockdata'];
685  $this->blocklist = $blockdata['blocklist'];
686  } else {
688  $this->findBlocks($this->template);
689  $blockdata['blockdata'] = $this->blockdata;
690  $blockdata['blocklist'] = $this->blocklist;
691  $blocks->set($this->real_filename, $blockdata, 60);
692  }
693 
694  // we don't need it any more
695  $this->template = '';
696 
698  if ($blockvariables = $variables->get($this->real_filename)) {
699  $this->blockvariables = $blockvariables;
700  } else {
701  $this->buildBlockvariablelist();
702  $variables->set($this->real_filename, $this->blockvariables, 60);
703  }
704  } // end func init
705 
714  public function free()
715  {
716  $this->err = array();
717 
718  $this->currentBlock = '__global__';
719 
720  $this->variableCache = array();
721  $this->blocklist = array();
722  $this->touchedBlocks = array();
723 
724  $this->flagBlocktrouble = false;
725  $this->flagGlobalParsed = false;
726  } // end func free
727 
741  public function setTemplate(
742  $template,
744  $removeEmptyBlocks = true
745  ) {
746  $this->removeUnknownVariables = $removeUnknownVariables;
747  $this->removeEmptyBlocks = $removeEmptyBlocks;
748 
749  if ($template == '' && $this->flagCacheTemplatefile) {
750  $this->variableCache = array();
751  $this->blockdata = array();
752  $this->touchedBlocks = array();
753  $this->currentBlock = '__global__';
754  } else {
755  $this->template = '<!-- BEGIN __global__ -->' . $template .
756  '<!-- END __global__ -->';
757  $this->init();
758  }
759 
760  if ($this->flagBlocktrouble) {
761  return false;
762  }
763 
764  return true;
765  } // end func setTemplate
766 
778  public function loadTemplatefile(
779  $filename,
781  $removeEmptyBlocks = true
782  ) {
783  $template = '';
784  if (!$this->flagCacheTemplatefile ||
785  $this->lastTemplatefile != $filename
786  ) {
787  $template = $this->getFile($filename);
788  }
789  $this->lastTemplatefile = $filename;
790 
791  return $template != '' ?
792  $this->setTemplate(
793  $template,
796  ) : false;
797  } // end func LoadTemplatefile
798 
810  public function setRoot($root)
811  {
812  if ($root != '' && substr($root, -1) != '/') {
813  $root .= '/';
814  }
815 
816  $this->fileRoot = $root;
817  } // end func setRoot
818 
822  public function buildBlockvariablelist()
823  {
824  foreach ($this->blocklist as $name => $content) {
825  preg_match_all($this->variablesRegExp, $content, $regs);
826 
827  if (count($regs[1]) != 0) {
828  foreach ($regs[1] as $k => $var) {
829  $this->blockvariables[$name][$var] = true;
830  }
831  } else {
832  $this->blockvariables[$name] = array();
833  }
834  }
835  } // end func buildBlockvariablelist
836 
840  public function getGlobalvariables()
841  {
842  $regs = array();
843  $values = array();
844 
845  foreach ($this->blockvariables['__global__'] as $allowedvar => $v) {
846  if (isset($this->variableCache[$allowedvar])) {
847  $regs[] = '@' . $this->openingDelimiter .
848  $allowedvar . $this->closingDelimiter . '@';
849  $values[] = $this->variableCache[$allowedvar];
850  unset($this->variableCache[$allowedvar]);
851  }
852  }
853 
854  return array($regs, $values);
855  } // end func getGlobalvariables
856 
863  public function findBlocks($string)
864  {
865  $blocklist = array();
866  if (preg_match_all($this->blockRegExp, $string, $regs, PREG_SET_ORDER)) {
867  foreach ($regs as $k => $match) {
868  $blockname = $match[1];
869  $blockcontent = $match[2];
870 
871  if (isset($this->blocklist[$blockname])) {
872  throw (new ilTemplateException($this->errorMessage(
874  $blockname
875  )));
876  }
877 
878  $this->blocklist[$blockname] = $blockcontent;
879  $this->blockdata[$blockname] = "";
880 
881  $blocklist[] = $blockname;
882 
883  $inner = $this->findBlocks($blockcontent);
884  foreach ($inner as $k => $name) {
885  $pattern = sprintf(
886  '@<!--\s+BEGIN\s+%s\s+-->(.*)<!--\s+END\s+%s\s+-->@sm',
887  $name,
888  $name
889  );
890 
891  $this->blocklist[$blockname] = preg_replace(
892  $pattern,
893  $this->openingDelimiter .
894  '__' . $name . '__' .
895  $this->closingDelimiter,
896  $this->blocklist[$blockname]
897  );
898  $this->blockinner[$blockname][] = $name;
899  $this->blockparents[$name] = $blockname;
900  }
901  }
902  }
903 
904  return $blocklist;
905  } // end func findBlocks
906 
912  public function getFile($filename)
913  {
914  if ($filename[0] == '/' && substr($this->fileRoot, -1) == '/') {
915  $filename = substr($filename, 1);
916  }
917 
918  $filename = $this->fileRoot . $filename;
919 
920  require_once('./Services/GlobalCache/classes/class.ilGlobalCache.php');
921  $this->real_filename = $filename;
923  if (!$content = $ilGlobalCache->get($filename)) {
924  if (!($fh = @fopen($filename, 'r'))) {
926  ': "' . $filename . '"'));
927  }
928 
929  $fsize = filesize($filename);
930  if ($fsize < 1) {
931  fclose($fh);
932  return '';
933  }
934 
935  $content = fread($fh, $fsize);
936  $ilGlobalCache->set($filename, $content, 60);
937  fclose($fh);
938  }
939 
940 
941  /* performance patch, 6.4.2017
942  return preg_replace_callback(
943  "#<!-- INCLUDE (.*) -->#im",
944  function ($hit) {
945  return $this->getFile($hit[1]);
946  },
947  $content
948  );*/
949 
950  return $content;
951  } // end func getFile
952 
960  public function _addPregDelimiters($str)
961  {
962  return '@' . $str . '@';
963  }
964 
971  public function _preserveOpeningDelimiter($str)
972  {
973  return (false === strpos($str, $this->openingDelimiter))?
974  $str:
975  str_replace(
976  $this->openingDelimiter,
977  $this->openingDelimiter .
978  '%preserved%' . $this->closingDelimiter,
979  $str
980  );
981  }
982 
991  public function errorMessage($value, $blockname = '')
992  {
993  static $errorMessages;
994  if (!isset($errorMessages)) {
995  $errorMessages = array(
996  IT_OK => '',
997  IT_ERROR => 'unknown error',
998  IT_TPL_NOT_FOUND => 'Cannot read the template file',
999  IT_BLOCK_NOT_FOUND => 'Cannot find this block',
1000  IT_BLOCK_DUPLICATE => 'The name of a block must be' .
1001  ' uniquewithin a template.' .
1002  ' Found "' . $blockname . '" twice.' .
1003  'Unpredictable results ' .
1004  'may appear.',
1005  IT_UNKNOWN_OPTION => 'Unknown option'
1006  );
1007  }
1008 
1009  return isset($errorMessages[$value]) ?
1010  $errorMessages[$value] : $errorMessages[IT_ERROR];
1011  }
1012 } // end class IntegratedTemplate
loadTemplatefile( $filename, $removeUnknownVariables=true, $removeEmptyBlocks=true)
Reads a template file from the disk.
Definition: IT.php:778
touchBlock($block)
Preserves an empty block even if removeEmptyBlocks is true.
Definition: IT.php:655
show($block='__global__')
Print a certain block with all replacements done.
Definition: IT.php:433
_addPregDelimiters($str)
Adds delimiters to a string, so it can be used as a pattern in preg_* functions.
Definition: IT.php:960
$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:840
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:991
$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:634
setOptions($options)
Sets the options for the template class.
Definition: IT.php:418
free()
Clears all datafields of the object.
Definition: IT.php:714
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:613
setRoot($root)
Sets the file root.
Definition: IT.php:810
const IT_UNKNOWN_OPTION
Definition: IT.php:28
$values
const IT_BLOCK_NOT_FOUND
Definition: IT.php:26
$flagCacheTemplatefile
Definition: IT.php:339
$_options
$_options[&#39;preserve_data&#39;] Whether to substitute variables and remove empty placeholders in data pass...
Definition: IT.php:354
$root
Definition: sabredav.php:45
parse($block='__global__', $flag_recursion=false)
Parses the given block.
Definition: IT.php:485
$filename
Definition: buildRTE.php:89
parseCurrentBlock()
Parses the current block.
Definition: IT.php:594
buildBlockvariablelist()
Build a list of all variables within of a block.
Definition: IT.php:822
static log($message, $log_level)
$_hiddenBlocks
List of blocks which should not be shown even if not "empty".
Definition: IT.php:282
__construct($root='', $options=null)
Builds some complex regular expressions and optinally sets the file root directory.
Definition: IT.php:370
$clearCacheOnParse
Definition: IT.php:305
$removeEmptyBlocks
Definition: IT.php:202
setTemplate( $template, $removeUnknownVariables=true, $removeEmptyBlocks=true)
Sets the template.
Definition: IT.php:741
$touchedBlocks
List of blocks to preverse even if they are "empty".
Definition: IT.php:275
_preserveOpeningDelimiter($str)
Replaces an opening delimiter by a special string.
Definition: IT.php:971
$ret
Definition: parser.php:6
init()
Clears all datafields of the object and rebuild the internal blocklist.
Definition: IT.php:677
setOption($option, $value)
Sets the option for the template class.
Definition: IT.php:397
const IT_BLOCK_DUPLICATE
Definition: IT.php:27
findBlocks($string)
Recusively builds a list of all blocks within the template.
Definition: IT.php:863
$lastTemplatefile
EXPERIMENTAL! FIXME!
Definition: IT.php:344
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:912
Integrated Template - IT.