ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ITX.php
Go to the documentation of this file.
1<?php
2
19declare(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}
$filename
Definition: buildRTE.php:78
Integrated Template Extension - ITX With this class you get the full power of the phplib template cla...
Definition: ITX.php:45
bool $haltOnWarning
Call die() on warning?
Definition: ITX.php:59
string $functionPrefix
Functionnameprefix used when searching function calls in the template.
Definition: ITX.php:69
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
removeBlockData(string $block)
Recursively removes all data assiciated with a block, including all inner blocks.
Definition: ITX.php:256
array $warn
Array with all warnings.
Definition: ITX.php:49
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
deleteFromBlockvariablelist(string $block, $variables)
Deletes one or many variables from the block variable list.
Definition: ITX.php:377
findPlaceholderBlocks(string $variable)
Returns an array of blocknames where the given variable placeholder is used.
Definition: ITX.php:429
updateBlockvariablelist(string $block)
Updates the variable list of a block.
Definition: ITX.php:394
buildFunctionlist()
Builds a functionlist from the template.
Definition: ITX.php:285
blockExists(string $blockname)
Checks wheter a block exists.
Definition: ITX.php:277
array $callback
List of callback functions specified by the user.
Definition: ITX.php:90
array $functions
List of functions found in the template.
Definition: ITX.php:85
init()
Clears all datafields of the object and rebuild the internal blocklist LoadTemplatefile() and setTemp...
Definition: ITX.php:108
string $functionnameRegExp
Functionname RegExp.
Definition: ITX.php:74
getValue(string $code, $delimiter)
Truncates the given code from the first occurence of $delimiter but ignores $delimiter enclosed by " ...
Definition: ITX.php:330
string $functionRegExp
RegExp used to grep function calls in the template.
Definition: ITX.php:80
string $checkblocknameRegExp
RegExp used to test for a valid blockname.
Definition: ITX.php:64
__construct(string $root='')
Builds some complex regexps and calls the constructor of the parent class.
Definition: ITX.php:99
replaceBlock(string $block, string $template, bool $keep_content=false)
Replaces an existing block with new content.
Definition: ITX.php:134
bool $printWarning
Print warnings?
Definition: ITX.php:54
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
Integrated Template - IT Well there's not much to say about it.
Definition: IT.php:119
string $closingDelimiter
Last character of a variable placeholder ( {VARIABLE_}_ ).
Definition: IT.php:149
free()
Clears all datafields of the object.
Definition: IT.php:623
buildBlockvariablelist()
Build a list of all variables within of a block.
Definition: IT.php:713
string $template
Content of the template.
Definition: IT.php:199
findBlocks(string $string)
Recusively builds a list of all blocks within the template.
Definition: IT.php:732
array $blockdata
Array with the parsed content of a block.
Definition: IT.php:209
getFile(string $filename)
Reads a file from disk and returns its content.
Definition: IT.php:777
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$message
Definition: xapiexit.php:31