Passed
Push — master ( ff89ed...1371da )
by Cody
03:09
created

MiniTemplator::processTemplateCommand()   B

Complexity

Conditions 11
Paths 9

Size

Total Lines 30
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 25
c 2
b 0
f 0
nc 9
nop 4
dl 0
loc 30
rs 7.3166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
* File MiniTemplator.class.php
4
* @package MiniTemplator
5
*/
6
7
/**
8
* A compact template engine for HTML files.
9
*
10
* Requires PHP 4.0.4 or newer.
11
*
12
* <pre>
13
* Template syntax:
14
*
15
*   Variables:
16
*     ${VariableName}
17
*
18
*   Blocks:
19
*     &lt;!-- $BeginBlock BlockName --&gt;
20
*     ... block content ...
21
*     &lt;!-- $EndBlock BlockName --&gt;
22
*
23
*   Include a subtemplate:
24
*     &lt;!-- $Include RelativeFileName --&gt;
25
* </pre>
26
*
27
* <pre>
28
* General remarks:
29
*  - Variable names and block names are case-insensitive.
30
*  - The same variable may be used multiple times within a template.
31
*  - Blocks can be nested.
32
*  - Multiple blocks with the same name may occur within a template.
33
* </pre>
34
*
35
* <pre>
36
* Public methods:
37
*   readTemplateFromFile   - Reads the template from a file.
38
*   setTemplateString      - Assigns a new template string.
39
*   setVariable            - Sets a template variable.
40
*   setVariableEsc         - Sets a template variable to an escaped string value.
41
*   variableExists         - Checks whether a template variable exists.
42
*   addBlock               - Adds an instance of a template block.
43
*   blockExists            - Checks whether a block exists.
44
*   reset                  - Clears all variables and blocks.
45
*   generateOutput         - Generates the HTML page and writes it to the PHP output stream.
46
*   generateOutputToFile   - Generates the HTML page and writes it to a file.
47
*   generateOutputToString - Generates the HTML page and writes it to a string.
48
* </pre>
49
*
50
* Home page: {@link http://www.source-code.biz/MiniTemplator}<br>
51
* License: This module is released under the GNU/LGPL license ({@link http://www.gnu.org/licenses/lgpl.html}).<br>
52
* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland. All rights reserved.<br>
53
* This product is provided "as is" without warranty of any kind.<br>
54
*
55
* Version history:<br>
56
* 2001-10-24 Christian d'Heureuse (chdh): VBasic version created.<br>
57
* 2002-01-26 Markus Angst: ported to PHP4.<br>
58
* 2003-04-07 chdh: changes to adjust to Java version.<br>
59
* 2003-07-08 chdh: Method variableExists added.
60
*   Method setVariable changed to trigger an error when the variable does not exist.<br>
61
* 2004-04-07 chdh: Parameter isOptional added to method setVariable.
62
*   Licensing changed from GPL to LGPL.<br>
63
* 2004-04-18 chdh: Method blockExists added.<br>
64
* 2004-10-28 chdh:<br>
65
*   Method setVariableEsc added.<br>
66
*   Multiple blocks with the same name may now occur within a template.<br>
67
*   No error ("unknown command") is generated any more, if a HTML comment starts with "${".<br>
68
* 2004-11-06 chdh:<br>
69
*   "$Include" command implemented.<br>
70
* 2004-11-20 chdh:<br>
71
*   "$Include" command changed so that the command text is not copied to the output file.<br>
72
*/
73
74
class MiniTemplator {
75
76
//--- public member variables ---------------------------------------------------------------------------------------
77
78
/**
79
* Base path for relative file names of subtemplates (for the $Include command).
80
* This path is prepended to the subtemplate file names. It must be set before
81
* readTemplateFromFile or setTemplateString.
82
* @access public
83
*/
84
var $subtemplateBasePath;
85
86
//--- private member variables --------------------------------------------------------------------------------------
87
88
/**#@+
89
* @access private
90
*/
91
92
var $maxNestingLevel = 50; // maximum number of block nestings
93
var $maxInclTemplateSize = 1000000; // maximum length of template string when including subtemplates
94
var $template; // Template file data
95
var $varTab; // variables table, array index is variable no
96
    // Fields:
97
    //  varName                       // variable name
98
    //  varValue                      // variable value
99
var $varTabCnt; // no of entries used in VarTab
100
var $varNameToNoMap; // maps variable names to variable numbers
101
var $varRefTab; // variable references table
102
    // Contains an entry for each variable reference in the template. Ordered by TemplatePos.
103
    // Fields:
104
    //  varNo                         // variable no
105
    //  tPosBegin                     // template position of begin of variable reference
106
    //  tPosEnd                       // template position of end of variable reference
107
    //  blockNo                       // block no of the (innermost) block that contains this variable reference
108
    //  blockVarNo                    // block variable no. Index into BlockInstTab.BlockVarTab
109
var $varRefTabCnt; // no of entries used in VarRefTab
110
var $blockTab; // Blocks table, array index is block no
111
    // Contains an entry for each block in the template. Ordered by TPosBegin.
112
    // Fields:
113
    //  blockName                     // block name
114
    //  nextWithSameName;             // block no of next block with same name or -1 (blocks are backward linked in relation to template position)
115
    //  tPosBegin                     // template position of begin of block
116
    //  tPosContentsBegin             // template pos of begin of block contents
117
    //  tPosContentsEnd               // template pos of end of block contents
118
    //  tPosEnd                       // template position of end of block
119
    //  nestingLevel                  // block nesting level
120
    //  parentBlockNo                 // block no of parent block
121
    //  definitionIsOpen              // true while $BeginBlock processed but no $EndBlock
122
    //  instances                     // number of instances of this block
123
    //  firstBlockInstNo              // block instance no of first instance of this block or -1
124
    //  lastBlockInstNo               // block instance no of last instance of this block or -1
125
    //  currBlockInstNo               // current block instance no, used during generation of output file
126
    //  blockVarCnt                   // no of variables in block
127
    //  blockVarNoToVarNoMap          // maps block variable numbers to variable numbers
128
    //  firstVarRefNo                 // variable reference no of first variable of this block or -1
129
var $blockTabCnt; // no of entries used in BlockTab
130
var $blockNameToNoMap; // maps block names to block numbers
131
var $openBlocksTab;
132
    // During parsing, this table contains the block numbers of the open parent blocks (nested outer blocks).
133
    // Indexed by the block nesting level.
134
var $blockInstTab; // block instances table
135
    // This table contains an entry for each block instance that has been added.
136
    // Indexed by BlockInstNo.
137
    // Fields:
138
    //  blockNo                       // block number
139
    //  instanceLevel                 // instance level of this block
140
    //     InstanceLevel is an instance counter per block.
141
    //     (In contrast to blockInstNo, which is an instance counter over the instances of all blocks)
142
    //  parentInstLevel               // instance level of parent block
143
    //  nextBlockInstNo               // pointer to next instance of this block or -1
144
    //     Forward chain for instances of same block.
145
    //  blockVarTab                   // block instance variables
146
var $blockInstTabCnt; // no of entries used in BlockInstTab
147
148
var $currentNestingLevel; // Current block nesting level during parsing.
149
var $templateValid; // true if a valid template is prepared
150
var $outputMode; // 0 = to PHP output stream, 1 = to file, 2 = to string
151
var $outputFileHandle; // file handle during writing of output file
152
var $outputError; // true when an output error occurred
153
var $outputString; // string buffer for the generated HTML page
154
155
/**#@-*/
156
157
//--- constructor ---------------------------------------------------------------------------------------------------
158
159
/**
160
* Constructs a MiniTemplator object.
161
* @access public
162
*/
163
function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
164
    $this->templateValid = false; }
165
166
//--- template string handling --------------------------------------------------------------------------------------
167
168
/**
169
* Reads the template from a file.
170
* @param  string   $fileName  name of the file that contains the template.
171
* @return boolean  true on success, false on error.
172
* @access public
173
*/
174
function readTemplateFromFile($fileName) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
175
    if (!$this->readFileIntoString($fileName, $s)) {
176
        $this->triggerError("Error while reading template file ".$fileName.".");
177
        return false; }
178
    if (!$this->setTemplateString($s)) {
179
        return false;
180
    }
181
    return true; }
182
183
/**
184
* Assigns a new template string.
185
* @param  string   $templateString  contents of the template file.
186
* @return boolean  true on success, false on error.
187
* @access public
188
*/
189
function setTemplateString($templateString) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
190
    $this->templateValid = false;
191
    $this->template = $templateString;
192
    if (!$this->parseTemplate()) {
193
        return false;
194
    }
195
    $this->reset();
196
    $this->templateValid = true;
197
    return true; }
198
199
/**
200
* Loads the template string for a subtemplate (used for the $Include command).
201
* @return boolean  true on success, false on error.
202
* @access private
203
*/
204
function loadSubtemplate($subtemplateName, &$s) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
205
    $subtemplateFileName = $this->combineFileSystemPath($this->subtemplateBasePath, $subtemplateName);
206
    if (!$this->readFileIntoString($subtemplateFileName, $s)) {
207
        $this->triggerError("Error while reading subtemplate file ".$subtemplateFileName.".");
208
        return false; }
209
    return true; }
210
211
//--- template parsing ----------------------------------------------------------------------------------------------
212
213
/**
214
* Parses the template.
215
* @return boolean  true on success, false on error.
216
* @access private
217
*/
218
function parseTemplate() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
219
    $this->initParsing();
220
    $this->beginMainBlock();
221
    if (!$this->parseTemplateCommands()) {
222
        return false;
223
    }
224
    $this->endMainBlock();
225
    if (!$this->checkBlockDefinitionsComplete()) {
226
        return false;
227
    }
228
    if (!$this->parseTemplateVariables()) {
229
        return false;
230
    }
231
    $this->associateVariablesWithBlocks();
232
    return true; }
233
234
/**
235
* @access private
236
*/
237
function initParsing() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
238
    $this->varTab = array();
239
    $this->varTabCnt = 0;
240
    $this->varNameToNoMap = array();
241
    $this->varRefTab = array();
242
    $this->varRefTabCnt = 0;
243
    $this->blockTab = array();
244
    $this->blockTabCnt = 0;
245
    $this->blockNameToNoMap = array();
246
    $this->openBlocksTab = array(); }
