Created
October 28, 2015 13:57
-
-
Save pixelbrackets/8067114f59db6a1af500 to your computer and use it in GitHub Desktop.
Add the iteratition feature of the TYPO3 Fluid ForViewHelper to the GroupedForViewhelper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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