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
21include_once("./Services/UICore/lib/html-it/exceptions/class.ilTemplateException.php");
22
23define('IT_OK', 1);
24define('IT_ERROR', -1);
25define('IT_TPL_NOT_FOUND', -2);
26define('IT_BLOCK_NOT_FOUND', -3);
27define('IT_BLOCK_DUPLICATE', -4);
28define('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
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
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
const IT_UNKNOWN_OPTION
Definition: IT.php:28
const IT_OK
Definition: IT.php:23
const IT_TPL_NOT_FOUND
Definition: IT.php:25
const IT_BLOCK_DUPLICATE
Definition: IT.php:27
const IT_ERROR
Definition: IT.php:24
const IT_BLOCK_NOT_FOUND
Definition: IT.php:26
if(! $in) print
$filename
Definition: buildRTE.php:89
An exception for terminatinating execution or to throw for unit testing.
$variablenameRegExp
Definition: IT.php:174
findBlocks($string)
Recusively builds a list of all blocks within the template.
Definition: IT.php:863
getGlobalvariables()
Returns a list of all global variables.
Definition: IT.php:840
free()
Clears all datafields of the object.
Definition: IT.php:714
buildBlockvariablelist()
Build a list of all variables within of a block.
Definition: IT.php:822
init()
Clears all datafields of the object and rebuild the internal blocklist.
Definition: IT.php:677
$clearCacheOnParse
Definition: IT.php:305
$removeEmptyBlocks
Definition: IT.php:202
_addPregDelimiters($str)
Adds delimiters to a string, so it can be used as a pattern in preg_* functions.
Definition: IT.php:960
$_options
$_options['preserve_data'] Whether to substitute variables and remove empty placeholders in data pass...
Definition: IT.php:354
$removeUnknownVariables
Definition: IT.php:195
$lastTemplatefile
EXPERIMENTAL! FIXME!
Definition: IT.php:344
setRoot($root)
Sets the file root.
Definition: IT.php:810
errorMessage($value, $blockname='')
Return a textual error message for a IT error code.
Definition: IT.php:991
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
setOption($option, $value)
Sets the option for the template class.
Definition: IT.php:397
$removeVariablesRegExp
RegExp used to strip unused variable placeholder.
Definition: IT.php:188
parseCurrentBlock()
Parses the current block.
Definition: IT.php:594
loadTemplatefile( $filename, $removeUnknownVariables=true, $removeEmptyBlocks=true)
Reads a template file from the disk.
Definition: IT.php:778
$_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
show($block='__global__')
Print a certain block with all replacements done.
Definition: IT.php:433
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:613
getFile($filename)
Reads a file from disk and returns its content.
Definition: IT.php:912
$flagCacheTemplatefile
Definition: IT.php:339
parse($block='__global__', $flag_recursion=false)
Parses the given block.
Definition: IT.php:485
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
touchBlock($block)
Preserves an empty block even if removeEmptyBlocks is true.
Definition: IT.php:655
_preserveOpeningDelimiter($str)
Replaces an opening delimiter by a special string.
Definition: IT.php:971
static log($message, $log_level)
static getInstance($component)
Integrated Template - IT.
$ret
Definition: parser.php:6
$root
Definition: sabredav.php:45
$values