[BUGFIX] Only count items in ForViewHelper when ``iteration`` argument is set 11/40711/3
authorMathias Brodala <mbrodala@pagemachine.de>
Mon, 29 Jun 2015 07:49:48 +0000 (09:49 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Mon, 29 Jun 2015 12:48:18 +0000 (14:48 +0200)
When using the ``iteration`` argument, the ``ForViewHelper`` provides
information about the current iteration, including the ``cycle`` and
``total``. Therefore it needs to count all elements.
The problem is, that this happens even if the iteration argument is
not specified leading to performance issues especially when iterating
over a (subset of a) lot of (remote) items.

This patch fixes this by adding a check for the ``iteration`` argument.

Resolves: #67801
Releases: master, 6.2
Change-Id: I4645ed03322bea36f2c36263378900f401626f24
Reviewed-on: http://review.typo3.org/40711
Reviewed-by: David Greiner <hallo@davidgreiner.de>
Tested-by: David Greiner <hallo@davidgreiner.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/fluid/Classes/ViewHelpers/ForViewHelper.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ForViewHelperTest.php

index d84ad63..3da8be4 100644 (file)
@@ -102,11 +102,13 @@ class ForViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
                        }
                        $arguments['each'] = array_reverse($arguments['each']);
                }
-               $iterationData = array(
-                       'index' => 0,
-                       'cycle' => 1,
-                       'total' => count($arguments['each'])
-               );
+               if ($arguments['iteration'] !== NULL) {
+                       $iterationData = array(
+                               'index' => 0,
+                               'cycle' => 1,
+                               'total' => count($arguments['each'])
+                       );
+               }
 
                $output = '';
                foreach ($arguments['each'] as $keyValue => $singleElement) {
index 10a575d..4f45ab1 100644 (file)
@@ -395,4 +395,22 @@ class ForViewHelperTest extends \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\ViewHelp
                $this->assertSame($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
        }
 
+       /**
+        * @test
+        */
+       public function iteratedItemsAreNotCountedIfIterationArgumentIsNotSet() {
+               $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
+
+               $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
+
+               $mockItems = $this->getMockBuilder(\ArrayObject::class)->setMethods(['count'])->disableOriginalConstructor()->getMock();
+               $mockItems->expects($this->never())->method('count');
+               $this->arguments['each'] = $mockItems;
+               $this->arguments['as'] = 'innerVariable';
+
+               $this->injectDependenciesIntoViewHelper($viewHelper);
+               $viewHelper->setViewHelperNode($viewHelperNode);
+               $viewHelper->render($this->arguments['each'], $this->arguments['as']);
+       }
+
 }