1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
28:
29:
30:
31: 32: 33: 34:
35: class Smarty_Compiler extends Smarty {
36:
37:
38: 39: 40:
41: var $_folded_blocks = array();
42: var $_current_file = null;
43: var $_current_line_no = 1;
44: var $_capture_stack = array();
45: var $_plugin_info = array();
46: var $_init_smarty_vars = false;
47: var $_permitted_tokens = array('true','false','yes','no','on','off','null');
48: var $_db_qstr_regexp = null;
49: var $_si_qstr_regexp = null;
50: var $_qstr_regexp = null;
51: var $_func_regexp = null;
52: var $_reg_obj_regexp = null;
53: var $_var_bracket_regexp = null;
54: var $_num_const_regexp = null;
55: var $_dvar_guts_regexp = null;
56: var $_dvar_regexp = null;
57: var $_cvar_regexp = null;
58: var $_svar_regexp = null;
59: var $_avar_regexp = null;
60: var $_mod_regexp = null;
61: var $_var_regexp = null;
62: var $_parenth_param_regexp = null;
63: var $_func_call_regexp = null;
64: var $_obj_ext_regexp = null;
65: var $_obj_start_regexp = null;
66: var $_obj_params_regexp = null;
67: var $_obj_call_regexp = null;
68: var $_cacheable_state = 0;
69: var $_cache_attrs_count = 0;
70: var $_nocache_count = 0;
71: var $_cache_serial = null;
72: var $_cache_include = null;
73:
74: var $_strip_depth = 0;
75: var $_additional_newline = "\n";
76:
77:
78: 79: 80:
81: public function __construct()
82: {
83:
84:
85:
86: $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
87:
88:
89:
90:
91: $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
92:
93:
94: $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
95:
96:
97:
98:
99:
100: $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
101:
102:
103:
104:
105:
106: $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
107:
108:
109:
110:
111:
112:
113:
114:
115:
116: $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
117: $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
118: $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
119: . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
120: $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
121:
122:
123:
124:
125: $this->_cvar_regexp = '\#\w+\#';
126:
127:
128:
129: $this->_svar_regexp = '\%\w+\.\w+\%';
130:
131:
132: $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
133: . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
134:
135:
136:
137:
138:
139:
140:
141:
142: $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155: $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
156: $this->_obj_restricted_param_regexp = '(?:'
157: . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
158: . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
159: $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
160: . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
161: $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
162: . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
163: $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
164: $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
165:
166:
167:
168:
169:
170:
171:
172:
173:
174: $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
175: . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
176:
177:
178:
179:
180: $this->_func_regexp = '[a-zA-Z_]\w*';
181:
182:
183:
184: $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195: $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
196: . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
197:
198:
199:
200:
201:
202:
203: $this->_parenth_param_regexp = '(?:\((?:\w+|'
204: . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
205: . $this->_param_regexp . ')))*)?\))';
206:
207:
208:
209:
210:
211:
212: $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
213: . $this->_parenth_param_regexp . '))';
214: }
215:
216: 217: 218: 219: 220: 221: 222: 223: 224:
225: function _compile_file($resource_name, $source_content, &$compiled_content)
226: {
227:
228: if ($this->security) {
229:
230: if ($this->php_handling == SMARTY_PHP_ALLOW &&
231: !$this->security_settings['PHP_HANDLING']) {
232: $this->php_handling = SMARTY_PHP_PASSTHRU;
233: }
234: }
235:
236: $this->_load_filters();
237:
238: $this->_current_file = $resource_name;
239: $this->_current_line_no = 1;
240: $ldq = preg_quote($this->left_delimiter, '~');
241: $rdq = preg_quote($this->right_delimiter, '~');
242:
243:
244: if (count($this->_plugins['prefilter']) > 0) {
245: foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
246: if ($prefilter === false) continue;
247: if ($prefilter[3] || is_callable($prefilter[0])) {
248: $source_content = call_user_func_array($prefilter[0],
249: array($source_content, &$this));
250: $this->_plugins['prefilter'][$filter_name][3] = true;
251: } else {
252: $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
253: }
254: }
255: }
256:
257:
258: $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
259:
260: preg_match_all($search, $source_content, $match, PREG_SET_ORDER);
261: $this->_folded_blocks = $match;
262: reset($this->_folded_blocks);
263:
264:
265: $source_content = preg_replace_callback($search, create_function ('$matches', "return '"
266: . $this->_quote_replace($this->left_delimiter) . 'php'
267: . "' . str_repeat(\"\n\", substr_count('\$matches[1]', \"\n\")) .'"
268: . $this->_quote_replace($this->right_delimiter)
269: . "';")
270: , $source_content);
271:
272:
273: preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
274: $template_tags = $_match[1];
275:
276: $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
277:
278:
279: for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
280:
281: if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
282:
283: $sp_match[1] = array_unique($sp_match[1]);
284: usort($sp_match[1], '_smarty_sort_length');
285: for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
286: $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
287: }
288:
289: for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
290: if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
291:
292: $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
293: } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
294:
295: $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
296: } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
297:
298: $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
299: } else {
300:
301: $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
302: $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
303: }
304: }
305: }
306: }
307:
308:
309: $compiled_tags = array();
310: for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
311: $this->_current_line_no += substr_count($text_blocks[$i], "\n");
312: $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
313: $this->_current_line_no += substr_count($template_tags[$i], "\n");
314: }
315: if (count($this->_tag_stack)>0) {
316: list($_open_tag, $_line_no) = end($this->_tag_stack);
317: $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
318: return;
319: }
320:
321: 322:
323: $strip = false;
324: for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
325: if ($compiled_tags[$i] == '{strip}') {
326: $compiled_tags[$i] = '';
327: $strip = true;
328:
329: $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
330: }
331: if ($strip) {
332:
333: for ($j = $i + 1; $j < $for_max; $j++) {
334:
335: $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
336: if ($compiled_tags[$j] == '{/strip}') {
337:
338: $text_blocks[$j] = rtrim($text_blocks[$j]);
339: }
340: $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
341: if ($compiled_tags[$j] == '{/strip}') {
342: $compiled_tags[$j] = "\n"; 343:
344: $strip = false;
345: $i = $j;
346: break;
347: }
348: }
349: }
350: }
351: $compiled_content = '';
352:
353: $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
354:
355:
356: for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
357: if ($compiled_tags[$i] == '') {
358:
359: $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
360: }
361:
362: $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
363: $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
364:
365: $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
366: }
367: $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
368:
369:
370: $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
371: $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
372:
373:
374: $compiled_content = str_replace($tag_guard, '<?', $compiled_content);
375:
376:
377: if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
378: $compiled_content = substr($compiled_content, 0, -1);
379: }
380:
381: if (!empty($this->_cache_serial)) {
382: $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
383: }
384:
385:
386: if (count($this->_plugins['postfilter']) > 0) {
387: foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
388: if ($postfilter === false) continue;
389: if ($postfilter[3] || is_callable($postfilter[0])) {
390: $compiled_content = call_user_func_array($postfilter[0],
391: array($compiled_content, &$this));
392: $this->_plugins['postfilter'][$filter_name][3] = true;
393: } else {
394: $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
395: }
396: }
397: }
398:
399:
400: $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
401: $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
402:
403:
404: $this->_plugins_code = '';
405: if (count($this->_plugin_info)) {
406: $_plugins_params = "array('plugins' => array(";
407: foreach ($this->_plugin_info as $plugin_type => $plugins) {
408: foreach ($plugins as $plugin_name => $plugin_info) {
409: $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
410: $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
411: }
412: }
413: $_plugins_params .= '))';
414: $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
415: $template_header .= $plugins_code;
416: $this->_plugin_info = array();
417: $this->_plugins_code = $plugins_code;
418: }
419:
420: if ($this->_init_smarty_vars) {
421: $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
422: $this->_init_smarty_vars = false;
423: }
424:
425: $compiled_content = $template_header . $compiled_content;
426: return true;
427: }
428:
429: 430: 431: 432: 433: 434:
435: function _compile_tag($template_tag)
436: {
437:
438: if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
439: return '';
440:
441:
442: if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
443: . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
444: (?:\s+(.*))?$
445: ~xs', $template_tag, $match)) {
446: $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
447: }
448:
449: $tag_command = $match[1];
450: $tag_modifier = isset($match[2]) ? $match[2] : null;
451: $tag_args = isset($match[3]) ? $match[3] : null;
452:
453: if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
454:
455: $_return = $this->_parse_var_props($tag_command . $tag_modifier);
456: return "<?php echo $_return; ?>" . $this->_additional_newline;
457: }
458:
459:
460: if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
461: return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
462: }
463:
464: switch ($tag_command) {
465: case 'include':
466: return $this->_compile_include_tag($tag_args);
467:
468: case 'include_php':
469: return $this->_compile_include_php_tag($tag_args);
470:
471: case 'if':
472: $this->_push_tag('if');
473: return $this->_compile_if_tag($tag_args);
474:
475: case 'else':
476: list($_open_tag) = end($this->_tag_stack);
477: if ($_open_tag != 'if' && $_open_tag != 'elseif')
478: $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
479: else
480: $this->_push_tag('else');
481: return '<?php else: ?>';
482:
483: case 'elseif':
484: list($_open_tag) = end($this->_tag_stack);
485: if ($_open_tag != 'if' && $_open_tag != 'elseif')
486: $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
487: if ($_open_tag == 'if')
488: $this->_push_tag('elseif');
489: return $this->_compile_if_tag($tag_args, true);
490:
491: case '/if':
492: $this->_pop_tag('if');
493: return '<?php endif; ?>';
494:
495: case 'capture':
496: return $this->_compile_capture_tag(true, $tag_args);
497:
498: case '/capture':
499: return $this->_compile_capture_tag(false);
500:
501: case 'ldelim':
502: return $this->left_delimiter;
503:
504: case 'rdelim':
505: return $this->right_delimiter;
506:
507: case 'section':
508: $this->_push_tag('section');
509: return $this->_compile_section_start($tag_args);
510:
511: case 'sectionelse':
512: $this->_push_tag('sectionelse');
513: return "<?php endfor; else: ?>";
514: break;
515:
516: case '/section':
517: $_open_tag = $this->_pop_tag('section');
518: if ($_open_tag == 'sectionelse')
519: return "<?php endif; ?>";
520: else
521: return "<?php endfor; endif; ?>";
522:
523: case 'foreach':
524: $this->_push_tag('foreach');
525: return $this->_compile_foreach_start($tag_args);
526: break;
527:
528: case 'foreachelse':
529: $this->_push_tag('foreachelse');
530: return "<?php endforeach; else: ?>";
531:
532: case '/foreach':
533: $_open_tag = $this->_pop_tag('foreach');
534: if ($_open_tag == 'foreachelse')
535: return "<?php endif; unset(\$_from); ?>";
536: else
537: return "<?php endforeach; endif; unset(\$_from); ?>";
538: break;
539:
540: case 'strip':
541: case '/strip':
542: if (substr($tag_command, 0, 1)=='/') {
543: $this->_pop_tag('strip');
544: if (--$this->_strip_depth==0) {
545: $this->_additional_newline = "\n";
546: return '{' . $tag_command . '}';
547: }
548: } else {
549: $this->_push_tag('strip');
550: if ($this->_strip_depth++==0) {
551: $this->_additional_newline = "";
552: return '{' . $tag_command . '}';
553: }
554: }
555: return '';
556:
557: case 'php':
558:
559: list(, $block) = each($this->_folded_blocks);
560: $this->_current_line_no += substr_count($block[0], "\n");
561: 562:
563: switch (count($block)) {
564: case 2:
565: return '';
566:
567: case 3:
568: return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
569:
570: case 4:
571: if ($this->security && !$this->security_settings['PHP_TAGS']) {
572: $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
573: return;
574: }
575: return '<?php ' . $block[3] .' ?>';
576: }
577: break;
578:
579: case 'insert':
580: return $this->_compile_insert_tag($tag_args);
581:
582: default:
583: if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
584: return $output;
585: } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
586: return $output;
587: } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
588: return $output;
589: } else {
590: $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
591: }
592:
593: }
594: }
595:
596:
597: 598: 599: 600: 601: 602: 603: 604: 605:
606: function _compile_compiler_tag($tag_command, $tag_args, &$output)
607: {
608: $found = false;
609: $have_function = true;
610:
611: 612: 613: 614:
615: if (isset($this->_plugins['compiler'][$tag_command])) {
616: $found = true;
617: $plugin_func = $this->_plugins['compiler'][$tag_command][0];
618: if (!is_callable($plugin_func)) {
619: $message = "compiler function '$tag_command' is not implemented";
620: $have_function = false;
621: }
622: }
623: 624: 625: 626:
627: else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
628: $found = true;
629:
630: include_once $plugin_file;
631:
632: $plugin_func = 'smarty_compiler_' . $tag_command;
633: if (!is_callable($plugin_func)) {
634: $message = "plugin function $plugin_func() not found in $plugin_file\n";
635: $have_function = false;
636: } else {
637: $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
638: }
639: }
640:
641: 642: 643: 644: 645: 646:
647: if ($found) {
648: if ($have_function) {
649: $output = call_user_func_array($plugin_func, array($tag_args, &$this));
650: if($output != '') {
651: $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
652: . $output
653: . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
654: }
655: } else {
656: $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
657: }
658: return true;
659: } else {
660: return false;
661: }
662: }
663:
664:
665: 666: 667: 668: 669: 670: 671: 672: 673: 674:
675: function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
676: {
677: if (substr($tag_command, 0, 1) == '/') {
678: $start_tag = false;
679: $tag_command = substr($tag_command, 1);
680: } else
681: $start_tag = true;
682:
683: $found = false;
684: $have_function = true;
685:
686: 687: 688: 689:
690: if (isset($this->_plugins['block'][$tag_command])) {
691: $found = true;
692: $plugin_func = $this->_plugins['block'][$tag_command][0];
693: if (!is_callable($plugin_func)) {
694: $message = "block function '$tag_command' is not implemented";
695: $have_function = false;
696: }
697: }
698: 699: 700: 701:
702: else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
703: $found = true;
704:
705: include_once $plugin_file;
706:
707: $plugin_func = 'smarty_block_' . $tag_command;
708: if (!function_exists($plugin_func)) {
709: $message = "plugin function $plugin_func() not found in $plugin_file\n";
710: $have_function = false;
711: } else {
712: $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
713:
714: }
715: }
716:
717: if (!$found) {
718: return false;
719: } else if (!$have_function) {
720: $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
721: return true;
722: }
723:
724: 725: 726: 727: 728:
729: $this->_add_plugin('block', $tag_command);
730:
731: if ($start_tag)
732: $this->_push_tag($tag_command);
733: else
734: $this->_pop_tag($tag_command);
735:
736: if ($start_tag) {
737: $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
738: $attrs = $this->_parse_attrs($tag_args);
739: $_cache_attrs='';
740: $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
741: $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
742: $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
743: $output .= 'while ($_block_repeat) { ob_start(); ?>';
744: } else {
745: $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
746: $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
747: if ($tag_modifier != '') {
748: $this->_parse_modifiers($_out_tag_text, $tag_modifier);
749: }
750: $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
751: $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
752: }
753:
754: return true;
755: }
756:
757:
758: 759: 760: 761: 762: 763: 764: 765:
766: function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
767: {
768: $found = false;
769: $have_function = true;
770:
771: 772: 773: 774:
775: if (isset($this->_plugins['function'][$tag_command])) {
776: $found = true;
777: $plugin_func = $this->_plugins['function'][$tag_command][0];
778: if (!is_callable($plugin_func)) {
779: $message = "custom function '$tag_command' is not implemented";
780: $have_function = false;
781: }
782: }
783: 784: 785: 786:
787: else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
788: $found = true;
789:
790: include_once $plugin_file;
791:
792: $plugin_func = 'smarty_function_' . $tag_command;
793: if (!function_exists($plugin_func)) {
794: $message = "plugin function $plugin_func() not found in $plugin_file\n";
795: $have_function = false;
796: } else {
797: $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
798:
799: }
800: }
801:
802: if (!$found) {
803: return false;
804: } else if (!$have_function) {
805: $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
806: return true;
807: }
808:
809: 810:
811: $this->_add_plugin('function', $tag_command);
812:
813: $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
814: $attrs = $this->_parse_attrs($tag_args);
815: $_cache_attrs = '';
816: $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
817:
818: $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
819: if($tag_modifier != '') {
820: $this->_parse_modifiers($output, $tag_modifier);
821: }
822:
823: if($output != '') {
824: $output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
825: . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
826: }
827:
828: return true;
829: }
830:
831: 832: 833: 834: 835: 836: 837: 838:
839: function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
840: {
841: if (substr($tag_command, 0, 1) == '/') {
842: $start_tag = false;
843: $tag_command = substr($tag_command, 1);
844: } else {
845: $start_tag = true;
846: }
847:
848: list($object, $obj_comp) = explode('->', $tag_command);
849:
850: $arg_list = array();
851: if(count($attrs)) {
852: $_assign_var = false;
853: foreach ($attrs as $arg_name => $arg_value) {
854: if($arg_name == 'assign') {
855: $_assign_var = $arg_value;
856: unset($attrs['assign']);
857: continue;
858: }
859: if (is_bool($arg_value))
860: $arg_value = $arg_value ? 'true' : 'false';
861: $arg_list[] = "'$arg_name' => $arg_value";
862: }
863: }
864:
865: if($this->_reg_objects[$object][2]) {
866:
867: $args = "array(".implode(',', (array)$arg_list)."), \$this";
868: } else {
869:
870: $args = implode(',', array_values($attrs));
871: if (empty($args)) {
872: $args = '';
873: }
874: }
875:
876: $prefix = '';
877: $postfix = '';
878: $newline = '';
879: if(!is_object($this->_reg_objects[$object][0])) {
880: $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
881: } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
882: $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
883: } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
884:
885: if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
886:
887: if ($start_tag) {
888: $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
889: $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
890: $prefix .= "while (\$_block_repeat) { ob_start();";
891: $return = null;
892: $postfix = '';
893: } else {
894: $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
895: $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
896: $postfix = "} array_pop(\$this->_tag_stack);";
897: }
898: } else {
899:
900: $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
901: }
902: } else {
903:
904: $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
905: }
906:
907: if($return != null) {
908: if($tag_modifier != '') {
909: $this->_parse_modifiers($return, $tag_modifier);
910: }
911:
912: if(!empty($_assign_var)) {
913: $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);";
914: } else {
915: $output = 'echo ' . $return . ';';
916: $newline = $this->_additional_newline;
917: }
918: } else {
919: $output = '';
920: }
921:
922: return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
923: }
924:
925: 926: 927: 928: 929: 930:
931: function _compile_insert_tag($tag_args)
932: {
933: $attrs = $this->_parse_attrs($tag_args);
934: $name = $this->_dequote($attrs['name']);
935:
936: if (empty($name)) {
937: return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
938: }
939:
940: if (!preg_match('~^\w+$~', $name)) {
941: return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
942: }
943:
944: if (!empty($attrs['script'])) {
945: $delayed_loading = true;
946: } else {
947: $delayed_loading = false;
948: }
949:
950: foreach ($attrs as $arg_name => $arg_value) {
951: if (is_bool($arg_value))
952: $arg_value = $arg_value ? 'true' : 'false';
953: $arg_list[] = "'$arg_name' => $arg_value";
954: }
955:
956: $this->_add_plugin('insert', $name, $delayed_loading);
957:
958: $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
959:
960: return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
961: }
962:
963: 964: 965: 966: 967: 968:
969: function _compile_include_tag($tag_args)
970: {
971: $attrs = $this->_parse_attrs($tag_args);
972: $arg_list = array();
973:
974: if (empty($attrs['file'])) {
975: $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
976: }
977:
978: foreach ($attrs as $arg_name => $arg_value) {
979: if ($arg_name == 'file') {
980: $include_file = $arg_value;
981: continue;
982: } else if ($arg_name == 'assign') {
983: $assign_var = $arg_value;
984: continue;
985: }
986: if (is_bool($arg_value))
987: $arg_value = $arg_value ? 'true' : 'false';
988: $arg_list[] = "'$arg_name' => $arg_value";
989: }
990:
991: $output = '<?php ';
992:
993: if (isset($assign_var)) {
994: $output .= "ob_start();\n";
995: }
996:
997: $output .=
998: "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
999:
1000:
1001: $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
1002: $output .= "\$this->_smarty_include($_params);\n" .
1003: "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
1004: "unset(\$_smarty_tpl_vars);\n";
1005:
1006: if (isset($assign_var)) {
1007: $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
1008: }
1009:
1010: $output .= ' ?>';
1011:
1012: return $output;
1013:
1014: }
1015:
1016: 1017: 1018: 1019: 1020: 1021:
1022: function _compile_include_php_tag($tag_args)
1023: {
1024: $attrs = $this->_parse_attrs($tag_args);
1025:
1026: if (empty($attrs['file'])) {
1027: $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
1028: }
1029:
1030: $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
1031: $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
1032:
1033: $arg_list = array();
1034: foreach($attrs as $arg_name => $arg_value) {
1035: if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
1036: if(is_bool($arg_value))
1037: $arg_value = $arg_value ? 'true' : 'false';
1038: $arg_list[] = "'$arg_name' => $arg_value";
1039: }
1040: }
1041:
1042: $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
1043:
1044: return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
1045: }
1046:
1047:
1048: 1049: 1050: 1051: 1052: 1053:
1054: function _compile_section_start($tag_args)
1055: {
1056: $attrs = $this->_parse_attrs($tag_args);
1057: $arg_list = array();
1058:
1059: $output = '<?php ';
1060: $section_name = $attrs['name'];
1061: if (empty($section_name)) {
1062: $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
1063: }
1064:
1065: $output .= "unset(\$this->_sections[$section_name]);\n";
1066: $section_props = "\$this->_sections[$section_name]";
1067:
1068: foreach ($attrs as $attr_name => $attr_value) {
1069: switch ($attr_name) {
1070: case 'loop':
1071: $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
1072: break;
1073:
1074: case 'show':
1075: if (is_bool($attr_value))
1076: $show_attr_value = $attr_value ? 'true' : 'false';
1077: else
1078: $show_attr_value = "(bool)$attr_value";
1079: $output .= "{$section_props}['show'] = $show_attr_value;\n";
1080: break;
1081:
1082: case 'name':
1083: $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
1084: break;
1085:
1086: case 'max':
1087: case 'start':
1088: $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
1089: break;
1090:
1091: case 'step':
1092: $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
1093: break;
1094:
1095: default:
1096: $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
1097: break;
1098: }
1099: }
1100:
1101: if (!isset($attrs['show']))
1102: $output .= "{$section_props}['show'] = true;\n";
1103:
1104: if (!isset($attrs['loop']))
1105: $output .= "{$section_props}['loop'] = 1;\n";
1106:
1107: if (!isset($attrs['max']))
1108: $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
1109: else
1110: $output .= "if ({$section_props}['max'] < 0)\n" .
1111: " {$section_props}['max'] = {$section_props}['loop'];\n";
1112:
1113: if (!isset($attrs['step']))
1114: $output .= "{$section_props}['step'] = 1;\n";
1115:
1116: if (!isset($attrs['start']))
1117: $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
1118: else {
1119: $output .= "if ({$section_props}['start'] < 0)\n" .
1120: " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
1121: "else\n" .
1122: " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
1123: }
1124:
1125: $output .= "if ({$section_props}['show']) {\n";
1126: if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
1127: $output .= " {$section_props}['total'] = {$section_props}['loop'];\n";
1128: } else {
1129: $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
1130: }
1131: $output .= " if ({$section_props}['total'] == 0)\n" .
1132: " {$section_props}['show'] = false;\n" .
1133: "} else\n" .
1134: " {$section_props}['total'] = 0;\n";
1135:
1136: $output .= "if ({$section_props}['show']):\n";
1137: $output .= "
1138: for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
1139: {$section_props}['iteration'] <= {$section_props}['total'];
1140: {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
1141: $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
1142: $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
1143: $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
1144: $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
1145: $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
1146:
1147: $output .= "?>";
1148:
1149: return $output;
1150: }
1151:
1152:
1153: 1154: 1155: 1156: 1157: 1158:
1159: function _compile_foreach_start($tag_args)
1160: {
1161: $attrs = $this->_parse_attrs($tag_args);
1162: $arg_list = array();
1163:
1164: if (empty($attrs['from'])) {
1165: return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
1166: }
1167: $from = $attrs['from'];
1168:
1169: if (empty($attrs['item'])) {
1170: return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
1171: }
1172: $item = $this->_dequote($attrs['item']);
1173: if (!preg_match('~^\w+$~', $item)) {
1174: return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
1175: }
1176:
1177: if (isset($attrs['key'])) {
1178: $key = $this->_dequote($attrs['key']);
1179: if (!preg_match('~^\w+$~', $key)) {
1180: return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
1181: }
1182: $key_part = "\$this->_tpl_vars['$key'] => ";
1183: } else {
1184: $key = null;
1185: $key_part = '';
1186: }
1187:
1188: if (isset($attrs['name'])) {
1189: $name = $attrs['name'];
1190: } else {
1191: $name = null;
1192: }
1193:
1194: $output = '<?php ';
1195: $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
1196: if (isset($name)) {
1197: $foreach_props = "\$this->_foreach[$name]";
1198: $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
1199: $output .= "if ({$foreach_props}['total'] > 0):\n";
1200: $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
1201: $output .= " {$foreach_props}['iteration']++;\n";
1202: } else {
1203: $output .= "if (count(\$_from)):\n";
1204: $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
1205: }
1206: $output .= '?>';
1207:
1208: return $output;
1209: }
1210:
1211:
1212: 1213: 1214: 1215: 1216: 1217: 1218:
1219:
1220: function _compile_capture_tag($start, $tag_args = '')
1221: {
1222: $attrs = $this->_parse_attrs($tag_args);
1223:
1224: if ($start) {
1225: $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
1226: $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
1227: $append = isset($attrs['append']) ? $attrs['append'] : null;
1228:
1229: $output = "<?php ob_start(); ?>";
1230: $this->_capture_stack[] = array($buffer, $assign, $append);
1231: } else {
1232: list($buffer, $assign, $append) = array_pop($this->_capture_stack);
1233: $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
1234: if (isset($assign)) {
1235: $output .= " \$this->assign($assign, ob_get_contents());";
1236: }
1237: if (isset($append)) {
1238: $output .= " \$this->append($append, ob_get_contents());";
1239: }
1240: $output .= "ob_end_clean(); ?>";
1241: }
1242:
1243: return $output;
1244: }
1245:
1246: 1247: 1248: 1249: 1250: 1251: 1252:
1253: function _compile_if_tag($tag_args, $elseif = false)
1254: {
1255:
1256:
1257: preg_match_all('~(?>
1258: ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
1259: ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string
1260: \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token
1261: \b\w+\b | # valid word token
1262: \S+ # anything else
1263: )~x', $tag_args, $match);
1264:
1265: $tokens = $match[0];
1266:
1267: if(empty($tokens)) {
1268: $_error_msg = $elseif ? "'elseif'" : "'if'";
1269: $_error_msg .= ' statement requires arguments';
1270: $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
1271: }
1272:
1273:
1274:
1275: $token_count = array_count_values($tokens);
1276: if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
1277: $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
1278: }
1279:
1280: $is_arg_stack = array();
1281:
1282: for ($i = 0; $i < count($tokens); $i++) {
1283:
1284: $token = &$tokens[$i];
1285:
1286: switch (strtolower($token)) {
1287: case '!':
1288: case '%':
1289: case '!==':
1290: case '==':
1291: case '===':
1292: case '>':
1293: case '<':
1294: case '!=':
1295: case '<>':
1296: case '<<':
1297: case '>>':
1298: case '<=':
1299: case '>=':
1300: case '&&':
1301: case '||':
1302: case '|':
1303: case '^':
1304: case '&':
1305: case '~':
1306: case ')':
1307: case ',':
1308: case '+':
1309: case '-':
1310: case '*':
1311: case '/':
1312: case '@':
1313: break;
1314:
1315: case 'eq':
1316: $token = '==';
1317: break;
1318:
1319: case 'ne':
1320: case 'neq':
1321: $token = '!=';
1322: break;
1323:
1324: case 'lt':
1325: $token = '<';
1326: break;
1327:
1328: case 'le':
1329: case 'lte':
1330: $token = '<=';
1331: break;
1332:
1333: case 'gt':
1334: $token = '>';
1335: break;
1336:
1337: case 'ge':
1338: case 'gte':
1339: $token = '>=';
1340: break;
1341:
1342: case 'and':
1343: $token = '&&';
1344: break;
1345:
1346: case 'or':
1347: $token = '||';
1348: break;
1349:
1350: case 'not':
1351: $token = '!';
1352: break;
1353:
1354: case 'mod':
1355: $token = '%';
1356: break;
1357:
1358: case '(':
1359: array_push($is_arg_stack, $i);
1360: break;
1361:
1362: case 'is':
1363: 1364: 1365:
1366: if ($tokens[$i-1] == ')') {
1367: $is_arg_start = array_pop($is_arg_stack);
1368: if ($is_arg_start != 0) {
1369: if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) {
1370: $is_arg_start--;
1371: }
1372: }
1373: } else
1374: $is_arg_start = $i-1;
1375: 1376:
1377: $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
1378:
1379: 1380: 1381: 1382: 1383:
1384: $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
1385:
1386:
1387: array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
1388:
1389: 1390:
1391: $i = $is_arg_start;
1392: break;
1393:
1394: default:
1395: if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
1396:
1397: if($this->security &&
1398: !in_array($token, $this->security_settings['IF_FUNCS'])) {
1399: $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
1400: }
1401: } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
1402:
1403: $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
1404: } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
1405:
1406: $token = $this->_parse_var_props($token);
1407: } elseif(is_numeric($token)) {
1408:
1409: } else {
1410: $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
1411: }
1412: break;
1413: }
1414: }
1415:
1416: if ($elseif)
1417: return '<?php elseif ('.implode(' ', $tokens).'): ?>';
1418: else
1419: return '<?php if ('.implode(' ', $tokens).'): ?>';
1420: }
1421:
1422:
1423: function _compile_arg_list($type, $name, $attrs, &$cache_code) {
1424: $arg_list = array();
1425:
1426: if (isset($type) && isset($name)
1427: && isset($this->_plugins[$type])
1428: && isset($this->_plugins[$type][$name])
1429: && empty($this->_plugins[$type][$name][4])
1430: && is_array($this->_plugins[$type][$name][5])
1431: ) {
1432:
1433: $_cache_attrs = $this->_plugins[$type][$name][5];
1434: $_count = $this->_cache_attrs_count++;
1435: $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
1436:
1437: } else {
1438:
1439: $_cache_attrs = null;
1440: }
1441:
1442: foreach ($attrs as $arg_name => $arg_value) {
1443: if (is_bool($arg_value))
1444: $arg_value = $arg_value ? 'true' : 'false';
1445: if (is_null($arg_value))
1446: $arg_value = 'null';
1447: if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
1448: $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
1449: } else {
1450: $arg_list[] = "'$arg_name' => $arg_value";
1451: }
1452: }
1453: return $arg_list;
1454: }
1455:
1456: 1457: 1458: 1459: 1460: 1461: 1462:
1463: function _parse_is_expr($is_arg, $tokens)
1464: {
1465: $expr_end = 0;
1466: $negate_expr = false;
1467:
1468: if (($first_token = array_shift($tokens)) == 'not') {
1469: $negate_expr = true;
1470: $expr_type = array_shift($tokens);
1471: } else
1472: $expr_type = $first_token;
1473:
1474: switch ($expr_type) {
1475: case 'even':
1476: if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
1477: $expr_end++;
1478: $expr_arg = $tokens[$expr_end++];
1479: $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
1480: } else
1481: $expr = "!(1 & $is_arg)";
1482: break;
1483:
1484: case 'odd':
1485: if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
1486: $expr_end++;
1487: $expr_arg = $tokens[$expr_end++];
1488: $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
1489: } else
1490: $expr = "(1 & $is_arg)";
1491: break;
1492:
1493: case 'div':
1494: if (@$tokens[$expr_end] == 'by') {
1495: $expr_end++;
1496: $expr_arg = $tokens[$expr_end++];
1497: $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
1498: } else {
1499: $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
1500: }
1501: break;
1502:
1503: default:
1504: $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
1505: break;
1506: }
1507:
1508: if ($negate_expr) {
1509: $expr = "!($expr)";
1510: }
1511:
1512: array_splice($tokens, 0, $expr_end, $expr);
1513:
1514: return $tokens;
1515: }
1516:
1517:
1518: 1519: 1520: 1521: 1522: 1523:
1524: function _parse_attrs($tag_args)
1525: {
1526:
1527:
1528: preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
1529: )+ |
1530: [=]
1531: ~x', $tag_args, $match);
1532: $tokens = $match[0];
1533:
1534: $attrs = array();
1535: 1536: 1537: 1538:
1539: $state = 0;
1540:
1541: foreach ($tokens as $token) {
1542: switch ($state) {
1543: case 0:
1544: 1545:
1546: if (preg_match('~^\w+$~', $token)) {
1547: $attr_name = $token;
1548: $state = 1;
1549: } else
1550: $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
1551: break;
1552:
1553: case 1:
1554:
1555: if ($token == '=') {
1556: $state = 2;
1557: } else
1558: $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
1559: break;
1560:
1561: case 2:
1562: 1563:
1564: if ($token != '=') {
1565: 1566:
1567: if (preg_match('~^(on|yes|true)$~', $token)) {
1568: $token = 'true';
1569: } else if (preg_match('~^(off|no|false)$~', $token)) {
1570: $token = 'false';
1571: } else if ($token == 'null') {
1572: $token = 'null';
1573: } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
1574:
1575: } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
1576:
1577: $token = '"'.addslashes($token).'"';
1578: }
1579:
1580: $attrs[$attr_name] = $token;
1581: $state = 0;
1582: } else
1583: $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
1584: break;
1585: }
1586: $last_token = $token;
1587: }
1588:
1589: if($state != 0) {
1590: if($state == 1) {
1591: $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
1592: } else {
1593: $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
1594: }
1595: }
1596:
1597: $this->_parse_vars_props($attrs);
1598:
1599: return $attrs;
1600: }
1601:
1602: 1603: 1604: 1605: 1606: 1607:
1608: function _parse_vars_props(&$tokens)
1609: {
1610: foreach($tokens as $key => $val) {
1611: $tokens[$key] = $this->_parse_var_props($val);
1612: }
1613: }
1614:
1615: 1616: 1617: 1618: 1619: 1620: 1621: 1622:
1623: function _parse_var_props($val)
1624: {
1625: $val = trim($val);
1626:
1627: if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
1628:
1629: $return = $this->_parse_var($match[1]);
1630: $modifiers = $match[2];
1631: if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
1632: $_default_mod_string = implode('|',(array)$this->default_modifiers);
1633: $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
1634: }
1635: $this->_parse_modifiers($return, $modifiers);
1636: return $return;
1637: } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
1638:
1639: preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
1640: $return = $this->_expand_quoted_text($match[1]);
1641: if($match[2] != '') {
1642: $this->_parse_modifiers($return, $match[2]);
1643: }
1644: return $return;
1645: }
1646: elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
1647:
1648: preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
1649: if($match[2] != '') {
1650: $this->_parse_modifiers($match[1], $match[2]);
1651: return $match[1];
1652: }
1653: }
1654: elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
1655:
1656: preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
1657: if($match[2] != '') {
1658: $this->_parse_modifiers($match[1], $match[2]);
1659: return $match[1];
1660: }
1661: }
1662: elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
1663:
1664: return $this->_parse_conf_var($val);
1665: }
1666: elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
1667:
1668: return $this->_parse_section_prop($val);
1669: }
1670: elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
1671:
1672: return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
1673: }
1674: return $val;
1675: }
1676:
1677: 1678: 1679: 1680: 1681: 1682:
1683: function _expand_quoted_text($var_expr)
1684: {
1685:
1686: if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
1687: $_match = $_match[0];
1688: $_replace = array();
1689: foreach($_match as $_var) {
1690: $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
1691: }
1692: $var_expr = strtr($var_expr, $_replace);
1693: $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
1694: } else {
1695: $_return = $var_expr;
1696: }
1697:
1698: $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return);
1699: return $_return;
1700: }
1701:
1702: 1703: 1704: 1705: 1706: 1707: 1708:
1709: function _parse_var($var_expr)
1710: {
1711: $_has_math = false;
1712: $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
1713:
1714: if(count($_math_vars) > 1) {
1715: $_first_var = "";
1716: $_complete_var = "";
1717: $_output = "";
1718:
1719: foreach($_math_vars as $_k => $_math_var) {
1720: $_math_var = $_math_vars[$_k];
1721:
1722: if(!empty($_math_var) || is_numeric($_math_var)) {
1723:
1724: if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
1725: $_has_math = true;
1726: if(!empty($_complete_var) || is_numeric($_complete_var)) {
1727: $_output .= $this->_parse_var($_complete_var);
1728: }
1729:
1730:
1731: $_output .= $_math_var;
1732:
1733: if(empty($_first_var))
1734: $_first_var = $_complete_var;
1735:
1736: $_complete_var = "";
1737: } else {
1738: $_complete_var .= $_math_var;
1739: }
1740: }
1741: }
1742: if($_has_math) {
1743: if(!empty($_complete_var) || is_numeric($_complete_var))
1744: $_output .= $this->_parse_var($_complete_var);
1745:
1746:
1747: $var_expr = $_complete_var;
1748: }
1749: }
1750:
1751:
1752: if(is_numeric(substr($var_expr, 0, 1)))
1753: $_var_ref = $var_expr;
1754: else
1755: $_var_ref = substr($var_expr, 1);
1756:
1757: if(!$_has_math) {
1758:
1759:
1760: preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
1761:
1762: $_indexes = $match[0];
1763: $_var_name = array_shift($_indexes);
1764:
1765:
1766: if ($_var_name == 'smarty') {
1767: 1768: 1769: 1770: 1771:
1772: if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
1773: $_output = $smarty_ref;
1774: } else {
1775: $_var_name = substr(array_shift($_indexes), 1);
1776: $_output = "\$this->_smarty_vars['$_var_name']";
1777: }
1778: } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
1779:
1780: if(count($_indexes) > 0)
1781: {
1782: $_var_name .= implode("", $_indexes);
1783: $_indexes = array();
1784: }
1785: $_output = $_var_name;
1786: } else {
1787: $_output = "\$this->_tpl_vars['$_var_name']";
1788: }
1789:
1790: foreach ($_indexes as $_index) {
1791: if (substr($_index, 0, 1) == '[') {
1792: $_index = substr($_index, 1, -1);
1793: if (is_numeric($_index)) {
1794: $_output .= "[$_index]";
1795: } elseif (substr($_index, 0, 1) == '$') {
1796: if (strpos($_index, '.') !== false) {
1797: $_output .= '[' . $this->_parse_var($_index) . ']';
1798: } else {
1799: $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
1800: }
1801: } else {
1802: $_var_parts = explode('.', $_index);
1803: $_var_section = $_var_parts[0];
1804: $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
1805: $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
1806: }
1807: } else if (substr($_index, 0, 1) == '.') {
1808: if (substr($_index, 1, 1) == '$')
1809: $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
1810: else
1811: $_output .= "['" . substr($_index, 1) . "']";
1812: } else if (substr($_index,0,2) == '->') {
1813: if(substr($_index,2,2) == '__') {
1814: $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
1815: } elseif($this->security && substr($_index, 2, 1) == '_') {
1816: $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
1817: } elseif (substr($_index, 2, 1) == '$') {
1818: if ($this->security) {
1819: $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
1820: } else {
1821: $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
1822: }
1823: } else {
1824: $_output .= $_index;
1825: }
1826: } elseif (substr($_index, 0, 1) == '(') {
1827: $_index = $this->_parse_parenth_args($_index);
1828: $_output .= $_index;
1829: } else {
1830: $_output .= $_index;
1831: }
1832: }
1833: }
1834:
1835: return $_output;
1836: }
1837:
1838: 1839: 1840: 1841: 1842: 1843:
1844: function _parse_parenth_args($parenth_args)
1845: {
1846: preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
1847: $orig_vals = $match = $match[0];
1848: $this->_parse_vars_props($match);
1849: $replace = array();
1850: for ($i = 0, $count = count($match); $i < $count; $i++) {
1851: $replace[$orig_vals[$i]] = $match[$i];
1852: }
1853: return strtr($parenth_args, $replace);
1854: }
1855:
1856: 1857: 1858: 1859: 1860:
1861: function _parse_conf_var($conf_var_expr)
1862: {
1863: $parts = explode('|', $conf_var_expr, 2);
1864: $var_ref = $parts[0];
1865: $modifiers = isset($parts[1]) ? $parts[1] : '';
1866:
1867: $var_name = substr($var_ref, 1, -1);
1868:
1869: $output = "\$this->_config[0]['vars']['$var_name']";
1870:
1871: $this->_parse_modifiers($output, $modifiers);
1872:
1873: return $output;
1874: }
1875:
1876: 1877: 1878: 1879: 1880: 1881:
1882: function _parse_section_prop($section_prop_expr)
1883: {
1884: $parts = explode('|', $section_prop_expr, 2);
1885: $var_ref = $parts[0];
1886: $modifiers = isset($parts[1]) ? $parts[1] : '';
1887:
1888: preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
1889: $section_name = $match[1];
1890: $prop_name = $match[2];
1891:
1892: $output = "\$this->_sections['$section_name']['$prop_name']";
1893:
1894: $this->_parse_modifiers($output, $modifiers);
1895:
1896: return $output;
1897: }
1898:
1899:
1900: 1901: 1902: 1903: 1904: 1905: 1906:
1907: function _parse_modifiers(&$output, $modifier_string)
1908: {
1909: preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
1910: list(, $_modifiers, $modifier_arg_strings) = $_match;
1911:
1912: for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
1913: $_modifier_name = $_modifiers[$_i];
1914:
1915: if($_modifier_name == 'smarty') {
1916:
1917: continue;
1918: }
1919:
1920: preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
1921: $_modifier_args = $_match[1];
1922:
1923: if (substr($_modifier_name, 0, 1) == '@') {
1924: $_map_array = false;
1925: $_modifier_name = substr($_modifier_name, 1);
1926: } else {
1927: $_map_array = true;
1928: }
1929:
1930: if (empty($this->_plugins['modifier'][$_modifier_name])
1931: && !$this->_get_plugin_filepath('modifier', $_modifier_name)
1932: && function_exists($_modifier_name)) {
1933: if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
1934: $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
1935: } else {
1936: $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false);
1937: }
1938: }
1939: $this->_add_plugin('modifier', $_modifier_name);
1940:
1941: $this->_parse_vars_props($_modifier_args);
1942:
1943: if($_modifier_name == 'default') {
1944:
1945: if(substr($output, 0, 1) == '$') {
1946: $output = '@' . $output;
1947: }
1948: if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
1949: $_modifier_args[0] = '@' . $_modifier_args[0];
1950: }
1951: }
1952: if (count($_modifier_args) > 0)
1953: $_modifier_args = ', '.implode(', ', $_modifier_args);
1954: else
1955: $_modifier_args = '';
1956:
1957: if ($_map_array) {
1958: $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
1959:
1960: } else {
1961:
1962: $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
1963:
1964: }
1965: }
1966: }
1967:
1968:
1969: 1970: 1971: 1972: 1973: 1974: 1975:
1976: function _add_plugin($type, $name, $delayed_loading = null)
1977: {
1978: if (!isset($this->_plugin_info[$type])) {
1979: $this->_plugin_info[$type] = array();
1980: }
1981: if (!isset($this->_plugin_info[$type][$name])) {
1982: $this->_plugin_info[$type][$name] = array($this->_current_file,
1983: $this->_current_line_no,
1984: $delayed_loading);
1985: }
1986: }
1987:
1988:
1989: 1990: 1991: 1992: 1993: 1994:
1995: function _compile_smarty_ref(&$indexes)
1996: {
1997:
1998: $_ref = substr($indexes[0], 1);
1999: foreach($indexes as $_index_no=>$_index) {
2000: if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
2001: $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
2002: }
2003: }
2004:
2005: switch ($_ref) {
2006: case 'now':
2007: $compiled_ref = 'time()';
2008: $_max_index = 1;
2009: break;
2010:
2011: case 'foreach':
2012: array_shift($indexes);
2013: $_var = $this->_parse_var_props(substr($indexes[0], 1));
2014: $_propname = substr($indexes[1], 1);
2015: $_max_index = 1;
2016: switch ($_propname) {
2017: case 'index':
2018: array_shift($indexes);
2019: $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
2020: break;
2021:
2022: case 'first':
2023: array_shift($indexes);
2024: $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
2025: break;
2026:
2027: case 'last':
2028: array_shift($indexes);
2029: $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
2030: break;
2031:
2032: case 'show':
2033: array_shift($indexes);
2034: $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
2035: break;
2036:
2037: default:
2038: unset($_max_index);
2039: $compiled_ref = "\$this->_foreach[$_var]";
2040: }
2041: break;
2042:
2043: case 'section':
2044: array_shift($indexes);
2045: $_var = $this->_parse_var_props(substr($indexes[0], 1));
2046: $compiled_ref = "\$this->_sections[$_var]";
2047: break;
2048:
2049: case 'get':
2050: if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
2051: $this->_syntax_error("(secure mode) super global access not permitted",
2052: E_USER_WARNING, __FILE__, __LINE__);
2053: return;
2054: }
2055: $compiled_ref = "\$_GET";
2056: break;
2057:
2058: case 'post':
2059: if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
2060: $this->_syntax_error("(secure mode) super global access not permitted",
2061: E_USER_WARNING, __FILE__, __LINE__);
2062: return;
2063: }
2064: $compiled_ref = "\$_POST";
2065: break;
2066:
2067: case 'cookies':
2068: if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
2069: $this->_syntax_error("(secure mode) super global access not permitted",
2070: E_USER_WARNING, __FILE__, __LINE__);
2071: return;
2072: }
2073: $compiled_ref = "\$_COOKIE";
2074: break;
2075:
2076: case 'env':
2077: if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
2078: $this->_syntax_error("(secure mode) super global access not permitted",
2079: E_USER_WARNING, __FILE__, __LINE__);
2080: return;
2081: }
2082: $compiled_ref = "\$_ENV";
2083: break;
2084:
2085: case 'server':
2086: if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
2087: $this->_syntax_error("(secure mode) super global access not permitted",
2088: E_USER_WARNING, __FILE__, __LINE__);
2089: return;
2090: }
2091: $compiled_ref = "\$_SERVER";
2092: break;
2093:
2094: case 'session':
2095: if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
2096: $this->_syntax_error("(secure mode) super global access not permitted",
2097: E_USER_WARNING, __FILE__, __LINE__);
2098: return;
2099: }
2100: $compiled_ref = "\$_SESSION";
2101: break;
2102:
2103: 2104: 2105: 2106:
2107: case 'request':
2108: if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
2109: $this->_syntax_error("(secure mode) super global access not permitted",
2110: E_USER_WARNING, __FILE__, __LINE__);
2111: return;
2112: }
2113: if ($this->request_use_auto_globals) {
2114: $compiled_ref = "\$_REQUEST";
2115: break;
2116: } else {
2117: $this->_init_smarty_vars = true;
2118: }
2119: return null;
2120:
2121: case 'capture':
2122: return null;
2123:
2124: case 'template':
2125: $compiled_ref = "'" . addslashes($this->_current_file) . "'";
2126: $_max_index = 1;
2127: break;
2128:
2129: case 'version':
2130: $compiled_ref = "'$this->_version'";
2131: $_max_index = 1;
2132: break;
2133:
2134: case 'const':
2135: if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
2136: $this->_syntax_error("(secure mode) constants not permitted",
2137: E_USER_WARNING, __FILE__, __LINE__);
2138: return;
2139: }
2140: array_shift($indexes);
2141: if (preg_match('!^\.\w+$!', $indexes[0])) {
2142: $compiled_ref = '@' . substr($indexes[0], 1);
2143: } else {
2144: $_val = $this->_parse_var_props(substr($indexes[0], 1));
2145: $compiled_ref = '@constant(' . $_val . ')';
2146: }
2147: $_max_index = 1;
2148: break;
2149:
2150: case 'config':
2151: $compiled_ref = "\$this->_config[0]['vars']";
2152: $_max_index = 3;
2153: break;
2154:
2155: case 'ldelim':
2156: $compiled_ref = "'$this->left_delimiter'";
2157: break;
2158:
2159: case 'rdelim':
2160: $compiled_ref = "'$this->right_delimiter'";
2161: break;
2162:
2163: default:
2164: $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
2165: break;
2166: }
2167:
2168: if (isset($_max_index) && count($indexes) > $_max_index) {
2169: $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
2170: }
2171:
2172: array_shift($indexes);
2173: return $compiled_ref;
2174: }
2175:
2176: 2177: 2178: 2179: 2180: 2181: 2182: 2183: 2184: 2185:
2186: function _compile_plugin_call($type, $name) {
2187: if (isset($this->_plugins[$type][$name])) {
2188:
2189: if (is_array($this->_plugins[$type][$name][0])) {
2190: return ((is_object($this->_plugins[$type][$name][0][0])) ?
2191: "\$this->_plugins['$type']['$name'][0][0]->"
2192: : (string)($this->_plugins[$type][$name][0][0]).'::'
2193: ). $this->_plugins[$type][$name][0][1];
2194:
2195: } else {
2196:
2197: return $this->_plugins[$type][$name][0];
2198:
2199: }
2200: } else {
2201:
2202: return 'smarty_'.$type.'_'.$name;
2203:
2204: }
2205: }
2206:
2207: 2208: 2209:
2210: function _load_filters()
2211: {
2212: if (count($this->_plugins['prefilter']) > 0) {
2213: foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
2214: if ($prefilter === false) {
2215: unset($this->_plugins['prefilter'][$filter_name]);
2216: $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
2217: require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
2218: smarty_core_load_plugins($_params, $this);
2219: }
2220: }
2221: }
2222: if (count($this->_plugins['postfilter']) > 0) {
2223: foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
2224: if ($postfilter === false) {
2225: unset($this->_plugins['postfilter'][$filter_name]);
2226: $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
2227: require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
2228: smarty_core_load_plugins($_params, $this);
2229: }
2230: }
2231: }
2232: }
2233:
2234:
2235: 2236: 2237: 2238: 2239: 2240:
2241: function _quote_replace($string)
2242: {
2243: return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
2244: }
2245:
2246: 2247: 2248: 2249: 2250: 2251: 2252: 2253:
2254: function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
2255: {
2256: $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
2257: }
2258:
2259:
2260: 2261: 2262: 2263: 2264: 2265:
2266: function _push_cacheable_state($type, $name) {
2267: $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
2268: if ($_cacheable
2269: || 0<$this->_cacheable_state++) return '';
2270: if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
2271: $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
2272: . $this->_cache_serial . '#' . $this->_nocache_count
2273: . '}\'; endif;';
2274: return $_ret;
2275: }
2276:
2277:
2278: 2279: 2280: 2281: 2282: 2283:
2284: function _pop_cacheable_state($type, $name) {
2285: $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
2286: if ($_cacheable
2287: || --$this->_cacheable_state>0) return '';
2288: return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
2289: . $this->_cache_serial . '#' . ($this->_nocache_count++)
2290: . '}\'; endif;';
2291: }
2292:
2293:
2294: 2295: 2296: 2297:
2298: function _push_tag($open_tag)
2299: {
2300: array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
2301: }
2302:
2303: 2304: 2305: 2306: 2307: 2308:
2309: function _pop_tag($close_tag)
2310: {
2311: $message = '';
2312: if (count($this->_tag_stack)>0) {
2313: list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
2314: if ($close_tag == $_open_tag) {
2315: return $_open_tag;
2316: }
2317: if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
2318: return $this->_pop_tag($close_tag);
2319: }
2320: if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
2321: $this->_pop_tag($close_tag);
2322: return $_open_tag;
2323: }
2324: if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
2325: $this->_pop_tag($close_tag);
2326: return $_open_tag;
2327: }
2328: if ($_open_tag == 'else' || $_open_tag == 'elseif') {
2329: $_open_tag = 'if';
2330: } elseif ($_open_tag == 'sectionelse') {
2331: $_open_tag = 'section';
2332: } elseif ($_open_tag == 'foreachelse') {
2333: $_open_tag = 'foreach';
2334: }
2335: $message = " expected {/$_open_tag} (opened line $_line_no).";
2336: }
2337: $this->_syntax_error("mismatched tag {/$close_tag}.$message",
2338: E_USER_ERROR, __FILE__, __LINE__);
2339: }
2340:
2341: }
2342:
2343: 2344: 2345: 2346: 2347: 2348: 2349: 2350:
2351: function _smarty_sort_length($a, $b)
2352: {
2353: if($a == $b)
2354: return 0;
2355:
2356: if(strlen($a) == strlen($b))
2357: return ($a > $b) ? -1 : 1;
2358:
2359: return (strlen($a) > strlen($b)) ? -1 : 1;
2360: }
2361:
2362:
2363:
2364:
2365: ?>
2366: