1<?php 2/** 3 * Smarty Internal Plugin Compile For 4 * Compiles the {for} {forelse} {/for} tags 5 * 6 * @package Smarty 7 * @subpackage Compiler 8 * @author Uwe Tews 9 */ 10 11/** 12 * Smarty Internal Plugin Compile For Class 13 * 14 * @package Smarty 15 * @subpackage Compiler 16 */ 17class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase 18{ 19 /** 20 * Compiles code for the {for} tag 21 * Smarty 3 does implement two different syntax's: 22 * - {for $var in $array} 23 * For looping over arrays or iterators 24 * - {for $x=0; $x<$y; $x++} 25 * For general loops 26 * The parser is generating different sets of attribute by which this compiler can 27 * determine which syntax is used. 28 * 29 * @param array $args array with attributes from parser 30 * @param object $compiler compiler object 31 * @param array $parameter array with compilation parameter 32 * 33 * @return string compiled code 34 */ 35 public function compile($args, $compiler, $parameter) 36 { 37 $compiler->loopNesting++; 38 if ($parameter === 0) { 39 $this->required_attributes = array('start', 'to'); 40 $this->optional_attributes = array('max', 'step'); 41 } else { 42 $this->required_attributes = array('start', 'ifexp', 'var', 'step'); 43 $this->optional_attributes = array(); 44 } 45 $this->mapCache = array(); 46 // check and get attributes 47 $_attr = $this->getAttributes($compiler, $args); 48 $output = "<?php\n"; 49 if ($parameter === 1) { 50 foreach ($_attr[ 'start' ] as $_statement) { 51 if (is_array($_statement[ 'var' ])) { 52 $var = $_statement[ 'var' ][ 'var' ]; 53 $index = $_statement[ 'var' ][ 'smarty_internal_index' ]; 54 } else { 55 $var = $_statement[ 'var' ]; 56 $index = ''; 57 } 58 $output .= "\$_smarty_tpl->tpl_vars[$var] = new Smarty_Variable(null, \$_smarty_tpl->isRenderingCache);\n"; 59 $output .= "\$_smarty_tpl->tpl_vars[$var]->value{$index} = {$_statement['value']};\n"; 60 } 61 if (is_array($_attr[ 'var' ])) { 62 $var = $_attr[ 'var' ][ 'var' ]; 63 $index = $_attr[ 'var' ][ 'smarty_internal_index' ]; 64 } else { 65 $var = $_attr[ 'var' ]; 66 $index = ''; 67 } 68 $output .= "if ($_attr[ifexp]) {\nfor (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$var]->value{$index}$_attr[step]) {\n"; 69 } else { 70 $_statement = $_attr[ 'start' ]; 71 if (is_array($_statement[ 'var' ])) { 72 $var = $_statement[ 'var' ][ 'var' ]; 73 $index = $_statement[ 'var' ][ 'smarty_internal_index' ]; 74 } else { 75 $var = $_statement[ 'var' ]; 76 $index = ''; 77 } 78 $output .= "\$_smarty_tpl->tpl_vars[$var] = new Smarty_Variable(null, \$_smarty_tpl->isRenderingCache);"; 79 if (isset($_attr[ 'step' ])) { 80 $output .= "\$_smarty_tpl->tpl_vars[$var]->step = $_attr[step];"; 81 } else { 82 $output .= "\$_smarty_tpl->tpl_vars[$var]->step = 1;"; 83 } 84 if (isset($_attr[ 'max' ])) { 85 $output .= "\$_smarty_tpl->tpl_vars[$var]->total = (int) min(ceil((\$_smarty_tpl->tpl_vars[$var]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$var]->step)),$_attr[max]);\n"; 86 } else { 87 $output .= "\$_smarty_tpl->tpl_vars[$var]->total = (int) ceil((\$_smarty_tpl->tpl_vars[$var]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$var]->step));\n"; 88 } 89 $output .= "if (\$_smarty_tpl->tpl_vars[$var]->total > 0) {\n"; 90 $output .= "for (\$_smarty_tpl->tpl_vars[$var]->value{$index} = $_statement[value], \$_smarty_tpl->tpl_vars[$var]->iteration = 1;\$_smarty_tpl->tpl_vars[$var]->iteration <= \$_smarty_tpl->tpl_vars[$var]->total;\$_smarty_tpl->tpl_vars[$var]->value{$index} += \$_smarty_tpl->tpl_vars[$var]->step, \$_smarty_tpl->tpl_vars[$var]->iteration++) {\n"; 91 $output .= "\$_smarty_tpl->tpl_vars[$var]->first = \$_smarty_tpl->tpl_vars[$var]->iteration === 1;"; 92 $output .= "\$_smarty_tpl->tpl_vars[$var]->last = \$_smarty_tpl->tpl_vars[$var]->iteration === \$_smarty_tpl->tpl_vars[$var]->total;"; 93 } 94 $output .= '?>'; 95 $this->openTag($compiler, 'for', array('for', $compiler->nocache)); 96 // maybe nocache because of nocache variables 97 $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; 98 // return compiled code 99 return $output; 100 } 101} 102 103/** 104 * Smarty Internal Plugin Compile Forelse Class 105 * 106 * @package Smarty 107 * @subpackage Compiler 108 */ 109class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase 110{ 111 /** 112 * Compiles code for the {forelse} tag 113 * 114 * @param array $args array with attributes from parser 115 * @param object $compiler compiler object 116 * @param array $parameter array with compilation parameter 117 * 118 * @return string compiled code 119 */ 120 public function compile($args, $compiler, $parameter) 121 { 122 // check and get attributes 123 $_attr = $this->getAttributes($compiler, $args); 124 list($openTag, $nocache) = $this->closeTag($compiler, array('for')); 125 $this->openTag($compiler, 'forelse', array('forelse', $nocache)); 126 return "<?php }} else { ?>"; 127 } 128} 129 130/** 131 * Smarty Internal Plugin Compile Forclose Class 132 * 133 * @package Smarty 134 * @subpackage Compiler 135 */ 136class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase 137{ 138 /** 139 * Compiles code for the {/for} tag 140 * 141 * @param array $args array with attributes from parser 142 * @param object $compiler compiler object 143 * @param array $parameter array with compilation parameter 144 * 145 * @return string compiled code 146 */ 147 public function compile($args, $compiler, $parameter) 148 { 149 $compiler->loopNesting--; 150 // check and get attributes 151 $_attr = $this->getAttributes($compiler, $args); 152 // must endblock be nocache? 153 if ($compiler->nocache) { 154 $compiler->tag_nocache = true; 155 } 156 list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('for', 'forelse')); 157 $output = "<?php }\n"; 158 if ($openTag !== 'forelse') { 159 $output .= "}\n"; 160 } 161 $output .= "?>"; 162 return $output; 163 } 164} 165