| 148 |
lars |
1 |
/*
|
|
|
2 |
* This file is part of Smarty.
|
|
|
3 |
*
|
|
|
4 |
* (c) 2015 Uwe Tews
|
|
|
5 |
*
|
|
|
6 |
* For the full copyright and license information, please view the LICENSE
|
|
|
7 |
* file that was distributed with this source code.
|
|
|
8 |
*/
|
|
|
9 |
%stack_size 500
|
|
|
10 |
%name TP_
|
|
|
11 |
%declare_class {
|
|
|
12 |
/**
|
|
|
13 |
* Smarty Template Parser Class
|
|
|
14 |
*
|
|
|
15 |
* This is the template parser.
|
|
|
16 |
* It is generated from the smarty_internal_templateparser.y file
|
|
|
17 |
*
|
|
|
18 |
* @author Uwe Tews <uwe.tews@googlemail.com>
|
|
|
19 |
*/
|
|
|
20 |
class Smarty_Internal_Templateparser
|
|
|
21 |
}
|
|
|
22 |
%include_class
|
|
|
23 |
{
|
|
|
24 |
const ERR1 = 'Security error: Call to private object member not allowed';
|
|
|
25 |
const ERR2 = 'Security error: Call to dynamic object member not allowed';
|
|
|
26 |
|
|
|
27 |
/**
|
|
|
28 |
* result status
|
|
|
29 |
*
|
|
|
30 |
* @var bool
|
|
|
31 |
*/
|
|
|
32 |
public $successful = true;
|
|
|
33 |
|
|
|
34 |
/**
|
|
|
35 |
* return value
|
|
|
36 |
*
|
|
|
37 |
* @var mixed
|
|
|
38 |
*/
|
|
|
39 |
public $retvalue = 0;
|
|
|
40 |
|
|
|
41 |
/**
|
|
|
42 |
* @var
|
|
|
43 |
*/
|
|
|
44 |
public $yymajor;
|
|
|
45 |
|
|
|
46 |
/**
|
|
|
47 |
* last index of array variable
|
|
|
48 |
*
|
|
|
49 |
* @var mixed
|
|
|
50 |
*/
|
|
|
51 |
public $last_index;
|
|
|
52 |
|
|
|
53 |
/**
|
|
|
54 |
* last variable name
|
|
|
55 |
*
|
|
|
56 |
* @var string
|
|
|
57 |
*/
|
|
|
58 |
public $last_variable;
|
|
|
59 |
|
|
|
60 |
/**
|
|
|
61 |
* root parse tree buffer
|
|
|
62 |
*
|
|
|
63 |
* @var Smarty_Internal_ParseTree_Template
|
|
|
64 |
*/
|
|
|
65 |
public $root_buffer;
|
|
|
66 |
|
|
|
67 |
/**
|
|
|
68 |
* current parse tree object
|
|
|
69 |
*
|
|
|
70 |
* @var Smarty_Internal_ParseTree
|
|
|
71 |
*/
|
|
|
72 |
public $current_buffer;
|
|
|
73 |
|
|
|
74 |
/**
|
|
|
75 |
* lexer object
|
|
|
76 |
*
|
|
|
77 |
* @var Smarty_Internal_Templatelexer
|
|
|
78 |
*/
|
|
|
79 |
public $lex;
|
|
|
80 |
|
|
|
81 |
/**
|
|
|
82 |
* internal error flag
|
|
|
83 |
*
|
|
|
84 |
* @var bool
|
|
|
85 |
*/
|
|
|
86 |
private $internalError = false;
|
|
|
87 |
|
|
|
88 |
/**
|
|
|
89 |
* {strip} status
|
|
|
90 |
*
|
|
|
91 |
* @var bool
|
|
|
92 |
*/
|
|
|
93 |
public $strip = false;
|
|
|
94 |
/**
|
|
|
95 |
* compiler object
|
|
|
96 |
*
|
|
|
97 |
* @var Smarty_Internal_TemplateCompilerBase
|
|
|
98 |
*/
|
|
|
99 |
public $compiler = null;
|
|
|
100 |
|
|
|
101 |
/**
|
|
|
102 |
* smarty object
|
|
|
103 |
*
|
|
|
104 |
* @var Smarty
|
|
|
105 |
*/
|
|
|
106 |
public $smarty = null;
|
|
|
107 |
|
|
|
108 |
/**
|
|
|
109 |
* template object
|
|
|
110 |
*
|
|
|
111 |
* @var Smarty_Internal_Template
|
|
|
112 |
*/
|
|
|
113 |
public $template = null;
|
|
|
114 |
|
|
|
115 |
/**
|
|
|
116 |
* block nesting level
|
|
|
117 |
*
|
|
|
118 |
* @var int
|
|
|
119 |
*/
|
|
|
120 |
public $block_nesting_level = 0;
|
|
|
121 |
|
|
|
122 |
/**
|
|
|
123 |
* security object
|
|
|
124 |
*
|
|
|
125 |
* @var Smarty_Security
|
|
|
126 |
*/
|
|
|
127 |
public $security = null;
|
|
|
128 |
|
|
|
129 |
/**
|
|
|
130 |
* template prefix array
|
|
|
131 |
*
|
|
|
132 |
* @var \Smarty_Internal_ParseTree[]
|
|
|
133 |
*/
|
|
|
134 |
public $template_prefix = array();
|
|
|
135 |
|
|
|
136 |
/**
|
|
|
137 |
* template prefix array
|
|
|
138 |
*
|
|
|
139 |
* @var \Smarty_Internal_ParseTree[]
|
|
|
140 |
*/
|
|
|
141 |
public $template_postfix = array();
|
|
|
142 |
|
|
|
143 |
/**
|
|
|
144 |
* constructor
|
|
|
145 |
*
|
|
|
146 |
* @param Smarty_Internal_Templatelexer $lex
|
|
|
147 |
* @param Smarty_Internal_TemplateCompilerBase $compiler
|
|
|
148 |
*/
|
|
|
149 |
public function __construct(Smarty_Internal_Templatelexer $lex, Smarty_Internal_TemplateCompilerBase $compiler)
|
|
|
150 |
{
|
|
|
151 |
$this->lex = $lex;
|
|
|
152 |
$this->compiler = $compiler;
|
|
|
153 |
$this->template = $this->compiler->template;
|
|
|
154 |
$this->smarty = $this->template->smarty;
|
|
|
155 |
$this->security = isset($this->smarty->security_policy) ? $this->smarty->security_policy : false;
|
|
|
156 |
$this->current_buffer = $this->root_buffer = new Smarty_Internal_ParseTree_Template();
|
|
|
157 |
}
|
|
|
158 |
|
|
|
159 |
/**
|
|
|
160 |
* insert PHP code in current buffer
|
|
|
161 |
*
|
|
|
162 |
* @param string $code
|
|
|
163 |
*/
|
|
|
164 |
public function insertPhpCode($code)
|
|
|
165 |
{
|
|
|
166 |
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Tag($this, $code));
|
|
|
167 |
}
|
|
|
168 |
|
|
|
169 |
/**
|
|
|
170 |
* error rundown
|
|
|
171 |
*
|
|
|
172 |
*/
|
|
|
173 |
public function errorRunDown()
|
|
|
174 |
{
|
|
|
175 |
while ($this->yystack !== array()) {
|
|
|
176 |
$this->yy_pop_parser_stack();
|
|
|
177 |
}
|
|
|
178 |
if (is_resource($this->yyTraceFILE)) {
|
|
|
179 |
fclose($this->yyTraceFILE);
|
|
|
180 |
}
|
|
|
181 |
}
|
|
|
182 |
|
|
|
183 |
/**
|
|
|
184 |
* merge PHP code with prefix code and return parse tree tag object
|
|
|
185 |
*
|
|
|
186 |
* @param string $code
|
|
|
187 |
*
|
|
|
188 |
* @return Smarty_Internal_ParseTree_Tag
|
|
|
189 |
*/
|
|
|
190 |
public function mergePrefixCode($code)
|
|
|
191 |
{
|
|
|
192 |
$tmp = '';
|
|
|
193 |
foreach ($this->compiler->prefix_code as $preCode) {
|
|
|
194 |
$tmp .= $preCode;
|
|
|
195 |
}
|
|
|
196 |
$this->compiler->prefix_code = array();
|
|
|
197 |
$tmp .= $code;
|
|
|
198 |
return new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp, true));
|
|
|
199 |
}
|
|
|
200 |
|
|
|
201 |
}
|
|
|
202 |
|
|
|
203 |
%token_prefix TP_
|
|
|
204 |
|
|
|
205 |
%parse_accept
|
|
|
206 |
{
|
|
|
207 |
$this->successful = !$this->internalError;
|
|
|
208 |
$this->internalError = false;
|
|
|
209 |
$this->retvalue = $this->_retvalue;
|
|
|
210 |
}
|
|
|
211 |
|
|
|
212 |
%syntax_error
|
|
|
213 |
{
|
|
|
214 |
$this->internalError = true;
|
|
|
215 |
$this->yymajor = $yymajor;
|
|
|
216 |
$this->compiler->trigger_template_error();
|
|
|
217 |
}
|
|
|
218 |
|
|
|
219 |
%stack_overflow
|
|
|
220 |
{
|
|
|
221 |
$this->internalError = true;
|
|
|
222 |
$this->compiler->trigger_template_error('Stack overflow in template parser');
|
|
|
223 |
}
|
|
|
224 |
|
|
|
225 |
|
|
|
226 |
%right VERT.
|
|
|
227 |
%left COLON.
|
|
|
228 |
|
|
|
229 |
|
|
|
230 |
//
|
|
|
231 |
// complete template
|
|
|
232 |
//
|
|
|
233 |
start(res) ::= template. {
|
|
|
234 |
$this->root_buffer->prepend_array($this, $this->template_prefix);
|
|
|
235 |
$this->root_buffer->append_array($this, $this->template_postfix);
|
|
|
236 |
res = $this->root_buffer->to_smarty_php($this);
|
|
|
237 |
}
|
|
|
238 |
|
|
|
239 |
// template text
|
|
|
240 |
template ::= template TEXT(B). {
|
|
|
241 |
$text = $this->yystack[ $this->yyidx + 0 ]->minor;
|
|
|
242 |
|
|
|
243 |
if ((string)$text == '') {
|
|
|
244 |
$this->current_buffer->append_subtree($this, null);
|
|
|
245 |
}
|
|
|
246 |
|
|
|
247 |
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($text, $this->strip));
|
|
|
248 |
}
|
|
|
249 |
// strip on
|
|
|
250 |
template ::= template STRIPON. {
|
|
|
251 |
$this->strip = true;
|
|
|
252 |
}
|
|
|
253 |
// strip off
|
|
|
254 |
template ::= template STRIPOFF. {
|
|
|
255 |
$this->strip = false;
|
|
|
256 |
}
|
|
|
257 |
|
|
|
258 |
// Literal
|
|
|
259 |
template ::= template LITERALSTART literal_e2(B) LITERALEND. {
|
|
|
260 |
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text(B));
|
|
|
261 |
}
|
|
|
262 |
|
|
|
263 |
|
|
|
264 |
literal_e2(A) ::= literal_e1(B) LITERALSTART literal_e1(C) LITERALEND. {
|
|
|
265 |
A = B.C;
|
|
|
266 |
}
|
|
|
267 |
literal_e2(A) ::= literal_e1(B). {
|
|
|
268 |
A = B;
|
|
|
269 |
}
|
|
|
270 |
|
|
|
271 |
literal_e1(A) ::= literal_e1(B) LITERAL(C). {
|
|
|
272 |
A = B.C;
|
|
|
273 |
|
|
|
274 |
}
|
|
|
275 |
|
|
|
276 |
literal_e1(A) ::= . {
|
|
|
277 |
A = '';
|
|
|
278 |
}
|
|
|
279 |
// Smarty tag
|
|
|
280 |
template ::= template smartytag(B). {
|
|
|
281 |
if ($this->compiler->has_code) {
|
|
|
282 |
$this->current_buffer->append_subtree($this, $this->mergePrefixCode(B));
|
|
|
283 |
}
|
|
|
284 |
$this->compiler->has_variable_string = false;
|
|
|
285 |
$this->block_nesting_level = count($this->compiler->_tag_stack);
|
|
|
286 |
}
|
|
|
287 |
|
|
|
288 |
|
|
|
289 |
// empty template
|
|
|
290 |
template ::= .
|
|
|
291 |
|
|
|
292 |
smartytag(A) ::= SIMPELOUTPUT(B). {
|
|
|
293 |
$var = trim(substr(B, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' $');
|
|
|
294 |
if (preg_match('/^(.*)(\s+nocache)$/', $var, $match)) {
|
|
|
295 |
A = $this->compiler->compileTag('private_print_expression',array('nocache'),array('value'=>$this->compiler->compileVariable('\''.$match[1].'\'')));
|
|
|
296 |
} else {
|
|
|
297 |
A = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$this->compiler->compileVariable('\''.$var.'\'')));
|
|
|
298 |
}
|
|
|
299 |
}
|
|
|
300 |
|
|
|
301 |
// simple tag like {name}
|
|
|
302 |
smartytag(A)::= SIMPLETAG(B). {
|
|
|
303 |
$tag = trim(substr(B, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()));
|
|
|
304 |
if ($tag == 'strip') {
|
|
|
305 |
$this->strip = true;
|
|
|
306 |
A = null;
|
|
|
307 |
} else {
|
|
|
308 |
if (defined($tag)) {
|
|
|
309 |
if ($this->security) {
|
|
|
310 |
$this->security->isTrustedConstant($tag, $this->compiler);
|
|
|
311 |
}
|
|
|
312 |
A = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$tag));
|
|
|
313 |
} else {
|
|
|
314 |
if (preg_match('/^(.*)(\s+nocache)$/', $tag, $match)) {
|
|
|
315 |
A = $this->compiler->compileTag($match[1],array('\'nocache\''));
|
|
|
316 |
} else {
|
|
|
317 |
A = $this->compiler->compileTag($tag,array());
|
|
|
318 |
}
|
|
|
319 |
}
|
|
|
320 |
}
|
|
|
321 |
}
|
|
|
322 |
// {$smarty.block.child} or {$smarty.block.parent}
|
|
|
323 |
smartytag(A) ::= SMARTYBLOCKCHILDPARENT(i). {
|
|
|
324 |
$j = strrpos(i,'.');
|
|
|
325 |
if (i[$j+1] == 'c') {
|
|
|
326 |
// {$smarty.block.child}
|
|
|
327 |
A = $this->compiler->compileTag('child',array(),array(i));
|
|
|
328 |
} else {
|
|
|
329 |
// {$smarty.block.parent}
|
|
|
330 |
A = $this->compiler->compileTag('parent',array(),array(i));
|
|
|
331 |
}
|
|
|
332 |
}
|
|
|
333 |
|
|
|
334 |
smartytag(A) ::= LDEL tagbody(B) RDEL. {
|
|
|
335 |
A = B;
|
|
|
336 |
}
|
|
|
337 |
|
|
|
338 |
smartytag(A) ::= tag(B) RDEL. {
|
|
|
339 |
A = B;
|
|
|
340 |
}
|
|
|
341 |
// output with optional attributes
|
|
|
342 |
tagbody(A) ::= outattr(B). {
|
|
|
343 |
A = $this->compiler->compileTag('private_print_expression',B[1],array('value'=>B[0]));
|
|
|
344 |
}
|
|
|
345 |
|
|
|
346 |
//
|
|
|
347 |
// Smarty tags start here
|
|
|
348 |
//
|
|
|
349 |
|
|
|
350 |
// assign new style
|
|
|
351 |
tagbody(A) ::= DOLLARID(B) eqoutattr(C). {
|
|
|
352 |
A = $this->compiler->compileTag('assign',array_merge(array(array('value'=>C[0]),array('var'=>'\''.substr(B,1).'\'')),C[1]));
|
|
|
353 |
}
|
|
|
354 |
|
|
|
355 |
tagbody(A) ::= varindexed(B) eqoutattr(C). {
|
|
|
356 |
A = $this->compiler->compileTag('assign',array_merge(array(array('value'=>C[0]),array('var'=>B['var'])),C[1]),array('smarty_internal_index'=>B['smarty_internal_index']));
|
|
|
357 |
}
|
|
|
358 |
|
|
|
359 |
eqoutattr(A) ::= EQUAL outattr(B). {
|
|
|
360 |
A = B;
|
|
|
361 |
}
|
|
|
362 |
|
|
|
363 |
outattr(A) ::= output(B) attributes(C). {
|
|
|
364 |
A = array(B,C);
|
|
|
365 |
}
|
|
|
366 |
|
|
|
367 |
output(A) ::= variable(B). {
|
|
|
368 |
A = B;
|
|
|
369 |
}
|
|
|
370 |
output(A) ::= value(B). {
|
|
|
371 |
A = B;
|
|
|
372 |
}
|
|
|
373 |
output(A) ::= expr(B). {
|
|
|
374 |
A = B;
|
|
|
375 |
}
|
|
|
376 |
|
|
|
377 |
// tag with optional Smarty2 style attributes
|
|
|
378 |
tag(res) ::= LDEL ID(i) attributes(a). {
|
|
|
379 |
if (defined(i)) {
|
|
|
380 |
if ($this->security) {
|
|
|
381 |
$this->security->isTrustedConstant(i, $this->compiler);
|
|
|
382 |
}
|
|
|
383 |
res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i));
|
|
|
384 |
} else {
|
|
|
385 |
res = $this->compiler->compileTag(i,a);
|
|
|
386 |
}
|
|
|
387 |
}
|
|
|
388 |
tag(res) ::= LDEL ID(i). {
|
|
|
389 |
if (defined(i)) {
|
|
|
390 |
if ($this->security) {
|
|
|
391 |
$this->security->isTrustedConstant(i, $this->compiler);
|
|
|
392 |
}
|
|
|
393 |
res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>i));
|
|
|
394 |
} else {
|
|
|
395 |
res = $this->compiler->compileTag(i,array());
|
|
|
396 |
}
|
|
|
397 |
}
|
|
|
398 |
|
|
|
399 |
|
|
|
400 |
// tag with modifier and optional Smarty2 style attributes
|
|
|
401 |
tag(res) ::= LDEL ID(i) modifierlist(l)attributes(a). {
|
|
|
402 |
if (defined(i)) {
|
|
|
403 |
if ($this->security) {
|
|
|
404 |
$this->security->isTrustedConstant(i, $this->compiler);
|
|
|
405 |
}
|
|
|
406 |
res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i, 'modifierlist'=>l));
|
|
|
407 |
} else {
|
|
|
408 |
res = $this->compiler->compileTag(i,a, array('modifierlist'=>l));
|
|
|
409 |
}
|
|
|
410 |
}
|
|
|
411 |
|
|
|
412 |
// registered object tag
|
|
|
413 |
tag(res) ::= LDEL ID(i) PTR ID(m) attributes(a). {
|
|
|
414 |
res = $this->compiler->compileTag(i,a,array('object_method'=>m));
|
|
|
415 |
}
|
|
|
416 |
|
|
|
417 |
// registered object tag with modifiers
|
|
|
418 |
tag(res) ::= LDEL ID(i) PTR ID(me) modifierlist(l) attributes(a). {
|
|
|
419 |
res = $this->compiler->compileTag(i,a,array('modifierlist'=>l, 'object_method'=>me));
|
|
|
420 |
}
|
|
|
421 |
|
|
|
422 |
// nocache tag
|
|
|
423 |
tag(res) ::= LDELMAKENOCACHE DOLLARID(i). {
|
|
|
424 |
res = $this->compiler->compileTag('make_nocache',array(array('var'=>'\''.substr(i,1).'\'')));
|
|
|
425 |
}
|
|
|
426 |
|
|
|
427 |
// {if}, {elseif} and {while} tag
|
|
|
428 |
tag(res) ::= LDELIF(i) expr(ie). {
|
|
|
429 |
$tag = trim(substr(i,$this->compiler->getLdelLength()));
|
|
|
430 |
res = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,array(),array('if condition'=>ie));
|
|
|
431 |
}
|
|
|
432 |
|
|
|
433 |
tag(res) ::= LDELIF(i) expr(ie) attributes(a). {
|
|
|
434 |
$tag = trim(substr(i,$this->compiler->getLdelLength()));
|
|
|
435 |
res = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,a,array('if condition'=>ie));
|
|
|
436 |
}
|
|
|
437 |
|
|
|
438 |
tag(res) ::= LDELIF(i) statement(ie). {
|
|
|
439 |
$tag = trim(substr(i,$this->compiler->getLdelLength()));
|
|
|
440 |
res = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,array(),array('if condition'=>ie));
|
|
|
441 |
}
|
|
|
442 |
|
|
|
443 |
tag(res) ::= LDELIF(i) statement(ie) attributes(a). {
|
|
|
444 |
$tag = trim(substr(i,$this->compiler->getLdelLength()));
|
|
|
445 |
res = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,a,array('if condition'=>ie));
|
|
|
446 |
}
|
|
|
447 |
|
|
|
448 |
// {for} tag
|
|
|
449 |
tag(res) ::= LDELFOR statements(st) SEMICOLON expr(ie) SEMICOLON varindexed(v2) foraction(e2) attributes(a). {
|
|
|
450 |
res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('ifexp'=>ie),array('var'=>v2),array('step'=>e2))),1);
|
|
|
451 |
}
|
|
|
452 |
|
|
|
453 |
foraction(res) ::= EQUAL expr(e). {
|
|
|
454 |
res = '='.e;
|
|
|
455 |
}
|
|
|
456 |
|
|
|
457 |
foraction(res) ::= INCDEC(e). {
|
|
|
458 |
res = e;
|
|
|
459 |
}
|
|
|
460 |
|
|
|
461 |
tag(res) ::= LDELFOR statement(st) TO expr(v) attributes(a). {
|
|
|
462 |
res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('to'=>v))),0);
|
|
|
463 |
}
|
|
|
464 |
|
|
|
465 |
tag(res) ::= LDELFOR statement(st) TO expr(v) STEP expr(v2) attributes(a). {
|
|
|
466 |
res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('to'=>v),array('step'=>v2))),0);
|
|
|
467 |
}
|
|
|
468 |
|
|
|
469 |
// {foreach} tag
|
|
|
470 |
tag(res) ::= LDELFOREACH SPACE expr(e) AS varvar(v0) attributes(a). {
|
|
|
471 |
res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>e),array('item'=>v0))));
|
|
|
472 |
}
|
|
|
473 |
|
|
|
474 |
tag(res) ::= LDELFOREACH SPACE expr(e) AS varvar(v1) APTR varvar(v0) attributes(a). {
|
|
|
475 |
res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>e),array('item'=>v0),array('key'=>v1))));
|
|
|
476 |
}
|
|
|
477 |
tag(res) ::= LDELFOREACH attributes(a). {
|
|
|
478 |
res = $this->compiler->compileTag('foreach',a);
|
|
|
479 |
}
|
|
|
480 |
|
|
|
481 |
// {setfilter}
|
|
|
482 |
tag(res) ::= LDELSETFILTER ID(m) modparameters(p). {
|
|
|
483 |
res = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array(array_merge(array(m),p))));
|
|
|
484 |
}
|
|
|
485 |
|
|
|
486 |
tag(res) ::= LDELSETFILTER ID(m) modparameters(p) modifierlist(l). {
|
|
|
487 |
res = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array_merge(array(array_merge(array(m),p)),l)));
|
|
|
488 |
}
|
|
|
489 |
|
|
|
490 |
|
|
|
491 |
// end of block tag {/....}
|
|
|
492 |
smartytag(res)::= CLOSETAG(t). {
|
|
|
493 |
$tag = trim(substr(t, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' /');
|
|
|
494 |
if ($tag === 'strip') {
|
|
|
495 |
$this->strip = false;
|
|
|
496 |
res = null;
|
|
|
497 |
} else {
|
|
|
498 |
res = $this->compiler->compileTag($tag.'close',array());
|
|
|
499 |
}
|
|
|
500 |
}
|
|
|
501 |
tag(res) ::= LDELSLASH ID(i). {
|
|
|
502 |
res = $this->compiler->compileTag(i.'close',array());
|
|
|
503 |
}
|
|
|
504 |
|
|
|
505 |
tag(res) ::= LDELSLASH ID(i) modifierlist(l). {
|
|
|
506 |
res = $this->compiler->compileTag(i.'close',array(),array('modifier_list'=>l));
|
|
|
507 |
}
|
|
|
508 |
|
|
|
509 |
// end of block object tag {/....}
|
|
|
510 |
tag(res) ::= LDELSLASH ID(i) PTR ID(m). {
|
|
|
511 |
res = $this->compiler->compileTag(i.'close',array(),array('object_method'=>m));
|
|
|
512 |
}
|
|
|
513 |
|
|
|
514 |
tag(res) ::= LDELSLASH ID(i) PTR ID(m) modifierlist(l). {
|
|
|
515 |
res = $this->compiler->compileTag(i.'close',array(),array('object_method'=>m, 'modifier_list'=>l));
|
|
|
516 |
}
|
|
|
517 |
|
|
|
518 |
//
|
|
|
519 |
//Attributes of Smarty tags
|
|
|
520 |
//
|
|
|
521 |
// list of attributes
|
|
|
522 |
attributes(res) ::= attributes(a1) attribute(a2). {
|
|
|
523 |
res = a1;
|
|
|
524 |
res[] = a2;
|
|
|
525 |
}
|
|
|
526 |
|
|
|
527 |
// single attribute
|
|
|
528 |
attributes(res) ::= attribute(a). {
|
|
|
529 |
res = array(a);
|
|
|
530 |
}
|
|
|
531 |
|
|
|
532 |
// no attributes
|
|
|
533 |
attributes(res) ::= . {
|
|
|
534 |
res = array();
|
|
|
535 |
}
|
|
|
536 |
|
|
|
537 |
// attribute
|
|
|
538 |
attribute(res) ::= SPACE ID(v) EQUAL ID(id). {
|
|
|
539 |
if (defined(id)) {
|
|
|
540 |
if ($this->security) {
|
|
|
541 |
$this->security->isTrustedConstant(id, $this->compiler);
|
|
|
542 |
}
|
|
|
543 |
res = array(v=>id);
|
|
|
544 |
} else {
|
|
|
545 |
res = array(v=>'\''.id.'\'');
|
|
|
546 |
}
|
|
|
547 |
}
|
|
|
548 |
|
|
|
549 |
attribute(res) ::= ATTR(v) expr(e). {
|
|
|
550 |
res = array(trim(v," =\n\r\t")=>e);
|
|
|
551 |
}
|
|
|
552 |
|
|
|
553 |
attribute(res) ::= ATTR(v) value(e). {
|
|
|
554 |
res = array(trim(v," =\n\r\t")=>e);
|
|
|
555 |
}
|
|
|
556 |
|
|
|
557 |
attribute(res) ::= SPACE ID(v). {
|
|
|
558 |
res = '\''.v.'\'';
|
|
|
559 |
}
|
|
|
560 |
|
|
|
561 |
attribute(res) ::= SPACE expr(e). {
|
|
|
562 |
res = e;
|
|
|
563 |
}
|
|
|
564 |
|
|
|
565 |
attribute(res) ::= SPACE value(v). {
|
|
|
566 |
res = v;
|
|
|
567 |
}
|
|
|
568 |
|
|
|
569 |
attribute(res) ::= SPACE INTEGER(i) EQUAL expr(e). {
|
|
|
570 |
res = array(i=>e);
|
|
|
571 |
}
|
|
|
572 |
|
|
|
573 |
|
|
|
574 |
|
|
|
575 |
//
|
|
|
576 |
// statement
|
|
|
577 |
//
|
|
|
578 |
statements(res) ::= statement(s). {
|
|
|
579 |
res = array(s);
|
|
|
580 |
}
|
|
|
581 |
|
|
|
582 |
statements(res) ::= statements(s1) COMMA statement(s). {
|
|
|
583 |
s1[]=s;
|
|
|
584 |
res = s1;
|
|
|
585 |
}
|
|
|
586 |
|
|
|
587 |
statement(res) ::= DOLLARID(i) EQUAL INTEGER(e). {
|
|
|
588 |
res = array('var' => '\''.substr(i,1).'\'', 'value'=>e);
|
|
|
589 |
}
|
|
|
590 |
statement(res) ::= DOLLARID(i) EQUAL expr(e). {
|
|
|
591 |
res = array('var' => '\''.substr(i,1).'\'', 'value'=>e);
|
|
|
592 |
}
|
|
|
593 |
|
|
|
594 |
statement(res) ::= varindexed(vi) EQUAL expr(e). {
|
|
|
595 |
res = array('var' => vi, 'value'=>e);
|
|
|
596 |
}
|
|
|
597 |
|
|
|
598 |
statement(res) ::= OPENP statement(st) CLOSEP. {
|
|
|
599 |
res = st;
|
|
|
600 |
}
|
|
|
601 |
|
|
|
602 |
|
|
|
603 |
//
|
|
|
604 |
// expressions
|
|
|
605 |
//
|
|
|
606 |
|
|
|
607 |
// single value
|
|
|
608 |
expr(res) ::= value(v). {
|
|
|
609 |
res = v;
|
|
|
610 |
}
|
|
|
611 |
|
|
|
612 |
// ternary
|
|
|
613 |
expr(res) ::= ternary(v). {
|
|
|
614 |
res = v;
|
|
|
615 |
}
|
|
|
616 |
|
|
|
617 |
// resources/streams
|
|
|
618 |
expr(res) ::= DOLLARID(i) COLON ID(i2). {
|
|
|
619 |
res = '$_smarty_tpl->getStreamVariable(\''.substr(i,1).'://' . i2 . '\')';
|
|
|
620 |
}
|
|
|
621 |
|
|
|
622 |
// arithmetic expression
|
|
|
623 |
expr(res) ::= expr(e) MATH(m) value(v). {
|
|
|
624 |
res = e . trim(m) . v;
|
|
|
625 |
}
|
|
|
626 |
|
|
|
627 |
expr(res) ::= expr(e) UNIMATH(m) value(v). {
|
|
|
628 |
res = e . trim(m) . v;
|
|
|
629 |
}
|
|
|
630 |
|
|
|
631 |
// if expression
|
|
|
632 |
// special conditions
|
|
|
633 |
expr(res) ::= expr(e1) tlop(c) value(e2). {
|
|
|
634 |
res = c['pre']. e1.c['op'].e2 .')';
|
|
|
635 |
}
|
|
|
636 |
// simple expression
|
|
|
637 |
expr(res) ::= expr(e1) lop(c) expr(e2). {
|
|
|
638 |
res = e1.c.e2;
|
|
|
639 |
}
|
|
|
640 |
|
|
|
641 |
expr(res) ::= expr(e1) scond(c). {
|
|
|
642 |
res = c . e1 . ')';
|
|
|
643 |
}
|
|
|
644 |
|
|
|
645 |
expr(res) ::= expr(e1) ISIN array(a). {
|
|
|
646 |
res = 'in_array('.e1.','.a.')';
|
|
|
647 |
}
|
|
|
648 |
|
|
|
649 |
expr(res) ::= expr(e1) ISIN value(v). {
|
|
|
650 |
res = 'in_array('.e1.',(array)'.v.')';
|
|
|
651 |
}
|
|
|
652 |
|
|
|
653 |
|
|
|
654 |
//
|
|
|
655 |
// ternary
|
|
|
656 |
//
|
|
|
657 |
ternary(res) ::= OPENP expr(v) CLOSEP QMARK DOLLARID(e1) COLON expr(e2). {
|
|
|
658 |
res = v.' ? '. $this->compiler->compileVariable('\''.substr(e1,1).'\'') . ' : '.e2;
|
|
|
659 |
}
|
|
|
660 |
|
|
|
661 |
ternary(res) ::= OPENP expr(v) CLOSEP QMARK expr(e1) COLON expr(e2). {
|
|
|
662 |
res = v.' ? '.e1.' : '.e2;
|
|
|
663 |
}
|
|
|
664 |
|
|
|
665 |
// value
|
|
|
666 |
value(res) ::= variable(v). {
|
|
|
667 |
res = v;
|
|
|
668 |
}
|
|
|
669 |
|
|
|
670 |
// +/- value
|
|
|
671 |
value(res) ::= UNIMATH(m) value(v). {
|
|
|
672 |
res = m.v;
|
|
|
673 |
}
|
|
|
674 |
|
|
|
675 |
// logical negation
|
|
|
676 |
value(res) ::= NOT value(v). {
|
|
|
677 |
res = '!'.v;
|
|
|
678 |
}
|
|
|
679 |
|
|
|
680 |
value(res) ::= TYPECAST(t) value(v). {
|
|
|
681 |
res = t.v;
|
|
|
682 |
}
|
|
|
683 |
|
|
|
684 |
value(res) ::= variable(v) INCDEC(o). {
|
|
|
685 |
res = v.o;
|
|
|
686 |
}
|
|
|
687 |
|
|
|
688 |
// numeric
|
|
|
689 |
value(res) ::= HEX(n). {
|
|
|
690 |
res = n;
|
|
|
691 |
}
|
|
|
692 |
|
|
|
693 |
value(res) ::= INTEGER(n). {
|
|
|
694 |
res = n;
|
|
|
695 |
}
|
|
|
696 |
|
|
|
697 |
value(res) ::= INTEGER(n1) DOT INTEGER(n2). {
|
|
|
698 |
res = n1.'.'.n2;
|
|
|
699 |
}
|
|
|
700 |
|
|
|
701 |
value(res) ::= INTEGER(n1) DOT. {
|
|
|
702 |
res = n1.'.';
|
|
|
703 |
}
|
|
|
704 |
|
|
|
705 |
value(res) ::= DOT INTEGER(n1). {
|
|
|
706 |
res = '.'.n1;
|
|
|
707 |
}
|
|
|
708 |
|
|
|
709 |
// ID, true, false, null
|
|
|
710 |
value(res) ::= ID(id). {
|
|
|
711 |
if (defined(id)) {
|
|
|
712 |
if ($this->security) {
|
|
|
713 |
$this->security->isTrustedConstant(id, $this->compiler);
|
|
|
714 |
}
|
|
|
715 |
res = id;
|
|
|
716 |
} else {
|
|
|
717 |
res = '\''.id.'\'';
|
|
|
718 |
}
|
|
|
719 |
}
|
|
|
720 |
|
|
|
721 |
// function call
|
|
|
722 |
value(res) ::= function(f). {
|
|
|
723 |
res = f;
|
|
|
724 |
}
|
|
|
725 |
|
|
|
726 |
// expression
|
|
|
727 |
value(res) ::= OPENP expr(e) CLOSEP. {
|
|
|
728 |
res = '('. e .')';
|
|
|
729 |
}
|
|
|
730 |
|
|
|
731 |
value(res) ::= variable(v1) INSTANCEOF(i) ns1(v2). {
|
|
|
732 |
res = v1.i.v2;
|
|
|
733 |
}
|
|
|
734 |
value(res) ::= variable(v1) INSTANCEOF(i) variable(v2). {
|
|
|
735 |
res = v1.i.v2;
|
|
|
736 |
}
|
|
|
737 |
|
|
|
738 |
// singele quoted string
|
|
|
739 |
value(res) ::= SINGLEQUOTESTRING(t). {
|
|
|
740 |
res = t;
|
|
|
741 |
}
|
|
|
742 |
|
|
|
743 |
// double quoted string
|
|
|
744 |
value(res) ::= doublequoted_with_quotes(s). {
|
|
|
745 |
res = s;
|
|
|
746 |
}
|
|
|
747 |
|
|
|
748 |
|
|
|
749 |
value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). {
|
|
|
750 |
if ($this->security && $this->security->static_classes !== array()) {
|
|
|
751 |
$this->compiler->trigger_template_error('dynamic static class not allowed by security setting');
|
|
|
752 |
}
|
|
|
753 |
$prefixVar = $this->compiler->getNewPrefixVariable();
|
|
|
754 |
if (vi['var'] === '\'smarty\'') {
|
|
|
755 |
$this->compiler->appendPrefixCode("<?php {$prefixVar} = ". $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).';?>');
|
|
|
756 |
} else {
|
|
|
757 |
$this->compiler->appendPrefixCode("<?php {$prefixVar} = ". $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'].';?>');
|
|
|
758 |
}
|
|
|
759 |
res = $prefixVar .'::'.r[0].r[1];
|
|
|
760 |
}
|
|
|
761 |
|
|
|
762 |
// Smarty tag
|
|
|
763 |
value(res) ::= smartytag(st). {
|
|
|
764 |
$prefixVar = $this->compiler->getNewPrefixVariable();
|
|
|
765 |
$tmp = $this->compiler->appendCode('<?php ob_start();?>', st);
|
|
|
766 |
$this->compiler->appendPrefixCode($this->compiler->appendCode($tmp, "<?php {$prefixVar} = ob_get_clean();?>"));
|
|
|
767 |
res = $prefixVar;
|
|
|
768 |
}
|
|
|
769 |
|
|
|
770 |
value(res) ::= value(v) modifierlist(l). {
|
|
|
771 |
res = $this->compiler->compileTag('private_modifier',array(),array('value'=>v,'modifierlist'=>l));
|
|
|
772 |
}
|
|
|
773 |
// name space constant
|
|
|
774 |
value(res) ::= NAMESPACE(c). {
|
|
|
775 |
res = c;
|
|
|
776 |
}
|
|
|
777 |
|
|
|
778 |
// array
|
|
|
779 |
value(res) ::= arraydef(a). {
|
|
|
780 |
res = a;
|
|
|
781 |
}
|
|
|
782 |
// static class access
|
|
|
783 |
value(res) ::= ns1(c)DOUBLECOLON static_class_access(s). {
|
|
|
784 |
if (!in_array(strtolower(c), array('self', 'parent')) && (!$this->security || $this->security->isTrustedStaticClassAccess(c, s, $this->compiler))) {
|
|
|
785 |
if (isset($this->smarty->registered_classes[c])) {
|
|
|
786 |
res = $this->smarty->registered_classes[c].'::'.s[0].s[1];
|
|
|
787 |
} else {
|
|
|
788 |
res = c.'::'.s[0].s[1];
|
|
|
789 |
}
|
|
|
790 |
} else {
|
|
|
791 |
$this->compiler->trigger_template_error ('static class \''.c.'\' is undefined or not allowed by security setting');
|
|
|
792 |
}
|
|
|
793 |
}
|
|
|
794 |
//
|
|
|
795 |
// namespace stuff
|
|
|
796 |
//
|
|
|
797 |
|
|
|
798 |
ns1(res) ::= ID(i). {
|
|
|
799 |
res = i;
|
|
|
800 |
}
|
|
|
801 |
|
|
|
802 |
ns1(res) ::= NAMESPACE(i). {
|
|
|
803 |
res = i;
|
|
|
804 |
}
|
|
|
805 |
|
|
|
806 |
|
|
|
807 |
|
|
|
808 |
|
|
|
809 |
//
|
|
|
810 |
// variables
|
|
|
811 |
//
|
|
|
812 |
// Smarty variable (optional array)
|
|
|
813 |
variable(res) ::= DOLLARID(i). {
|
|
|
814 |
res = $this->compiler->compileVariable('\''.substr(i,1).'\'');
|
|
|
815 |
}
|
|
|
816 |
variable(res) ::= varindexed(vi). {
|
|
|
817 |
if (vi['var'] === '\'smarty\'') {
|
|
|
818 |
$smarty_var = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']);
|
|
|
819 |
res = $smarty_var;
|
|
|
820 |
} else {
|
|
|
821 |
// used for array reset,next,prev,end,current
|
|
|
822 |
$this->last_variable = vi['var'];
|
|
|
823 |
$this->last_index = vi['smarty_internal_index'];
|
|
|
824 |
res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'];
|
|
|
825 |
}
|
|
|
826 |
}
|
|
|
827 |
|
|
|
828 |
// variable with property
|
|
|
829 |
variable(res) ::= varvar(v) AT ID(p). {
|
|
|
830 |
res = '$_smarty_tpl->tpl_vars['. v .']->'.p;
|
|
|
831 |
}
|
|
|
832 |
|
|
|
833 |
// object
|
|
|
834 |
variable(res) ::= object(o). {
|
|
|
835 |
res = o;
|
|
|
836 |
}
|
|
|
837 |
|
|
|
838 |
// config variable
|
|
|
839 |
variable(res) ::= HATCH ID(i) HATCH. {
|
|
|
840 |
res = $this->compiler->compileConfigVariable('\'' . i . '\'');
|
|
|
841 |
}
|
|
|
842 |
|
|
|
843 |
variable(res) ::= HATCH ID(i) HATCH arrayindex(a). {
|
|
|
844 |
res = '(is_array($tmp = ' . $this->compiler->compileConfigVariable('\'' . i . '\'') . ') ? $tmp'.a.' :null)';
|
|
|
845 |
}
|
|
|
846 |
|
|
|
847 |
variable(res) ::= HATCH variable(v) HATCH. {
|
|
|
848 |
res = $this->compiler->compileConfigVariable(v);
|
|
|
849 |
}
|
|
|
850 |
|
|
|
851 |
variable(res) ::= HATCH variable(v) HATCH arrayindex(a). {
|
|
|
852 |
res = '(is_array($tmp = ' . $this->compiler->compileConfigVariable(v) . ') ? $tmp'.a.' : null)';
|
|
|
853 |
}
|
|
|
854 |
|
|
|
855 |
varindexed(res) ::= DOLLARID(i) arrayindex(a). {
|
|
|
856 |
res = array('var'=>'\''.substr(i,1).'\'', 'smarty_internal_index'=>a);
|
|
|
857 |
}
|
|
|
858 |
varindexed(res) ::= varvar(v) arrayindex(a). {
|
|
|
859 |
res = array('var'=>v, 'smarty_internal_index'=>a);
|
|
|
860 |
}
|
|
|
861 |
|
|
|
862 |
//
|
|
|
863 |
// array index
|
|
|
864 |
//
|
|
|
865 |
// multiple array index
|
|
|
866 |
arrayindex(res) ::= arrayindex(a1) indexdef(a2). {
|
|
|
867 |
res = a1.a2;
|
|
|
868 |
}
|
|
|
869 |
|
|
|
870 |
// no array index
|
|
|
871 |
arrayindex ::= . {
|
|
|
872 |
return;
|
|
|
873 |
}
|
|
|
874 |
|
|
|
875 |
// single index definition
|
|
|
876 |
// Smarty2 style index
|
|
|
877 |
indexdef(res) ::= DOT DOLLARID(i). {
|
|
|
878 |
res = '['.$this->compiler->compileVariable('\''.substr(i,1).'\'').']';
|
|
|
879 |
}
|
|
|
880 |
indexdef(res) ::= DOT varvar(v). {
|
|
|
881 |
res = '['.$this->compiler->compileVariable(v).']';
|
|
|
882 |
}
|
|
|
883 |
|
|
|
884 |
indexdef(res) ::= DOT varvar(v) AT ID(p). {
|
|
|
885 |
res = '['.$this->compiler->compileVariable(v).'->'.p.']';
|
|
|
886 |
}
|
|
|
887 |
|
|
|
888 |
indexdef(res) ::= DOT ID(i). {
|
|
|
889 |
res = '[\''. i .'\']';
|
|
|
890 |
}
|
|
|
891 |
|
|
|
892 |
indexdef(res) ::= DOT INTEGER(n). {
|
|
|
893 |
res = '['. n .']';
|
|
|
894 |
}
|
|
|
895 |
|
|
|
896 |
|
|
|
897 |
indexdef(res) ::= DOT LDEL expr(e) RDEL. {
|
|
|
898 |
res = '['. e .']';
|
|
|
899 |
}
|
|
|
900 |
|
|
|
901 |
// section tag index
|
|
|
902 |
indexdef(res) ::= OPENB ID(i)CLOSEB. {
|
|
|
903 |
res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\'index\']').']';
|
|
|
904 |
}
|
|
|
905 |
|
|
|
906 |
indexdef(res) ::= OPENB ID(i) DOT ID(i2) CLOSEB. {
|
|
|
907 |
res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\''.i2.'\']').']';
|
|
|
908 |
}
|
|
|
909 |
indexdef(res) ::= OPENB SINGLEQUOTESTRING(s) CLOSEB. {
|
|
|
910 |
res = '['.s.']';
|
|
|
911 |
}
|
|
|
912 |
indexdef(res) ::= OPENB INTEGER(n) CLOSEB. {
|
|
|
913 |
res = '['.n.']';
|
|
|
914 |
}
|
|
|
915 |
indexdef(res) ::= OPENB DOLLARID(i) CLOSEB. {
|
|
|
916 |
res = '['.$this->compiler->compileVariable('\''.substr(i,1).'\'').']';
|
|
|
917 |
}
|
|
|
918 |
indexdef(res) ::= OPENB variable(v) CLOSEB. {
|
|
|
919 |
res = '['.v.']';
|
|
|
920 |
}
|
|
|
921 |
indexdef(res) ::= OPENB value(v) CLOSEB. {
|
|
|
922 |
res = '['.v.']';
|
|
|
923 |
}
|
|
|
924 |
|
|
|
925 |
// PHP style index
|
|
|
926 |
indexdef(res) ::= OPENB expr(e) CLOSEB. {
|
|
|
927 |
res = '['. e .']';
|
|
|
928 |
}
|
|
|
929 |
|
|
|
930 |
// for assign append array
|
|
|
931 |
indexdef(res) ::= OPENB CLOSEB. {
|
|
|
932 |
res = '[]';
|
|
|
933 |
}
|
|
|
934 |
|
|
|
935 |
|
|
|
936 |
//
|
|
|
937 |
// variable variable names
|
|
|
938 |
//
|
|
|
939 |
|
|
|
940 |
// singel identifier element
|
|
|
941 |
varvar(res) ::= DOLLARID(i). {
|
|
|
942 |
res = '\''.substr(i,1).'\'';
|
|
|
943 |
}
|
|
|
944 |
// single $
|
|
|
945 |
varvar(res) ::= DOLLAR. {
|
|
|
946 |
res = '\'\'';
|
|
|
947 |
}
|
|
|
948 |
|
|
|
949 |
// sequence of identifier elements
|
|
|
950 |
varvar(res) ::= varvar(v1) varvarele(v2). {
|
|
|
951 |
res = v1.'.'.v2;
|
|
|
952 |
}
|
|
|
953 |
|
|
|
954 |
// fix sections of element
|
|
|
955 |
varvarele(res) ::= ID(s). {
|
|
|
956 |
res = '\''.s.'\'';
|
|
|
957 |
}
|
|
|
958 |
varvarele(res) ::= SIMPELOUTPUT(i). {
|
|
|
959 |
$var = trim(substr(i, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' $');
|
|
|
960 |
res = $this->compiler->compileVariable('\''.$var.'\'');
|
|
|
961 |
}
|
|
|
962 |
|
|
|
963 |
// variable sections of element
|
|
|
964 |
varvarele(res) ::= LDEL expr(e) RDEL. {
|
|
|
965 |
res = '('.e.')';
|
|
|
966 |
}
|
|
|
967 |
|
|
|
968 |
//
|
|
|
969 |
// objects
|
|
|
970 |
//
|
|
|
971 |
object(res) ::= varindexed(vi) objectchain(oc). {
|
|
|
972 |
if (vi['var'] === '\'smarty\'') {
|
|
|
973 |
res = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).oc;
|
|
|
974 |
} else {
|
|
|
975 |
res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'].oc;
|
|
|
976 |
}
|
|
|
977 |
}
|
|
|
978 |
|
|
|
979 |
// single element
|
|
|
980 |
objectchain(res) ::= objectelement(oe). {
|
|
|
981 |
res = oe;
|
|
|
982 |
}
|
|
|
983 |
|
|
|
984 |
// chain of elements
|
|
|
985 |
objectchain(res) ::= objectchain(oc) objectelement(oe). {
|
|
|
986 |
res = oc.oe;
|
|
|
987 |
}
|
|
|
988 |
|
|
|
989 |
// variable
|
|
|
990 |
objectelement(res)::= PTR ID(i) arrayindex(a). {
|
|
|
991 |
if ($this->security && substr(i,0,1) === '_') {
|
|
|
992 |
$this->compiler->trigger_template_error (self::ERR1);
|
|
|
993 |
}
|
|
|
994 |
res = '->'.i.a;
|
|
|
995 |
}
|
|
|
996 |
|
|
|
997 |
objectelement(res)::= PTR varvar(v) arrayindex(a). {
|
|
|
998 |
if ($this->security) {
|
|
|
999 |
$this->compiler->trigger_template_error (self::ERR2);
|
|
|
1000 |
}
|
|
|
1001 |
res = '->{'.$this->compiler->compileVariable(v).a.'}';
|
|
|
1002 |
}
|
|
|
1003 |
|
|
|
1004 |
objectelement(res)::= PTR LDEL expr(e) RDEL arrayindex(a). {
|
|
|
1005 |
if ($this->security) {
|
|
|
1006 |
$this->compiler->trigger_template_error (self::ERR2);
|
|
|
1007 |
}
|
|
|
1008 |
res = '->{'.e.a.'}';
|
|
|
1009 |
}
|
|
|
1010 |
|
|
|
1011 |
objectelement(res)::= PTR ID(ii) LDEL expr(e) RDEL arrayindex(a). {
|
|
|
1012 |
if ($this->security) {
|
|
|
1013 |
$this->compiler->trigger_template_error (self::ERR2);
|
|
|
1014 |
}
|
|
|
1015 |
res = '->{\''.ii.'\'.'.e.a.'}';
|
|
|
1016 |
}
|
|
|
1017 |
|
|
|
1018 |
// method
|
|
|
1019 |
objectelement(res)::= PTR method(f). {
|
|
|
1020 |
res = '->'.f;
|
|
|
1021 |
}
|
|
|
1022 |
|
|
|
1023 |
|
|
|
1024 |
//
|
|
|
1025 |
// function
|
|
|
1026 |
//
|
|
|
1027 |
function(res) ::= ns1(f) OPENP params(p) CLOSEP. {
|
|
|
1028 |
res = $this->compiler->compilePHPFunctionCall(f, p);
|
|
|
1029 |
}
|
|
|
1030 |
|
|
|
1031 |
|
|
|
1032 |
//
|
|
|
1033 |
// method
|
|
|
1034 |
//
|
|
|
1035 |
method(res) ::= ID(f) OPENP params(p) CLOSEP. {
|
|
|
1036 |
if ($this->security && substr(f,0,1) === '_') {
|
|
|
1037 |
$this->compiler->trigger_template_error (self::ERR1);
|
|
|
1038 |
}
|
|
|
1039 |
res = f . '('. implode(',',p) .')';
|
|
|
1040 |
}
|
|
|
1041 |
|
|
|
1042 |
method(res) ::= DOLLARID(f) OPENP params(p) CLOSEP. {
|
|
|
1043 |
if ($this->security) {
|
|
|
1044 |
$this->compiler->trigger_template_error (self::ERR2);
|
|
|
1045 |
}
|
|
|
1046 |
$prefixVar = $this->compiler->getNewPrefixVariable();
|
|
|
1047 |
$this->compiler->appendPrefixCode("<?php {$prefixVar} = ".$this->compiler->compileVariable('\''.substr(f,1).'\'').';?>');
|
|
|
1048 |
res = $prefixVar .'('. implode(',',p) .')';
|
|
|
1049 |
}
|
|
|
1050 |
|
|
|
1051 |
// function/method parameter
|
|
|
1052 |
// multiple parameters
|
|
|
1053 |
params(res) ::= params(p) COMMA expr(e). {
|
|
|
1054 |
res = array_merge(p,array(e));
|
|
|
1055 |
}
|
|
|
1056 |
|
|
|
1057 |
// single parameter
|
|
|
1058 |
params(res) ::= expr(e). {
|
|
|
1059 |
res = array(e);
|
|
|
1060 |
}
|
|
|
1061 |
|
|
|
1062 |
// kein parameter
|
|
|
1063 |
params(res) ::= . {
|
|
|
1064 |
res = array();
|
|
|
1065 |
}
|
|
|
1066 |
|
|
|
1067 |
//
|
|
|
1068 |
// modifier
|
|
|
1069 |
//
|
|
|
1070 |
modifierlist(res) ::= modifierlist(l) modifier(m) modparameters(p). {
|
|
|
1071 |
res = array_merge(l,array(array_merge(m,p)));
|
|
|
1072 |
}
|
|
|
1073 |
|
|
|
1074 |
modifierlist(res) ::= modifier(m) modparameters(p). {
|
|
|
1075 |
res = array(array_merge(m,p));
|
|
|
1076 |
}
|
|
|
1077 |
|
|
|
1078 |
modifier(res) ::= VERT AT ID(m). {
|
|
|
1079 |
res = array(m);
|
|
|
1080 |
}
|
|
|
1081 |
|
|
|
1082 |
modifier(res) ::= VERT ID(m). {
|
|
|
1083 |
res = array(m);
|
|
|
1084 |
}
|
|
|
1085 |
|
|
|
1086 |
//
|
|
|
1087 |
// modifier parameter
|
|
|
1088 |
//
|
|
|
1089 |
// multiple parameter
|
|
|
1090 |
modparameters(res) ::= modparameters(mps) modparameter(mp). {
|
|
|
1091 |
res = array_merge(mps,mp);
|
|
|
1092 |
}
|
|
|
1093 |
|
|
|
1094 |
// no parameter
|
|
|
1095 |
modparameters(res) ::= . {
|
|
|
1096 |
res = array();
|
|
|
1097 |
}
|
|
|
1098 |
|
|
|
1099 |
// parameter expression
|
|
|
1100 |
modparameter(res) ::= COLON value(mp). {
|
|
|
1101 |
res = array(mp);
|
|
|
1102 |
}
|
|
|
1103 |
modparameter(res) ::= COLON UNIMATH(m) value(mp). {
|
|
|
1104 |
res = array(trim(m).mp);
|
|
|
1105 |
}
|
|
|
1106 |
|
|
|
1107 |
modparameter(res) ::= COLON array(mp). {
|
|
|
1108 |
res = array(mp);
|
|
|
1109 |
}
|
|
|
1110 |
|
|
|
1111 |
// static class methode call
|
|
|
1112 |
static_class_access(res) ::= method(m). {
|
|
|
1113 |
res = array(m, '', 'method');
|
|
|
1114 |
}
|
|
|
1115 |
|
|
|
1116 |
// static class methode call with object chainig
|
|
|
1117 |
static_class_access(res) ::= method(m) objectchain(oc). {
|
|
|
1118 |
res = array(m, oc, 'method');
|
|
|
1119 |
}
|
|
|
1120 |
|
|
|
1121 |
// static class constant
|
|
|
1122 |
static_class_access(res) ::= ID(v). {
|
|
|
1123 |
res = array(v, '');
|
|
|
1124 |
}
|
|
|
1125 |
|
|
|
1126 |
// static class variables
|
|
|
1127 |
static_class_access(res) ::= DOLLARID(v) arrayindex(a). {
|
|
|
1128 |
res = array(v, a, 'property');
|
|
|
1129 |
}
|
|
|
1130 |
|
|
|
1131 |
// static class variables with object chain
|
|
|
1132 |
static_class_access(res) ::= DOLLARID(v) arrayindex(a) objectchain(oc). {
|
|
|
1133 |
res = array(v, a.oc, 'property');
|
|
|
1134 |
}
|
|
|
1135 |
|
|
|
1136 |
|
|
|
1137 |
// if conditions and operators
|
|
|
1138 |
lop(res) ::= LOGOP(o). {
|
|
|
1139 |
res = ' '. trim(o) . ' ';
|
|
|
1140 |
}
|
|
|
1141 |
|
|
|
1142 |
lop(res) ::= SLOGOP(o). {
|
|
|
1143 |
static $lops = array(
|
|
|
1144 |
'eq' => ' == ',
|
|
|
1145 |
'ne' => ' != ',
|
|
|
1146 |
'neq' => ' != ',
|
|
|
1147 |
'gt' => ' > ',
|
|
|
1148 |
'ge' => ' >= ',
|
|
|
1149 |
'gte' => ' >= ',
|
|
|
1150 |
'lt' => ' < ',
|
|
|
1151 |
'le' => ' <= ',
|
|
|
1152 |
'lte' => ' <= ',
|
|
|
1153 |
'mod' => ' % ',
|
|
|
1154 |
'and' => ' && ',
|
|
|
1155 |
'or' => ' || ',
|
|
|
1156 |
'xor' => ' xor ',
|
|
|
1157 |
);
|
|
|
1158 |
$op = strtolower(preg_replace('/\s*/', '', o));
|
|
|
1159 |
res = $lops[$op];
|
|
|
1160 |
}
|
|
|
1161 |
tlop(res) ::= TLOGOP(o). {
|
|
|
1162 |
static $tlops = array(
|
|
|
1163 |
'isdivby' => array('op' => ' % ', 'pre' => '!('),
|
|
|
1164 |
'isnotdivby' => array('op' => ' % ', 'pre' => '('),
|
|
|
1165 |
'isevenby' => array('op' => ' / ', 'pre' => '!(1 & '),
|
|
|
1166 |
'isnotevenby' => array('op' => ' / ', 'pre' => '(1 & '),
|
|
|
1167 |
'isoddby' => array('op' => ' / ', 'pre' => '(1 & '),
|
|
|
1168 |
'isnotoddby' => array('op' => ' / ', 'pre' => '!(1 & '),
|
|
|
1169 |
);
|
|
|
1170 |
$op = strtolower(preg_replace('/\s*/', '', o));
|
|
|
1171 |
res = $tlops[$op];
|
|
|
1172 |
}
|
|
|
1173 |
|
|
|
1174 |
scond(res) ::= SINGLECOND(o). {
|
|
|
1175 |
static $scond = array (
|
|
|
1176 |
'iseven' => '!(1 & ',
|
|
|
1177 |
'isnoteven' => '(1 & ',
|
|
|
1178 |
'isodd' => '(1 & ',
|
|
|
1179 |
'isnotodd' => '!(1 & ',
|
|
|
1180 |
);
|
|
|
1181 |
$op = strtolower(str_replace(' ', '', o));
|
|
|
1182 |
res = $scond[$op];
|
|
|
1183 |
}
|
|
|
1184 |
|
|
|
1185 |
//
|
|
|
1186 |
// ARRAY element assignment
|
|
|
1187 |
//
|
|
|
1188 |
arraydef(res) ::= OPENB arrayelements(a) CLOSEB. {
|
|
|
1189 |
res = 'array('.a.')';
|
|
|
1190 |
}
|
|
|
1191 |
arraydef(res) ::= ARRAYOPEN arrayelements(a) CLOSEP. {
|
|
|
1192 |
res = 'array('.a.')';
|
|
|
1193 |
}
|
|
|
1194 |
|
|
|
1195 |
arrayelements(res) ::= arrayelement(a). {
|
|
|
1196 |
res = a;
|
|
|
1197 |
}
|
|
|
1198 |
|
|
|
1199 |
arrayelements(res) ::= arrayelements(a1) COMMA arrayelement(a). {
|
|
|
1200 |
res = a1.','.a;
|
|
|
1201 |
}
|
|
|
1202 |
|
|
|
1203 |
arrayelements ::= . {
|
|
|
1204 |
return;
|
|
|
1205 |
}
|
|
|
1206 |
|
|
|
1207 |
arrayelement(res) ::= value(e1) APTR expr(e2). {
|
|
|
1208 |
res = e1.'=>'.e2;
|
|
|
1209 |
}
|
|
|
1210 |
|
|
|
1211 |
arrayelement(res) ::= ID(i) APTR expr(e2). {
|
|
|
1212 |
res = '\''.i.'\'=>'.e2;
|
|
|
1213 |
}
|
|
|
1214 |
|
|
|
1215 |
arrayelement(res) ::= expr(e). {
|
|
|
1216 |
res = e;
|
|
|
1217 |
}
|
|
|
1218 |
|
|
|
1219 |
|
|
|
1220 |
//
|
|
|
1221 |
// double quoted strings
|
|
|
1222 |
//
|
|
|
1223 |
doublequoted_with_quotes(res) ::= QUOTE QUOTE. {
|
|
|
1224 |
res = '\'\'';
|
|
|
1225 |
}
|
|
|
1226 |
|
|
|
1227 |
doublequoted_with_quotes(res) ::= QUOTE doublequoted(s) QUOTE. {
|
|
|
1228 |
$this->compiler->leaveDoubleQuote();
|
|
|
1229 |
res = s->to_smarty_php($this);
|
|
|
1230 |
}
|
|
|
1231 |
|
|
|
1232 |
|
|
|
1233 |
doublequoted(res) ::= doublequoted(o1) doublequotedcontent(o2). {
|
|
|
1234 |
o1->append_subtree($this, o2);
|
|
|
1235 |
res = o1;
|
|
|
1236 |
}
|
|
|
1237 |
|
|
|
1238 |
doublequoted(res) ::= doublequotedcontent(o). {
|
|
|
1239 |
res = new Smarty_Internal_ParseTree_Dq($this, o);
|
|
|
1240 |
}
|
|
|
1241 |
|
|
|
1242 |
doublequotedcontent(res) ::= BACKTICK variable(v) BACKTICK. {
|
|
|
1243 |
res = new Smarty_Internal_ParseTree_Code('(string)'.v);
|
|
|
1244 |
}
|
|
|
1245 |
|
|
|
1246 |
doublequotedcontent(res) ::= BACKTICK expr(e) BACKTICK. {
|
|
|
1247 |
res = new Smarty_Internal_ParseTree_Code('(string)('.e.')');
|
|
|
1248 |
}
|
|
|
1249 |
|
|
|
1250 |
doublequotedcontent(res) ::= DOLLARID(i). {
|
|
|
1251 |
res = new Smarty_Internal_ParseTree_Code('(string)$_smarty_tpl->tpl_vars[\''. substr(i,1) .'\']->value');
|
|
|
1252 |
}
|
|
|
1253 |
|
|
|
1254 |
doublequotedcontent(res) ::= LDEL variable(v) RDEL. {
|
|
|
1255 |
res = new Smarty_Internal_ParseTree_Code('(string)'.v);
|
|
|
1256 |
}
|
|
|
1257 |
|
|
|
1258 |
doublequotedcontent(res) ::= LDEL expr(e) RDEL. {
|
|
|
1259 |
res = new Smarty_Internal_ParseTree_Code('(string)('.e.')');
|
|
|
1260 |
}
|
|
|
1261 |
|
|
|
1262 |
doublequotedcontent(res) ::= smartytag(st). {
|
|
|
1263 |
res = new Smarty_Internal_ParseTree_Tag($this, st);
|
|
|
1264 |
}
|
|
|
1265 |
|
|
|
1266 |
doublequotedcontent(res) ::= TEXT(o). {
|
|
|
1267 |
res = new Smarty_Internal_ParseTree_DqContent(o);
|
|
|
1268 |
}
|
|
|
1269 |
|