| 1: | <?php
|
| 2: | |
| 3: | |
| 4: | |
| 5: | |
| 6: | |
| 7: | |
| 8: | |
| 9: |
|
| 10: |
|
| 11: | |
| 12: | |
| 13: | |
| 14: | |
| 15: | |
| 16: | |
| 17: | |
| 18: | |
| 19: | |
| 20: | |
| 21: |
|
| 22: | abstract class Smarty_Internal_TemplateCompilerBase
|
| 23: | {
|
| 24: | |
| 25: | |
| 26: | |
| 27: | |
| 28: |
|
| 29: | public static $_tag_objects = array();
|
| 30: |
|
| 31: | |
| 32: | |
| 33: | |
| 34: | |
| 35: |
|
| 36: | public static $prefixVariableNumber = 0;
|
| 37: |
|
| 38: | |
| 39: | |
| 40: | |
| 41: | |
| 42: |
|
| 43: | public $smarty = null;
|
| 44: |
|
| 45: | |
| 46: | |
| 47: | |
| 48: | |
| 49: |
|
| 50: | public $parser = null;
|
| 51: |
|
| 52: | |
| 53: | |
| 54: | |
| 55: | |
| 56: |
|
| 57: | public $nocache_hash = null;
|
| 58: |
|
| 59: | |
| 60: | |
| 61: | |
| 62: | |
| 63: |
|
| 64: | public $suppressNocacheProcessing = false;
|
| 65: |
|
| 66: | |
| 67: | |
| 68: | |
| 69: | |
| 70: |
|
| 71: | public $caching = 0;
|
| 72: |
|
| 73: | |
| 74: | |
| 75: | |
| 76: | |
| 77: |
|
| 78: | public $_tag_stack = array();
|
| 79: |
|
| 80: | |
| 81: | |
| 82: | |
| 83: | |
| 84: |
|
| 85: | public $_tag_stack_count = array();
|
| 86: |
|
| 87: | |
| 88: | |
| 89: | |
| 90: | |
| 91: |
|
| 92: | public $required_plugins = array('compiled' => array(), 'nocache' => array());
|
| 93: |
|
| 94: | |
| 95: | |
| 96: | |
| 97: | |
| 98: |
|
| 99: | public $required_plugins_stack = array();
|
| 100: |
|
| 101: | |
| 102: | |
| 103: | |
| 104: | |
| 105: |
|
| 106: | public $template = null;
|
| 107: |
|
| 108: | |
| 109: | |
| 110: | |
| 111: | |
| 112: |
|
| 113: | public $mergedSubTemplatesData = array();
|
| 114: |
|
| 115: | |
| 116: | |
| 117: | |
| 118: | |
| 119: |
|
| 120: | public $mergedSubTemplatesCode = array();
|
| 121: |
|
| 122: | |
| 123: | |
| 124: | |
| 125: | |
| 126: |
|
| 127: | public $templateProperties = array();
|
| 128: |
|
| 129: | |
| 130: | |
| 131: | |
| 132: | |
| 133: |
|
| 134: | public $trace_line_offset = 0;
|
| 135: |
|
| 136: | |
| 137: | |
| 138: | |
| 139: | |
| 140: |
|
| 141: | public $trace_uid = '';
|
| 142: |
|
| 143: | |
| 144: | |
| 145: | |
| 146: | |
| 147: |
|
| 148: | public $trace_filepath = '';
|
| 149: |
|
| 150: | |
| 151: | |
| 152: | |
| 153: | |
| 154: |
|
| 155: | public $trace_stack = array();
|
| 156: |
|
| 157: | |
| 158: | |
| 159: | |
| 160: | |
| 161: |
|
| 162: | public $default_handler_plugins = array();
|
| 163: |
|
| 164: | |
| 165: | |
| 166: | |
| 167: | |
| 168: |
|
| 169: | public $default_modifier_list = null;
|
| 170: |
|
| 171: | |
| 172: | |
| 173: | |
| 174: | |
| 175: |
|
| 176: | public $forceNocache = false;
|
| 177: |
|
| 178: | |
| 179: | |
| 180: | |
| 181: | |
| 182: |
|
| 183: | public $write_compiled_code = true;
|
| 184: |
|
| 185: | |
| 186: | |
| 187: | |
| 188: | |
| 189: |
|
| 190: | public $tpl_function = array();
|
| 191: |
|
| 192: | |
| 193: | |
| 194: | |
| 195: | |
| 196: |
|
| 197: | public $called_functions = array();
|
| 198: |
|
| 199: | |
| 200: | |
| 201: | |
| 202: | |
| 203: |
|
| 204: | public $blockOrFunctionCode = '';
|
| 205: |
|
| 206: | |
| 207: | |
| 208: | |
| 209: | |
| 210: |
|
| 211: | public $php_handling = 0;
|
| 212: |
|
| 213: | |
| 214: | |
| 215: | |
| 216: | |
| 217: |
|
| 218: | public $modifier_plugins = array();
|
| 219: |
|
| 220: | |
| 221: | |
| 222: | |
| 223: | |
| 224: |
|
| 225: | public $known_modifier_type = array();
|
| 226: |
|
| 227: | |
| 228: | |
| 229: | |
| 230: | |
| 231: |
|
| 232: | public $parent_compiler = null;
|
| 233: |
|
| 234: | |
| 235: | |
| 236: | |
| 237: | |
| 238: |
|
| 239: | public $nocache = false;
|
| 240: |
|
| 241: | |
| 242: | |
| 243: | |
| 244: | |
| 245: |
|
| 246: | public $tag_nocache = false;
|
| 247: |
|
| 248: | |
| 249: | |
| 250: | |
| 251: | |
| 252: |
|
| 253: | public $prefix_code = array();
|
| 254: |
|
| 255: | |
| 256: | |
| 257: | |
| 258: | |
| 259: |
|
| 260: | public $usedPrefixVariables = array();
|
| 261: |
|
| 262: | |
| 263: | |
| 264: | |
| 265: | |
| 266: |
|
| 267: | public $prefixCodeStack = array();
|
| 268: |
|
| 269: | |
| 270: | |
| 271: | |
| 272: | |
| 273: |
|
| 274: | public $has_code = false;
|
| 275: |
|
| 276: | |
| 277: | |
| 278: | |
| 279: | |
| 280: |
|
| 281: | public $has_variable_string = false;
|
| 282: |
|
| 283: | |
| 284: | |
| 285: | |
| 286: | |
| 287: |
|
| 288: | public $variable_filter_stack = array();
|
| 289: |
|
| 290: | |
| 291: | |
| 292: | |
| 293: | |
| 294: |
|
| 295: | public $variable_filters = array();
|
| 296: |
|
| 297: | |
| 298: | |
| 299: | |
| 300: | |
| 301: |
|
| 302: | public $loopNesting = 0;
|
| 303: |
|
| 304: | |
| 305: | |
| 306: | |
| 307: | |
| 308: |
|
| 309: | public $stripRegEx = '![\t ]*[\r\n]+[\t ]*!';
|
| 310: |
|
| 311: | |
| 312: | |
| 313: | |
| 314: | |
| 315: |
|
| 316: | public $plugin_search_order = array(
|
| 317: | 'function',
|
| 318: | 'block',
|
| 319: | 'compiler',
|
| 320: | 'class'
|
| 321: | );
|
| 322: |
|
| 323: | |
| 324: | |
| 325: | |
| 326: | |
| 327: |
|
| 328: | public $_cache = array();
|
| 329: |
|
| 330: | |
| 331: | |
| 332: | |
| 333: | |
| 334: |
|
| 335: | private $ldelPreg = '[{]';
|
| 336: |
|
| 337: | |
| 338: | |
| 339: | |
| 340: | |
| 341: |
|
| 342: | private $rdelPreg = '[}]';
|
| 343: |
|
| 344: | |
| 345: | |
| 346: | |
| 347: | |
| 348: |
|
| 349: | private $rdelLength = 0;
|
| 350: |
|
| 351: | |
| 352: | |
| 353: | |
| 354: | |
| 355: |
|
| 356: | private $ldelLength = 0;
|
| 357: |
|
| 358: | |
| 359: | |
| 360: | |
| 361: | |
| 362: |
|
| 363: | private $literalPreg = '';
|
| 364: |
|
| 365: | |
| 366: | |
| 367: | |
| 368: | |
| 369: |
|
| 370: | public function __construct(Smarty $smarty)
|
| 371: | {
|
| 372: | $this->smarty = $smarty;
|
| 373: | $this->nocache_hash = str_replace(
|
| 374: | array(
|
| 375: | '.',
|
| 376: | ','
|
| 377: | ),
|
| 378: | '_',
|
| 379: | uniqid(mt_rand(), true)
|
| 380: | );
|
| 381: | }
|
| 382: |
|
| 383: | |
| 384: | |
| 385: | |
| 386: | |
| 387: | |
| 388: | |
| 389: | |
| 390: | |
| 391: | |
| 392: |
|
| 393: | public function compileTemplate(
|
| 394: | Smarty_Internal_Template $template,
|
| 395: | $nocache = null,
|
| 396: | Smarty_Internal_TemplateCompilerBase $parent_compiler = null
|
| 397: | ) {
|
| 398: |
|
| 399: | $_compiled_code = $template->smarty->ext->_codeFrame->create(
|
| 400: | $template,
|
| 401: | $this->compileTemplateSource(
|
| 402: | $template,
|
| 403: | $nocache,
|
| 404: | $parent_compiler
|
| 405: | ),
|
| 406: | $this->postFilter($this->blockOrFunctionCode) .
|
| 407: | join('', $this->mergedSubTemplatesCode),
|
| 408: | false,
|
| 409: | $this
|
| 410: | );
|
| 411: | return $_compiled_code;
|
| 412: | }
|
| 413: |
|
| 414: | |
| 415: | |
| 416: | |
| 417: | |
| 418: | |
| 419: | |
| 420: | |
| 421: | |
| 422: | |
| 423: |
|
| 424: | public function compileTemplateSource(
|
| 425: | Smarty_Internal_Template $template,
|
| 426: | $nocache = null,
|
| 427: | Smarty_Internal_TemplateCompilerBase $parent_compiler = null
|
| 428: | ) {
|
| 429: | try {
|
| 430: |
|
| 431: | $this->template = $template;
|
| 432: | if (property_exists($this->template->smarty, 'plugin_search_order')) {
|
| 433: | $this->plugin_search_order = $this->template->smarty->plugin_search_order;
|
| 434: | }
|
| 435: | if ($this->smarty->debugging) {
|
| 436: | if (!isset($this->smarty->_debug)) {
|
| 437: | $this->smarty->_debug = new Smarty_Internal_Debug();
|
| 438: | }
|
| 439: | $this->smarty->_debug->start_compile($this->template);
|
| 440: | }
|
| 441: | if (isset($this->template->smarty->security_policy)) {
|
| 442: | $this->php_handling = $this->template->smarty->security_policy->php_handling;
|
| 443: | } else {
|
| 444: | $this->php_handling = $this->template->smarty->php_handling;
|
| 445: | }
|
| 446: | $this->parent_compiler = $parent_compiler ? $parent_compiler : $this;
|
| 447: | $nocache = isset($nocache) ? $nocache : false;
|
| 448: | if (empty($template->compiled->nocache_hash)) {
|
| 449: | $template->compiled->nocache_hash = $this->nocache_hash;
|
| 450: | } else {
|
| 451: | $this->nocache_hash = $template->compiled->nocache_hash;
|
| 452: | }
|
| 453: | $this->caching = $template->caching;
|
| 454: |
|
| 455: | $this->nocache = $nocache;
|
| 456: | $this->tag_nocache = false;
|
| 457: |
|
| 458: | $this->template->compiled->has_nocache_code = false;
|
| 459: | $this->has_variable_string = false;
|
| 460: | $this->prefix_code = array();
|
| 461: |
|
| 462: | if ($this->smarty->merge_compiled_includes || $this->template->source->handler->checkTimestamps()) {
|
| 463: | $this->parent_compiler->template->compiled->file_dependency[ $this->template->source->uid ] =
|
| 464: | array(
|
| 465: | $this->template->source->filepath,
|
| 466: | $this->template->source->getTimeStamp(),
|
| 467: | $this->template->source->type,
|
| 468: | );
|
| 469: | }
|
| 470: | $this->smarty->_current_file = $this->template->source->filepath;
|
| 471: |
|
| 472: | if (!empty($this->template->source->components)) {
|
| 473: |
|
| 474: |
|
| 475: | $_content =
|
| 476: | Smarty_Internal_Compile_Extends::extendsSourceArrayCode($this->template);
|
| 477: | } else {
|
| 478: |
|
| 479: | $_content = $this->template->source->getContent();
|
| 480: | }
|
| 481: | $_compiled_code = $this->postFilter($this->doCompile($this->preFilter($_content), true));
|
| 482: | if (!empty($this->required_plugins[ 'compiled' ]) || !empty($this->required_plugins[ 'nocache' ])) {
|
| 483: | $_compiled_code = '<?php ' . $this->compileRequiredPlugins() . "?>\n" . $_compiled_code;
|
| 484: | }
|
| 485: | } catch (Exception $e) {
|
| 486: | if ($this->smarty->debugging) {
|
| 487: | $this->smarty->_debug->end_compile($this->template);
|
| 488: | }
|
| 489: | $this->_tag_stack = array();
|
| 490: |
|
| 491: | $this->parent_compiler = null;
|
| 492: | $this->template = null;
|
| 493: | $this->parser = null;
|
| 494: | throw $e;
|
| 495: | }
|
| 496: | if ($this->smarty->debugging) {
|
| 497: | $this->smarty->_debug->end_compile($this->template);
|
| 498: | }
|
| 499: | $this->parent_compiler = null;
|
| 500: | $this->parser = null;
|
| 501: | return $_compiled_code;
|
| 502: | }
|
| 503: |
|
| 504: | |
| 505: | |
| 506: | |
| 507: | |
| 508: | |
| 509: | |
| 510: | |
| 511: |
|
| 512: | public function postFilter($code)
|
| 513: | {
|
| 514: |
|
| 515: | if (!empty($code)
|
| 516: | && (isset($this->smarty->autoload_filters[ 'post' ]) || isset($this->smarty->registered_filters[ 'post' ]))
|
| 517: | ) {
|
| 518: | return $this->smarty->ext->_filterHandler->runFilter('post', $code, $this->template);
|
| 519: | } else {
|
| 520: | return $code;
|
| 521: | }
|
| 522: | }
|
| 523: |
|
| 524: | |
| 525: | |
| 526: | |
| 527: | |
| 528: | |
| 529: | |
| 530: | |
| 531: |
|
| 532: | public function preFilter($_content)
|
| 533: | {
|
| 534: |
|
| 535: | if ($_content !== ''
|
| 536: | && ((isset($this->smarty->autoload_filters[ 'pre' ]) || isset($this->smarty->registered_filters[ 'pre' ])))
|
| 537: | ) {
|
| 538: | return $this->smarty->ext->_filterHandler->runFilter('pre', $_content, $this->template);
|
| 539: | } else {
|
| 540: | return $_content;
|
| 541: | }
|
| 542: | }
|
| 543: |
|
| 544: | |
| 545: | |
| 546: | |
| 547: | |
| 548: | |
| 549: | |
| 550: | |
| 551: | |
| 552: | |
| 553: | |
| 554: | |
| 555: | |
| 556: | |
| 557: | |
| 558: | |
| 559: | |
| 560: |
|
| 561: | public function compileTag($tag, $args, $parameter = array())
|
| 562: | {
|
| 563: | $this->prefixCodeStack[] = $this->prefix_code;
|
| 564: | $this->prefix_code = array();
|
| 565: | $result = $this->compileTag2($tag, $args, $parameter);
|
| 566: | $this->prefix_code = array_merge($this->prefix_code, array_pop($this->prefixCodeStack));
|
| 567: | return $result;
|
| 568: | }
|
| 569: |
|
| 570: | |
| 571: | |
| 572: | |
| 573: | |
| 574: | |
| 575: | |
| 576: |
|
| 577: | public function compileVariable($variable)
|
| 578: | {
|
| 579: | if (!strpos($variable, '(')) {
|
| 580: |
|
| 581: | $var = trim($variable, '\'');
|
| 582: | $this->tag_nocache = $this->tag_nocache |
|
| 583: | $this->template->ext->getTemplateVars->_getVariable(
|
| 584: | $this->template,
|
| 585: | $var,
|
| 586: | null,
|
| 587: | true,
|
| 588: | false
|
| 589: | )->nocache;
|
| 590: |
|
| 591: | }
|
| 592: | return '$_smarty_tpl->tpl_vars[' . $variable . ']->value';
|
| 593: | }
|
| 594: |
|
| 595: | |
| 596: | |
| 597: | |
| 598: | |
| 599: | |
| 600: | |
| 601: |
|
| 602: | public function compileConfigVariable($variable)
|
| 603: | {
|
| 604: |
|
| 605: | return '$_smarty_tpl->smarty->ext->configLoad->_getConfigVariable($_smarty_tpl, ' . $variable . ')';
|
| 606: | }
|
| 607: |
|
| 608: | |
| 609: | |
| 610: | |
| 611: | |
| 612: | |
| 613: | |
| 614: | |
| 615: | |
| 616: |
|
| 617: | public function compilePHPFunctionCall($name, $parameter)
|
| 618: | {
|
| 619: | if (!$this->smarty->security_policy || $this->smarty->security_policy->isTrustedPhpFunction($name, $this)) {
|
| 620: | if (strcasecmp($name, 'isset') === 0 || strcasecmp($name, 'empty') === 0
|
| 621: | || strcasecmp($name, 'array') === 0 || is_callable($name)
|
| 622: | ) {
|
| 623: | $func_name = strtolower($name);
|
| 624: |
|
| 625: | if ($func_name === 'isset') {
|
| 626: | if (count($parameter) === 0) {
|
| 627: | $this->trigger_template_error('Illegal number of parameter in "isset()"');
|
| 628: | }
|
| 629: |
|
| 630: | $pa = array();
|
| 631: | foreach ($parameter as $p) {
|
| 632: | $pa[] = $this->syntaxMatchesVariable($p) ? 'isset(' . $p . ')' : '(' . $p . ' !== null )';
|
| 633: | }
|
| 634: | return '(' . implode(' && ', $pa) . ')';
|
| 635: |
|
| 636: | } elseif (in_array(
|
| 637: | $func_name,
|
| 638: | array(
|
| 639: | 'empty',
|
| 640: | 'reset',
|
| 641: | 'current',
|
| 642: | 'end',
|
| 643: | 'prev',
|
| 644: | 'next'
|
| 645: | )
|
| 646: | )
|
| 647: | ) {
|
| 648: | if (count($parameter) !== 1) {
|
| 649: | $this->trigger_template_error("Illegal number of parameter in '{$func_name()}'");
|
| 650: | }
|
| 651: | if ($func_name === 'empty') {
|
| 652: | if (!$this->syntaxMatchesVariable($parameter[0]) && version_compare(PHP_VERSION, '5.5.0', '<')) {
|
| 653: | return '(' . $parameter[ 0 ] . ' === false )';
|
| 654: | } else {
|
| 655: | return $func_name . '(' .
|
| 656: | str_replace("')->value", "',null,true,false)->value", $parameter[ 0 ]) . ')';
|
| 657: | }
|
| 658: | } else {
|
| 659: | return $func_name . '(' . $parameter[ 0 ] . ')';
|
| 660: | }
|
| 661: | } else {
|
| 662: | return $name . '(' . implode(',', $parameter) . ')';
|
| 663: | }
|
| 664: | } else {
|
| 665: | $this->trigger_template_error("unknown function '{$name}'");
|
| 666: | }
|
| 667: | }
|
| 668: | }
|
| 669: |
|
| 670: | |
| 671: | |
| 672: | |
| 673: | |
| 674: | |
| 675: | |
| 676: |
|
| 677: | private function syntaxMatchesVariable($string) {
|
| 678: | static $regex_pattern = '/^\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*((->)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\[.*]*\])*$/';
|
| 679: | return 1 === preg_match($regex_pattern, trim($string));
|
| 680: | }
|
| 681: |
|
| 682: | |
| 683: | |
| 684: | |
| 685: | |
| 686: | |
| 687: | |
| 688: | |
| 689: |
|
| 690: | public function processText($text)
|
| 691: | {
|
| 692: |
|
| 693: | if (strpos($text, '<') === false) {
|
| 694: | return preg_replace($this->stripRegEx, '', $text);
|
| 695: | }
|
| 696: |
|
| 697: | $store = array();
|
| 698: | $_store = 0;
|
| 699: |
|
| 700: |
|
| 701: | $_offset = 0;
|
| 702: | if (preg_match_all(
|
| 703: | '#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
|
| 704: | $text,
|
| 705: | $matches,
|
| 706: | PREG_OFFSET_CAPTURE | PREG_SET_ORDER
|
| 707: | )
|
| 708: | ) {
|
| 709: | foreach ($matches as $match) {
|
| 710: | $store[] = $match[ 0 ][ 0 ];
|
| 711: | $_length = strlen($match[ 0 ][ 0 ]);
|
| 712: | $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
|
| 713: | $text = substr_replace($text, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
|
| 714: | $_offset += $_length - strlen($replace);
|
| 715: | $_store++;
|
| 716: | }
|
| 717: | }
|
| 718: | $expressions = array(
|
| 719: | '#(:SMARTY@!@|>)[\040\011]+(?=@!@SMARTY:|<)#s' => '\1 \2',
|
| 720: |
|
| 721: | '#(:SMARTY@!@|>)[\040\011]*[\n]\s*(?=@!@SMARTY:|<)#s' => '\1\2',
|
| 722: |
|
| 723: | '#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
|
| 724: | '#>[\040\011]+$#Ss' => '> ',
|
| 725: | '#>[\040\011]*[\n]\s*$#Ss' => '>',
|
| 726: | $this->stripRegEx => '',
|
| 727: | );
|
| 728: | $text = preg_replace(array_keys($expressions), array_values($expressions), $text);
|
| 729: | $_offset = 0;
|
| 730: | if (preg_match_all(
|
| 731: | '#@!@SMARTY:([0-9]+):SMARTY@!@#is',
|
| 732: | $text,
|
| 733: | $matches,
|
| 734: | PREG_OFFSET_CAPTURE | PREG_SET_ORDER
|
| 735: | )
|
| 736: | ) {
|
| 737: | foreach ($matches as $match) {
|
| 738: | $_length = strlen($match[ 0 ][ 0 ]);
|
| 739: | $replace = $store[ $match[ 1 ][ 0 ] ];
|
| 740: | $text = substr_replace($text, $replace, $match[ 0 ][ 1 ] + $_offset, $_length);
|
| 741: | $_offset += strlen($replace) - $_length;
|
| 742: | $_store++;
|
| 743: | }
|
| 744: | }
|
| 745: | return $text;
|
| 746: | }
|
| 747: |
|
| 748: | |
| 749: | |
| 750: | |
| 751: | |
| 752: | |
| 753: | |
| 754: | |
| 755: | |
| 756: | |
| 757: | |
| 758: | |
| 759: | |
| 760: | |
| 761: | |
| 762: |
|
| 763: | public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null)
|
| 764: | {
|
| 765: |
|
| 766: | $tagCompiler = $this->getTagCompiler($tag);
|
| 767: |
|
| 768: | return $tagCompiler === false ? false : $tagCompiler->compile($args, $this, $param1, $param2, $param3);
|
| 769: | }
|
| 770: |
|
| 771: | |
| 772: | |
| 773: | |
| 774: | |
| 775: | |
| 776: | |
| 777: | |
| 778: | |
| 779: | |
| 780: |
|
| 781: | public function getTagCompiler($tag)
|
| 782: | {
|
| 783: |
|
| 784: | if (!isset(self::$_tag_objects[ $tag ])) {
|
| 785: |
|
| 786: | $_tag = explode('_', $tag);
|
| 787: | $_tag = array_map('ucfirst', $_tag);
|
| 788: | $class_name = 'Smarty_Internal_Compile_' . implode('_', $_tag);
|
| 789: | if (class_exists($class_name)
|
| 790: | && (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))
|
| 791: | ) {
|
| 792: | self::$_tag_objects[ $tag ] = new $class_name;
|
| 793: | } else {
|
| 794: | self::$_tag_objects[ $tag ] = false;
|
| 795: | }
|
| 796: | }
|
| 797: | return self::$_tag_objects[ $tag ];
|
| 798: | }
|
| 799: |
|
| 800: | |
| 801: | |
| 802: | |
| 803: | |
| 804: | |
| 805: | |
| 806: | |
| 807: | |
| 808: |
|
| 809: | public function getPlugin($plugin_name, $plugin_type)
|
| 810: | {
|
| 811: | $function = null;
|
| 812: | if ($this->caching && ($this->nocache || $this->tag_nocache)) {
|
| 813: | if (isset($this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ])) {
|
| 814: | $function =
|
| 815: | $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ];
|
| 816: | } elseif (isset($this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ])) {
|
| 817: | $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ] =
|
| 818: | $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ];
|
| 819: | $function =
|
| 820: | $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ];
|
| 821: | }
|
| 822: | } else {
|
| 823: | if (isset($this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ])) {
|
| 824: | $function =
|
| 825: | $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ];
|
| 826: | } elseif (isset($this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ])) {
|
| 827: | $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ] =
|
| 828: | $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ];
|
| 829: | $function =
|
| 830: | $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ];
|
| 831: | }
|
| 832: | }
|
| 833: | if (isset($function)) {
|
| 834: | if ($plugin_type === 'modifier') {
|
| 835: | $this->modifier_plugins[ $plugin_name ] = true;
|
| 836: | }
|
| 837: | return $function;
|
| 838: | }
|
| 839: |
|
| 840: | $function = 'smarty_' . $plugin_type . '_' . $plugin_name;
|
| 841: | $file = $this->smarty->loadPlugin($function, false);
|
| 842: | if (is_string($file)) {
|
| 843: | if ($this->caching && ($this->nocache || $this->tag_nocache)) {
|
| 844: | $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'file' ] =
|
| 845: | $file;
|
| 846: | $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ] =
|
| 847: | $function;
|
| 848: | } else {
|
| 849: | $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'file' ] =
|
| 850: | $file;
|
| 851: | $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ] =
|
| 852: | $function;
|
| 853: | }
|
| 854: | if ($plugin_type === 'modifier') {
|
| 855: | $this->modifier_plugins[ $plugin_name ] = true;
|
| 856: | }
|
| 857: | return $function;
|
| 858: | }
|
| 859: | if (is_callable($function)) {
|
| 860: |
|
| 861: | return $function;
|
| 862: | }
|
| 863: | return false;
|
| 864: | }
|
| 865: |
|
| 866: | |
| 867: | |
| 868: | |
| 869: | |
| 870: | |
| 871: | |
| 872: | |
| 873: | |
| 874: |
|
| 875: | public function getPluginFromDefaultHandler($tag, $plugin_type)
|
| 876: | {
|
| 877: | $callback = null;
|
| 878: | $script = null;
|
| 879: | $cacheable = true;
|
| 880: | $result = call_user_func_array(
|
| 881: | $this->smarty->default_plugin_handler_func,
|
| 882: | array(
|
| 883: | $tag,
|
| 884: | $plugin_type,
|
| 885: | $this->template,
|
| 886: | &$callback,
|
| 887: | &$script,
|
| 888: | &$cacheable,
|
| 889: | )
|
| 890: | );
|
| 891: | if ($result) {
|
| 892: | $this->tag_nocache = $this->tag_nocache || !$cacheable;
|
| 893: | if ($script !== null) {
|
| 894: | if (is_file($script)) {
|
| 895: | if ($this->caching && ($this->nocache || $this->tag_nocache)) {
|
| 896: | $this->required_plugins[ 'nocache' ][ $tag ][ $plugin_type ][ 'file' ] =
|
| 897: | $script;
|
| 898: | $this->required_plugins[ 'nocache' ][ $tag ][ $plugin_type ][ 'function' ] =
|
| 899: | $callback;
|
| 900: | } else {
|
| 901: | $this->required_plugins[ 'compiled' ][ $tag ][ $plugin_type ][ 'file' ] =
|
| 902: | $script;
|
| 903: | $this->required_plugins[ 'compiled' ][ $tag ][ $plugin_type ][ 'function' ] =
|
| 904: | $callback;
|
| 905: | }
|
| 906: | include_once $script;
|
| 907: | } else {
|
| 908: | $this->trigger_template_error("Default plugin handler: Returned script file '{$script}' for '{$tag}' not found");
|
| 909: | }
|
| 910: | }
|
| 911: | if (is_callable($callback)) {
|
| 912: | $this->default_handler_plugins[ $plugin_type ][ $tag ] = array(
|
| 913: | $callback,
|
| 914: | true,
|
| 915: | array()
|
| 916: | );
|
| 917: | return true;
|
| 918: | } else {
|
| 919: | $this->trigger_template_error("Default plugin handler: Returned callback for '{$tag}' not callable");
|
| 920: | }
|
| 921: | }
|
| 922: | return false;
|
| 923: | }
|
| 924: |
|
| 925: | |
| 926: | |
| 927: | |
| 928: | |
| 929: | |
| 930: | |
| 931: | |
| 932: |
|
| 933: | public function appendCode($left, $right)
|
| 934: | {
|
| 935: | if (preg_match('/\s*\?>\s?$/D', $left) && preg_match('/^<\?php\s+/', $right)) {
|
| 936: | $left = preg_replace('/\s*\?>\s?$/D', "\n", $left);
|
| 937: | $left .= preg_replace('/^<\?php\s+/', '', $right);
|
| 938: | } else {
|
| 939: | $left .= $right;
|
| 940: | }
|
| 941: | return $left;
|
| 942: | }
|
| 943: |
|
| 944: | |
| 945: | |
| 946: | |
| 947: | |
| 948: | |
| 949: | |
| 950: | |
| 951: | |
| 952: | |
| 953: | |
| 954: |
|
| 955: | public function processNocacheCode($content, $is_code)
|
| 956: | {
|
| 957: |
|
| 958: | if ($is_code && !empty($content)) {
|
| 959: |
|
| 960: | if ((!($this->template->source->handler->recompiled) || $this->forceNocache) && $this->caching
|
| 961: | && !$this->suppressNocacheProcessing && ($this->nocache || $this->tag_nocache)
|
| 962: | ) {
|
| 963: | $this->template->compiled->has_nocache_code = true;
|
| 964: | $_output = addcslashes($content, '\'\\');
|
| 965: | $_output = str_replace('^#^', '\'', $_output);
|
| 966: | $_output =
|
| 967: | "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/{$_output}/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
|
| 968: |
|
| 969: | foreach ($this->modifier_plugins as $plugin_name => $dummy) {
|
| 970: | if (isset($this->required_plugins[ 'compiled' ][ $plugin_name ][ 'modifier' ])) {
|
| 971: | $this->required_plugins[ 'nocache' ][ $plugin_name ][ 'modifier' ] =
|
| 972: | $this->required_plugins[ 'compiled' ][ $plugin_name ][ 'modifier' ];
|
| 973: | }
|
| 974: | }
|
| 975: | } else {
|
| 976: | $_output = $content;
|
| 977: | }
|
| 978: | } else {
|
| 979: | $_output = $content;
|
| 980: | }
|
| 981: | $this->modifier_plugins = array();
|
| 982: | $this->suppressNocacheProcessing = false;
|
| 983: | $this->tag_nocache = false;
|
| 984: | return $_output;
|
| 985: | }
|
| 986: |
|
| 987: | |
| 988: | |
| 989: | |
| 990: | |
| 991: | |
| 992: | |
| 993: |
|
| 994: | public function getId($input)
|
| 995: | {
|
| 996: | if (preg_match('~^([\'"]*)([0-9]*[a-zA-Z_]\w*)\1$~', $input, $match)) {
|
| 997: | return $match[ 2 ];
|
| 998: | }
|
| 999: | return false;
|
| 1000: | }
|
| 1001: |
|
| 1002: | |
| 1003: | |
| 1004: | |
| 1005: | |
| 1006: | |
| 1007: | |
| 1008: |
|
| 1009: | public function getVariableName($input)
|
| 1010: | {
|
| 1011: | if (preg_match('~^[$]_smarty_tpl->tpl_vars\[[\'"]*([0-9]*[a-zA-Z_]\w*)[\'"]*\]->value$~', $input, $match)) {
|
| 1012: | return $match[ 1 ];
|
| 1013: | }
|
| 1014: | return false;
|
| 1015: | }
|
| 1016: |
|
| 1017: | |
| 1018: | |
| 1019: | |
| 1020: | |
| 1021: |
|
| 1022: | public function setNocacheInVariable($varName)
|
| 1023: | {
|
| 1024: |
|
| 1025: | if ($_var = $this->getId($varName)) {
|
| 1026: | if (isset($this->template->tpl_vars[ $_var ])) {
|
| 1027: | $this->template->tpl_vars[ $_var ] = clone $this->template->tpl_vars[ $_var ];
|
| 1028: | $this->template->tpl_vars[ $_var ]->nocache = true;
|
| 1029: | } else {
|
| 1030: | $this->template->tpl_vars[ $_var ] = new Smarty_Variable(null, true);
|
| 1031: | }
|
| 1032: | }
|
| 1033: | }
|
| 1034: |
|
| 1035: | |
| 1036: | |
| 1037: | |
| 1038: | |
| 1039: | |
| 1040: | |
| 1041: |
|
| 1042: | public function convertScope($_attr, $validScopes)
|
| 1043: | {
|
| 1044: | $_scope = 0;
|
| 1045: | if (isset($_attr[ 'scope' ])) {
|
| 1046: | $_scopeName = trim($_attr[ 'scope' ], '\'"');
|
| 1047: | if (is_numeric($_scopeName) && in_array($_scopeName, $validScopes)) {
|
| 1048: | $_scope = $_scopeName;
|
| 1049: | } elseif (is_string($_scopeName)) {
|
| 1050: | $_scopeName = trim($_scopeName, '\'"');
|
| 1051: | $_scope = isset($validScopes[ $_scopeName ]) ? $validScopes[ $_scopeName ] : false;
|
| 1052: | } else {
|
| 1053: | $_scope = false;
|
| 1054: | }
|
| 1055: | if ($_scope === false) {
|
| 1056: | $err = var_export($_scopeName, true);
|
| 1057: | $this->trigger_template_error("illegal value '{$err}' for \"scope\" attribute", null, true);
|
| 1058: | }
|
| 1059: | }
|
| 1060: | return $_scope;
|
| 1061: | }
|
| 1062: |
|
| 1063: | |
| 1064: | |
| 1065: | |
| 1066: | |
| 1067: | |
| 1068: | |
| 1069: |
|
| 1070: | public function makeNocacheCode($code)
|
| 1071: | {
|
| 1072: | return "echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/<?php " .
|
| 1073: | str_replace('^#^', '\'', addcslashes($code, '\'\\')) .
|
| 1074: | "?>/*/%%SmartyNocache:{$this->nocache_hash}%%*/';\n";
|
| 1075: | }
|
| 1076: |
|
| 1077: | |
| 1078: | |
| 1079: | |
| 1080: | |
| 1081: | |
| 1082: | |
| 1083: | |
| 1084: | |
| 1085: | |
| 1086: | |
| 1087: | |
| 1088: |
|
| 1089: | public function trigger_template_error($args = null, $line = null, $tagline = null)
|
| 1090: | {
|
| 1091: | $lex = $this->parser->lex;
|
| 1092: | if ($tagline === true) {
|
| 1093: |
|
| 1094: | $line = $lex->taglineno;
|
| 1095: | } elseif (!isset($line)) {
|
| 1096: |
|
| 1097: | $line = $lex->line;
|
| 1098: | } else {
|
| 1099: | $line = (int)$line;
|
| 1100: | }
|
| 1101: | if (in_array(
|
| 1102: | $this->template->source->type,
|
| 1103: | array(
|
| 1104: | 'eval',
|
| 1105: | 'string'
|
| 1106: | )
|
| 1107: | )
|
| 1108: | ) {
|
| 1109: | $templateName = $this->template->source->type . ':' . trim(
|
| 1110: | preg_replace(
|
| 1111: | '![\t\r\n]+!',
|
| 1112: | ' ',
|
| 1113: | strlen($lex->data) > 40 ?
|
| 1114: | substr($lex->data, 0, 40) .
|
| 1115: | '...' : $lex->data
|
| 1116: | )
|
| 1117: | );
|
| 1118: | } else {
|
| 1119: | $templateName = $this->template->source->type . ':' . $this->template->source->filepath;
|
| 1120: | }
|
| 1121: |
|
| 1122: | $match = preg_split("/\n/", $lex->data);
|
| 1123: | $error_text =
|
| 1124: | 'Syntax error in template "' . (empty($this->trace_filepath) ? $templateName : $this->trace_filepath) .
|
| 1125: | '" on line ' . ($line + $this->trace_line_offset) . ' "' .
|
| 1126: | trim(preg_replace('![\t\r\n]+!', ' ', $match[ $line - 1 ])) . '" ';
|
| 1127: | if (isset($args)) {
|
| 1128: |
|
| 1129: | $error_text .= $args;
|
| 1130: | } else {
|
| 1131: | $expect = array();
|
| 1132: |
|
| 1133: | $error_text .= ' - Unexpected "' . $lex->value . '"';
|
| 1134: | if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4) {
|
| 1135: | foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
|
| 1136: | $exp_token = $this->parser->yyTokenName[ $token ];
|
| 1137: | if (isset($lex->smarty_token_names[ $exp_token ])) {
|
| 1138: |
|
| 1139: | $expect[] = '"' . $lex->smarty_token_names[ $exp_token ] . '"';
|
| 1140: | } else {
|
| 1141: |
|
| 1142: | $expect[] = $this->parser->yyTokenName[ $token ];
|
| 1143: | }
|
| 1144: | }
|
| 1145: | $error_text .= ', expected one of: ' . implode(' , ', $expect);
|
| 1146: | }
|
| 1147: | }
|
| 1148: | if ($this->smarty->_parserdebug) {
|
| 1149: | $this->parser->errorRunDown();
|
| 1150: | echo ob_get_clean();
|
| 1151: | flush();
|
| 1152: | }
|
| 1153: | $e = new SmartyCompilerException($error_text);
|
| 1154: | $e->line = $line;
|
| 1155: | $e->source = trim(preg_replace('![\t\r\n]+!', ' ', $match[ $line - 1 ]));
|
| 1156: | $e->desc = $args;
|
| 1157: | $e->template = $this->template->source->filepath;
|
| 1158: | throw $e;
|
| 1159: | }
|
| 1160: |
|
| 1161: | |
| 1162: | |
| 1163: | |
| 1164: | |
| 1165: | |
| 1166: | |
| 1167: |
|
| 1168: | public function getVarExport($value)
|
| 1169: | {
|
| 1170: | return preg_replace('/\s/', '', var_export($value, true));
|
| 1171: | }
|
| 1172: |
|
| 1173: | |
| 1174: | |
| 1175: | |
| 1176: |
|
| 1177: | public function enterDoubleQuote()
|
| 1178: | {
|
| 1179: | array_push($this->_tag_stack_count, $this->getTagStackCount());
|
| 1180: | }
|
| 1181: |
|
| 1182: | |
| 1183: | |
| 1184: | |
| 1185: | |
| 1186: |
|
| 1187: | public function getTagStackCount()
|
| 1188: | {
|
| 1189: | return count($this->_tag_stack);
|
| 1190: | }
|
| 1191: |
|
| 1192: | |
| 1193: | |
| 1194: | |
| 1195: | |
| 1196: |
|
| 1197: | public function replaceDelimiter($lexerPreg)
|
| 1198: | {
|
| 1199: | return str_replace(
|
| 1200: | array('SMARTYldel', 'SMARTYliteral', 'SMARTYrdel', 'SMARTYautoliteral', 'SMARTYal'),
|
| 1201: | array(
|
| 1202: | $this->ldelPreg, $this->literalPreg, $this->rdelPreg,
|
| 1203: | $this->smarty->getAutoLiteral() ? '{1,}' : '{9}',
|
| 1204: | $this->smarty->getAutoLiteral() ? '' : '\\s*'
|
| 1205: | ),
|
| 1206: | $lexerPreg
|
| 1207: | );
|
| 1208: | }
|
| 1209: |
|
| 1210: | |
| 1211: | |
| 1212: |
|
| 1213: | public function initDelimiterPreg()
|
| 1214: | {
|
| 1215: | $ldel = $this->smarty->getLeftDelimiter();
|
| 1216: | $this->ldelLength = strlen($ldel);
|
| 1217: | $this->ldelPreg = '';
|
| 1218: | foreach (str_split($ldel, 1) as $chr) {
|
| 1219: | $this->ldelPreg .= '[' . preg_quote($chr,'/') . ']';
|
| 1220: | }
|
| 1221: | $rdel = $this->smarty->getRightDelimiter();
|
| 1222: | $this->rdelLength = strlen($rdel);
|
| 1223: | $this->rdelPreg = '';
|
| 1224: | foreach (str_split($rdel, 1) as $chr) {
|
| 1225: | $this->rdelPreg .= '[' . preg_quote($chr,'/') . ']';
|
| 1226: | }
|
| 1227: | $literals = $this->smarty->getLiterals();
|
| 1228: | if (!empty($literals)) {
|
| 1229: | foreach ($literals as $key => $literal) {
|
| 1230: | $literalPreg = '';
|
| 1231: | foreach (str_split($literal, 1) as $chr) {
|
| 1232: | $literalPreg .= '[' . preg_quote($chr,'/') . ']';
|
| 1233: | }
|
| 1234: | $literals[ $key ] = $literalPreg;
|
| 1235: | }
|
| 1236: | $this->literalPreg = '|' . implode('|', $literals);
|
| 1237: | } else {
|
| 1238: | $this->literalPreg = '';
|
| 1239: | }
|
| 1240: | }
|
| 1241: |
|
| 1242: | |
| 1243: | |
| 1244: | |
| 1245: | |
| 1246: | |
| 1247: |
|
| 1248: | public function leaveDoubleQuote()
|
| 1249: | {
|
| 1250: | if (array_pop($this->_tag_stack_count) !== $this->getTagStackCount()) {
|
| 1251: | $tag = $this->getOpenBlockTag();
|
| 1252: | $this->trigger_template_error(
|
| 1253: | "unclosed '{{$tag}}' in doubled quoted string",
|
| 1254: | null,
|
| 1255: | true
|
| 1256: | );
|
| 1257: | }
|
| 1258: | }
|
| 1259: |
|
| 1260: | |
| 1261: | |
| 1262: | |
| 1263: | |
| 1264: |
|
| 1265: | public function getLdelPreg()
|
| 1266: | {
|
| 1267: | return $this->ldelPreg;
|
| 1268: | }
|
| 1269: |
|
| 1270: | |
| 1271: | |
| 1272: | |
| 1273: | |
| 1274: |
|
| 1275: | public function getRdelPreg()
|
| 1276: | {
|
| 1277: | return $this->rdelPreg;
|
| 1278: | }
|
| 1279: |
|
| 1280: | |
| 1281: | |
| 1282: | |
| 1283: | |
| 1284: |
|
| 1285: | public function getLdelLength()
|
| 1286: | {
|
| 1287: | return $this->ldelLength;
|
| 1288: | }
|
| 1289: |
|
| 1290: | |
| 1291: | |
| 1292: | |
| 1293: | |
| 1294: |
|
| 1295: | public function getRdelLength()
|
| 1296: | {
|
| 1297: | return $this->rdelLength;
|
| 1298: | }
|
| 1299: |
|
| 1300: | |
| 1301: | |
| 1302: | |
| 1303: | |
| 1304: |
|
| 1305: | public function getOpenBlockTag()
|
| 1306: | {
|
| 1307: | $tagCount = $this->getTagStackCount();
|
| 1308: | if ($tagCount) {
|
| 1309: | return $this->_tag_stack[ $tagCount - 1 ][ 0 ];
|
| 1310: | } else {
|
| 1311: | return false;
|
| 1312: | }
|
| 1313: | }
|
| 1314: |
|
| 1315: | |
| 1316: | |
| 1317: | |
| 1318: | |
| 1319: | |
| 1320: | |
| 1321: |
|
| 1322: | public function isVariable($value)
|
| 1323: | {
|
| 1324: | if (is_string($value)) {
|
| 1325: | return preg_match('/[$(]/', $value);
|
| 1326: | }
|
| 1327: | if (is_bool($value) || is_numeric($value)) {
|
| 1328: | return false;
|
| 1329: | }
|
| 1330: | if (is_array($value)) {
|
| 1331: | foreach ($value as $k => $v) {
|
| 1332: | if ($this->isVariable($k) || $this->isVariable($v)) {
|
| 1333: | return true;
|
| 1334: | }
|
| 1335: | }
|
| 1336: | return false;
|
| 1337: | }
|
| 1338: | return false;
|
| 1339: | }
|
| 1340: |
|
| 1341: | |
| 1342: | |
| 1343: | |
| 1344: | |
| 1345: |
|
| 1346: | public function getNewPrefixVariable()
|
| 1347: | {
|
| 1348: | ++self::$prefixVariableNumber;
|
| 1349: | return $this->getPrefixVariable();
|
| 1350: | }
|
| 1351: |
|
| 1352: | |
| 1353: | |
| 1354: | |
| 1355: | |
| 1356: |
|
| 1357: | public function getPrefixVariable()
|
| 1358: | {
|
| 1359: | return '$_prefixVariable' . self::$prefixVariableNumber;
|
| 1360: | }
|
| 1361: |
|
| 1362: | |
| 1363: | |
| 1364: | |
| 1365: | |
| 1366: |
|
| 1367: | public function appendPrefixCode($code)
|
| 1368: | {
|
| 1369: | $this->prefix_code[] = $code;
|
| 1370: | }
|
| 1371: |
|
| 1372: | |
| 1373: | |
| 1374: | |
| 1375: | |
| 1376: |
|
| 1377: | public function getPrefixCode()
|
| 1378: | {
|
| 1379: | $code = '';
|
| 1380: | $prefixArray = array_merge($this->prefix_code, array_pop($this->prefixCodeStack));
|
| 1381: | $this->prefixCodeStack[] = array();
|
| 1382: | foreach ($prefixArray as $c) {
|
| 1383: | $code = $this->appendCode($code, $c);
|
| 1384: | }
|
| 1385: | $this->prefix_code = array();
|
| 1386: | return $code;
|
| 1387: | }
|
| 1388: |
|
| 1389: | |
| 1390: | |
| 1391: | |
| 1392: | |
| 1393: |
|
| 1394: | public function saveRequiredPlugins($init = false)
|
| 1395: | {
|
| 1396: | $this->required_plugins_stack[] = $this->required_plugins;
|
| 1397: | if ($init) {
|
| 1398: | $this->required_plugins = array('compiled' => array(), 'nocache' => array());
|
| 1399: | }
|
| 1400: | }
|
| 1401: |
|
| 1402: | |
| 1403: | |
| 1404: |
|
| 1405: | public function restoreRequiredPlugins()
|
| 1406: | {
|
| 1407: | $this->required_plugins = array_pop($this->required_plugins_stack);
|
| 1408: | }
|
| 1409: |
|
| 1410: | |
| 1411: | |
| 1412: | |
| 1413: | |
| 1414: | |
| 1415: |
|
| 1416: | public function compileRequiredPlugins()
|
| 1417: | {
|
| 1418: | $code = $this->compileCheckPlugins($this->required_plugins[ 'compiled' ]);
|
| 1419: | if ($this->caching && !empty($this->required_plugins[ 'nocache' ])) {
|
| 1420: | $code .= $this->makeNocacheCode($this->compileCheckPlugins($this->required_plugins[ 'nocache' ]));
|
| 1421: | }
|
| 1422: | return $code;
|
| 1423: | }
|
| 1424: |
|
| 1425: | |
| 1426: | |
| 1427: | |
| 1428: | |
| 1429: | |
| 1430: | |
| 1431: | |
| 1432: |
|
| 1433: | public function compileCheckPlugins($requiredPlugins)
|
| 1434: | {
|
| 1435: | if (!empty($requiredPlugins)) {
|
| 1436: | $plugins = array();
|
| 1437: | foreach ($requiredPlugins as $plugin) {
|
| 1438: | foreach ($plugin as $data) {
|
| 1439: | $plugins[] = $data;
|
| 1440: | }
|
| 1441: | }
|
| 1442: | return '$_smarty_tpl->_checkPlugins(' . $this->getVarExport($plugins) . ');' . "\n";
|
| 1443: | } else {
|
| 1444: | return '';
|
| 1445: | }
|
| 1446: | }
|
| 1447: |
|
| 1448: | |
| 1449: | |
| 1450: | |
| 1451: | |
| 1452: | |
| 1453: | |
| 1454: | |
| 1455: |
|
| 1456: | abstract protected function doCompile($_content, $isTemplateSource = false);
|
| 1457: |
|
| 1458: | public function cStyleComment($string) {
|
| 1459: | return '/*' . str_replace('*/', '* /' , $string) . '*/';
|
| 1460: | }
|
| 1461: |
|
| 1462: | |
| 1463: | |
| 1464: | |
| 1465: | |
| 1466: | |
| 1467: | |
| 1468: | |
| 1469: | |
| 1470: | |
| 1471: | |
| 1472: |
|
| 1473: | private function compileTag2($tag, $args, $parameter)
|
| 1474: | {
|
| 1475: | $plugin_type = '';
|
| 1476: |
|
| 1477: |
|
| 1478: | $this->has_code = true;
|
| 1479: |
|
| 1480: | if (isset($this->smarty->_cache[ 'get_used_tags' ])) {
|
| 1481: | $this->template->_cache[ 'used_tags' ][] = array(
|
| 1482: | $tag,
|
| 1483: | $args
|
| 1484: | );
|
| 1485: | }
|
| 1486: |
|
| 1487: | foreach ($args as $arg) {
|
| 1488: | if (!is_array($arg)) {
|
| 1489: | if ($arg === "'nocache'" || $arg === 'nocache') {
|
| 1490: | $this->tag_nocache = true;
|
| 1491: | }
|
| 1492: | } else {
|
| 1493: | foreach ($arg as $k => $v) {
|
| 1494: | if (($k === "'nocache'" || $k === 'nocache') && (trim($v, "'\" ") === 'true')) {
|
| 1495: | $this->tag_nocache = true;
|
| 1496: | }
|
| 1497: | }
|
| 1498: | }
|
| 1499: | }
|
| 1500: |
|
| 1501: | if (($_output = $this->callTagCompiler($tag, $args, $parameter)) === false) {
|
| 1502: | if (isset($this->parent_compiler->tpl_function[ $tag ])
|
| 1503: | || (isset($this->template->smarty->ext->_tplFunction)
|
| 1504: | && $this->template->smarty->ext->_tplFunction->getTplFunction($this->template, $tag) !== false)
|
| 1505: | ) {
|
| 1506: |
|
| 1507: | $args[ '_attr' ][ 'name' ] = "'{$tag}'";
|
| 1508: | $_output = $this->callTagCompiler('call', $args, $parameter);
|
| 1509: | }
|
| 1510: | }
|
| 1511: | if ($_output !== false) {
|
| 1512: | if ($_output !== true) {
|
| 1513: |
|
| 1514: | if ($this->has_code) {
|
| 1515: |
|
| 1516: | return $_output;
|
| 1517: | }
|
| 1518: | }
|
| 1519: |
|
| 1520: | return null;
|
| 1521: | } else {
|
| 1522: |
|
| 1523: | if (isset($args[ '_attr' ])) {
|
| 1524: | foreach ($args[ '_attr' ] as $key => $attribute) {
|
| 1525: | if (is_array($attribute)) {
|
| 1526: | $args = array_merge($args, $attribute);
|
| 1527: | }
|
| 1528: | }
|
| 1529: | }
|
| 1530: |
|
| 1531: | if (strlen($tag) < 6 || substr($tag, -5) !== 'close') {
|
| 1532: |
|
| 1533: | if (isset($this->smarty->registered_objects[ $tag ]) && isset($parameter[ 'object_method' ])) {
|
| 1534: | $method = $parameter[ 'object_method' ];
|
| 1535: | if (!in_array($method, $this->smarty->registered_objects[ $tag ][ 3 ])
|
| 1536: | && (empty($this->smarty->registered_objects[ $tag ][ 1 ])
|
| 1537: | || in_array($method, $this->smarty->registered_objects[ $tag ][ 1 ]))
|
| 1538: | ) {
|
| 1539: | return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $method);
|
| 1540: | } elseif (in_array($method, $this->smarty->registered_objects[ $tag ][ 3 ])) {
|
| 1541: | return $this->callTagCompiler(
|
| 1542: | 'private_object_block_function',
|
| 1543: | $args,
|
| 1544: | $parameter,
|
| 1545: | $tag,
|
| 1546: | $method
|
| 1547: | );
|
| 1548: | } else {
|
| 1549: |
|
| 1550: | $this->trigger_template_error(
|
| 1551: | 'not allowed method "' . $method . '" in registered object "' .
|
| 1552: | $tag . '"',
|
| 1553: | null,
|
| 1554: | true
|
| 1555: | );
|
| 1556: | }
|
| 1557: | }
|
| 1558: |
|
| 1559: | foreach (array(
|
| 1560: | Smarty::PLUGIN_COMPILER,
|
| 1561: | Smarty::PLUGIN_FUNCTION,
|
| 1562: | Smarty::PLUGIN_BLOCK,
|
| 1563: | ) as $plugin_type) {
|
| 1564: | if (isset($this->smarty->registered_plugins[ $plugin_type ][ $tag ])) {
|
| 1565: |
|
| 1566: | if ($plugin_type === Smarty::PLUGIN_COMPILER) {
|
| 1567: | $new_args = array();
|
| 1568: | foreach ($args as $key => $mixed) {
|
| 1569: | if (is_array($mixed)) {
|
| 1570: | $new_args = array_merge($new_args, $mixed);
|
| 1571: | } else {
|
| 1572: | $new_args[ $key ] = $mixed;
|
| 1573: | }
|
| 1574: | }
|
| 1575: | if (!$this->smarty->registered_plugins[ $plugin_type ][ $tag ][ 1 ]) {
|
| 1576: | $this->tag_nocache = true;
|
| 1577: | }
|
| 1578: | return call_user_func_array(
|
| 1579: | $this->smarty->registered_plugins[ $plugin_type ][ $tag ][ 0 ],
|
| 1580: | array(
|
| 1581: | $new_args,
|
| 1582: | $this
|
| 1583: | )
|
| 1584: | );
|
| 1585: | }
|
| 1586: |
|
| 1587: | if ($plugin_type === Smarty::PLUGIN_FUNCTION || $plugin_type === Smarty::PLUGIN_BLOCK) {
|
| 1588: | return $this->callTagCompiler(
|
| 1589: | 'private_registered_' . $plugin_type,
|
| 1590: | $args,
|
| 1591: | $parameter,
|
| 1592: | $tag
|
| 1593: | );
|
| 1594: | }
|
| 1595: | }
|
| 1596: | }
|
| 1597: |
|
| 1598: | foreach ($this->plugin_search_order as $plugin_type) {
|
| 1599: | if ($plugin_type === Smarty::PLUGIN_COMPILER
|
| 1600: | && $this->smarty->loadPlugin('smarty_compiler_' . $tag)
|
| 1601: | && (!isset($this->smarty->security_policy)
|
| 1602: | || $this->smarty->security_policy->isTrustedTag($tag, $this))
|
| 1603: | ) {
|
| 1604: | $plugin = 'smarty_compiler_' . $tag;
|
| 1605: | if (is_callable($plugin)) {
|
| 1606: |
|
| 1607: | $new_args = array();
|
| 1608: | foreach ($args as $key => $mixed) {
|
| 1609: | if (is_array($mixed)) {
|
| 1610: | $new_args = array_merge($new_args, $mixed);
|
| 1611: | } else {
|
| 1612: | $new_args[ $key ] = $mixed;
|
| 1613: | }
|
| 1614: | }
|
| 1615: | return $plugin($new_args, $this->smarty);
|
| 1616: | }
|
| 1617: | if (class_exists($plugin, false)) {
|
| 1618: | $plugin_object = new $plugin;
|
| 1619: | if (method_exists($plugin_object, 'compile')) {
|
| 1620: | return $plugin_object->compile($args, $this);
|
| 1621: | }
|
| 1622: | }
|
| 1623: | throw new SmartyException("Plugin '{$tag}' not callable");
|
| 1624: | } else {
|
| 1625: | if ($function = $this->getPlugin($tag, $plugin_type)) {
|
| 1626: | if (!isset($this->smarty->security_policy)
|
| 1627: | || $this->smarty->security_policy->isTrustedTag($tag, $this)
|
| 1628: | ) {
|
| 1629: | return $this->callTagCompiler(
|
| 1630: | 'private_' . $plugin_type . '_plugin',
|
| 1631: | $args,
|
| 1632: | $parameter,
|
| 1633: | $tag,
|
| 1634: | $function
|
| 1635: | );
|
| 1636: | }
|
| 1637: | }
|
| 1638: | }
|
| 1639: | }
|
| 1640: | if (is_callable($this->smarty->default_plugin_handler_func)) {
|
| 1641: | $found = false;
|
| 1642: |
|
| 1643: | foreach ($this->plugin_search_order as $plugin_type) {
|
| 1644: | if (isset($this->default_handler_plugins[ $plugin_type ][ $tag ])) {
|
| 1645: | $found = true;
|
| 1646: | break;
|
| 1647: | }
|
| 1648: | }
|
| 1649: | if (!$found) {
|
| 1650: |
|
| 1651: | foreach ($this->plugin_search_order as $plugin_type) {
|
| 1652: | if ($this->getPluginFromDefaultHandler($tag, $plugin_type)) {
|
| 1653: | $found = true;
|
| 1654: | break;
|
| 1655: | }
|
| 1656: | }
|
| 1657: | }
|
| 1658: | if ($found) {
|
| 1659: |
|
| 1660: | if ($plugin_type === Smarty::PLUGIN_COMPILER) {
|
| 1661: | $new_args = array();
|
| 1662: | foreach ($args as $key => $mixed) {
|
| 1663: | if (is_array($mixed)) {
|
| 1664: | $new_args = array_merge($new_args, $mixed);
|
| 1665: | } else {
|
| 1666: | $new_args[ $key ] = $mixed;
|
| 1667: | }
|
| 1668: | }
|
| 1669: | return call_user_func_array(
|
| 1670: | $this->default_handler_plugins[ $plugin_type ][ $tag ][ 0 ],
|
| 1671: | array(
|
| 1672: | $new_args,
|
| 1673: | $this
|
| 1674: | )
|
| 1675: | );
|
| 1676: | } else {
|
| 1677: | return $this->callTagCompiler(
|
| 1678: | 'private_registered_' . $plugin_type,
|
| 1679: | $args,
|
| 1680: | $parameter,
|
| 1681: | $tag
|
| 1682: | );
|
| 1683: | }
|
| 1684: | }
|
| 1685: | }
|
| 1686: | } else {
|
| 1687: |
|
| 1688: | $base_tag = substr($tag, 0, -5);
|
| 1689: |
|
| 1690: | if (isset($this->smarty->registered_objects[ $base_tag ]) && isset($parameter[ 'object_method' ])) {
|
| 1691: | $method = $parameter[ 'object_method' ];
|
| 1692: | if (in_array($method, $this->smarty->registered_objects[ $base_tag ][ 3 ])) {
|
| 1693: | return $this->callTagCompiler(
|
| 1694: | 'private_object_block_function',
|
| 1695: | $args,
|
| 1696: | $parameter,
|
| 1697: | $tag,
|
| 1698: | $method
|
| 1699: | );
|
| 1700: | } else {
|
| 1701: |
|
| 1702: | $this->trigger_template_error(
|
| 1703: | 'not allowed closing tag method "' . $method .
|
| 1704: | '" in registered object "' . $base_tag . '"',
|
| 1705: | null,
|
| 1706: | true
|
| 1707: | );
|
| 1708: | }
|
| 1709: | }
|
| 1710: |
|
| 1711: | if (isset($this->smarty->registered_plugins[ Smarty::PLUGIN_BLOCK ][ $base_tag ])
|
| 1712: | || isset($this->default_handler_plugins[ Smarty::PLUGIN_BLOCK ][ $base_tag ])
|
| 1713: | ) {
|
| 1714: | return $this->callTagCompiler('private_registered_block', $args, $parameter, $tag);
|
| 1715: | }
|
| 1716: |
|
| 1717: | if (isset($this->smarty->registered_plugins[ Smarty::PLUGIN_FUNCTION ][ $tag ])) {
|
| 1718: | return $this->callTagCompiler('private_registered_function', $args, $parameter, $tag);
|
| 1719: | }
|
| 1720: |
|
| 1721: | if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) {
|
| 1722: | return $this->callTagCompiler('private_block_plugin', $args, $parameter, $tag, $function);
|
| 1723: | }
|
| 1724: |
|
| 1725: | if ($function = $this->getPlugin($tag, Smarty::PLUGIN_FUNCTION)) {
|
| 1726: | if (!isset($this->smarty->security_policy)
|
| 1727: | || $this->smarty->security_policy->isTrustedTag($tag, $this)
|
| 1728: | ) {
|
| 1729: | return $this->callTagCompiler('private_function_plugin', $args, $parameter, $tag, $function);
|
| 1730: | }
|
| 1731: | }
|
| 1732: |
|
| 1733: | if (isset($this->smarty->registered_plugins[ Smarty::PLUGIN_COMPILER ][ $tag ])) {
|
| 1734: |
|
| 1735: | $args = array();
|
| 1736: | if (!$this->smarty->registered_plugins[ Smarty::PLUGIN_COMPILER ][ $tag ][ 1 ]) {
|
| 1737: | $this->tag_nocache = true;
|
| 1738: | }
|
| 1739: | return call_user_func_array(
|
| 1740: | $this->smarty->registered_plugins[ Smarty::PLUGIN_COMPILER ][ $tag ][ 0 ],
|
| 1741: | array(
|
| 1742: | $args,
|
| 1743: | $this
|
| 1744: | )
|
| 1745: | );
|
| 1746: | }
|
| 1747: | if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) {
|
| 1748: | $plugin = 'smarty_compiler_' . $tag;
|
| 1749: | if (is_callable($plugin)) {
|
| 1750: | return $plugin($args, $this->smarty);
|
| 1751: | }
|
| 1752: | if (class_exists($plugin, false)) {
|
| 1753: | $plugin_object = new $plugin;
|
| 1754: | if (method_exists($plugin_object, 'compile')) {
|
| 1755: | return $plugin_object->compile($args, $this);
|
| 1756: | }
|
| 1757: | }
|
| 1758: | throw new SmartyException("Plugin '{$tag}' not callable");
|
| 1759: | }
|
| 1760: | }
|
| 1761: | $this->trigger_template_error("unknown tag '{$tag}'", null, true);
|
| 1762: | }
|
| 1763: | }
|
| 1764: | }
|
| 1765: | |