247
248
/**
249
* Registers the main block.
250
* The main block is an implicitly defined block that covers the whole template.
251
* @access private
252
*/
253
function beginMainBlock() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
254
    $blockNo = 0;
255
    $this->registerBlock('@@InternalMainBlock@@', $blockNo);
256
    $bte = & $this->blockTab[$blockNo];
257
    $bte['tPosBegin'] = 0;
258
    $bte['tPosContentsBegin'] = 0;
259
    $bte['nestingLevel'] = 0;
260
    $bte['parentBlockNo'] = -1;
261
    $bte['definitionIsOpen'] = true;
262
    $this->openBlocksTab[0] = $blockNo;
263
    $this->currentNestingLevel = 1; }
264
265
/**
266
* Completes the main block registration.
267
* @access private
268
*/
269
function endMainBlock() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
270
    $bte = & $this->blockTab[0];
271
    $bte['tPosContentsEnd'] = strlen($this->template);
272
    $bte['tPosEnd'] = strlen($this->template);
273
    $bte['definitionIsOpen'] = false;
274
    $this->currentNestingLevel -= 1; }
275
276
/**
277
* Parses commands within the template in the format "<!-- $command parameters -->".
278
* @return boolean  true on success, false on error.
279
* @access private
280
*/
281
function parseTemplateCommands() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
282
    $p = 0;
283
    while (true) {
284
        $p0 = strpos($this->template, '<!--', $p);
285
        if ($p0 === false) {
286
            break;
287
        }
288
        $p = strpos($this->template, '-->', $p0);
289
        if ($p === false) {
290
            $this->triggerError("Invalid HTML comment in template at offset $p0.");
291
            return false; }
292
        $p += 3;
293
        $cmdL = substr($this->template, $p0 + 4, $p - $p0 - 7);
294
        if (!$this->processTemplateCommand($cmdL, $p0, $p, $resumeFromStart)) {
295
                    return false;
296
        }
297
        if ($resumeFromStart) {
298
            $p = $p0;
299
        }
300
        }
301
    return true; }
302
303
/**
304
* @return boolean  true on success, false on error.
305
* @access private
306
*/
307
function processTemplateCommand($cmdL, $cmdTPosBegin, $cmdTPosEnd, &$resumeFromStart) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
308
    $resumeFromStart = false;
309
    $p = 0;
310
    $cmd = '';
311
    if (!$this->parseWord($cmdL, $p, $cmd)) {
312
        return true;
313
    }
314
    $parms = substr($cmdL, $p);
315
    switch (strtoupper($cmd)) {
316
    case '$BEGINBLOCK':
317
     if (!$this->processBeginBlockCmd($parms, $cmdTPosBegin, $cmdTPosEnd)) {
318
                return false;
319
        }
320
        break;
321
    case '$ENDBLOCK':
322
     if (!$this->processEndBlockCmd($parms, $cmdTPosBegin, $cmdTPosEnd)) {
323
                return false;
324
        }
325
        break;
326
    case '$INCLUDE':
327
     if (!$this->processincludeCmd($parms, $cmdTPosBegin, $cmdTPosEnd)) {
328
                return false;
329
        }
330
        $resumeFromStart = true;
331
        break;
332
    default:
333
     if ($cmd{0} == '$' && !(strlen($cmd) >= 2 && $cmd{1} == '{')) {
334
        $this->triggerError("Unknown command \"$cmd\" in template at offset $cmdTPosBegin.");
335
        return false; }}
336
    return true; }
337
338
/**
339
* Processes the $BeginBlock command.
340
* @return boolean  true on success, false on error.
341
* @access private
342
*/
343
function processBeginBlockCmd($parms, $cmdTPosBegin, $cmdTPosEnd) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
344
    $p = 0;
345
    if (!$this->parseWord($parms, $p, $blockName)) {
346
        $this->triggerError("Missing block name in \$BeginBlock command in template at offset $cmdTPosBegin.");
347
        return false; }
348
    if (trim(substr($parms, $p)) != '') {
349
        $this->triggerError("Extra parameter in \$BeginBlock command in template at offset $cmdTPosBegin.");
350
        return false; }
351
    $this->registerBlock($blockName, $blockNo);
352
    $btr = & $this->blockTab[$blockNo];
353
    $btr['tPosBegin'] = $cmdTPosBegin;
354
    $btr['tPosContentsBegin'] = $cmdTPosEnd;
355
    $btr['nestingLevel'] = $this->currentNestingLevel;
356
    $btr['parentBlockNo'] = $this->openBlocksTab[$this->currentNestingLevel - 1];
357
    $this->openBlocksTab[$this->currentNestingLevel] = $blockNo;
358
    $this->currentNestingLevel += 1;
359
    if ($this->currentNestingLevel > $this->maxNestingLevel) {
360
        $this->triggerError("Block nesting overflow in template at offset $cmdTPosBegin.");
361
        return false; }
362
    return true; }
363
364
/**
365
* Processes the $EndBlock command.
366
* @return boolean  true on success, false on error.
367
* @access private
368
*/
369
function processEndBlockCmd($parms, $cmdTPosBegin, $cmdTPosEnd) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
370
    $p = 0;
