ILIAS  trunk Revision v11.0_alpha-1731-gff9cd7e2bd3
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
ITX.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 // +----------------------------------------------------------------------+
22 // +----------------------------------------------------------------------+
23 // | This source file is subject to the New BSD license, That is bundled |
24 // | the world-wide-web at |
25 // | http://www.opensource.org/licenses/bsd-license.php |
26 // | If you did not receive a copy of the new BSD license and are unable |
27 // | to obtain it through the world-wide-web, please send a note to |
28 // | pajoye@php.net, so we can mail you a copy immediately. |
29 // +----------------------------------------------------------------------+
30 // | Author: Ulf Wendel <ulf.wendel@phpdoc.de> |
31 // | Pierre-Alain Joye <pajoye@php.net> |
32 // +----------------------------------------------------------------------+
45 {
49  public array $warn = [];
50 
54  public bool $printWarning = false;
55 
59  public bool $haltOnWarning = false;
60 
64  public string $checkblocknameRegExp = '';
65 
69  public string $functionPrefix = 'func_';
70 
74  public string $functionnameRegExp = '[_a-zA-Z]+[A-Za-z_0-9]*';
75 
80  public string $functionRegExp = '';
81 
85  public array $functions = [];
86 
90  public array $callback = [];
91 
99  public function __construct(string $root = '')
100  {
101  $this->checkblocknameRegExp = '@' . $this->blocknameRegExp . '@';
102  $this->functionRegExp = '@' . $this->functionPrefix . '(' .
103  $this->functionnameRegExp . ')\s*\(@sm';
104 
105  parent::__construct($root);
106  }
107 
108  protected function init(): void
109  {
110  $this->free();
111  $this->buildFunctionlist();
112  $this->findBlocks($this->template);
113  // we don't need it any more
114  $this->template = '';
115  $this->buildBlockvariablelist();
116  }
117 
134  public function replaceBlock(string $block, string $template, bool $keep_content = false): bool
135  {
136  if (!isset($this->blocklist[$block])) {
137  throw new ilTemplateException("The block " . "'$block'" . " does not exist in the template and thus it can't be replaced.");
138  }
139 
140  if ($template === '') {
141  throw new ilTemplateException('No block content given.');
142  }
143 
144  if ($keep_content) {
145  $blockdata = $this->blockdata[$block];
146  }
147 
148  // remove all kinds of links to the block / data of the block
149  $this->removeBlockData($block);
150 
151  $template = "<!-- BEGIN $block -->" . $template . "<!-- END $block -->";
152  $parents = $this->blockparents[$block];
153  $this->findBlocks($template);
154  $this->blockparents[$block] = $parents;
155 
156  // KLUDGE: rebuild the list for all block - could be done faster
157  $this->buildBlockvariablelist();
158 
159  if ($keep_content) {
160  $this->blockdata[$block] = $blockdata;
161  }
162 
163  return true;
164  }
165 
186  public function addBlock(string $placeholder, string $blockname, string $template): bool
187  {
188  // Don't trust any user even if it's a programmer or yourself...
189  if ($placeholder === '') {
190  throw new ilTemplateException('No variable placeholder given.');
191  }
192 
193  if ($blockname === '' ||
194  !preg_match($this->checkblocknameRegExp, $blockname)) {
195  throw new ilTemplateException("No or invalid blockname '$blockname' given.");
196  }
197 
198  if ($template === '') {
199  throw new ilTemplateException('No block content given.');
200  }
201 
202  if (isset($this->blocklist[$blockname])) {
203  throw new ilTemplateException('The block ' . $blockname . ' already exists.');
204  }
205 
206  // find out where to insert the new block
207  $parents = $this->findPlaceholderBlocks($placeholder);
208  if (count($parents) === 0) {
209  throw (new ilTemplateException("The variable placeholder" .
210  " '$placeholder' was not found in the template."));
211  }
212 
213  if (count($parents) > 1) {
214  $msg = '';
215  foreach ($parents as $index => $parent) {
216  $msg .= (isset($parents[$index + 1])) ?
217  "$parent, " : $parent;
218  }
219 
220  throw new ilTemplateException("The variable placeholder " . "'$placeholder'" . " must be unique, found in multiple blocks '$msg'.");
221  }
222 
223  $template = "<!-- BEGIN $blockname -->" . $template . "<!-- END $blockname -->";
224  $this->findBlocks($template);
225  if ($this->flagBlocktrouble) {
226  return false; // findBlocks() already throws an exception
227  }
228  $this->blockinner[$parents[0]][] = $blockname;
229  $this->blocklist[$parents[0]] = preg_replace(
230  '@' . $this->openingDelimiter . $placeholder .
231  $this->closingDelimiter . '@',
232  $this->openingDelimiter . '__' . $blockname . '__' .
233  $this->closingDelimiter,
234  $this->blocklist[$parents[0]]
235  );
236 
237  $this->deleteFromBlockvariablelist($parents[0], $placeholder);
238  $this->updateBlockvariablelist($blockname);
239 
240  return true;
241  }
242 
248  public function addBlockfile(string $placeholder, string $blockname, string $filename): bool
249  {
250  return $this->addBlock($placeholder, $blockname, $this->getFile($filename));
251  }
252 
256  public function removeBlockData(string $block): void
257  {
258  if (isset($this->blockinner[$block])) {
259  foreach ($this->blockinner[$block] as $inner) {
260  $this->removeBlockData($inner);
261  }
262 
263  unset($this->blockinner[$block]);
264  }
265 
266  unset(
267  $this->blocklist[$block],
268  $this->blockdata[$block],
269  $this->blockvariables[$block],
270  $this->touchedBlocks[$block]
271  );
272  }
273 
277  public function blockExists(string $blockname): bool
278  {
279  return isset($this->blocklist[$blockname]);
280  }
281 
285  public function buildFunctionlist(): void
286  {
287  $this->functions = [];
288 
290  $num = 0;
291 
292  while (preg_match($this->functionRegExp, $template, $regs)) {
293  $pos = strpos($template, $regs[0]);
294  $template = substr($template, $pos + strlen($regs[0]));
295 
296  $head = $this->getValue($template, ')');
297  $args = [];
298 
299  $search = $regs[0] . $head . ')';
300 
301  $replace = $this->openingDelimiter .
302  '__function' . $num . '__' .
304 
305  $this->template = str_replace($search, $replace, $this->template);
306  $template = str_replace($search, $replace, $template);
307 
308  while ($head !== '' && $args2 = $this->getValue($head, ',')) {
309  $arg2 = trim($args2);
310  $args[] = ('"' === $arg2[0] || "'" === $arg2[0]) ?
311  substr($arg2, 1, -1) : $arg2;
312  if ($arg2 === $head) {
313  break;
314  }
315  $head = substr($head, strlen($arg2) + 1);
316  }
317 
318  $this->functions[$num++] = [
319  'name' => $regs[1],
320  'args' => $args
321  ];
322  }
323  }
324 
330  public function getValue(string $code, $delimiter): string
331  {
332  if ($code === '') {
333  return '';
334  }
335 
336  if (!is_array($delimiter)) {
337  $delimiter = [$delimiter => true];
338  }
339 
340  $len = strlen($code);
341  $enclosed = false;
342  $enclosed_by = '';
343 
344  if (isset($delimiter[$code[0]])) {
345  $i = 1;
346  } else {
347  for ($i = 0; $i < $len; ++$i) {
348  $char = $code[$i];
349 
350  if (
351  ($char === '"' || $char === "'") &&
352  ($char === $enclosed_by || '' === $enclosed_by) &&
353  (0 === $i || ($i > 0 && '\\' !== $code[$i - 1]))
354  ) {
355  if (!$enclosed) {
356  $enclosed_by = $char;
357  } else {
358  $enclosed_by = "";
359  }
360  $enclosed = !$enclosed;
361  }
362 
363  if (!$enclosed && isset($delimiter[$char])) {
364  break;
365  }
366  }
367  }
368 
369  return substr($code, 0, $i);
370  }
371 
377  public function deleteFromBlockvariablelist(string $block, $variables): void
378  {
379  if (!is_array($variables)) {
380  $variables = [$variables => true];
381  }
382 
383  reset($this->blockvariables[$block]);
384  foreach ($this->blockvariables[$block] as $varname => $val) {
385  if (isset($variables[$varname])) {
386  unset($this->blockvariables[$block][$varname]);
387  }
388  }
389  }
390 
394  public function updateBlockvariablelist(string $block): void
395  {
396  preg_match_all(
397  $this->variablesRegExp,
398  $this->blocklist[$block],
399  $regs
400  );
401 
402  if (count($regs[1]) !== 0) {
403  foreach ($regs[1] as $var) {
404  $this->blockvariables[$block][$var] = true;
405  }
406  } else {
407  $this->blockvariables[$block] = [];
408  }
409 
410  // check if any inner blocks were found
411  if (isset($this->blockinner[$block]) &&
412  is_array($this->blockinner[$block]) &&
413  count($this->blockinner[$block]) > 0
414  ) {
415  /*
416  * loop through inner blocks, registering the variable
417  * placeholders in each
418  */
419  foreach ($this->blockinner[$block] as $childBlock) {
420  $this->updateBlockvariablelist($childBlock);
421  }
422  }
423  }
424 
429  public function findPlaceholderBlocks(string $variable): array
430  {
431  $parents = [];
432  reset($this->blocklist);
433  foreach ($this->blocklist as $blockname => $content) {
434  reset($this->blockvariables[$blockname]);
435  foreach ($this->blockvariables[$blockname] as $varname => $val) {
436  if ($variable === $varname) {
437  $parents[] = $blockname;
438  }
439  }
440  }
441 
442  return $parents;
443  }
444 
449  public function warning(string $message, string $file = '', int $line = 0): void
450  {
451  $message = sprintf(
452  'HTML_Template_ITX Warning: %s [File: %s, Line: %d]',
453  $message,
454  $file,
455  $line
456  );
457 
458  $this->warn[] = $message;
459 
460  if ($this->printWarning) {
461  print $message;
462  }
463 
464  if ($this->haltOnWarning) {
465  die($message);
466  }
467  }
468 }
string $functionRegExp
RegExp used to grep function calls in the template.
Definition: ITX.php:80
string $closingDelimiter
Last character of a variable placeholder ( {VARIABLE_}_ ).
Definition: IT.php:149
string $functionnameRegExp
Functionname RegExp.
Definition: ITX.php:74
string $template
Content of the template.
Definition: IT.php:199
string $functionPrefix
Functionnameprefix used when searching function calls in the template.
Definition: ITX.php:69
removeBlockData(string $block)
Recursively removes all data assiciated with a block, including all inner blocks. ...
Definition: ITX.php:256
replaceBlock(string $block, string $template, bool $keep_content=false)
Replaces an existing block with new content.
Definition: ITX.php:134
Integrated Template Extension - ITX With this class you get the full power of the phplib template cla...
Definition: ITX.php:44
findBlocks(string $string)
Recusively builds a list of all blocks within the template.
Definition: IT.php:732
free()
Clears all datafields of the object.
Definition: IT.php:623
array $callback
List of callback functions specified by the user.
Definition: ITX.php:90
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:449
updateBlockvariablelist(string $block)
Updates the variable list of a block.
Definition: ITX.php:394
bool $printWarning
Print warnings?
Definition: ITX.php:54
__construct(string $root='')
Builds some complex regexps and calls the constructor of the parent class.
Definition: ITX.php:99
getFile(string $filename)
Reads a file from disk and returns its content.
Definition: IT.php:777
Integrated Template - IT Well there&#39;s not much to say about it.
Definition: IT.php:118
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:248
$filename
Definition: buildRTE.php:78
buildBlockvariablelist()
Build a list of all variables within of a block.
Definition: IT.php:713
__construct(Container $dic, ilPlugin $plugin)
array $warn
Array with all warnings.
Definition: ITX.php:49
$message
Definition: xapiexit.php:31
findPlaceholderBlocks(string $variable)
Returns an array of blocknames where the given variable placeholder is used.
Definition: ITX.php:429
array $blockdata
Array with the parsed content of a block.
Definition: IT.php:209
array $functions
List of functions found in the template.
Definition: ITX.php:85
deleteFromBlockvariablelist(string $block, $variables)
Deletes one or many variables from the block variable list.
Definition: ITX.php:377
blockExists(string $blockname)
Checks wheter a block exists.
Definition: ITX.php:277
bool $haltOnWarning
Call die() on warning?
Definition: ITX.php:59
addBlock(string $placeholder, string $blockname, string $template)
Adds a block to the template changing a variable placeholder to a block placeholder.
Definition: ITX.php:186
string $checkblocknameRegExp
RegExp used to test for a valid blockname.
Definition: ITX.php:64
buildFunctionlist()
Builds a functionlist from the template.
Definition: ITX.php:285
getValue(string $code, $delimiter)
Truncates the given code from the first occurence of $delimiter but ignores $delimiter enclosed by " ...
Definition: ITX.php:330