PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/core/Associates/Smarty/sysplugins/smarty_internal_compile_block.php

https://gitlab.com/fiesta-framework/Documentation
PHP | 444 lines | 330 code | 19 blank | 95 comment | 3 complexity | ebb355746a3eefb47fbabddd660dfb92 MD5 | raw file
  1. <?php
  2. /**
  3. * Smarty Internal Plugin Compile Block
  4. * Compiles the {block}{/block} tags
  5. *
  6. * @package Smarty
  7. * @subpackage Compiler
  8. * @author Uwe Tews
  9. */
  10. /**
  11. * Smarty Internal Plugin Compile Block Class
  12. *
  13. * @package Smarty
  14. * @subpackage Compiler
  15. */
  16. class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
  17. {
  18. const parent = '____SMARTY_BLOCK_PARENT____';
  19. /**
  20. * Attribute definition: Overwrites base class.
  21. *
  22. * @var array
  23. * @see Smarty_Internal_CompileBase
  24. */
  25. public $required_attributes = array('name');
  26. /**
  27. * Attribute definition: Overwrites base class.
  28. *
  29. * @var array
  30. * @see Smarty_Internal_CompileBase
  31. */
  32. public $shorttag_order = array('name');
  33. /**
  34. * Attribute definition: Overwrites base class.
  35. *
  36. * @var array
  37. * @see Smarty_Internal_CompileBase
  38. */
  39. public $option_flags = array('hide', 'append', 'prepend', 'nocache');
  40. /**
  41. * Attribute definition: Overwrites base class.
  42. *
  43. * @var array
  44. * @see Smarty_Internal_CompileBase
  45. */
  46. public $optional_attributes = array('internal_file', 'internal_uid', 'internal_line');
  47. /**
  48. * nested child block names
  49. *
  50. * @var array
  51. */
  52. public static $nested_block_names = array();
  53. /**
  54. * child block source buffer
  55. *
  56. * @var array
  57. */
  58. public static $block_data = array();
  59. /**
  60. * Compiles code for the {block} tag
  61. *
  62. * @param array $args array with attributes from parser
  63. * @param object $compiler compiler object
  64. *
  65. * @return boolean true
  66. */
  67. public function compile($args, $compiler)
  68. {
  69. // check and get attributes
  70. $_attr = $this->getAttributes($compiler, $args);
  71. $_name = trim($_attr['name'], "\"'");
  72. // existing child must override parent settings
  73. if (isset($compiler->template->block_data[$_name]) && $compiler->template->block_data[$_name]['mode'] == 'replace') {
  74. $_attr['append'] = false;
  75. $_attr['prepend'] = false;
  76. }
  77. // check if we process an inheritance child template
  78. if ($compiler->inheritance_child) {
  79. array_unshift(self::$nested_block_names, $_name);
  80. // build {block} for child block
  81. self::$block_data[$_name]['source'] =
  82. "{$compiler->smarty->left_delimiter}private_child_block name={$_attr['name']} file='{$compiler->template->source->filepath}' type='{$compiler->template->source->type}' resource='{$compiler->template->template_resource}'" .
  83. " uid='{$compiler->template->source->uid}' line={$compiler->lex->line}";
  84. if ($_attr['nocache']) {
  85. self::$block_data[$_name]['source'] .= ' nocache';
  86. }
  87. self::$block_data[$_name]['source'] .= $compiler->smarty->right_delimiter;
  88. $save = array($_attr, $compiler->inheritance);
  89. $this->openTag($compiler, 'block', $save);
  90. // set flag for {block} tag
  91. $compiler->inheritance = true;
  92. $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
  93. $compiler->has_code = false;
  94. return;
  95. }
  96. // must merge includes
  97. if ($_attr['nocache'] == true) {
  98. $compiler->tag_nocache = true;
  99. }
  100. $save = array($_attr, $compiler->inheritance, $compiler->parser->current_buffer, $compiler->nocache);
  101. $this->openTag($compiler, 'block', $save);
  102. $compiler->inheritance = true;
  103. $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
  104. $compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
  105. $compiler->has_code = false;
  106. return true;
  107. }
  108. /**
  109. * Compile saved child block source
  110. *
  111. * @param object $compiler compiler object
  112. * @param string $_name optional name of child block
  113. *
  114. * @return string compiled code of child block
  115. */
  116. static function compileChildBlock($compiler, $_name = null)
  117. {
  118. if ($compiler->inheritance_child) {
  119. $name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
  120. if (isset($compiler->template->block_data[$name1])) {
  121. // replace inner block name with generic
  122. Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= $compiler->template->block_data[$name1]['source'];
  123. Smarty_Internal_Compile_Block::$block_data[$name1]['child'] = true;
  124. }
  125. $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
  126. $compiler->has_code = false;
  127. return;
  128. }
  129. // if called by {$smarty.block.child} we must search the name of enclosing {block}
  130. if ($_name == null) {
  131. $stack_count = count($compiler->_tag_stack);
  132. while (--$stack_count >= 0) {
  133. if ($compiler->_tag_stack[$stack_count][0] == 'block') {
  134. $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
  135. break;
  136. }
  137. }
  138. }
  139. if ($_name == null) {
  140. $compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ', $compiler->lex->taglineno);
  141. }
  142. // undefined child?
  143. if (!isset($compiler->template->block_data[$_name]['source'])) {
  144. $compiler->popTrace();
  145. return '';
  146. }
  147. // flag that child is already compile by {$smarty.block.child} inclusion
  148. $compiler->template->block_data[$_name]['compiled'] = true;
  149. $_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
  150. $compiler->template->compile_id, $compiler->template->caching, $compiler->template->cache_lifetime);
  151. if ($compiler->smarty->debugging) {
  152. Smarty_Internal_Debug::ignore($_tpl);
  153. }
  154. $_tpl->tpl_vars = $compiler->template->tpl_vars;
  155. $_tpl->variable_filters = $compiler->template->variable_filters;
  156. $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
  157. $_tpl->allow_relative_path = true;
  158. $_tpl->compiler->inheritance = true;
  159. $_tpl->compiler->suppressHeader = true;
  160. $_tpl->compiler->suppressFilter = true;
  161. $_tpl->compiler->suppressTemplatePropertyHeader = true;
  162. $_tpl->compiler->suppressMergedTemplates = true;
  163. $nocache = $compiler->nocache || $compiler->tag_nocache;
  164. if (strpos($compiler->template->block_data[$_name]['source'], self::parent) !== false) {
  165. $_output = str_replace(self::parent, $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl, $nocache));
  166. } elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
  167. $_output = $_tpl->compiler->compileTemplate($_tpl, $nocache) . $compiler->parser->current_buffer->to_smarty_php();
  168. } elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
  169. $_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl, $nocache);
  170. } elseif (!empty($compiler->template->block_data[$_name])) {
  171. $_output = $_tpl->compiler->compileTemplate($_tpl, $nocache);
  172. }
  173. $compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
  174. $compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
  175. $compiler->merged_templates = array_merge($compiler->merged_templates, $_tpl->compiler->merged_templates);
  176. $compiler->template->variable_filters = $_tpl->variable_filters;
  177. if ($_tpl->has_nocache_code) {
  178. $compiler->template->has_nocache_code = true;
  179. }
  180. foreach ($_tpl->required_plugins as $key => $tmp1) {
  181. if ($compiler->nocache && $compiler->template->caching) {
  182. $code = 'nocache';
  183. } else {
  184. $code = $key;
  185. }
  186. foreach ($tmp1 as $name => $tmp) {
  187. foreach ($tmp as $type => $data) {
  188. $compiler->template->required_plugins[$code][$name][$type] = $data;
  189. }
  190. }
  191. }
  192. unset($_tpl);
  193. $compiler->has_code = true;
  194. return $_output;
  195. }
  196. /**
  197. * Compile $smarty.block.parent
  198. *
  199. * @param object $compiler compiler object
  200. * @param string $_name optional name of child block
  201. *
  202. * @return string compiled code of child block
  203. */
  204. static function compileParentBlock($compiler, $_name = null)
  205. {
  206. // if called by {$smarty.block.parent} we must search the name of enclosing {block}
  207. if ($_name == null) {
  208. $stack_count = count($compiler->_tag_stack);
  209. while (--$stack_count >= 0) {
  210. if ($compiler->_tag_stack[$stack_count][0] == 'block') {
  211. $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
  212. break;
  213. }
  214. }
  215. }
  216. if ($_name == null) {
  217. $compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ', $compiler->lex->taglineno);
  218. }
  219. if (empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
  220. $compiler->trigger_template_error(' illegal {$smarty.block.parent} in parent template ', $compiler->lex->taglineno);
  221. }
  222. Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= Smarty_Internal_Compile_Block::parent;
  223. $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
  224. $compiler->has_code = false;
  225. return;
  226. }
  227. /**
  228. * Process block source
  229. *
  230. * @param $compiler
  231. * @param string $source source text
  232. *
  233. */
  234. static function blockSource($compiler, $source)
  235. {
  236. Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= $source;
  237. }
  238. }
  239. /**
  240. * Smarty Internal Plugin Compile BlockClose Class
  241. *
  242. * @package Smarty
  243. * @subpackage Compiler
  244. */
  245. class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
  246. {
  247. /**
  248. * Compiles code for the {/block} tag
  249. *
  250. * @param array $args array with attributes from parser
  251. * @param object $compiler compiler object
  252. *
  253. * @return string compiled code
  254. */
  255. public function compile($args, $compiler)
  256. {
  257. $compiler->has_code = true;
  258. // check and get attributes
  259. $_attr = $this->getAttributes($compiler, $args);
  260. $saved_data = $this->closeTag($compiler, array('block'));
  261. $_name = trim($saved_data[0]['name'], "\"'");
  262. // reset flag for {block} tag
  263. $compiler->inheritance = $saved_data[1];
  264. // check if we process an inheritance child template
  265. if ($compiler->inheritance_child) {
  266. $name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
  267. Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= "{$compiler->smarty->left_delimiter}/private_child_block{$compiler->smarty->right_delimiter}";
  268. array_shift(Smarty_Internal_Compile_Block::$nested_block_names);
  269. if (!empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
  270. $name2 = Smarty_Internal_Compile_Block::$nested_block_names[0];
  271. if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
  272. if (isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child']) || !isset($compiler->template->block_data[$name1])) {
  273. Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
  274. } else {
  275. if ($compiler->template->block_data[$name1]['mode'] == 'append') {
  276. Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
  277. } elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
  278. Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'] . Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
  279. } else {
  280. Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'];
  281. }
  282. }
  283. }
  284. unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
  285. $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
  286. } else {
  287. if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
  288. if (isset($compiler->template->block_data[$name1]) && !isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child'])) {
  289. if (strpos($compiler->template->block_data[$name1]['source'], Smarty_Internal_Compile_Block::parent) !== false) {
  290. $compiler->template->block_data[$name1]['source'] =
  291. str_replace(Smarty_Internal_Compile_Block::parent, Smarty_Internal_Compile_Block::$block_data[$name1]['source'], $compiler->template->block_data[$name1]['source']);
  292. } elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
  293. $compiler->template->block_data[$name1]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
  294. } elseif ($compiler->template->block_data[$name1]['mode'] == 'append') {
  295. $compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
  296. }
  297. } else {
  298. $compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
  299. }
  300. $compiler->template->block_data[$name1]['mode'] = 'replace';
  301. if ($saved_data[0]['append']) {
  302. $compiler->template->block_data[$name1]['mode'] = 'append';
  303. }
  304. if ($saved_data[0]['prepend']) {
  305. $compiler->template->block_data[$name1]['mode'] = 'prepend';
  306. }
  307. }
  308. unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
  309. $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
  310. }
  311. $compiler->has_code = false;
  312. return;
  313. }
  314. if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
  315. $_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
  316. } else {
  317. if ($saved_data[0]['hide'] && !isset($compiler->template->block_data[$_name]['source'])) {
  318. $_output = '';
  319. } else {
  320. $_output = $compiler->parser->current_buffer->to_smarty_php();
  321. }
  322. }
  323. unset($compiler->template->block_data[$_name]['compiled']);
  324. // reset flags
  325. $compiler->parser->current_buffer = $saved_data[2];
  326. if ($compiler->nocache) {
  327. $compiler->tag_nocache = true;
  328. }
  329. $compiler->nocache = $saved_data[3];
  330. // $_output content has already nocache code processed
  331. $compiler->suppressNocacheProcessing = true;
  332. return $_output;
  333. }
  334. }
  335. /**
  336. * Smarty Internal Plugin Compile Child Block Class
  337. *
  338. * @package Smarty
  339. * @subpackage Compiler
  340. */
  341. class Smarty_Internal_Compile_Private_Child_Block extends Smarty_Internal_CompileBase
  342. {
  343. /**
  344. * Attribute definition: Overwrites base class.
  345. *
  346. * @var array
  347. * @see Smarty_Internal_CompileBase
  348. */
  349. public $required_attributes = array('name', 'file', 'uid', 'line', 'type', 'resource');
  350. /**
  351. * Compiles code for the {private_child_block} tag
  352. *
  353. * @param array $args array with attributes from parser
  354. * @param object $compiler compiler object
  355. *
  356. * @return boolean true
  357. */
  358. public function compile($args, $compiler)
  359. {
  360. // check and get attributes
  361. $_attr = $this->getAttributes($compiler, $args);
  362. // update template with original template resource of {block}
  363. if (trim($_attr['type'], "'") == 'file') {
  364. $compiler->template->template_resource = 'file:' . realpath(trim($_attr['file'], "'"));
  365. } else {
  366. $compiler->template->template_resource = trim($_attr['resource'], "'");
  367. }
  368. // source object
  369. unset ($compiler->template->source);
  370. $exists = $compiler->template->source->exists;
  371. // must merge includes
  372. if ($_attr['nocache'] == true) {
  373. $compiler->tag_nocache = true;
  374. }
  375. $save = array($_attr, $compiler->nocache);
  376. // set trace back to child block
  377. $compiler->pushTrace(trim($_attr['file'], "\"'"), trim($_attr['uid'], "\"'"), $_attr['line'] - $compiler->lex->line);
  378. $this->openTag($compiler, 'private_child_block', $save);
  379. $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
  380. $compiler->has_code = false;
  381. return true;
  382. }
  383. }
  384. /**
  385. * Smarty Internal Plugin Compile Child Block Close Class
  386. *
  387. * @package Smarty
  388. * @subpackage Compiler
  389. */
  390. class Smarty_Internal_Compile_Private_Child_Blockclose extends Smarty_Internal_CompileBase
  391. {
  392. /**
  393. * Compiles code for the {/private_child_block} tag
  394. *
  395. * @param array $args array with attributes from parser
  396. * @param object $compiler compiler object
  397. *
  398. * @return boolean true
  399. */
  400. public function compile($args, $compiler)
  401. {
  402. // check and get attributes
  403. $_attr = $this->getAttributes($compiler, $args);
  404. $saved_data = $this->closeTag($compiler, array('private_child_block'));
  405. // end of child block
  406. $compiler->popTrace();
  407. $compiler->nocache = $saved_data[1];
  408. $compiler->has_code = false;
  409. return true;
  410. }
  411. }