Re: PHP5 Iterators + foreach

messju mohr <[email protected]>
Newsgroups gmane.comp.php.smarty.devel
Message-ID <[email protected]>
On Sun, Aug 01, 2004 at 02:33:52AM +1000, Robert Amos wrote:
> Hi all,
> 
> after the discussions in the IRC channel over the past few days about
> adding support for iterators to foreach, I worked up the following
> patch that adds almost complete support for it except for a few
> specific problems.
> 
> When you're using foreach properties (like foreach.name.iteration,
> etc) the last and total properties wont work. This is mostly because
> you can't use count() on an iterator. This was discussed on the
> php-dev list a few months back but nothing seems to have become of
> that.
> 
> So I submit this now, and hopefully one of the other "smarties" might
> have a brainwave and find a solution that doesn't involve looping over
> the iterator twice. And testing with php4 would be nice also :)

it doesn't work with php4.  ...->getIterator()->valid(); raises a
syntax error.

another issue is: in some cases you are working on $from more than
once insted of assigning it ot a \$_from . this is problematic if your
from attribute has modifiers applied or contains a method-call. the methods would be called more than once, which isn't expected behaviour.

FWIW: i'd do the check for function_exists('is_a') at compile-time not
at runtime. there are other places in smarty that make compiled
templates not absolutely portable between different versions of php so
it wouldnt't make the situation worse to keep that out of the
compiled-template here, IMHO.

greetings
messju

 
> For my test cases you can see:
> <http://smarty.lexx.odynia.org/foreach.php> (please no flattening my
> modem)
> 
> Special thanks must go to mensi firstly, for requesting this and doing
> most of the thinking, and messju for his input ;)
> 
> -bok
> 
> Patch count be found below, and here:
> <http://smarty.lexx.odynia.org/Smarty_Compiler.class.php.diff>
> 
> Index: Smarty_Compiler.class.php
> ===================================================================
> RCS file: /repository/smarty/libs/Smarty_Compiler.class.php,v
> retrieving revision 1.329
> diff -u -r1.329 Smarty_Compiler.class.php
> --- libs/Smarty_Compiler.class.php   27 Jul 2004 17:59:35 -0000      1.329
> +++ libs/Smarty_Compiler.class.php   31 Jul 2004 16:26:27 -0000
> @@ -1162,8 +1162,13 @@
>          }
> 
>          if (isset($name)) {
> -            $output .= "{$foreach_props}['total'] = count(\$_from =
> (array)$from);\n";
> -            $output .= "{$foreach_props}['show'] =
> {$foreach_props}['total'] > 0;\n";
> +            $output .= "if (function_exists('is_a') && is_a($from,
> 'IteratorAggregate')):\n";
> +            $output .= "   {$foreach_props}['show'] =
> {$from}->getIterator()->valid();\n";
> +            $output .= "   \$_from = $from;\n";
> +            $output .= "else:\n";
> +            $output .= "   {$foreach_props}['total'] = count(\$_from
> = (array)$from);\n";
> +            $output .= "   {$foreach_props}['show'] =
> {$foreach_props}['total'] > 0;\n";
> +            $output .= "endif;\n";
>              $output .= "if ({$foreach_props}['show']):\n";
>              $output .= "{$foreach_props}['iteration'] = 0;\n";
>              $output .= "    foreach (\$_from as
> $key_part\$this->_tpl_vars['$item']):\n";
> @@ -1171,7 +1176,16 @@
>              $output .= "        {$foreach_props}['first'] =
> ({$foreach_props}['iteration'] == 1);\n";
>              $output .= "        {$foreach_props}['last']  =
> ({$foreach_props}['iteration'] == {$foreach_props}['total']);\n";
>          } else {
> -            $output .= "if (count(\$_from = (array)$from)):\n";
> +            $output .= "\$_show = false;\n";
> +            $output .= "if (function_exists('is_a') && is_a($from,
> 'IteratorAggregate')):\n";
> +            $output .= "    if ({$from}->getIterator()->valid()):\n";
> +            $output .= "        \$_show = true;\n";
> +            $output .= "    endif;\n";
> +            $output .= "    \$_from = $from;\n";
> +            $output .= "elseif (count(\$_from = (array)$from)):\n";
> +            $output .= "    \$_show = true;\n";
> +            $output .= "endif;\n";
> +            $output .= "if (\$_show):\n";
>              $output .= "    foreach (\$_from as
> $key_part\$this->_tpl_vars['$item']):\n";
>          }
>          $output .= '?>';
> 
> -- 
> Smarty Development Mailing List (http://smarty.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php

-- 
Smarty Development Mailing List (http://smarty.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.