371
    if (!$this->parseWord($parms, $p, $blockName)) {
372
        $this->triggerError("Missing block name in \$EndBlock command in template at offset $cmdTPosBegin.");
373
        return false; }
374
    if (trim(substr($parms, $p)) != '') {
375
        $this->triggerError("Extra parameter in \$EndBlock command in template at offset $cmdTPosBegin.");
376
        return false; }
377
    if (!$this->lookupBlockName($blockName, $blockNo)) {
378
        $this->triggerError("Undefined block name \"$blockName\" in \$EndBlock command in template at offset $cmdTPosBegin.");
379
        return false; }
380
    $this->currentNestingLevel -= 1;
381
    $btr = & $this->blockTab[$blockNo];
382
    if (!$btr['definitionIsOpen']) {
383
        $this->triggerError("Multiple \$EndBlock command for block \"$blockName\" in template at offset $cmdTPosBegin.");
384
        return false; }
385
    if ($btr['nestingLevel'] != $this->currentNestingLevel) {
386
        $this->triggerError("Block nesting level mismatch at \$EndBlock command for block \"$blockName\" in template at offset $cmdTPosBegin.");
387
        return false; }
388
    $btr['tPosContentsEnd'] = $cmdTPosBegin;
389
    $btr['tPosEnd'] = $cmdTPosEnd;
390
    $btr['definitionIsOpen'] = false;
391
    return true; }
392
393
/**
394
* @access private
395
*/
396
function registerBlock($blockName, &$blockNo) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
397
    $blockNo = $this->blockTabCnt++;
398
    $btr = & $this->blockTab[$blockNo];
399
    $btr = array();
400
    $btr['blockName'] = $blockName;
401
    if (!$this->lookupBlockName($blockName, $btr['nextWithSameName'])) {
402
            $btr['nextWithSameName'] = -1;
403
    }
404
    $btr['definitionIsOpen'] = true;
405
    $btr['instances'] = 0;
406
    $btr['firstBlockInstNo'] = -1;
407
    $btr['lastBlockInstNo'] = -1;
408
    $btr['blockVarCnt'] = 0;
409
    $btr['firstVarRefNo'] = -1;
410
    $btr['blockVarNoToVarNoMap'] = array();
411
    $this->blockNameToNoMap[strtoupper($blockName)] = $blockNo; }
412
413
/**
414
* Checks that all block definitions are closed.
415
* @return boolean  true on success, false on error.
416
* @access private
417
*/
418
function checkBlockDefinitionsComplete() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
419
    for ($blockNo = 0; $blockNo < $this->blockTabCnt; $blockNo++) {
420
        $btr = & $this->blockTab[$blockNo];
421
        if ($btr['definitionIsOpen']) {
422
            $this->triggerError("Missing \$EndBlock command in template for block ".$btr['blockName'].".");
423
            return false; }}
424
    if ($this->currentNestingLevel != 0) {
425
        $this->triggerError("Block nesting level error at end of template.");
426
        return false; }
427
    return true; }
428
429
/**
430
* Processes the $Include command.
431
* @return boolean  true on success, false on error.
432
* @access private
433
*/
434
function processIncludeCmd($parms, $cmdTPosBegin, $cmdTPosEnd) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
435
    $p = 0;
436
    if (!$this->parseWordOrQuotedString($parms, $p, $subtemplateName)) {
437
        $this->triggerError("Missing or invalid subtemplate name in \$Include command in template at offset $cmdTPosBegin.");
438
        return false; }
439
    if (trim(substr($parms, $p)) != '') {
440
        $this->triggerError("Extra parameter in \$include command in template at offset $cmdTPosBegin.");
441
        return false; }
442
    return $this->insertSubtemplate($subtemplateName, $cmdTPosBegin, $cmdTPosEnd); }
443
444
/**
445
* Processes the $Include command.
446
* @return boolean  true on success, false on error.
447
* @access private
448
*/
449
function insertSubtemplate($subtemplateName, $tPos1, $tPos2) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
450
    if (strlen($this->template) > $this->maxInclTemplateSize) {
451
        $this->triggerError("Subtemplate include aborted because the internal template string is longer than $this->maxInclTemplateSize characters.");
452
        return false; }
453
    if (!$this->loadSubtemplate($subtemplateName, $subtemplate)) {
454
        return false;
455
    }
456
    // (Copying the template to insert a subtemplate is a bit slow. In a future implementation of MiniTemplator,
457
    // a table could be used that contains references to the string fragments.)
458
    $this->template = substr($this->template, 0, $tPos1).$subtemplate.substr($this->template, $tPos2);
459
    return true; }
460
461
/**
462
* Parses variable references within the template in the format "${VarName}".
463
* @return boolean  true on success, false on error.
464
* @access private
465
*/
466
function parseTemplateVariables() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
467
    $p = 0;
468
    while (true) {
469
        $p = strpos($this->template, '${', $p);
470
        if ($p === false) {
471
            break;
472
        }
473
        $p0 = $p;
474
        $p = strpos($this->template, '}', $p);
475
        if ($p === false) {
476
            $this->triggerError("Invalid variable reference in template at offset $p0.");
477
            return false; }
478
        $p += 1;
479
        $varName = trim(substr($this->template, $p0 + 2, $p - $p0 - 3));
480
        if (strlen($varName) == 0) {
481
            $this->triggerError("Empty variable name in template at offset $p0.");
482
            return false; }
483
        $this->registerVariableReference($varName, $p0, $p); }
