You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

smarty_internal_compile_break.php 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. /**
  3. * Smarty Internal Plugin Compile Break
  4. * Compiles the {break} tag
  5. *
  6. * @package Smarty
  7. * @subpackage Compiler
  8. * @author Uwe Tews
  9. */
  10. /**
  11. * Smarty Internal Plugin Compile Break Class
  12. *
  13. * @package Smarty
  14. * @subpackage Compiler
  15. */
  16. class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase
  17. {
  18. /**
  19. * Attribute definition: Overwrites base class.
  20. *
  21. * @var array
  22. * @see Smarty_Internal_CompileBase
  23. */
  24. public $optional_attributes = array('levels');
  25. /**
  26. * Attribute definition: Overwrites base class.
  27. *
  28. * @var array
  29. * @see Smarty_Internal_CompileBase
  30. */
  31. public $shorttag_order = array('levels');
  32. /**
  33. * Tag name may be overloaded by Smarty_Internal_Compile_Continue
  34. *
  35. * @var string
  36. */
  37. public $tag = 'break';
  38. /**
  39. * Compiles code for the {break} tag
  40. *
  41. * @param array $args array with attributes from parser
  42. * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
  43. *
  44. * @return string compiled code
  45. * @throws \SmartyCompilerException
  46. */
  47. public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
  48. {
  49. list($levels, $foreachLevels) = $this->checkLevels($args, $compiler);
  50. $output = "<?php ";
  51. if ($foreachLevels > 0 && $this->tag === 'continue') {
  52. $foreachLevels--;
  53. }
  54. if ($foreachLevels > 0) {
  55. /* @var Smarty_Internal_Compile_Foreach $foreachCompiler */
  56. $foreachCompiler = $compiler->getTagCompiler('foreach');
  57. $output .= $foreachCompiler->compileRestore($foreachLevels);
  58. }
  59. $output .= "{$this->tag} {$levels};?>";
  60. return $output;
  61. }
  62. /**
  63. * check attributes and return array of break and foreach levels
  64. *
  65. * @param array $args array with attributes from parser
  66. * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
  67. *
  68. * @return array
  69. * @throws \SmartyCompilerException
  70. */
  71. public function checkLevels($args, Smarty_Internal_TemplateCompilerBase $compiler)
  72. {
  73. static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
  74. // check and get attributes
  75. $_attr = $this->getAttributes($compiler, $args);
  76. if ($_attr[ 'nocache' ] === true) {
  77. $compiler->trigger_template_error('nocache option not allowed', null, true);
  78. }
  79. if (isset($_attr[ 'levels' ])) {
  80. if (!is_numeric($_attr[ 'levels' ])) {
  81. $compiler->trigger_template_error('level attribute must be a numeric constant', null, true);
  82. }
  83. $levels = $_attr[ 'levels' ];
  84. } else {
  85. $levels = 1;
  86. }
  87. $level_count = $levels;
  88. $stack_count = count($compiler->_tag_stack) - 1;
  89. $foreachLevels = 0;
  90. $lastTag = '';
  91. while ($level_count > 0 && $stack_count >= 0) {
  92. if (isset($_is_loopy[ $compiler->_tag_stack[ $stack_count ][ 0 ] ])) {
  93. $lastTag = $compiler->_tag_stack[ $stack_count ][ 0 ];
  94. if ($level_count === 0) {
  95. break;
  96. }
  97. $level_count --;
  98. if ($compiler->_tag_stack[ $stack_count ][ 0 ] === 'foreach') {
  99. $foreachLevels ++;
  100. }
  101. }
  102. $stack_count --;
  103. }
  104. if ($level_count !== 0) {
  105. $compiler->trigger_template_error("cannot {$this->tag} {$levels} level(s)", null, true);
  106. }
  107. if ($lastTag === 'foreach' && $this->tag === 'break' && $foreachLevels > 0) {
  108. $foreachLevels --;
  109. }
  110. return array($levels, $foreachLevels);
  111. }
  112. }