smarty_internal_compile_extends.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. /**
  3. * Smarty Internal Plugin Compile extend
  4. *
  5. * Compiles the {extends} tag
  6. *
  7. * @package Smarty
  8. * @subpackage Compiler
  9. * @author Uwe Tews
  10. */
  11. /**
  12. * Smarty Internal Plugin Compile extend Class
  13. */
  14. class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
  15. /**
  16. * Compiles code for the {extends} tag
  17. *
  18. * @param array $args array with attributes from parser
  19. * @param object $compiler compiler object
  20. * @return string compiled code
  21. */
  22. public function compile($args, $compiler)
  23. {
  24. $this->compiler = $compiler;
  25. $this->smarty = $compiler->smarty;
  26. $this->_rdl = preg_quote($this->smarty->right_delimiter);
  27. $this->_ldl = preg_quote($this->smarty->left_delimiter);
  28. $this->required_attributes = array('file');
  29. // check and get attributes
  30. $_attr = $this->_get_attributes($args);
  31. $_smarty_tpl = $compiler->template;
  32. // $include_file = '';
  33. eval('$include_file = ' . $_attr['file'] . ';');
  34. // create template object
  35. $_template = new $compiler->smarty->template_class($include_file, $this->smarty, $compiler->template);
  36. // save file dependency
  37. $template_sha1 = sha1($_template->getTemplateFilepath());
  38. if (isset($compiler->template->properties['file_dependency'][$template_sha1])) {
  39. $this->compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"",$compiler->lex->line-1);
  40. }
  41. $compiler->template->properties['file_dependency'][$template_sha1] = array($_template->getTemplateFilepath(), $_template->getTemplateTimestamp());
  42. $_content = $compiler->template->template_source;
  43. if (preg_match_all("!({$this->_ldl}block\s(.+?){$this->_rdl})!", $_content, $s) !=
  44. preg_match_all("!({$this->_ldl}/block(.*?){$this->_rdl})!", $_content, $c)) {
  45. $this->compiler->trigger_template_error('unmatched {block} {/block} pairs');
  46. }
  47. preg_match_all("!{$this->_ldl}block\s(.+?){$this->_rdl}|{$this->_ldl}/block(.*?){$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
  48. $_result_count = count($_result[0]);
  49. $_start = 0;
  50. while ($_start < $_result_count) {
  51. $_end = 0;
  52. $_level = 1;
  53. while ($_level != 0) {
  54. $_end++;
  55. if (!strpos($_result[0][$_start + $_end][0], '/')) {
  56. $_level++;
  57. } else {
  58. $_level--;
  59. }
  60. }
  61. $_block_content = str_replace($this->smarty->left_delimiter . '$smarty.block.parent' . $this->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%',
  62. substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])));
  63. $this->saveBlockData($_block_content, $_result[0][$_start][0], $compiler->template);
  64. $_start = $_start + $_end + 1;
  65. }
  66. $compiler->template->template_source = $_template->getTemplateSource();
  67. $compiler->template->template_filepath = $_template->getTemplateFilepath();
  68. $compiler->abort_and_recompile = true;
  69. return ' ';
  70. }
  71. protected function saveBlockData($block_content, $block_tag, $template)
  72. {
  73. if (0 == preg_match("!(.?)(name=)(.*?)(?=(\s|{$this->_rdl}))!", $block_tag, $_match)) {
  74. $this->compiler->trigger_template_error("\"" . $block_tag . "\" missing name attribute");
  75. } else {
  76. $_name = trim($_match[3], '\'"');
  77. // replace {$smarty.block.child}
  78. if (strpos($block_content, $this->smarty->left_delimiter . '$smarty.block.child' . $this->smarty->right_delimiter) !== false) {
  79. if (isset($this->smarty->block_data[$_name])) {
  80. $block_content = str_replace($this->smarty->left_delimiter . '$smarty.block.child' . $this->smarty->right_delimiter,
  81. $this->smarty->block_data[$_name]['source'], $block_content);
  82. unset($this->smarty->block_data[$_name]);
  83. } else {
  84. $block_content = str_replace($this->smarty->left_delimiter . '$smarty.block.child' . $this->smarty->right_delimiter,
  85. '', $block_content);
  86. }
  87. }
  88. if (isset($this->smarty->block_data[$_name])) {
  89. if (strpos($this->smarty->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
  90. $this->smarty->block_data[$_name]['source'] =
  91. str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $this->smarty->block_data[$_name]['source']);
  92. } elseif ($this->smarty->block_data[$_name]['mode'] == 'prepend') {
  93. $this->smarty->block_data[$_name]['source'] .= $block_content;
  94. } elseif ($this->smarty->block_data[$_name]['mode'] == 'append') {
  95. $this->smarty->block_data[$_name]['source'] = $block_content . $this->smarty->block_data[$_name]['source'];
  96. }
  97. } else {
  98. $this->smarty->block_data[$_name]['source'] = $block_content;
  99. }
  100. if (preg_match('/(.?)(append)(.*)/', $block_tag, $_match) != 0) {
  101. $this->smarty->block_data[$_name]['mode'] = 'append';
  102. } elseif (preg_match('/(.?)(prepend)(.*)/', $block_tag, $_match) != 0) {
  103. $this->smarty->block_data[$_name]['mode'] = 'prepend';
  104. } else {
  105. $this->smarty->block_data[$_name]['mode'] = 'replace';
  106. }
  107. $this->smarty->block_data[$_name]['file'] = $template->getTemplateFilepath();
  108. }
  109. }
  110. }
  111. ?>