484
    return true; }
485
486
/**
487
* @access private
488
*/
489
function registerVariableReference($varName, $tPosBegin, $tPosEnd) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
490
    if (!$this->lookupVariableName($varName, $varNo)) {
491
            $this->registerVariable($varName, $varNo);
492
    }
493
    $varRefNo = $this->varRefTabCnt++;
494
    $vrtr = & $this->varRefTab[$varRefNo];
495
    $vrtr = array();
496
    $vrtr['tPosBegin'] = $tPosBegin;
497
    $vrtr['tPosEnd'] = $tPosEnd;
498
    $vrtr['varNo'] = $varNo; }
499
500
/**
501
* @access private
502
*/
503
function registerVariable($varName, &$varNo) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
504
    $varNo = $this->varTabCnt++;
505
    $vtr = & $this->varTab[$varNo];
506
    $vtr = array();
507
    $vtr['varName'] = $varName;
508
    $vtr['varValue'] = '';
509
    $this->varNameToNoMap[strtoupper($varName)] = $varNo; }
510
511
/**
512
* Associates variable references with blocks.
513
* @access private
514
*/
515
function associateVariablesWithBlocks() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
516
    $varRefNo = 0;
517
    $activeBlockNo = 0;
518
    $nextBlockNo = 1;
519
    while ($varRefNo < $this->varRefTabCnt) {
520
        $vrtr = & $this->varRefTab[$varRefNo];
521
        $varRefTPos = $vrtr['tPosBegin'];
522
        $varNo = $vrtr['varNo'];
523
        if ($varRefTPos >= $this->blockTab[$activeBlockNo]['tPosEnd']) {
524
            $activeBlockNo = $this->blockTab[$activeBlockNo]['parentBlockNo'];
525
            continue; }
526
        if ($nextBlockNo < $this->blockTabCnt) {
527
            if ($varRefTPos >= $this->blockTab[$nextBlockNo]['tPosBegin']) {
528
            $activeBlockNo = $nextBlockNo;
529
            $nextBlockNo += 1;
530
            continue; }}
531
        $btr = & $this->blockTab[$activeBlockNo];
532
        if ($varRefTPos < $btr['tPosBegin']) {
533
                    $this->programLogicError(1);
534
        }
535
        $blockVarNo = $btr['blockVarCnt']++;
536
        $btr['blockVarNoToVarNoMap'][$blockVarNo] = $varNo;
537
        if ($btr['firstVarRefNo'] == -1) {
538
                    $btr['firstVarRefNo'] = $varRefNo;
539
        }
540
        $vrtr['blockNo'] = $activeBlockNo;
541
        $vrtr['blockVarNo'] = $blockVarNo;
542
        $varRefNo += 1; }}
543
544
//--- build up (template variables and blocks) ----------------------------------------------------------------------
545
546
/**
547
* Clears all variables and blocks.
548
* This method can be used to produce another HTML page with the same
549
* template. It is faster than creating another MiniTemplator object,
550
* because the template does not have to be parsed again.
551
* All variable values are cleared and all added block instances are deleted.
552
* @access public
553
*/
554
function reset() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
555
    for ($varNo = 0; $varNo < $this->varTabCnt; $varNo++) {
556
            $this->varTab[$varNo]['varValue'] = '';
557
    }
558
    for ($blockNo = 0; $blockNo < $this->blockTabCnt; $blockNo++) {
559
        $btr = & $this->blockTab[$blockNo];
560
        $btr['instances'] = 0;
561
        $btr['firstBlockInstNo'] = -1;
562
        $btr['lastBlockInstNo'] = -1; }
563
    $this->blockInstTab = array();
564
    $this->blockInstTabCnt = 0; }
565
566
/**
567
* Sets a template variable.
568
* For variables that are used in blocks, the variable value
569
* must be set before {@link addBlock} is called.
570
* @param  string  $variableName   the name of the variable to be set.
571
* @param  string  $variableValue  the new value of the variable.
572
* @param  boolean $isOptional     Specifies whether an error should be
573
*    generated when the variable does not exist in the template. If
574
*    $isOptional is false and the variable does not exist, an error is
575
*    generated.
576
* @return boolean true on success, or false on error (e.g. when no
577
*    variable with the specified name exists in the template and
578
*    $isOptional is false).
579
* @access public
580
*/
581
function setVariable($variableName, $variableValue, $isOptional = false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
582
    if (!$this->templateValid) {$this->triggerError("Template not valid."); return false; }
583
    if (!$this->lookupVariableName($variableName, $varNo)) {
584
        if ($isOptional) {
585
            return true;
586
        }
587
        $this->triggerError("Variable \"$variableName\" not defined in template.");
588
        return false; }
589
    $this->varTab[$varNo]['varValue'] = $variableValue;
590
    return true; }
