ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
ITX.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 BSD license 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: ITX.php,v 1.16 2006/08/17 15:47:22 dsp Exp $
19 //
20 
21 
40 {
47  public $warn = array();
48 
55  public $printWarning = false;
56 
63  public $haltOnWarning = false;
64 
69  public $checkblocknameRegExp = '';
70 
75  public $functionPrefix = 'func_';
76 
81  public $functionnameRegExp = '[_a-zA-Z]+[A-Za-z_0-9]*';
82 
91  public $functionRegExp = '';
92 
98  public $functions = array();
99 
105  public $callback = array();
106 
116  public function __construct($root = '')
117  {
118  $this->checkblocknameRegExp = '@' . $this->blocknameRegExp . '@';
119  $this->functionRegExp = '@' . $this->functionPrefix . '(' .
120  $this->functionnameRegExp . ')\s*\(@sm';
121 
122  parent::__construct($root);
123  } // end func constructor
124 
125  public function init()
126  {
127  $this->free();
128  $this->buildFunctionlist();
129  $this->findBlocks($this->template);
130  // we don't need it any more
131  $this->template = '';
132  $this->buildBlockvariablelist();
133  } // end func init
134 
160  public function replaceBlock($block, $template, $keep_content = false)
161  {
162  if (!isset($this->blocklist[$block])) {
163  throw (new ilTemplateException("The block " . "'$block'" .
164  " does not exist in the template and thus it can't be replaced."));
165  }
166 
167  if ($template == '') {
168  throw (new ilTemplateException('No block content given.'));
169  }
170 
171  if ($keep_content) {
172  $blockdata = $this->blockdata[$block];
173  }
174 
175  // remove all kinds of links to the block / data of the block
176  $this->removeBlockData($block);
177 
178  $template = "<!-- BEGIN $block -->" . $template . "<!-- END $block -->";
179  $parents = $this->blockparents[$block];
180  $this->findBlocks($template);
181  $this->blockparents[$block] = $parents;
182 
183  // KLUDGE: rebuild the list for all block - could be done faster
184  $this->buildBlockvariablelist();
185 
186  if ($keep_content) {
187  $this->blockdata[$block] = $blockdata;
188  }
189 
190  // old TODO - I'm not sure if we need this
191  // update caches
192 
193  return true;
194  } // end func replaceBlock
195 
205  public function replaceBlockfile($block, $filename, $keep_content = false)
206  {
207  return $this->replaceBlock($block, $this->getFile($filename), $keep_content);
208  } // end func replaceBlockfile
209 
241  public function addBlock($placeholder, $blockname, $template)
242  {
243  // Don't trust any user even if it's a programmer or yourself...
244  if ($placeholder == '') {
245  throw (new ilTemplateException('No variable placeholder given.'));
246  } elseif ($blockname == '' ||
247  !preg_match($this->checkblocknameRegExp, $blockname)
248  ) {
249  throw (new ilTemplateException("No or invalid blockname '$blockname' given."));
250  } elseif ($template == '') {
251  throw (new ilTemplateException('No block content given.'));
252  } elseif (isset($this->blocklist[$blockname])) {
253  throw (new ilTemplateException('The block ' . $blockname . ' already exists.'));
254  }
255 
256  // find out where to insert the new block
257  $parents = $this->findPlaceholderBlocks($placeholder);
258  if (count($parents) == 0) {
259  throw (new ilTemplateException("The variable placeholder" .
260  " '$placeholder' was not found in the template."));
261  return;
262  } elseif (count($parents) > 1) {
263  reset($parents);
264  foreach ($parents as $k => $parent) {
265  $msg .= "$parent, ";
266  }
267  $msg = substr($parent, -2);
268  throw (new ilTemplateException("The variable placeholder " . "'$placeholder'" .
269  " must be unique, found in multiple blocks '$msg'."));
270  }
271 
272  $template = "<!-- BEGIN $blockname -->" . $template . "<!-- END $blockname -->";
273  $this->findBlocks($template);
274  if ($this->flagBlocktrouble) {
275  return false; // findBlocks() already throws an exception
276  }
277  $this->blockinner[$parents[0]][] = $blockname;
278  $this->blocklist[$parents[0]] = preg_replace(
279  '@' . $this->openingDelimiter . $placeholder .
280  $this->closingDelimiter . '@',
281  $this->openingDelimiter . '__' . $blockname . '__' .
282  $this->closingDelimiter,
283  $this->blocklist[$parents[0]]
284  );
285 
286  $this->deleteFromBlockvariablelist($parents[0], $placeholder);
287  $this->updateBlockvariablelist($blockname);
288 
289  return true;
290  } // end func addBlock
291 
302  public function addBlockfile($placeholder, $blockname, $filename)
303  {
304  return $this->addBlock($placeholder, $blockname, $this->getFile($filename));
305  } // end func addBlockfile
306 
321  public function placeholderExists($placeholder, $block = '')
322  {
323  if ($placeholder == '') {
324  throw (new ilTemplateException('No placeholder name given.'));
325  }
326 
327  if ($block != '' && !isset($this->blocklist[$block])) {
328  throw (new ilTemplateException("Unknown block '$block'."));
329  }
330 
331  // name of the block where the given placeholder was found
332  $found = '';
333 
334  if ($block != '') {
335  if (is_array($variables = $this->blockvariables[$block])) {
336  // search the value in the list of blockvariables
337  reset($variables);
338  foreach ($variables as $k => $variable) {
339  if ($k == $placeholder) {
340  $found = $block;
341  break;
342  }
343  }
344  }
345  } else {
346 
347  // search all blocks and return the name of the first block that
348  // contains the placeholder
349  reset($this->blockvariables);
350  foreach ($this->blockvariables as $blockname => $variables) {
351  if (is_array($variables) && isset($variables[$placeholder])) {
352  $found = $blockname;
353  break;
354  }
355  }
356  }
357 
358  return $found;
359  } // end func placeholderExists
360 
367  public function performCallback()
368  {
369  reset($this->functions);
370  foreach ($this->functions as $func_id => $function) {
371  if (isset($this->callback[$function['name']])) {
372  if ($this->callback[$function['name']]['expandParameters']) {
373  $callFunction = 'call_user_func_array';
374  } else {
375  $callFunction = 'call_user_func';
376  }
377 
378  if ($this->callback[$function['name']]['object'] != '') {
379  $call =
380  $callFunction(
381  array(
382  &$GLOBALS[$this->callback[$function['name']]['object']],
383  $this->callback[$function['name']]['function']),
384  $function['args']
385  );
386  } else {
387  $call =
388  $callFunction(
389  $this->callback[$function['name']]['function'],
390  $function['args']
391  );
392  }
393  $this->variableCache['__function' . $func_id . '__'] = $call;
394  }
395  }
396  } // end func performCallback
397 
404  public function getFunctioncalls()
405  {
406  return $this->functions;
407  } // end func getFunctioncalls
408 
416  public function setFunctioncontent($functionID, $replacement)
417  {
418  $this->variableCache['__function' . $functionID . '__'] = $replacement;
419  } // end func setFunctioncontent
420 
468  public function setCallbackFunction($tplfunction, $callbackfunction, $callbackobject = '', $expandCallbackParameters=false)
469  {
470  if ($tplfunction == '' || $callbackfunction == '') {
471  throw (new ilTemplateException("No template function " . "('$tplfunction')" .
472  " and/or no callback function ('$callbackfunction') given."));
473  }
474  $this->callback[$tplfunction] = array(
475  'function' => $callbackfunction,
476  'object' => $callbackobject,
477  'expandParameters' => (boolean) $expandCallbackParameters
478  );
479 
480  return true;
481  } // end func setCallbackFunction
482 
495  {
496  $this->callback = $functions;
497  } // end func setCallbackFunctiontable
498 
505  public function removeBlockData($block)
506  {
507  if (isset($this->blockinner[$block])) {
508  foreach ($this->blockinner[$block] as $k => $inner) {
509  $this->removeBlockData($inner);
510  }
511 
512  unset($this->blockinner[$block]);
513  }
514 
515  unset($this->blocklist[$block]);
516  unset($this->blockdata[$block]);
517  unset($this->blockvariables[$block]);
518  unset($this->touchedBlocks[$block]);
519  } // end func removeBlockinner
520 
528  public function getBlocklist()
529  {
530  $blocklist = array();
531  foreach ($this->blocklist as $block => $content) {
532  $blocklist[$block] = $block;
533  }
534 
535  return $blocklist;
536  } // end func getBlocklist
537 
546  public function blockExists($blockname)
547  {
548  return isset($this->blocklist[$blockname]);
549  } // end func blockExists
550 
559  public function getBlockvariables($block)
560  {
561  if (!isset($this->blockvariables[$block])) {
562  return array();
563  }
564 
565  $variables = array();
566  foreach ($this->blockvariables[$block] as $variable => $v) {
567  $variables[$variable] = $variable;
568  }
569 
570  return $variables;
571  } // end func getBlockvariables
572 
582  public function BlockvariableExists($block, $variable)
583  {
584  return isset($this->blockvariables[$block][$variable]);
585  } // end func BlockvariableExists
586 
591  public function buildFunctionlist()
592  {
593  $this->functions = array();
594 
596  $num = 0;
597 
598  while (preg_match($this->functionRegExp, $template, $regs)) {
599  $pos = strpos($template, $regs[0]);
600  $template = substr($template, $pos + strlen($regs[0]));
601 
602  $head = $this->getValue($template, ')');
603  $args = array();
604 
605  $search = $regs[0] . $head . ')';
606 
607  $replace = $this->openingDelimiter .
608  '__function' . $num . '__' .
610 
611  $this->template = str_replace($search, $replace, $this->template);
612  $template = str_replace($search, $replace, $template);
613 
614  while ($head != '' && $args2 = $this->getValue($head, ',')) {
615  $arg2 = trim($args2);
616  $args[] = ('"' == $arg2{0} || "'" == $arg2{0}) ?
617  substr($arg2, 1, -1) : $arg2;
618  if ($arg2 == $head) {
619  break;
620  }
621  $head = substr($head, strlen($arg2) + 1);
622  }
623 
624  $this->functions[$num++] = array(
625  'name' => $regs[1],
626  'args' => $args
627  );
628  }
629  } // end func buildFunctionlist
630 
641  public function getValue($code, $delimiter)
642  {
643  if ($code == '') {
644  return '';
645  }
646 
647  if (!is_array($delimiter)) {
648  $delimiter = array( $delimiter => true );
649  }
650 
651  $len = strlen($code);
652  $enclosed = false;
653  $enclosed_by = '';
654 
655  if (isset($delimiter[$code[0]])) {
656  $i = 1;
657  } else {
658  for ($i = 0; $i < $len; ++$i) {
659  $char = $code[$i];
660 
661  if (
662  ($char == '"' || $char == "'") &&
663  ($char == $enclosed_by || '' == $enclosed_by) &&
664  (0 == $i || ($i > 0 && '\\' != $code[$i - 1]))
665  ) {
666  if (!$enclosed) {
667  $enclosed_by = $char;
668  } else {
669  $enclosed_by = "";
670  }
671  $enclosed = !$enclosed;
672  }
673 
674  if (!$enclosed && isset($delimiter[$char])) {
675  break;
676  }
677  }
678  }
679 
680  return substr($code, 0, $i);
681  } // end func getValue
682 
691  public function deleteFromBlockvariablelist($block, $variables)
692  {
693  if (!is_array($variables)) {
694  $variables = array($variables => true);
695  }
696 
697  reset($this->blockvariables[$block]);
698  foreach ($this->blockvariables[$block] as $varname => $val) {
699  if (isset($variables[$varname])) {
700  unset($this->blockvariables[$block][$varname]);
701  }
702  }
703  } // end deleteFromBlockvariablelist
704 
711  public function updateBlockvariablelist($block)
712  {
713  preg_match_all(
714  $this->variablesRegExp,
715  $this->blocklist[$block],
716  $regs
717  );
718 
719  if (count($regs[1]) != 0) {
720  foreach ($regs[1] as $k => $var) {
721  $this->blockvariables[$block][$var] = true;
722  }
723  } else {
724  $this->blockvariables[$block] = array();
725  }
726 
727  // check if any inner blocks were found
728  if (isset($this->blockinner[$block]) &&
729  is_array($this->blockinner[$block]) &&
730  count($this->blockinner[$block]) > 0
731  ) {
732  /*
733  * loop through inner blocks, registering the variable
734  * placeholders in each
735  */
736  foreach ($this->blockinner[$block] as $childBlock) {
737  $this->updateBlockvariablelist($childBlock);
738  }
739  }
740  } // end func updateBlockvariablelist
741 
750  public function findPlaceholderBlocks($variable)
751  {
752  $parents = array();
753  reset($this->blocklist);
754  foreach ($this->blocklist as $blockname => $content) {
755  reset($this->blockvariables[$blockname]);
756  foreach ($this->blockvariables[$blockname] as $varname => $val) {
757  if ($variable == $varname) {
758  $parents[] = $blockname;
759  }
760  }
761  }
762 
763  return $parents;
764  } // end func findPlaceholderBlocks
765 
776  public function warning($message, $file = '', $line = 0)
777  {
778  $message = sprintf(
779  'HTML_Template_ITX Warning: %s [File: %s, Line: %d]',
780  $message,
781  $file,
782  $line
783  );
784 
785  $this->warn[] = $message;
786 
787  if ($this->printWarning) {
788  print $message;
789  }
790 
791  if ($this->haltOnWarning) {
792  die($message);
793  }
794  } // end func warning
795 } // end class HTML_Template_ITX
addBlockfile($placeholder, $blockname, $filename)
Adds a block taken from a file to the template changing a variable placeholder to a block placeholder...
Definition: ITX.php:302
deleteFromBlockvariablelist($block, $variables)
Deletes one or many variables from the block variable list.
Definition: ITX.php:691
List implemented functions
$delimiter
Definition: showstats.php:16
$code
Definition: example_050.php:99
setCallbackFuntiontable($functions)
Sets the Callback function lookup table.
Definition: ITX.php:494
findPlaceholderBlocks($variable)
Returns an array of blocknames where the given variable placeholder is used.
Definition: ITX.php:750
__construct($root='')
Builds some complex regexps and calls the constructor of the parent class.
Definition: ITX.php:116
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
getBlocklist()
Returns a list of blocknames in the template.
Definition: ITX.php:528
addBlock($placeholder, $blockname, $template)
Adds a block to the template changing a variable placeholder to a block placeholder.
Definition: ITX.php:241
getFunctioncalls()
Returns a list of all function calls in the current template.
Definition: ITX.php:404
removeBlockData($block)
Recursively removes all data assiciated with a block, including all inner blocks. ...
Definition: ITX.php:505
getBlockvariables($block)
Returns a list of variables of a block.
Definition: ITX.php:559
replaceBlockfile($block, $filename, $keep_content=false)
Replaces an existing block with new content from a file.
Definition: ITX.php:205
free()
Clears all datafields of the object.
Definition: IT.php:714
catch(Exception $e) $message
getValue($code, $delimiter)
Truncates the given code from the first occurence of $delimiter but ignores $delimiter enclosed by " ...
Definition: ITX.php:641
setCallbackFunction($tplfunction, $callbackfunction, $callbackobject='', $expandCallbackParameters=false)
Sets a callback function.
Definition: ITX.php:468
setFunctioncontent($functionID, $replacement)
Replaces a function call with the given replacement.
Definition: ITX.php:416
Create styles array
The data for the language used.
blockExists($blockname)
Checks wheter a block exists.
Definition: ITX.php:546
buildBlockvariablelist()
Build a list of all variables within of a block.
Definition: IT.php:822
updateBlockvariablelist($block)
Updates the variable list of a block.
Definition: ITX.php:711
BlockvariableExists($block, $variable)
Checks wheter a block variable exists.
Definition: ITX.php:582
warning($message, $file='', $line=0)
Handles warnings, saves them to $warn and prints them or calls die() depending on the flags...
Definition: ITX.php:776
$function
Definition: cas.php:28
$i
Definition: disco.tpl.php:19
$checkblocknameRegExp
Definition: ITX.php:69
placeholderExists($placeholder, $block='')
Returns the name of the (first) block that contains the specified placeholder.
Definition: ITX.php:321
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
findBlocks($string)
Recusively builds a list of all blocks within the template.
Definition: IT.php:863
getFile($filename)
Reads a file from disk and returns its content.
Definition: IT.php:912
replaceBlock($block, $template, $keep_content=false)
Replaces an existing block with new content.
Definition: ITX.php:160
Integrated Template - IT.
buildFunctionlist()
Builds a functionlist from the template.
Definition: ITX.php:591
performCallback()
Checks the list of function calls in the template and calls their callback function.
Definition: ITX.php:367