ILIAS  release_8 Revision v8.23
ITX.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 // +----------------------------------------------------------------------+
6 // | Copyright (c) 1997-2005 Ulf Wendel, Pierre-Alain Joye |
7 // +----------------------------------------------------------------------+
8 // | This source file is subject to the New BSD license, That is bundled |
9 // | with this package in the file LICENSE, and is available through |
10 // | the world-wide-web at |
11 // | http://www.opensource.org/licenses/bsd-license.php |
12 // | If you did not receive a copy of the new BSD license and are unable |
13 // | to obtain it through the world-wide-web, please send a note to |
14 // | pajoye@php.net, so we can mail you a copy immediately. |
15 // +----------------------------------------------------------------------+
16 // | Author: Ulf Wendel <ulf.wendel@phpdoc.de> |
17 // | Pierre-Alain Joye <pajoye@php.net> |
18 // +----------------------------------------------------------------------+
19 
32 {
36  public array $warn = [];
37 
41  public bool $printWarning = false;
42 
46  public bool $haltOnWarning = false;
47 
51  public string $checkblocknameRegExp = '';
52 
56  public string $functionPrefix = 'func_';
57 
61  public string $functionnameRegExp = '[_a-zA-Z]+[A-Za-z_0-9]*';
62 
67  public string $functionRegExp = '';
68 
72  public array $functions = [];
73 
77  public array $callback = [];
78 
86  public function __construct(string $root = '')
87  {
88  $this->checkblocknameRegExp = '@' . $this->blocknameRegExp . '@';
89  $this->functionRegExp = '@' . $this->functionPrefix . '(' .
90  $this->functionnameRegExp . ')\s*\(@sm';
91 
92  parent::__construct($root);
93  }
94 
95  protected function init(): void
96  {
97  $this->free();
98  $this->buildFunctionlist();
99  $this->findBlocks($this->template);
100  // we don't need it any more
101  $this->template = '';
102  $this->buildBlockvariablelist();
103  }
104 
121  public function replaceBlock(string $block, string $template, bool $keep_content = false): bool
122  {
123  if (!isset($this->blocklist[$block])) {
124  throw new ilTemplateException("The block " . "'$block'" . " does not exist in the template and thus it can't be replaced.");
125  }
126 
127  if ($template === '') {
128  throw new ilTemplateException('No block content given.');
129  }
130 
131  if ($keep_content) {
132  $blockdata = $this->blockdata[$block];
133  }
134 
135  // remove all kinds of links to the block / data of the block
136  $this->removeBlockData($block);
137 
138  $template = "<!-- BEGIN $block -->" . $template . "<!-- END $block -->";
139  $parents = $this->blockparents[$block];
140  $this->findBlocks($template);
141  $this->blockparents[$block] = $parents;
142 
143  // KLUDGE: rebuild the list for all block - could be done faster
144  $this->buildBlockvariablelist();
145 
146  if ($keep_content) {
147  $this->blockdata[$block] = $blockdata;
148  }
149 
150  return true;
151  }
152 
173  public function addBlock(string $placeholder, string $blockname, string $template): bool
174  {
175  // Don't trust any user even if it's a programmer or yourself...
176  if ($placeholder === '') {
177  throw new ilTemplateException('No variable placeholder given.');
178  }
179 
180  if ($blockname === '' ||
181  !preg_match($this->checkblocknameRegExp, $blockname)) {
182  throw new ilTemplateException("No or invalid blockname '$blockname' given.");
183  }
184 
185  if ($template === '') {
186  throw new ilTemplateException('No block content given.');
187  }
188 
189  if (isset($this->blocklist[$blockname])) {
190  throw new ilTemplateException('The block ' . $blockname . ' already exists.');
191  }
192 
193  // find out where to insert the new block
194  $parents = $this->findPlaceholderBlocks($placeholder);
195  if (count($parents) === 0) {
196  throw (new ilTemplateException("The variable placeholder" .
197  " '$placeholder' was not found in the template."));
198  }
199 
200  if (count($parents) > 1) {
201  $msg = '';
202  foreach ($parents as $index => $parent) {
203  $msg .= (isset($parents[$index + 1])) ?
204  "$parent, " : $parent;
205  }
206 
207  throw new ilTemplateException("The variable placeholder " . "'$placeholder'" . " must be unique, found in multiple blocks '$msg'.");
208  }
209 
210  $template = "<!-- BEGIN $blockname -->" . $template . "<!-- END $blockname -->";
211  $this->findBlocks($template);
212  if ($this->flagBlocktrouble) {
213  return false; // findBlocks() already throws an exception
214  }
215  $this->blockinner[$parents[0]][] = $blockname;
216  $this->blocklist[$parents[0]] = preg_replace(
217  '@' . $this->openingDelimiter . $placeholder .
218  $this->closingDelimiter . '@',
219  $this->openingDelimiter . '__' . $blockname . '__' .
220  $this->closingDelimiter,
221  $this->blocklist[$parents[0]]
222  );
223 
224  $this->deleteFromBlockvariablelist($parents[0], $placeholder);
225  $this->updateBlockvariablelist($blockname);
226 
227  return true;
228  }
229 
235  public function addBlockfile(string $placeholder, string $blockname, string $filename): bool
236  {
237  return $this->addBlock($placeholder, $blockname, $this->getFile($filename));
238  }
239 
243  public function removeBlockData(string $block): void
244  {
245  if (isset($this->blockinner[$block])) {
246  foreach ($this->blockinner[$block] as $inner) {
247  $this->removeBlockData($inner);
248  }
249 
250  unset($this->blockinner[$block]);
251  }
252 
253  unset(
254  $this->blocklist[$block],
255  $this->blockdata[$block],
256  $this->blockvariables[$block],
257  $this->touchedBlocks[$block]
258  );
259  }
260 
264  public function blockExists(string $blockname): bool
265  {
266  return isset($this->blocklist[$blockname]);
267  }
268 
272  public function buildFunctionlist(): void
273  {
274  $this->functions = [];
275 
277  $num = 0;
278 
279  while (preg_match($this->functionRegExp, $template, $regs)) {
280  $pos = strpos($template, $regs[0]);
281  $template = substr($template, $pos + strlen($regs[0]));
282 
283  $head = $this->getValue($template, ')');
284  $args = [];
285 
286  $search = $regs[0] . $head . ')';
287 
288  $replace = $this->openingDelimiter .
289  '__function' . $num . '__' .
291 
292  $this->template = str_replace($search, $replace, $this->template);
293  $template = str_replace($search, $replace, $template);
294 
295  while ($head !== '' && $args2 = $this->getValue($head, ',')) {
296  $arg2 = trim($args2);
297  $args[] = ('"' === $arg2[0] || "'" === $arg2[0]) ?
298  substr($arg2, 1, -1) : $arg2;
299  if ($arg2 === $head) {
300  break;
301  }
302  $head = substr($head, strlen($arg2) + 1);
303  }
304 
305  $this->functions[$num++] = [
306  'name' => $regs[1],
307  'args' => $args
308  ];
309  }
310  }
311 
317  public function getValue(string $code, $delimiter): string
318  {
319  if ($code === '') {
320  return '';
321  }
322 
323  if (!is_array($delimiter)) {
324  $delimiter = [$delimiter => true];
325  }
326 
327  $len = strlen($code);
328  $enclosed = false;
329  $enclosed_by = '';
330 
331  if (isset($delimiter[$code[0]])) {
332  $i = 1;
333  } else {
334  for ($i = 0; $i < $len; ++$i) {
335  $char = $code[$i];
336 
337  if (
338  ($char === '"' || $char === "'") &&
339  ($char === $enclosed_by || '' === $enclosed_by) &&
340  (0 === $i || ($i > 0 && '\\' !== $code[$i - 1]))
341  ) {
342  if (!$enclosed) {
343  $enclosed_by = $char;
344  } else {
345  $enclosed_by = "";
346  }
347  $enclosed = !$enclosed;
348  }
349 
350  if (!$enclosed && isset($delimiter[$char])) {
351  break;
352  }
353  }
354  }
355 
356  return substr($code, 0, $i);
357  }
358 
364  public function deleteFromBlockvariablelist(string $block, $variables): void
365  {
366  if (!is_array($variables)) {
367  $variables = [$variables => true];
368  }
369 
370  reset($this->blockvariables[$block]);
371  foreach ($this->blockvariables[$block] as $varname => $val) {
372  if (isset($variables[$varname])) {
373  unset($this->blockvariables[$block][$varname]);
374  }
375  }
376  }
377 
381  public function updateBlockvariablelist(string $block): void
382  {
383  preg_match_all(
384  $this->variablesRegExp,
385  $this->blocklist[$block],
386  $regs
387  );
388 
389  if (count($regs[1]) !== 0) {
390  foreach ($regs[1] as $var) {
391  $this->blockvariables[$block][$var] = true;
392  }
393  } else {
394  $this->blockvariables[$block] = [];
395  }
396 
397  // check if any inner blocks were found
398  if (isset($this->blockinner[$block]) &&
399  is_array($this->blockinner[$block]) &&
400  count($this->blockinner[$block]) > 0
401  ) {
402  /*
403  * loop through inner blocks, registering the variable
404  * placeholders in each
405  */
406  foreach ($this->blockinner[$block] as $childBlock) {
407  $this->updateBlockvariablelist($childBlock);
408  }
409  }
410  }
411 
416  public function findPlaceholderBlocks(string $variable): array
417  {
418  $parents = [];
419  reset($this->blocklist);
420  foreach ($this->blocklist as $blockname => $content) {
421  reset($this->blockvariables[$blockname]);
422  foreach ($this->blockvariables[$blockname] as $varname => $val) {
423  if ($variable === $varname) {
424  $parents[] = $blockname;
425  }
426  }
427  }
428 
429  return $parents;
430  }
431 
436  public function warning(string $message, string $file = '', int $line = 0): void
437  {
438  $message = sprintf(
439  'HTML_Template_ITX Warning: %s [File: %s, Line: %d]',
440  $message,
441  $file,
442  $line
443  );
444 
445  $this->warn[] = $message;
446 
447  if ($this->printWarning) {
448  print $message;
449  }
450 
451  if ($this->haltOnWarning) {
452  die($message);
453  }
454  }
455 }
string $functionRegExp
RegExp used to grep function calls in the template.
Definition: ITX.php:67
string $closingDelimiter
Last character of a variable placeholder ( {VARIABLE_}_ ).
Definition: IT.php:125
string $functionnameRegExp
Functionname RegExp.
Definition: ITX.php:61
string $template
Content of the template.
Definition: IT.php:175
string $functionPrefix
Functionnameprefix used when searching function calls in the template.
Definition: ITX.php:56
removeBlockData(string $block)
Recursively removes all data assiciated with a block, including all inner blocks. ...
Definition: ITX.php:243
replaceBlock(string $block, string $template, bool $keep_content=false)
Replaces an existing block with new content.
Definition: ITX.php:121
Integrated Template Extension - ITX With this class you get the full power of the phplib template cla...
Definition: ITX.php:31
$index
Definition: metadata.php:145
findBlocks(string $string)
Recusively builds a list of all blocks within the template.
Definition: IT.php:705
free()
Clears all datafields of the object.
Definition: IT.php:596
array $callback
List of callback functions specified by the user.
Definition: ITX.php:77
warning(string $message, string $file='', int $line=0)
Handles warnings, saves them to $warn and prints them or calls die() depending on the flags...
Definition: ITX.php:436
updateBlockvariablelist(string $block)
Updates the variable list of a block.
Definition: ITX.php:381
bool $printWarning
Print warnings?
Definition: ITX.php:41
__construct(string $root='')
Builds some complex regexps and calls the constructor of the parent class.
Definition: ITX.php:86
getFile(string $filename)
Reads a file from disk and returns its content.
Definition: IT.php:750
Integrated Template - IT Well there&#39;s not much to say about it.
Definition: IT.php:97
addBlockfile(string $placeholder, string $blockname, string $filename)
Adds a block taken from a file to the template changing a variable placeholder to a block placeholder...
Definition: ITX.php:235
$filename
Definition: buildRTE.php:78
buildBlockvariablelist()
Build a list of all variables within of a block.
Definition: IT.php:686
__construct(Container $dic, ilPlugin $plugin)
array $warn
Array with all warnings.
Definition: ITX.php:36
$message
Definition: xapiexit.php:32
findPlaceholderBlocks(string $variable)
Returns an array of blocknames where the given variable placeholder is used.
Definition: ITX.php:416
array $blockdata
Array with the parsed content of a block.
Definition: IT.php:185
array $functions
List of functions found in the template.
Definition: ITX.php:72
deleteFromBlockvariablelist(string $block, $variables)
Deletes one or many variables from the block variable list.
Definition: ITX.php:364
blockExists(string $blockname)
Checks wheter a block exists.
Definition: ITX.php:264
bool $haltOnWarning
Call die() on warning?
Definition: ITX.php:46
addBlock(string $placeholder, string $blockname, string $template)
Adds a block to the template changing a variable placeholder to a block placeholder.
Definition: ITX.php:173
string $checkblocknameRegExp
RegExp used to test for a valid blockname.
Definition: ITX.php:51
$i
Definition: metadata.php:41
buildFunctionlist()
Builds a functionlist from the template.
Definition: ITX.php:272
getValue(string $code, $delimiter)
Truncates the given code from the first occurence of $delimiter but ignores $delimiter enclosed by " ...
Definition: ITX.php:317