| 1: | <?php
|
| 2: | |
| 3: | |
| 4: | |
| 5: | |
| 6: | |
| 7: | |
| 8: | |
| 9: |
|
| 10: |
|
| 11: | |
| 12: | |
| 13: | |
| 14: | |
| 15: | |
| 16: |
|
| 17: | class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_ForeachSection
|
| 18: | {
|
| 19: | |
| 20: | |
| 21: | |
| 22: | |
| 23: | |
| 24: |
|
| 25: | public $required_attributes = array('from', 'item');
|
| 26: |
|
| 27: | |
| 28: | |
| 29: | |
| 30: | |
| 31: | |
| 32: |
|
| 33: | public $optional_attributes = array('name', 'key', 'properties');
|
| 34: |
|
| 35: | |
| 36: | |
| 37: | |
| 38: | |
| 39: | |
| 40: |
|
| 41: | public $shorttag_order = array('from', 'item', 'key', 'name');
|
| 42: |
|
| 43: | |
| 44: | |
| 45: | |
| 46: | |
| 47: |
|
| 48: | public $counter = 0;
|
| 49: |
|
| 50: | |
| 51: | |
| 52: | |
| 53: | |
| 54: |
|
| 55: | public $tagName = 'foreach';
|
| 56: |
|
| 57: | |
| 58: | |
| 59: | |
| 60: | |
| 61: |
|
| 62: | public $nameProperties = array('first', 'last', 'index', 'iteration', 'show', 'total');
|
| 63: |
|
| 64: | |
| 65: | |
| 66: | |
| 67: | |
| 68: |
|
| 69: | public $itemProperties = array('first', 'last', 'index', 'iteration', 'show', 'total', 'key');
|
| 70: |
|
| 71: | |
| 72: | |
| 73: | |
| 74: | |
| 75: |
|
| 76: | public $isNamed = false;
|
| 77: |
|
| 78: | |
| 79: | |
| 80: | |
| 81: | |
| 82: | |
| 83: | |
| 84: | |
| 85: | |
| 86: | |
| 87: |
|
| 88: | public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
|
| 89: | {
|
| 90: | $compiler->loopNesting++;
|
| 91: |
|
| 92: | $this->isNamed = false;
|
| 93: |
|
| 94: | $_attr = $this->getAttributes($compiler, $args);
|
| 95: | $from = $_attr[ 'from' ];
|
| 96: | $item = $compiler->getId($_attr[ 'item' ]);
|
| 97: | if ($item === false) {
|
| 98: | $item = $compiler->getVariableName($_attr[ 'item' ]);
|
| 99: | }
|
| 100: | $key = $name = null;
|
| 101: | $attributes = array('item' => $item);
|
| 102: | if (isset($_attr[ 'key' ])) {
|
| 103: | $key = $compiler->getId($_attr[ 'key' ]);
|
| 104: | if ($key === false) {
|
| 105: | $key = $compiler->getVariableName($_attr[ 'key' ]);
|
| 106: | }
|
| 107: | $attributes[ 'key' ] = $key;
|
| 108: | }
|
| 109: | if (isset($_attr[ 'name' ])) {
|
| 110: | $this->isNamed = true;
|
| 111: | $name = $attributes[ 'name' ] = $compiler->getId($_attr[ 'name' ]);
|
| 112: | }
|
| 113: | foreach ($attributes as $a => $v) {
|
| 114: | if ($v === false) {
|
| 115: | $compiler->trigger_template_error("'{$a}' attribute/variable has illegal value", null, true);
|
| 116: | }
|
| 117: | }
|
| 118: | $fromName = $compiler->getVariableName($_attr[ 'from' ]);
|
| 119: | if ($fromName) {
|
| 120: | foreach (array('item', 'key') as $a) {
|
| 121: | if (isset($attributes[ $a ]) && $attributes[ $a ] === $fromName) {
|
| 122: | $compiler->trigger_template_error(
|
| 123: | "'{$a}' and 'from' may not have same variable name '{$fromName}'",
|
| 124: | null,
|
| 125: | true
|
| 126: | );
|
| 127: | }
|
| 128: | }
|
| 129: | }
|
| 130: | $itemVar = "\$_smarty_tpl->tpl_vars['{$item}']";
|
| 131: | $local = '$__foreach_' . $attributes[ 'item' ] . '_' . $this->counter++ . '_';
|
| 132: |
|
| 133: | $itemAttr = array();
|
| 134: | $namedAttr = array();
|
| 135: | $this->scanForProperties($attributes, $compiler);
|
| 136: | if (!empty($this->matchResults[ 'item' ])) {
|
| 137: | $itemAttr = $this->matchResults[ 'item' ];
|
| 138: | }
|
| 139: | if (!empty($this->matchResults[ 'named' ])) {
|
| 140: | $namedAttr = $this->matchResults[ 'named' ];
|
| 141: | }
|
| 142: | if (isset($_attr[ 'properties' ]) && preg_match_all('/[\'](.*?)[\']/', $_attr[ 'properties' ], $match)) {
|
| 143: | foreach ($match[ 1 ] as $prop) {
|
| 144: | if (in_array($prop, $this->itemProperties)) {
|
| 145: | $itemAttr[ $prop ] = true;
|
| 146: | } else {
|
| 147: | $compiler->trigger_template_error("Invalid property '{$prop}'", null, true);
|
| 148: | }
|
| 149: | }
|
| 150: | if ($this->isNamed) {
|
| 151: | foreach ($match[ 1 ] as $prop) {
|
| 152: | if (in_array($prop, $this->nameProperties)) {
|
| 153: | $nameAttr[ $prop ] = true;
|
| 154: | } else {
|
| 155: | $compiler->trigger_template_error("Invalid property '{$prop}'", null, true);
|
| 156: | }
|
| 157: | }
|
| 158: | }
|
| 159: | }
|
| 160: | if (isset($itemAttr[ 'first' ])) {
|
| 161: | $itemAttr[ 'index' ] = true;
|
| 162: | }
|
| 163: | if (isset($namedAttr[ 'first' ])) {
|
| 164: | $namedAttr[ 'index' ] = true;
|
| 165: | }
|
| 166: | if (isset($namedAttr[ 'last' ])) {
|
| 167: | $namedAttr[ 'iteration' ] = true;
|
| 168: | $namedAttr[ 'total' ] = true;
|
| 169: | }
|
| 170: | if (isset($itemAttr[ 'last' ])) {
|
| 171: | $itemAttr[ 'iteration' ] = true;
|
| 172: | $itemAttr[ 'total' ] = true;
|
| 173: | }
|
| 174: | if (isset($namedAttr[ 'show' ])) {
|
| 175: | $namedAttr[ 'total' ] = true;
|
| 176: | }
|
| 177: | if (isset($itemAttr[ 'show' ])) {
|
| 178: | $itemAttr[ 'total' ] = true;
|
| 179: | }
|
| 180: | $keyTerm = '';
|
| 181: | if (isset($attributes[ 'key' ])) {
|
| 182: | $keyTerm = "\$_smarty_tpl->tpl_vars['{$key}']->value => ";
|
| 183: | }
|
| 184: | if (isset($itemAttr[ 'key' ])) {
|
| 185: | $keyTerm = "{$itemVar}->key => ";
|
| 186: | }
|
| 187: | if ($this->isNamed) {
|
| 188: | $foreachVar = "\$_smarty_tpl->tpl_vars['__smarty_foreach_{$attributes['name']}']";
|
| 189: | }
|
| 190: | $needTotal = isset($itemAttr[ 'total' ]);
|
| 191: |
|
| 192: | $this->openTag(
|
| 193: | $compiler,
|
| 194: | 'foreach',
|
| 195: | array('foreach', $compiler->nocache, $local, $itemVar, empty($itemAttr) ? 1 : 2)
|
| 196: | );
|
| 197: |
|
| 198: | $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
| 199: |
|
| 200: | $output = "<?php\n";
|
| 201: | $output .= "\$_from = \$_smarty_tpl->smarty->ext->_foreach->init(\$_smarty_tpl, $from, " .
|
| 202: | var_export($item, true);
|
| 203: | if ($name || $needTotal || $key) {
|
| 204: | $output .= ', ' . var_export($needTotal, true);
|
| 205: | }
|
| 206: | if ($name || $key) {
|
| 207: | $output .= ', ' . var_export($key, true);
|
| 208: | }
|
| 209: | if ($name) {
|
| 210: | $output .= ', ' . var_export($name, true) . ', ' . var_export($namedAttr, true);
|
| 211: | }
|
| 212: | $output .= ");\n";
|
| 213: | if (isset($itemAttr[ 'show' ])) {
|
| 214: | $output .= "{$itemVar}->show = ({$itemVar}->total > 0);\n";
|
| 215: | }
|
| 216: | if (isset($itemAttr[ 'iteration' ])) {
|
| 217: | $output .= "{$itemVar}->iteration = 0;\n";
|
| 218: | }
|
| 219: | if (isset($itemAttr[ 'index' ])) {
|
| 220: | $output .= "{$itemVar}->index = -1;\n";
|
| 221: | }
|
| 222: | $output .= "{$itemVar}->do_else = true;\n";
|
| 223: | $output .= "if (\$_from !== null) foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n";
|
| 224: | $output .= "{$itemVar}->do_else = false;\n";
|
| 225: | if (isset($attributes[ 'key' ]) && isset($itemAttr[ 'key' ])) {
|
| 226: | $output .= "\$_smarty_tpl->tpl_vars['{$key}']->value = {$itemVar}->key;\n";
|
| 227: | }
|
| 228: | if (isset($itemAttr[ 'iteration' ])) {
|
| 229: | $output .= "{$itemVar}->iteration++;\n";
|
| 230: | }
|
| 231: | if (isset($itemAttr[ 'index' ])) {
|
| 232: | $output .= "{$itemVar}->index++;\n";
|
| 233: | }
|
| 234: | if (isset($itemAttr[ 'first' ])) {
|
| 235: | $output .= "{$itemVar}->first = !{$itemVar}->index;\n";
|
| 236: | }
|
| 237: | if (isset($itemAttr[ 'last' ])) {
|
| 238: | $output .= "{$itemVar}->last = {$itemVar}->iteration === {$itemVar}->total;\n";
|
| 239: | }
|
| 240: | if (isset($foreachVar)) {
|
| 241: | if (isset($namedAttr[ 'iteration' ])) {
|
| 242: | $output .= "{$foreachVar}->value['iteration']++;\n";
|
| 243: | }
|
| 244: | if (isset($namedAttr[ 'index' ])) {
|
| 245: | $output .= "{$foreachVar}->value['index']++;\n";
|
| 246: | }
|
| 247: | if (isset($namedAttr[ 'first' ])) {
|
| 248: | $output .= "{$foreachVar}->value['first'] = !{$foreachVar}->value['index'];\n";
|
| 249: | }
|
| 250: | if (isset($namedAttr[ 'last' ])) {
|
| 251: | $output .= "{$foreachVar}->value['last'] = {$foreachVar}->value['iteration'] === {$foreachVar}->value['total'];\n";
|
| 252: | }
|
| 253: | }
|
| 254: | if (!empty($itemAttr)) {
|
| 255: | $output .= "{$local}saved = {$itemVar};\n";
|
| 256: | }
|
| 257: | $output .= '?>';
|
| 258: | return $output;
|
| 259: | }
|
| 260: |
|
| 261: | |
| 262: | |
| 263: | |
| 264: | |
| 265: | |
| 266: | |
| 267: |
|
| 268: | public function compileRestore($levels)
|
| 269: | {
|
| 270: | return "\$_smarty_tpl->smarty->ext->_foreach->restore(\$_smarty_tpl, {$levels});";
|
| 271: | }
|
| 272: | }
|
| 273: |
|
| 274: | |
| 275: | |
| 276: | |
| 277: | |
| 278: | |
| 279: |
|
| 280: | class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase
|
| 281: | {
|
| 282: | |
| 283: | |
| 284: | |
| 285: | |
| 286: | |
| 287: | |
| 288: | |
| 289: |
|
| 290: | public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
|
| 291: | {
|
| 292: |
|
| 293: | $_attr = $this->getAttributes($compiler, $args);
|
| 294: | list($openTag, $nocache, $local, $itemVar, $restore) = $this->closeTag($compiler, array('foreach'));
|
| 295: | $this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $local, $itemVar, 0));
|
| 296: | $output = "<?php\n";
|
| 297: | if ($restore === 2) {
|
| 298: | $output .= "{$itemVar} = {$local}saved;\n";
|
| 299: | }
|
| 300: | $output .= "}\nif ({$itemVar}->do_else) {\n?>";
|
| 301: | return $output;
|
| 302: | }
|
| 303: | }
|
| 304: |
|
| 305: | |
| 306: | |
| 307: | |
| 308: | |
| 309: | |
| 310: |
|
| 311: | class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase
|
| 312: | {
|
| 313: | |
| 314: | |
| 315: | |
| 316: | |
| 317: | |
| 318: | |
| 319: | |
| 320: | |
| 321: |
|
| 322: | public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
|
| 323: | {
|
| 324: | $compiler->loopNesting--;
|
| 325: |
|
| 326: | if ($compiler->nocache) {
|
| 327: | $compiler->tag_nocache = true;
|
| 328: | }
|
| 329: | list(
|
| 330: | $openTag, $compiler->nocache, $local, $itemVar, $restore
|
| 331: | ) = $this->closeTag($compiler, array('foreach', 'foreachelse'));
|
| 332: | $output = "<?php\n";
|
| 333: | if ($restore === 2) {
|
| 334: | $output .= "{$itemVar} = {$local}saved;\n";
|
| 335: | }
|
| 336: | $output .= "}\n";
|
| 337: |
|
| 338: | $foreachCompiler = $compiler->getTagCompiler('foreach');
|
| 339: | $output .= $foreachCompiler->compileRestore(1);
|
| 340: | $output .= "?>";
|
| 341: | return $output;
|
| 342: | }
|
| 343: | }
|
| 344: | |