Initial commit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Abstract class with basic functionality for loop view helpers.
|
||||
*
|
||||
* @author Danilo Bürger <danilo.buerger@hmspl.de>, Heimspiel GmbH
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
abstract class AbstractLoopViewHelper extends AbstractViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('iteration', 'string', 'Variable name to insert result into, suppresses output', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $i
|
||||
* @param integer $from
|
||||
* @param integer $to
|
||||
* @param integer $step
|
||||
* @param string $iterationArgument
|
||||
* @return string
|
||||
*/
|
||||
protected function renderIteration($i, $from, $to, $step, $iterationArgument) {
|
||||
if (FALSE === empty($iterationArgument)) {
|
||||
$cycle = intval(($i - $from) / $step) + 1;
|
||||
$iteration = array(
|
||||
'index' => $i,
|
||||
'cycle' => $cycle,
|
||||
'isOdd' => (0 === $cycle % 2 ? FALSE : TRUE),
|
||||
'isEven' => (0 === $cycle % 2 ? TRUE : FALSE),
|
||||
'isFirst' => ($i === $from ? TRUE : FALSE),
|
||||
'isLast' => $this->isLast($i, $from, $to, $step)
|
||||
);
|
||||
$this->templateVariableContainer->add($iterationArgument, $iteration);
|
||||
$content = $this->renderChildren();
|
||||
$this->templateVariableContainer->remove($iterationArgument);
|
||||
} else {
|
||||
$content = $this->renderChildren();
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $i
|
||||
* @param integer $from
|
||||
* @param integer $to
|
||||
* @param integer $step
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isLast($i, $from, $to, $step) {
|
||||
if ($from === $to) {
|
||||
$isLast = TRUE;
|
||||
} elseif ($from < $to) {
|
||||
$isLast = ($i + $step > $to);
|
||||
} else {
|
||||
$isLast = ($i + $step < $to);
|
||||
}
|
||||
|
||||
return $isLast;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Creates chunks from an input Array/Traversable with option to allocate items to a fixed number of chunks
|
||||
*
|
||||
* @author Benjamin Rau <rau@codearts.at>, codearts
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class ChunkViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('subject', 'mixed', 'The subject Traversable/Array instance to shift', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @param integer $count The count of items per chunk or if fixed number of chunks
|
||||
* @param boolean $fixed Whether to allocate items to a fixed number of chunks or not
|
||||
* @param boolean $preserveKeys If set to true, the original array keys will be preserved in the chunks
|
||||
* @throws \Exception
|
||||
* @return array
|
||||
*/
|
||||
public function render($count, $fixed = FALSE, $preserveKeys = FALSE) {
|
||||
$subject = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('subject');
|
||||
$output = array();
|
||||
if (0 >= $count) {
|
||||
return $output;
|
||||
}
|
||||
if (TRUE === (boolean) $fixed) {
|
||||
$subjectSize = count($subject);
|
||||
if (0 < $subjectSize) {
|
||||
$chunkSize = ceil($subjectSize / $count);
|
||||
$output = array_chunk($subject, $chunkSize, $preserveKeys);
|
||||
}
|
||||
// Fill the resulting array with empty items to get the desired element count
|
||||
$elementCount = count($output);
|
||||
if ($elementCount < $count) {
|
||||
$output += array_fill($elementCount, $count - $elementCount, NULL);
|
||||
}
|
||||
} else {
|
||||
$output = array_chunk($subject, $count, $preserveKeys);
|
||||
}
|
||||
return $this->renderChildrenWithVariableOrReturnInput($output);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\BasicViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Explode ViewHelper
|
||||
*
|
||||
* Explodes a string by $glue
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class ExplodeViewHelper extends AbstractViewHelper {
|
||||
|
||||
use BasicViewHelperTrait;
|
||||
use TemplateVariableViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $method = 'explode';
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('content', 'string', 'String to be exploded by glue', FALSE, NULL);
|
||||
$this->registerArgument('glue', 'string', 'String used as glue in the string to be exploded. Use glue value of "constant:NAMEOFCONSTANT" (fx "constant:LF" for linefeed as glue)', FALSE, ',');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render() {
|
||||
$content = $this->getArgumentFromArgumentsOrTagContent('content');
|
||||
$glue = $this->resolveGlue();
|
||||
$output = call_user_func_array($this->method, array($glue, $content));
|
||||
return $this->renderChildrenWithVariableOrReturnInput($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the proper glue string to use for implode/explode operation
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveGlue() {
|
||||
$glue = $this->arguments['glue'];
|
||||
if (FALSE !== strpos($glue, ':') && 1 < strlen($glue)) {
|
||||
// glue contains a special type identifier, resolve the actual glue
|
||||
list ($type, $value) = explode(':', $glue);
|
||||
switch ($type) {
|
||||
case 'constant':
|
||||
$glue = constant($value);
|
||||
break;
|
||||
default:
|
||||
$glue = $value;
|
||||
}
|
||||
}
|
||||
return $glue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ### Iterator / Extract VieWHelper
|
||||
*
|
||||
* Loop through the iterator and extract a key, optionally join the
|
||||
* results if more than one value is found.
|
||||
*
|
||||
* #### Extract values from an array by key
|
||||
*
|
||||
* The extbase version of indexed_search returns an array of the
|
||||
* previous search, which cannot easily be shown in the input field
|
||||
* of the result page. This can be solved.
|
||||
*
|
||||
* #### Input from extbase version of indexed_search">
|
||||
*
|
||||
* array(
|
||||
* 0 => array(
|
||||
* 'sword' => 'firstWord',
|
||||
* 'oper' => 'AND'
|
||||
* ),
|
||||
* 1 => array(
|
||||
* 'sword' => 'secondWord',
|
||||
* 'oper' => 'AND'
|
||||
* ),
|
||||
* 3 => array(
|
||||
* 'sword' => 'thirdWord',
|
||||
* 'oper' => 'AND'
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* Show the previous search words in the search form of the
|
||||
* result page:
|
||||
*
|
||||
* #### Example
|
||||
* <f:form.textfield name="search[sword]"
|
||||
* value="{v:iterator.extract(key:'sword', content: searchWords) -> v:iterator.implode(glue: ' ')}"
|
||||
* class="tx-indexedsearch-searchbox-sword" />
|
||||
*
|
||||
* #### Get the names of several users
|
||||
*
|
||||
* Provided we have a bunch of FrontendUsers and we need to show
|
||||
* their firstname combined into a string:
|
||||
*
|
||||
* <h2>Welcome
|
||||
* <v:iterator.implode glue=", "><v:iterator.extract key="firstname" content="frontendUsers" /></v:iterator.implode>
|
||||
* <!-- alternative: -->
|
||||
* {frontendUsers -> v:iterator.extract(key: 'firstname') -> v:iterator.implode(glue: ', ')}
|
||||
* </h2>
|
||||
*
|
||||
* #### Output
|
||||
*
|
||||
* <h2>Welcome Peter, Paul, Marry</h2>
|
||||
*
|
||||
* #### Complex example
|
||||
*
|
||||
* {anArray->v:iterator.extract(path: 'childProperty.secondNestedChildObject')->v:iterator.sort(direction: 'DESC', sortBy: 'propertyOnSecondChild')->v:iterator.slice(length: 10)->v:iterator.extract(key: 'uid')}
|
||||
*
|
||||
* #### Single return value
|
||||
*
|
||||
* Outputs the "uid" value of the first record in variable $someRecords without caring if there are more than
|
||||
* one records. Always extracts the first value and then stops. Equivalent of chaning -> v:iterator.first().
|
||||
* {someRecords -> v:iterator.extract(key: 'uid', single: TRUE)}
|
||||
*
|
||||
* @author Andreas Lappe <nd@kaeufli.ch>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class ExtractViewHelper extends AbstractViewHelper {
|
||||
|
||||
/**
|
||||
* @param string $key The name of the key from which you wish to extract the value
|
||||
* @param mixed $content The array or Iterator that contains either the value or arrays of values
|
||||
* @param boolean $recursive If TRUE, attempts to extract the key from deep nested arrays
|
||||
* @param boolean $single If TRUE, returns only one value - always the first one - instead of an array of values
|
||||
* @return array
|
||||
*/
|
||||
public function render($key, $content = NULL, $recursive = TRUE, $single = FALSE) {
|
||||
if (NULL === $content) {
|
||||
$content = $this->renderChildren();
|
||||
}
|
||||
try {
|
||||
// extraction from Iterators could potentially use a getter method which throws
|
||||
// exceptions - although this would be bad practice. Catch the exception here
|
||||
// and turn it into a WARNING log message so that output does not break.
|
||||
if (TRUE === (boolean) $recursive) {
|
||||
$result = $this->recursivelyExtractKey($content, $key);
|
||||
} else {
|
||||
$result = $this->extractByKey($content, $key);
|
||||
}
|
||||
} catch (\Exception $error) {
|
||||
GeneralUtility::sysLog($error->getMessage(), 'vhs', GeneralUtility::SYSLOG_SEVERITY_WARNING);
|
||||
$result = array();
|
||||
}
|
||||
|
||||
if (TRUE === (boolean) $single) {
|
||||
return reset($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract by key
|
||||
*
|
||||
* @param \Traversable $iterator
|
||||
* @param string $key
|
||||
* @return mixed NULL or whatever we found at $key
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function extractByKey($iterator, $key) {
|
||||
if (FALSE === is_array($iterator) && FALSE === $iterator instanceof \Traversable) {
|
||||
throw new \Exception('Traversable object or array expected but received ' . gettype($iterator), 1361532490);
|
||||
}
|
||||
|
||||
$result = ObjectAccess::getPropertyPath($iterator, $key);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively extract the key
|
||||
*
|
||||
* @param \Traversable $iterator
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function recursivelyExtractKey($iterator, $key) {
|
||||
$content = array();
|
||||
|
||||
foreach ($iterator as $v) {
|
||||
// Lets see if we find something directly:
|
||||
$result = ObjectAccess::getPropertyPath($v, $key);
|
||||
if (NULL !== $result) {
|
||||
$content[] = $result;
|
||||
} elseif (TRUE === is_array($v) || TRUE === $v instanceof \Traversable) {
|
||||
$content[] = $this->recursivelyExtractKey($v, $key);
|
||||
}
|
||||
}
|
||||
|
||||
$content = $this->flattenArray($content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten the result structure, to iterate it cleanly in fluid
|
||||
*
|
||||
* @param array $content
|
||||
* @param array $flattened
|
||||
* @return array
|
||||
*/
|
||||
public function flattenArray(array $content, $flattened = NULL) {
|
||||
foreach ($content as $sub) {
|
||||
if (TRUE === is_array($sub)) {
|
||||
$flattened = $this->flattenArray($sub, $flattened);
|
||||
} else {
|
||||
$flattened[] = $sub;
|
||||
}
|
||||
}
|
||||
|
||||
return $flattened;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ### Iterator: Filter ViewHelper
|
||||
*
|
||||
* Filters an array by filtering the array, analysing each member
|
||||
* and assering if it is equal to (weak type) the `filter` parameter.
|
||||
* If `propertyName` is set, the ViewHelper will try to extract this
|
||||
* property from each member of the array.
|
||||
*
|
||||
* Iterators and ObjectStorage etc. are supported.
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class FilterViewHelper extends AbstractViewHelper {
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @param mixed $subject The subject iterator/array to be filtered
|
||||
* @param mixed $filter The comparison value
|
||||
* @param string $propertyName Optional property name to extract and use for comparison instead of the object; use on ObjectStorage etc. Note: supports dot-path expressions.
|
||||
* @param boolean $preserveKeys If TRUE, keys in the array are preserved - even if they are numeric
|
||||
* @param boolean $invert Invert the behavior of the view helper
|
||||
* @param boolean $nullFilter If TRUE and $filter is NULL (not set) - to filter NULL or empty values
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($subject = NULL, $filter = NULL, $propertyName = NULL, $preserveKeys = FALSE, $invert = FALSE, $nullFilter = FALSE) {
|
||||
if (NULL === $subject) {
|
||||
$subject = $this->renderChildren();
|
||||
}
|
||||
if (NULL === $subject || (FALSE === is_array($subject) && FALSE === $subject instanceof \Traversable)) {
|
||||
return array();
|
||||
}
|
||||
if ((FALSE === (boolean) $nullFilter && NULL === $filter) || '' === $filter) {
|
||||
return $subject;
|
||||
}
|
||||
if (TRUE === $subject instanceof \Traversable) {
|
||||
$subject = iterator_to_array($subject);
|
||||
}
|
||||
$items = array();
|
||||
$invert = (boolean) $invert;
|
||||
$invertFlag = TRUE === $invert ? FALSE : TRUE;
|
||||
foreach ($subject as $key => $item) {
|
||||
if ($invertFlag === $this->filter($item, $filter, $propertyName)) {
|
||||
$items[$key] = $item;
|
||||
}
|
||||
}
|
||||
return TRUE === $preserveKeys ? $items : array_values($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter an item/value according to desired filter. Returns TRUE if
|
||||
* the item should be included, FALSE otherwise. This default method
|
||||
* simply does a weak comparison (==) for sameness.
|
||||
*
|
||||
* @param mixed $item
|
||||
* @param mixed $filter Could be a single value or an Array. If so the function returns TRUE when $item matches with any value in it.
|
||||
* @param string $propertyName
|
||||
* @return boolean
|
||||
*/
|
||||
protected function filter($item, $filter, $propertyName) {
|
||||
if (FALSE === empty($propertyName) && (TRUE === is_object($item) || TRUE === is_array($item))) {
|
||||
$value = ObjectAccess::getPropertyPath($item, $propertyName);
|
||||
} else {
|
||||
$value = $item;
|
||||
}
|
||||
return is_array($filter) ? in_array($value, $filter) : ($value == $filter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Returns the first element of $haystack
|
||||
*
|
||||
* @author Claus Due
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class FirstViewHelper extends AbstractViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('haystack', 'mixed', 'Haystack in which to look for needle', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @throws Exception
|
||||
* @return mixed|NULL
|
||||
*/
|
||||
public function render() {
|
||||
$haystack = $this->arguments['haystack'];
|
||||
if (NULL === $haystack) {
|
||||
$haystack = $this->renderChildren();
|
||||
}
|
||||
if (FALSE === is_array($haystack) && FALSE === $haystack instanceof \Iterator && NULL !== $haystack) {
|
||||
throw new Exception('Invalid argument supplied to Iterator/FirstViewHelper - expected array, Iterator or NULL but got ' .
|
||||
gettype($haystack), 1351958398);
|
||||
}
|
||||
if (NULL === $haystack) {
|
||||
return NULL;
|
||||
}
|
||||
foreach ($haystack as $needle) {
|
||||
return $needle;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Repeats rendering of children with a typical for loop: starting at
|
||||
* index $from it will loop until the index has reached $to.
|
||||
*
|
||||
* @author Danilo Bürger <danilo.buerger@hmspl.de>, Heimspiel GmbH
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class ForViewHelper extends AbstractLoopViewHelper {
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('to', 'integer', 'Number that the index needs to reach before stopping', TRUE);
|
||||
$this->registerArgument('from', 'integer', 'Starting number for the index', FALSE, 0);
|
||||
$this->registerArgument('step', 'integer', 'Stepping number that the index is increased by after each loop', FALSE, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \RuntimeException
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$to = intval($this->arguments['to']);
|
||||
$from = intval($this->arguments['from']);
|
||||
$step = intval($this->arguments['step']);
|
||||
$iteration = $this->arguments['iteration'];
|
||||
$content = '';
|
||||
|
||||
if (0 === $step) {
|
||||
throw new \RuntimeException('"step" may not be 0.', 1383267698);
|
||||
}
|
||||
if ($from < $to && 0 > $step) {
|
||||
throw new \RuntimeException('"step" must be greater than 0 if "from" is smaller than "to".', 1383268407);
|
||||
}
|
||||
if ($from > $to && 0 < $step) {
|
||||
throw new \RuntimeException('"step" must be smaller than 0 if "from" is greater than "to".', 1383268415);
|
||||
}
|
||||
|
||||
if (TRUE === $this->templateVariableContainer->exists($iteration)) {
|
||||
$backupVariable = $this->templateVariableContainer->get($iteration);
|
||||
$this->templateVariableContainer->remove($iteration);
|
||||
}
|
||||
|
||||
if ($from === $to) {
|
||||
$content = $this->renderIteration($from, $from, $to, $step, $iteration);
|
||||
} elseif ($from < $to) {
|
||||
for ($i = $from; $i <= $to; $i += $step) {
|
||||
$content .= $this->renderIteration($i, $from, $to, $step, $iteration);
|
||||
}
|
||||
} else {
|
||||
for ($i = $from; $i >= $to; $i += $step) {
|
||||
$content .= $this->renderIteration($i, $from, $to, $step, $iteration);
|
||||
}
|
||||
}
|
||||
|
||||
if (TRUE === isset($backupVariable)) {
|
||||
$this->templateVariableContainer->add($iteration, $backupVariable);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implode ViewHelper
|
||||
*
|
||||
* Implodes an array or array-convertible object by $glue
|
||||
*
|
||||
* @author Claus Due
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class ImplodeViewHelper extends ExplodeViewHelper {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $method = 'implode';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\ViewHelpers\Condition\Iterator\ContainsViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
|
||||
/**
|
||||
* Searches $haystack for index of $needle, returns -1 if $needle
|
||||
* is not in $haystack
|
||||
*
|
||||
* @author Claus Due
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class IndexOfViewHelper extends ContainsViewHelper {
|
||||
|
||||
/**
|
||||
* Render
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
return static::renderStatic(
|
||||
$this->arguments,
|
||||
$this->buildRenderChildrenClosure(),
|
||||
$this->renderingContext
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation for use in compiled templates
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
|
||||
$evaluation = self::assertHaystackHasNeedle($arguments['haystack'], $arguments['needle'], $arguments);
|
||||
|
||||
if (FALSE !== $evaluation) {
|
||||
return intval($evaluation);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Intersects arrays/Traversables $a and $b into an array
|
||||
*
|
||||
* @author Danilo Bürger <danilo.buerger@hmspl.de>, Heimspiel GmbH
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class IntersectViewHelper extends AbstractViewHelper {
|
||||
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
|
||||
$this->registerArgument('a', 'mixed', 'First Array/Traversable/CSV', FALSE, NULL);
|
||||
$this->registerArgument('b', 'mixed', 'Second Array/Traversable/CSV', TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render() {
|
||||
$a = $this->arguments['a'];
|
||||
if (NULL === $a) {
|
||||
$a = $this->renderChildren();
|
||||
}
|
||||
|
||||
$a = $this->arrayFromArrayOrTraversableOrCSV($a);
|
||||
$b = $this->arrayFromArrayOrTraversableOrCSV($this->arguments['b']);
|
||||
|
||||
return array_intersect($a, $b);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\VhsViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Gets keys from an iterator
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @author Stefan Neufeind <info (at) speedpartner.de>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class KeysViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('subject', 'mixed', 'Input to work on - Array/Traversable/...', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render() {
|
||||
$subject = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('subject');
|
||||
$content = array_keys($subject);
|
||||
return $this->renderChildrenWithVariableOrReturnInput($content);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Returns the last element of $haystack
|
||||
*
|
||||
* @author Claus Due
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class LastViewHelper extends AbstractViewHelper {
|
||||
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Initialize arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('haystack', 'mixed', 'Haystack in which to look for needle', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return mixed|NULL
|
||||
*/
|
||||
public function render() {
|
||||
$haystack = $this->arguments['haystack'];
|
||||
if (NULL === $haystack) {
|
||||
$haystack = $this->renderChildren();
|
||||
}
|
||||
$haystack = $this->arrayFromArrayOrTraversableOrCSV($haystack);
|
||||
|
||||
return array_pop($haystack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Repeats rendering of children $count times while updating $iteration
|
||||
*
|
||||
* @author Danilo Bürger <danilo.buerger@hmspl.de>, Heimspiel GmbH
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class LoopViewHelper extends AbstractLoopViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
|
||||
$this->registerArgument('count', 'integer', 'Number of times to render child content', TRUE);
|
||||
$this->registerArgument('minimum', 'integer', 'Minimum number of loops before stopping', FALSE, 0);
|
||||
$this->registerArgument('maximum', 'integer', 'Maxiumum number of loops before stopping', FALSE, PHP_INT_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$count = intval($this->arguments['count']);
|
||||
$minimum = intval($this->arguments['minimum']);
|
||||
$maximum = intval($this->arguments['maximum']);
|
||||
$iteration = $this->arguments['iteration'];
|
||||
$content = '';
|
||||
|
||||
if ($count < $minimum) {
|
||||
$count = $minimum;
|
||||
} elseif ($count > $maximum) {
|
||||
$count = $maximum;
|
||||
}
|
||||
|
||||
if (TRUE === $this->templateVariableContainer->exists($iteration)) {
|
||||
$backupVariable = $this->templateVariableContainer->get($iteration);
|
||||
$this->templateVariableContainer->remove($iteration);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$content .= $this->renderIteration($i, 0, $count, 1, $iteration);
|
||||
}
|
||||
|
||||
if (TRUE === isset($backupVariable)) {
|
||||
$this->templateVariableContainer->add($iteration, $backupVariable);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $i
|
||||
* @param integer $from
|
||||
* @param integer $to
|
||||
* @param integer $step
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isLast($i, $from, $to, $step) {
|
||||
return ($i + $step >= $to);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Merges arrays/Traversables $a and $b into an array
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class MergeViewHelper extends AbstractViewHelper {
|
||||
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('a', 'mixed', 'First array/Traversable - if not set, the ViewHelper can be in a chain (inline-notation)', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges arrays/Traversables $a and $b into an array
|
||||
*
|
||||
* @param mixed $b Second array/Traversable
|
||||
* @param boolean $useKeys If TRUE, comparison is done while also observing (and merging) the keys used in each array
|
||||
* @return array
|
||||
*/
|
||||
public function render($b, $useKeys = TRUE) {
|
||||
$a = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('a');
|
||||
$b = $this->arrayFromArrayOrTraversableOrCSV($b, $useKeys);
|
||||
$merged = $this->mergeArrays($a, $b);
|
||||
return $merged;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\ViewHelpers\Condition\Iterator\ContainsViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
|
||||
/**
|
||||
* Returns next element in array $haystack from position of $needle
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class NextViewHelper extends ContainsViewHelper {
|
||||
|
||||
/**
|
||||
* Render
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
return static::renderStatic(
|
||||
$this->arguments,
|
||||
$this->buildRenderChildrenClosure(),
|
||||
$this->renderingContext
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation for use in compiled templates
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
|
||||
$evaluation = self::assertHaystackHasNeedle($arguments['haystack'], $arguments['needle'], $arguments);
|
||||
return self::getNeedleAtIndex($evaluation !== FALSE ? $evaluation + 1 : -1, $arguments);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Pops the last value off $subject (but does not change $subject itself as array_pop would)
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class PopViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('subject', 'mixed', 'Input to work on - Array/Traversable/...', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function render() {
|
||||
$subject = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('subject');
|
||||
$output = array_pop($subject);
|
||||
return $this->renderChildrenWithVariableOrReturnInput($output);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\ViewHelpers\Condition\Iterator\ContainsViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
|
||||
/**
|
||||
* Returns previous element in array $haystack from position of $needle
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class PreviousViewHelper extends ContainsViewHelper {
|
||||
|
||||
/**
|
||||
* Render
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
return static::renderStatic(
|
||||
$this->arguments,
|
||||
$this->buildRenderChildrenClosure(),
|
||||
$this->renderingContext
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation for use in compiled templates
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
|
||||
$evaluation = self::assertHaystackHasNeedle($arguments['haystack'], $arguments['needle'], $arguments);
|
||||
return self::getNeedleAtIndex($evaluation !== FALSE ? $evaluation - 1 : -1, $arguments);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Returns random element from array
|
||||
*
|
||||
* @author Björn Fromme, <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class RandomViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('subject', 'mixed', 'The subject Traversable/Array instance from which to select a random element', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @throws Exception
|
||||
* @return mixed
|
||||
*/
|
||||
public function render() {
|
||||
$subject = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('subject');
|
||||
$randomElement = $subject[array_rand($subject)];
|
||||
return $this->renderChildrenWithVariableOrReturnInput($randomElement);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* ### Iterator Reversal ViewHelper
|
||||
*
|
||||
* Reverses the order of every member of an Iterator/Array,
|
||||
* preserving the original keys.
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class ReverseViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Initialize arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('subject', 'mixed', 'The input array/Traversable to reverse', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Render" method - sorts a target list-type target. Either $array or
|
||||
* $objectStorage must be specified. If both are, ObjectStorage takes precedence.
|
||||
*
|
||||
* Returns the same type as $subject. Ignores NULL values which would be
|
||||
* OK to use in an f:for (empty loop as result)
|
||||
*
|
||||
* @throws \Exception
|
||||
* @return mixed
|
||||
*/
|
||||
public function render() {
|
||||
$array = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('subject');
|
||||
$array = array_reverse($array, TRUE);
|
||||
return $this->renderChildrenWithVariableOrReturnInput($array);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Shifts the first value off $subject (but does not change $subject itself as array_shift would)
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class ShiftViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Initialize arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('subject', 'mixed', 'The input array/Traversable to shift', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render() {
|
||||
$subject = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('subject');
|
||||
$output = array_shift($subject);
|
||||
return $this->renderChildrenWithVariableOrReturnInput($output);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Slice an Iterator by $start and $length
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class SliceViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Initialize arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('haystack', 'mixed', 'The input array/Traversable to reverse', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @param integer $start
|
||||
* @param integer $length
|
||||
* @return array
|
||||
*/
|
||||
public function render($start = 0, $length = NULL) {
|
||||
$haystack = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('haystack');
|
||||
$output = array_slice($haystack, $start, $length, TRUE);
|
||||
return $this->renderChildrenWithVariableOrReturnInput($output);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\BasicViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Sorts an instance of ObjectStorage, an Iterator implementation,
|
||||
* an Array or a QueryResult (including Lazy counterparts).
|
||||
*
|
||||
* Can be used inline, i.e.:
|
||||
* <f:for each="{dataset -> vhs:iterator.sort(sortBy: 'name')}" as="item">
|
||||
* // iterating data which is ONLY sorted while rendering this particular loop
|
||||
* </f:for>
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class SortViewHelper extends AbstractViewHelper {
|
||||
|
||||
use BasicViewHelperTrait;
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Contains all flags that are allowed to be used
|
||||
* with the sorting functions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $allowedSortFlags = array(
|
||||
'SORT_REGULAR',
|
||||
'SORT_STRING',
|
||||
'SORT_NUMERIC',
|
||||
'SORT_NATURAL',
|
||||
'SORT_LOCALE_STRING',
|
||||
'SORT_FLAG_CASE'
|
||||
);
|
||||
|
||||
/**
|
||||
* Initialize arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('subject', 'mixed', 'The array/Traversable instance to sort', FALSE, NULL);
|
||||
$this->registerArgument('sortBy', 'string', 'Which property/field to sort by - leave out for numeric sorting based on indexes(keys)');
|
||||
$this->registerArgument('order', 'string', 'ASC, DESC, RAND or SHUFFLE. RAND preserves keys, SHUFFLE does not - but SHUFFLE is faster', FALSE, 'ASC');
|
||||
$this->registerArgument('sortFlags', 'string', 'Constant name from PHP for `SORT_FLAGS`: `SORT_REGULAR`, `SORT_STRING`, `SORT_NUMERIC`, `SORT_NATURAL`, `SORT_LOCALE_STRING` or `SORT_FLAG_CASE`. You can provide a comma seperated list or array to use a combination of flags.', FALSE, 'SORT_REGULAR');
|
||||
}
|
||||
|
||||
/**
|
||||
* "Render" method - sorts a target list-type target. Either $array or
|
||||
* $objectStorage must be specified. If both are, ObjectStorage takes precedence.
|
||||
*
|
||||
* Returns the same type as $subject. Ignores NULL values which would be
|
||||
* OK to use in an f:for (empty loop as result)
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function render() {
|
||||
$subject = $this->getArgumentFromArgumentsOrTagContent('subject');
|
||||
$sorted = NULL;
|
||||
if (TRUE === is_array($subject)) {
|
||||
$sorted = $this->sortArray($subject);
|
||||
} else {
|
||||
if (TRUE === $subject instanceof ObjectStorage || TRUE === $subject instanceof LazyObjectStorage) {
|
||||
$sorted = $this->sortObjectStorage($subject);
|
||||
} elseif (TRUE === $subject instanceof \Iterator) {
|
||||
/** @var \Iterator $subject */
|
||||
$array = iterator_to_array($subject, TRUE);
|
||||
$sorted = $this->sortArray($array);
|
||||
} elseif (TRUE === $subject instanceof QueryResultInterface) {
|
||||
/** @var QueryResultInterface $subject */
|
||||
$sorted = $this->sortArray($subject->toArray());
|
||||
} elseif (NULL !== $subject) {
|
||||
// a NULL value is respected and ignored, but any
|
||||
// unrecognized value other than this is considered a
|
||||
// fatal error.
|
||||
throw new \Exception('Unsortable variable type passed to Iterator/SortViewHelper. Expected any of Array, QueryResult, ' .
|
||||
' ObjectStorage or Iterator implementation but got ' . gettype($subject), 1351958941);
|
||||
}
|
||||
}
|
||||
return $this->renderChildrenWithVariableOrReturnInput($sorted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort an array
|
||||
*
|
||||
* @param array|\Iterator $array
|
||||
* @return array
|
||||
*/
|
||||
protected function sortArray($array) {
|
||||
$sorted = array();
|
||||
foreach ($array as $index => $object) {
|
||||
if (TRUE === isset($this->arguments['sortBy'])) {
|
||||
$index = $this->getSortValue($object);
|
||||
}
|
||||
while (isset($sorted[$index])) {
|
||||
$index .= '.1';
|
||||
}
|
||||
$sorted[$index] = $object;
|
||||
}
|
||||
if ('ASC' === $this->arguments['order']) {
|
||||
ksort($sorted, $this->getSortFlags());
|
||||
} elseif ('RAND' === $this->arguments['order']) {
|
||||
$sortedKeys = array_keys($sorted);
|
||||
shuffle($sortedKeys);
|
||||
$backup = $sorted;
|
||||
$sorted = array();
|
||||
foreach ($sortedKeys as $sortedKey) {
|
||||
$sorted[$sortedKey] = $backup[$sortedKey];
|
||||
}
|
||||
} elseif ('SHUFFLE' === $this->arguments['order']) {
|
||||
shuffle($sorted);
|
||||
} else {
|
||||
krsort($sorted, $this->getSortFlags());
|
||||
}
|
||||
return $sorted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort an ObjectStorage instance
|
||||
*
|
||||
* @param ObjectStorage $storage
|
||||
* @return ObjectStorage
|
||||
*/
|
||||
protected function sortObjectStorage($storage) {
|
||||
/** @var ObjectManager $objectManager */
|
||||
$objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
|
||||
/** @var ObjectStorage $temp */
|
||||
$temp = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage');
|
||||
foreach ($storage as $item) {
|
||||
$temp->attach($item);
|
||||
}
|
||||
$sorted = $this->sortArray($storage);
|
||||
$storage = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage');
|
||||
foreach ($sorted as $item) {
|
||||
$storage->attach($item);
|
||||
}
|
||||
return $storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value to use as sorting value from $object
|
||||
*
|
||||
* @param mixed $object
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getSortValue($object) {
|
||||
$field = $this->arguments['sortBy'];
|
||||
$value = ObjectAccess::getPropertyPath($object, $field);
|
||||
if (TRUE === $value instanceof \DateTime) {
|
||||
$value = intval($value->format('U'));
|
||||
} elseif (TRUE === $value instanceof ObjectStorage || TRUE === $value instanceof LazyObjectStorage) {
|
||||
$value = $value->count();
|
||||
} elseif (is_array($value)) {
|
||||
$value = count($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the supplied flags into the proper value for the sorting
|
||||
* function.
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getSortFlags() {
|
||||
$constants = $this->arrayFromArrayOrTraversableOrCSV($this->arguments['sortFlags']);
|
||||
$flags = 0;
|
||||
foreach ($constants as $constant) {
|
||||
if (FALSE === in_array($constant, $this->allowedSortFlags)) {
|
||||
throw new Exception('The constant "' . $constant . '" you\'re trying to use as a sortFlag is not allowed. Allowed constants are: ' . implode(', ', $this->allowedSortFlags) . '.', 1404220538);
|
||||
}
|
||||
$flags = $flags | constant(trim($constant));
|
||||
}
|
||||
return $flags;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Iterator;
|
||||
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2014 Claus Due <claus@namelesscoder.net>
|
||||
*
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\ArrayConsumingViewHelperTrait;
|
||||
use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Gets values from an iterator, removing current keys (if any exist)
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Iterator
|
||||
*/
|
||||
class ValuesViewHelper extends AbstractViewHelper {
|
||||
|
||||
use TemplateVariableViewHelperTrait;
|
||||
use ArrayConsumingViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Initialize arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerAsArgument();
|
||||
$this->registerArgument('subject', 'mixed', 'The array/Traversable instance from which to get values', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function render() {
|
||||
$subject = $this->getArgumentFromArgumentsOrTagContentAndConvertToArray('subject');
|
||||
$output = array_values($subject);
|
||||
return $this->renderChildrenWithVariableOrReturnInput($output);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user