591
592
/**
593
* Sets a template variable to an escaped string.
594
* This method is identical to (@link setVariable), except that
595
* the characters &lt;, &gt;, &amp;, ' and " of variableValue are
596
* replaced by their corresponding HTML/XML character entity codes.
597
* For variables that are used in blocks, the variable value
598
* must be set before {@link addBlock} is called.
599
* @param  string  $variableName   the name of the variable to be set.
600
* @param  string  $variableValue  the new value of the variable. Special HTML/XML characters are escaped.
601
* @param  boolean $isOptional     Specifies whether an error should be
602
*    generated when the variable does not exist in the template. If
603
*    $isOptional is false and the variable does not exist, an error is
604
*    generated.
605
* @return boolean true on success, or false on error (e.g. when no
606
*    variable with the specified name exists in the template and
607
*    $isOptional is false).
608
* @access public
609
*/
610
function setVariableEsc($variableName, $variableValue, $isOptional = false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
611
    return $this->setVariable($variableName, htmlspecialchars($variableValue, ENT_QUOTES), $isOptional); }
612
613
/**
614
* Checks whether a variable with the specified name exists within the template.
615
* @param  string  $variableName   the name of the variable.
616
* @return boolean true if the variable exists, or false when no
617
*    variable with the specified name exists in the template.
618
* @access public
619
*/
620
function variableExists($variableName) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
621
    if (!$this->templateValid) {$this->triggerError("Template not valid."); return false; }
622
    return $this->lookupVariableName($variableName, $varNo); }
623
624
/**
625
* Adds an instance of a template block.
626
* If the block contains variables, these variables must be set
627
* before the block is added.
628
* If the block contains subblocks (nested blocks), the subblocks
629
* must be added before this block is added.
630
* If multiple blocks exist with the specified name, an instance
631
* is added for each block occurence.
632
* @param  string   blockName the name of the block to be added.
0 ignored issues
show
Bug introduced by
The type blockName was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
633
* @return boolean  true on success, false on error (e.g. when no
634
*    block with the specified name exists in the template).
635
* @access public
636
*/
637
function addBlock($blockName) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
638
    if (!$this->templateValid) {$this->triggerError("Template not valid."); return false; }
639
    if (!$this->lookupBlockName($blockName, $blockNo)) {
640
        $this->triggerError("Block \"$blockName\" not defined in template.");
641
        return false; }
642
    while ($blockNo != -1) {
643
        $this->addBlockByNo($blockNo);
644
        $blockNo = $this->blockTab[$blockNo]['nextWithSameName']; }
645
    return true; }
646
647
/**
648
* @access private
649
*/
650
function addBlockByNo($blockNo) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
651
    $btr = & $this->blockTab[$blockNo];
652
    $this->registerBlockInstance($blockInstNo);
653
    $bitr = & $this->blockInstTab[$blockInstNo];
654
    if ($btr['firstBlockInstNo'] == -1) {
655
            $btr['firstBlockInstNo'] = $blockInstNo;
656
    }
657
    if ($btr['lastBlockInstNo'] != -1) {
658
            $this->blockInstTab[$btr['lastBlockInstNo']]['nextBlockInstNo'] = $blockInstNo;
659
    }
660
            // set forward pointer of chain
661
    $btr['lastBlockInstNo'] = $blockInstNo;
662
    $parentBlockNo = $btr['parentBlockNo'];
663
    $blockVarCnt = $btr['blockVarCnt'];
664
    $bitr['blockNo'] = $blockNo;
665
    $bitr['instanceLevel'] = $btr['instances']++;
666
    if ($parentBlockNo == -1) {
667
            $bitr['parentInstLevel'] = -1;
668
    } else {
669
            $bitr['parentInstLevel'] = $this->blockTab[$parentBlockNo]['instances'];
670
    }
671
    $bitr['nextBlockInstNo'] = -1;
672
    $bitr['blockVarTab'] = array();
673
    // copy instance variables for this block
674
    for ($blockVarNo = 0; $blockVarNo < $blockVarCnt; $blockVarNo++) {
675
        $varNo = $btr['blockVarNoToVarNoMap'][$blockVarNo];
676
        $bitr['blockVarTab'][$blockVarNo] = $this->varTab[$varNo]['varValue']; }}
677
678
/**
679
* @access private
680
*/
681
function registerBlockInstance(&$blockInstNo) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
682
    $blockInstNo = $this->blockInstTabCnt++; }
683
684
/**
685
* Checks whether a block with the specified name exists within the template.
686
* @param  string  $blockName   the name of the block.
687
* @return boolean true if the block exists, or false when no
688
*    block with the specified name exists in the template.
689
* @access public
690
*/
691
function blockExists($blockName) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
692
    if (!$this->templateValid) {$this->triggerError("Template not valid."); return false; }
693
    return $this->lookupBlockName($blockName, $blockNo); }
694
695
//--- output generation ---------------------------------------------------------------------------------------------
696
697
/**
698
* Generates the HTML page and writes it to the PHP output stream.
699
* @return boolean  true on success, false on error.
700
* @access public
701
*/
702
function generateOutput() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
703
    $this->outputMode = 0;
704
    if (!$this->generateOutputPage()) {
705
        return false;
706
    }
707
    return true; }
708
709
/**
710
* Generates the HTML page and writes it to a file.
711
* @param  string   $fileName  name of the output file.
712
* @return boolean  true on success, false on error.
713
* @access public
714
*/
715
function generateOutputToFile($fileName) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
716
    $fh = fopen($fileName, "wb");
