1: <?php
  2:   3:   4:   5:   6:   7:   8:   9: 
 10: 
 11:  12:  13:  14:  15:  16: 
 17: class Smarty_Internal_Compile_Section extends Smarty_Internal_CompileBase
 18: {
 19:      20:  21:  22:  23:  24: 
 25:     public $required_attributes = array('name', 'loop');
 26:      27:  28:  29:  30:  31: 
 32:     public $shorttag_order = array('name', 'loop');
 33:      34:  35:  36:  37:  38: 
 39:     public $optional_attributes = array('start', 'step', 'max', 'show');
 40: 
 41:      42:  43:  44:  45:  46:  47:  48: 
 49:     public function compile($args, $compiler)
 50:     {
 51:         
 52:         $_attr = $this->getAttributes($compiler, $args);
 53: 
 54:         $this->openTag($compiler, 'section', array('section', $compiler->nocache));
 55:         
 56:         $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
 57: 
 58:         $output = "<?php ";
 59: 
 60:         $section_name = $_attr['name'];
 61: 
 62:         $output .= "if (isset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name])) unset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]);\n";
 63:         $section_props = "\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]";
 64: 
 65:         foreach ($_attr as $attr_name => $attr_value) {
 66:             switch ($attr_name) {
 67:                 case 'loop':
 68:                     $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int) \$_loop); unset(\$_loop);\n";
 69:                     break;
 70: 
 71:                 case 'show':
 72:                     if (is_bool($attr_value)) {
 73:                         $show_attr_value = $attr_value ? 'true' : 'false';
 74:                     } else {
 75:                         $show_attr_value = "(bool) $attr_value";
 76:                     }
 77:                     $output .= "{$section_props}['show'] = $show_attr_value;\n";
 78:                     break;
 79: 
 80:                 case 'name':
 81:                     $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
 82:                     break;
 83: 
 84:                 case 'max':
 85:                 case 'start':
 86:                     $output .= "{$section_props}['$attr_name'] = (int) $attr_value;\n";
 87:                     break;
 88: 
 89:                 case 'step':
 90:                     $output .= "{$section_props}['$attr_name'] = ((int) $attr_value) == 0 ? 1 : (int) $attr_value;\n";
 91:                     break;
 92:             }
 93:         }
 94: 
 95:         if (!isset($_attr['show'])) {
 96:             $output .= "{$section_props}['show'] = true;\n";
 97:         }
 98: 
 99:         if (!isset($_attr['loop'])) {
100:             $output .= "{$section_props}['loop'] = 1;\n";
101:         }
102: 
103:         if (!isset($_attr['max'])) {
104:             $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
105:         } else {
106:             $output .= "if ({$section_props}['max'] < 0)\n" . "    {$section_props}['max'] = {$section_props}['loop'];\n";
107:         }
108: 
109:         if (!isset($_attr['step'])) {
110:             $output .= "{$section_props}['step'] = 1;\n";
111:         }
112: 
113:         if (!isset($_attr['start'])) {
114:             $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
115:         } else {
116:             $output .= "if ({$section_props}['start'] < 0)\n" . "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . "else\n" . "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
117:         }
118: 
119:         $output .= "if ({$section_props}['show']) {\n";
120:         if (!isset($_attr['start']) && !isset($_attr['step']) && !isset($_attr['max'])) {
121:             $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";
122:         } else {
123:             $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";
124:         }
125:         $output .= "    if ({$section_props}['total'] == 0)\n" . "        {$section_props}['show'] = false;\n" . "} else\n" . "    {$section_props}['total'] = 0;\n";
126: 
127:         $output .= "if ({$section_props}['show']):\n";
128:         $output .= "
129:             for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
130:                  {$section_props}['iteration'] <= {$section_props}['total'];
131:                  {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
132:         $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
133:         $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
134:         $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
135:         $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";
136:         $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";
137: 
138:         $output .= "?>";
139: 
140:         return $output;
141:     }
142: }
143: 
144: 145: 146: 147: 148: 149: 
150: class Smarty_Internal_Compile_Sectionelse extends Smarty_Internal_CompileBase
151: {
152:     153: 154: 155: 156: 157: 158: 159: 
160:     public function compile($args, $compiler)
161:     {
162:         
163:         $_attr = $this->getAttributes($compiler, $args);
164: 
165:         list($openTag, $nocache) = $this->closeTag($compiler, array('section'));
166:         $this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache));
167: 
168:         return "<?php endfor; else: ?>";
169:     }
170: }
171: 
172: 173: 174: 175: 176: 177: 
178: class Smarty_Internal_Compile_Sectionclose extends Smarty_Internal_CompileBase
179: {
180:     181: 182: 183: 184: 185: 186: 187: 
188:     public function compile($args, $compiler)
189:     {
190:         
191:         $_attr = $this->getAttributes($compiler, $args);
192: 
193:         
194:         if ($compiler->nocache) {
195:             $compiler->tag_nocache = true;
196:         }
197: 
198:         list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('section', 'sectionelse'));
199: 
200:         if ($openTag == 'sectionelse') {
201:             return "<?php endif; ?>";
202:         } else {
203:             return "<?php endfor; endif; ?>";
204:         }
205:     }
206: }
207: