Fix {foreach} for non-`\Countable` `\Traversable`s
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 17 Aug 2017 13:27:51 +0000 (15:27 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Fri, 18 Aug 2017 11:03:30 +0000 (13:03 +0200)
wcfsetup/install/files/lib/system/template/TemplateScriptingCompiler.class.php

index 0be950c6a4cc53889507742d3e4a8f1799ae9d14..53e1f595342b077237b2851361273dd025046d25 100644 (file)
@@ -689,19 +689,27 @@ class TemplateScriptingCompiler {
                        $foreachProp = "\$this->v['tpl']['foreach'][".$args['name']."]";
                }
                
+               $foreachHash = "\$_foreach_".StringUtil::getRandomID();
+               
                $phpCode = "<?php\n";
+               $phpCode .= $foreachHash." = ".$args['from'].";\n";
+               $phpCode .= $foreachHash."_cnt = (".$foreachHash." !== null ? 1 : 0);\n";
+               $phpCode .= "if (is_array(".$foreachHash.") || (".$foreachHash." instanceof \\Countable)) {\n";
+               $phpCode .= $foreachHash."_cnt = count(".$foreachHash.");\n";
+               $phpCode .= "}\n";
+               
                if (!empty($foreachProp)) {
-                       $phpCode .= $foreachProp."['total'] = count(".$args['from'].");\n";
+                       $phpCode .= $foreachProp."['total'] = ".$foreachHash."_cnt;\n";
                        $phpCode .= $foreachProp."['show'] = (".$foreachProp."['total'] > 0 ? true : false);\n";
                        $phpCode .= $foreachProp."['iteration'] = 0;\n";
                }
-               $phpCode .= "if (count(".$args['from'].") > 0) {\n";
+               $phpCode .= "if (".$foreachHash."_cnt > 0) {\n";
                
                if (isset($args['key'])) {
-                       $phpCode .= "foreach (".$args['from']." as ".(mb_substr($args['key'], 0, 1) != '$' ? "\$this->v[".$args['key']."]" : $args['key'])." => ".(mb_substr($args['item'], 0, 1) != '$' ? "\$this->v[".$args['item']."]" : $args['item']).") {\n";
+                       $phpCode .= "foreach (".$foreachHash." as ".(mb_substr($args['key'], 0, 1) != '$' ? "\$this->v[".$args['key']."]" : $args['key'])." => ".(mb_substr($args['item'], 0, 1) != '$' ? "\$this->v[".$args['item']."]" : $args['item']).") {\n";
                }
                else {
-                       $phpCode .= "foreach (".$args['from']." as ".(mb_substr($args['item'], 0, 1) != '$' ? "\$this->v[".$args['item']."]" : $args['item']).") {\n";
+                       $phpCode .= "foreach (".$foreachHash." as ".(mb_substr($args['item'], 0, 1) != '$' ? "\$this->v[".$args['item']."]" : $args['item']).") {\n";
                }
                
                if (!empty($foreachProp)) {