Skip to content

Instantly share code, notes, and snippets.

@pixelbrackets
Created October 28, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pixelbrackets/8067114f59db6a1af500 to your computer and use it in GitHub Desktop.
Save pixelbrackets/8067114f59db6a1af500 to your computer and use it in GitHub Desktop.
Add the iteratition feature of the TYPO3 Fluid ForViewHelper to the GroupedForViewhelper
<?php
namespace Pixelbrackets\AcmeSitepackage\ViewHelpers;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* Grouped loop viewhelper
*
* Iterates through elements and groups them by a specified property first
*
* This custom viewhelper adds the iteratition feature of the ForViewHelper to the GroupedForViewhelper
*
* @see TYPO3\CMS\Fluid\ViewHelpers\GroupedForViewHelper & TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper
*/
class GroupedForViewHelper extends AbstractViewHelper {
/**
* Iterates through elements of $each and renders child nodes
*
* @param array $each The array or \TYPO3\CMS\Extbase\Persistence\ObjectStorage to iterated over
* @param string $as The name of the iteration variable
* @param string $groupBy Group by this property
* @param string $groupKey The name of the variable to store the current group
* @param string $iteration The name of the variable to store iteration information (index, cycle, isFirst, isLast, isEven, isOdd)
* @return string Rendered string
* @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
* @api
*/
public function render($each, $as, $groupBy, $groupKey = 'groupKey', $iteration = NULL) {
$output = '';
if ($each === NULL) {
return '';
}
if (is_object($each)) {
if (!$each instanceof \Traversable) {
throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('GroupedForViewHelper only supports arrays and objects implementing \Traversable interface', 1253108907);
}
$each = iterator_to_array($each);
}
$groups = $this->groupElements($each, $groupBy);
if ($iteration !== NULL) {
$iterationData = array(
'index' => 0,
'cycle' => 1,
'total' => count($groups)
);
}
foreach ($groups['values'] as $currentGroupIndex => $group) {
$this->templateVariableContainer->add($groupKey, $groups['keys'][$currentGroupIndex]);
$this->templateVariableContainer->add($as, $group);
if (iteration !== NULL) {
$iterationData['isFirst'] = $iterationData['cycle'] === 1;
$iterationData['isLast'] = $iterationData['cycle'] === $iterationData['total'];
$iterationData['isEven'] = $iterationData['cycle'] % 2 === 0;
$iterationData['isOdd'] = !$iterationData['isEven'];
$this->templateVariableContainer->add($iteration, $iterationData);
$iterationData['index']++;
$iterationData['cycle']++;
}
$output .= $this->renderChildren();
$this->templateVariableContainer->remove($groupKey);
$this->templateVariableContainer->remove($as);
if (iteration !== NULL) {
$this->templateVariableContainer->remove($iteration);
}
}
return $output;
}
/**
* Groups the given array by the specified groupBy property.
*
* @param array $elements The array / traversable object to be grouped
* @param string $groupBy Group by this property
* @return array The grouped array in the form array('keys' => array('key1' => [key1value], 'key2' => [key2value], ...), 'values' => array('key1' => array([key1value] => [element1]), ...), ...)
* @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
*/
protected function groupElements(array $elements, $groupBy) {
$groups = array('keys' => array(), 'values' => array());
foreach ($elements as $key => $value) {
if (is_array($value)) {
$currentGroupIndex = isset($value[$groupBy]) ? $value[$groupBy] : NULL;
} elseif (is_object($value)) {
$currentGroupIndex = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getPropertyPath($value, $groupBy);
} else {
throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('GroupedForViewHelper only supports multi-dimensional arrays and objects', 1253120365);
}
$currentGroupKeyValue = $currentGroupIndex;
if (is_object($currentGroupIndex)) {
if ($currentGroupIndex instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
$currentGroupIndex = $currentGroupIndex->_loadRealInstance();
}
$currentGroupIndex = spl_object_hash($currentGroupIndex);
}
$groups['keys'][$currentGroupIndex] = $currentGroupKeyValue;
$groups['values'][$currentGroupIndex][$key] = $value;
}
return $groups;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment