ILIAS  release_7 Revision v7.30-3-g800a261c036
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
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
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
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:865
getGlobalvariables()
Returns a list of all global variables.
Definition: IT.php:842
free()
Clears all datafields of the object.
Definition: IT.php:716
buildBlockvariablelist()
Build a list of all variables within of a block.
Definition: IT.php:824
init()
Clears all datafields of the object and rebuild the internal blocklist.
Definition: IT.php:679
$clearCacheOnParse
Definition: IT.php:307
$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:962
$_options
$_options['preserve_data'] Whether to substitute variables and remove empty placeholders in data pass...
Definition: IT.php:356
$removeUnknownVariables
Definition: IT.php:195
$lastTemplatefile
EXPERIMENTAL! FIXME!
Definition: IT.php:346
setRoot($root)
Sets the file root.
Definition: IT.php:812
errorMessage($value, $blockname='')
Return a textual error message for a IT error code.
Definition: IT.php:993
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
setOption($option, $value)
Sets the option for the template class.
Definition: IT.php:399
$removeVariablesRegExp
RegExp used to strip unused variable placeholder.
Definition: IT.php:188
parseCurrentBlock()
Parses the current block.
Definition: IT.php:596
loadTemplatefile( $filename, $removeUnknownVariables=true, $removeEmptyBlocks=true)
Reads a template file from the disk.
Definition: IT.php:780
$_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
show($block='__global__')
Print a certain block with all replacements done.
Definition: IT.php:435
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:615
getFile($filename)
Reads a file from disk and returns its content.
Definition: IT.php:914
$flagCacheTemplatefile
Definition: IT.php:341
parse($block='__global__', $flag_recursion=false)
Parses the given block.
Definition: IT.php:487
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
touchBlock($block)
Preserves an empty block even if removeEmptyBlocks is true.
Definition: IT.php:657
_preserveOpeningDelimiter($str)
Replaces an opening delimiter by a special string.
Definition: IT.php:973
static log($message, $log_level)
static getInstance($component)
if($format !==null) $name
Definition: metadata.php:230
Integrated Template - IT.
$ret
Definition: parser.php:6