Skip to content

Commit

Permalink
Merge pull request #14 from Sebobo/SortRecursiveByIndex
Browse files Browse the repository at this point in the history
Add recursive flowquery operation to sort nodes by their index
  • Loading branch information
dimaip committed Mar 9, 2016
2 parents d98ad52 + 002f2d7 commit db56b66
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use TYPO3\TYPO3CR\Domain\Model\NodeInterface;

/**
* EEL sort() operation to sort Nodes
* FlowQuery operation to filter Nodes by a date property
*/
class FilterByDateOperation extends AbstractOperation
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use TYPO3\TYPO3CR\Domain\Model\NodeInterface;

/**
* EEL sort() operation to sort Nodes
* FlowQuery operation to sort Nodes by a property
*/
class SortOperation extends AbstractOperation
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php
namespace Flowpack\Listable\TypoScript\Eel\FlowQueryOperations;

/* *
* This script belongs to the Flow package "Flowpack.Listable". *
* */

use TYPO3\Flow\Annotations as Flow;
use TYPO3\TYPO3CR\Domain\Model\NodeInterface;
use TYPO3\Eel\FlowQuery\FlowQuery;
use TYPO3\Eel\FlowQuery\Operations\AbstractOperation;

/**
* Sort Nodes by their position in the node tree.
*
* Use it like this:
*
* ${q(node).children().sortRecursive(['ASC'|'DESC'])}
*/
class SortRecursiveByIndexOperation extends AbstractOperation
{
/**
* {@inheritdoc}
*
* @var string
*/
protected static $shortName = 'sortRecursiveByIndex';

/**
* {@inheritdoc}
*
* @var int
*/
protected static $priority = 100;

/**
* {@inheritdoc}
*
* We can only handle TYPO3CR Nodes.
*
* @param mixed $context
*
* @return bool
*/
public function canEvaluate($context)
{
return (isset($context[0]) && ($context[0] instanceof NodeInterface));
}

/**
* {@inheritdoc}
*
* @param FlowQuery $flowQuery the FlowQuery object
* @param array $arguments the arguments for this operation
*
* @return mixed
*/
public function evaluate(FlowQuery $flowQuery, array $arguments)
{
$nodes = $flowQuery->getContext();

$sortOrder = 'ASC';
if (isset($arguments[0]) && !empty($arguments[0]) && in_array($arguments[0], array('ASC', 'DESC'))) {
$sortOrder = $arguments[0];
}

$indexPathCache = [];

/** @var NodeInterface $node */
foreach ($nodes as $node) {
// Collect the list of sorting indices for all parents of the node and the node itself
$nodeIdentifier = $node->getIdentifier();
$indexPath = array($node->getIndex());
while ($node = $node->getParent()) {
$indexPath[] = $node->getIndex();
}
$indexPathCache[$nodeIdentifier] = $indexPath;
}

$cmpIndex = function (NodeInterface $a, NodeInterface $b) use ($indexPathCache) {
if ($a == $b) {
return 0;
}

// Compare index path starting from the site root until a difference is found
$aIndexPath = $indexPathCache[$a->getIdentifier()];
$bIndexPath = $indexPathCache[$b->getIdentifier()];
while (count($aIndexPath) > 0 && count($bIndexPath) > 0) {
$diff = (array_pop($aIndexPath) - array_pop($bIndexPath));
if ($diff !== 0) {
return $diff < 0 ? -1 : 1;
}
}

return 0;
};

usort($nodes, $cmpIndex);

if ($sortOrder === 'DESC') {
$nodes = array_reverse($nodes);
}

$flowQuery->setContext($nodes);
}
}
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,29 @@ [email protected] = ${request.pluginArguments.listable-pagi
```

To make urls pretty, see [Routes.yaml](https://github.com/flowpack/Flowpack.Listable/blob/master/Configuration/Routes.yaml).

# Helper FlowQueries you can use

## filterByDate

Filter nodes by properties of type date

## filterByReference

Filter nodes by properties of type reference or references

## sort

Sort nodes by any property

Example:

${q(site).find('[instanceof TYPO3.Neos:Document]').sort('title', ['ASC'|'DESC']).get()}

## sortRecursiveByIndex

Sort nodes recursively by their sorting property.

Example:

${q(site).find('[instanceof TYPO3.Neos:Document]').sortRecursiveByIndex(['ASC'|'DESC']).get()}

0 comments on commit db56b66

Please sign in to comment.