717
    if ($fh === false) {
718
        return false;
719
    }
720
    $this->outputMode = 1;
721
    $this->outputFileHandle = $fh;
722
    $ok = $this->generateOutputPage();
723
    fclose($fh);
724
    return $ok; }
725
726
/**
727
* Generates the HTML page and writes it to a string.
728
* @param  string   $outputString  variable that receives
729
*                  the contents of the generated HTML page.
730
* @return boolean  true on success, false on error.
731
* @access public
732
*/
733
function generateOutputToString(&$outputString) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
734
    $outputString = "Error";
735
    $this->outputMode = 2;
736
    $this->outputString = "";
737
    if (!$this->generateOutputPage()) {
738
        return false;
739
    }
740
    $outputString = $this->outputString;
741
    return true; }
742
743
/**
744
* @access private
745
* @return boolean  true on success, false on error.
746
*/
747
function generateOutputPage() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
748
    if (!$this->templateValid) {$this->triggerError("Template not valid."); return false; }
749
    if ($this->blockTab[0]['instances'] == 0) {
750
            $this->addBlockByNo(0);
751
    }
752
    // add main block
753
    for ($blockNo = 0; $blockNo < $this->blockTabCnt; $blockNo++) {
754
        $btr = & $this->blockTab[$blockNo];
755
        $btr['currBlockInstNo'] = $btr['firstBlockInstNo']; }
756
    $this->outputError = false;
757
    $this->writeBlockInstances(0, -1);
758
    if ($this->outputError) {
759
        return false;
760
    }
761
    return true; }
762
763
/**
764
* Writes all instances of a block that are contained within a specific
765
* parent block instance.
766
* Called recursively.
767
* @access private
768
*/
769
function writeBlockInstances($blockNo, $parentInstLevel) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
770
    $btr = & $this->blockTab[$blockNo];
771
    while (!$this->outputError) {
772
        $blockInstNo = $btr['currBlockInstNo'];
773
        if ($blockInstNo == -1) {
774
            break;
775
        }
776
        $bitr = & $this->blockInstTab[$blockInstNo];
777
        if ($bitr['parentInstLevel'] < $parentInstLevel) {
778
                    $this->programLogicError(2);
779
        }
780
        if ($bitr['parentInstLevel'] > $parentInstLevel) {
781
            break;
782
        }
783
        $this->writeBlockInstance($blockInstNo);
784
        $btr['currBlockInstNo'] = $bitr['nextBlockInstNo']; }}
785
786
/**
787
* @access private
788
*/
789
function writeBlockInstance($blockInstNo) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
790
    $bitr = & $this->blockInstTab[$blockInstNo];
791
    $blockNo = $bitr['blockNo'];
792
    $btr = & $this->blockTab[$blockNo];
793
    $tPos = $btr['tPosContentsBegin'];
794
    $subBlockNo = $blockNo + 1;
795
    $varRefNo = $btr['firstVarRefNo'];
796
    while (!$this->outputError) {
797
        $tPos2 = $btr['tPosContentsEnd'];
798
        $kind = 0; // assume end-of-block
799
        if ($varRefNo != -1 && $varRefNo < $this->varRefTabCnt) {  // check for variable reference
800
            $vrtr = & $this->varRefTab[$varRefNo];
801
            if ($vrtr['tPosBegin'] < $tPos) {
802
            $varRefNo += 1;
803
            continue; }
804
            if ($vrtr['tPosBegin'] < $tPos2) {
805
            $tPos2 = $vrtr['tPosBegin'];
806
            $kind = 1; }}
807
        if ($subBlockNo < $this->blockTabCnt) {   // check for subblock
808
            $subBtr = & $this->blockTab[$subBlockNo];
809
            if ($subBtr['tPosBegin'] < $tPos) {
810
            $subBlockNo += 1;
811
            continue; }
812
            if ($subBtr['tPosBegin'] < $tPos2) {
813
            $tPos2 = $subBtr['tPosBegin'];
814
            $kind = 2; }}
815
        if ($tPos2 > $tPos) {
816
                    $this->writeString(substr($this->template, $tPos, $tPos2 - $tPos));
817
        }
818
        switch ($kind) {
819
        case 0:         // end of block
820
        return;
821
        case 1:         // variable
822
        $vrtr = & $this->varRefTab[$varRefNo];
823
        if ($vrtr['blockNo'] != $blockNo) {
824
                    $this->programLogicError(4);
825
        }
826
        $variableValue = $bitr['blockVarTab'][$vrtr['blockVarNo']];
827
        $this->writeString($variableValue);
828
        $tPos = $vrtr['tPosEnd'];
829
        $varRefNo += 1;
830
        break;
831
        case 2:         // sub block
832
        $subBtr = & $this->blockTab[$subBlockNo];
833
        if ($subBtr['parentBlockNo'] != $blockNo) {
834
                    $this->programLogicError(3);
835
        }
836
        $this->writeBlockInstances($subBlockNo, $bitr['instanceLevel']); // recursive call
837
        $tPos = $subBtr['tPosEnd'];
838
        $subBlockNo += 1;
839
        break; }}}
840
841
/**
842
* @access private
843
*/
844
function writeString($s) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
845
    if ($this->outputError) {
846
        return;
847
    }
848
    switch ($this->outputMode) {
849
        case 0:
850
            print($s);
851
            break;
852
        case 1:
853
            $rc = fwrite($this->outputFileHandle, $s);
854
            if ($rc === false) {
855
                $this->outputError = true;
856
            }
857
            break;
858
        case 2:
859
            $this->outputString .= $s;
860
            break;
861
    }
862
}
863
864
//--- name lookup routines ------------------------------------------------------------------------------------------
865
866
/**
867
* Maps variable name to variable number.
868
* @return boolean  true on success, false if the variable is not found.
869
* @access private
870
*/
871
function lookupVariableName($varName, &$varNo) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
872
    $x = & $this->varNameToNoMap[strtoupper($varName)];
873
    if (!isset($x)) {
874
        return false;
875
    }
876
    $varNo = $x;
877
    return true; }
878
879
/**
880
* Maps block name to block number.
881
* If there are multiple blocks with the same name, the block number of the last
882
* registered block with that name is returned.
883
* @return boolean  true on success, false when the block is not found.
884
* @access private
885
*/
886
function lookupBlockName($blockName, &$blockNo) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
887
    $x = & $this->blockNameToNoMap[strtoupper($blockName)];
888
    if (!isset($x)) {
889
        return false;
890
    }
891
    $blockNo = $x;
892
    return true; }
893
894
//--- general utility routines -----------------------------------------------------------------------------------------
895
896
/**
897
* Reads a file into a string.
898
* @return boolean  true on success, false on error.
899
* @access private
900
*/
901
function readFileIntoString($fileName, &$s) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
902
    if (function_exists('version_compare') && version_compare(phpversion(), "4.3.0", ">=")) {
903
        $s = file_get_contents($fileName);
904
        if ($s === false) {
905
            return false;
906
        }
907
        return true; }
908
    $fh = fopen($fileName, "rb");
909
    if ($fh === false) {
910
        return false;
911
    }
912
    $fileSize = filesize($fileName);
913
    if ($fileSize === false) {fclose($fh); return false; }
914
    $s = fread($fh, $fileSize);
915
    fclose($fh);
916
    if (strlen($s) != $fileSize) {
917
        return false;
918
    }
919
    return true; }
920
921
/**
922
* @access private
923
* @return boolean  true on success, false when the end of the string is reached.
924
*/
925
function parseWord($s, &$p, &$w) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
926
    $sLen = strlen($s);
927
    while ($p < $sLen && ord($s{$p}) <= 32) {
928
        $p++;
929
    }
930
    if ($p >= $sLen) {
931
        return false;
932
    }
933
    $p0 = $p;
934
    while ($p < $sLen && ord($s{$p}) > 32) {
935
        $p++;
936
    }
937
    $w = substr($s, $p0, $p - $p0);
938
    return true; }
939
940
/**
941
* @access private
942
* @return boolean  true on success, false on error.
943
*/
944
function parseQuotedString($s, &$p, &$w) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
945
    $sLen = strlen($s);
946
    while ($p < $sLen && ord($s{$p}) <= 32) {
947
        $p++;
948
    }
949
    if ($p >= $sLen) {
950
        return false;
951
    }
952
    if (substr($s, $p, 1) != '"') {
953
        return false;
954
    }
955
    $p++; $p0 = $p;
956
    while ($p < $sLen && $s{$p} != '"') {
957
        $p++;
958
    }
959
    if ($p >= $sLen) {
960
        return false;
961
    }
962
    $w = substr($s, $p0, $p - $p0);
963
    $p++;
964
    return true; }
965
966
/**
967
* @access private
968
* @return boolean  true on success, false on error.
969
*/
970
function parseWordOrQuotedString($s, &$p, &$w) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
971
    $sLen = strlen($s);
972
    while ($p < $sLen && ord($s{$p}) <= 32) {
973
        $p++;
974
    }
975
    if ($p >= $sLen) {
976
        return false;
977
    }
978
    if (substr($s, $p, 1) == '"') {
979
            return $this->parseQuotedString($s, $p, $w);
980
    } else {
981
            return $this->parseWord($s, $p, $w);
982
    }
983
    }
984
985
/**
986
* Combine two file system paths.
987
* @access private
988
*/
989
function combineFileSystemPath($path1, $path2) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
990
    if ($path1 == '' || $path2 == '') {
991
        return $path2;
992
    }
993
    $s = $path1;
994
    if (substr($s, -1) != '\\' && substr($s, -1) != '/') {
995
        $s = $s."/";
996
    }
997
    if (substr($path2, 0, 1) == '\\' || substr($path2, 0, 1) == '/') {
998
            $s = $s.substr($path2, 1);
999
    } else {
1000
            $s = $s.$path2;
1001
    }
1002
    return $s; }
1003
1004
/**
1005
* @access private
1006
*/
1007
function triggerError($msg) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1008
    trigger_error("MiniTemplator error: $msg", E_USER_ERROR); }
1009
1010
/**
1011
* @access private
1012
*/
1013
function programLogicError($errorId) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1014
    die ("MiniTemplator: Program logic error $errorId.\n"); }
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1015
1016
}
1017
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
1018