Skip to content

Instantly share code, notes, and snippets.

@Sebobo
Created April 6, 2015 18:46
Show Gist options
  • Save Sebobo/cc337fc7733fb11d05fa to your computer and use it in GitHub Desktop.
Save Sebobo/cc337fc7733fb11d05fa to your computer and use it in GitHub Desktop.
Sortoperation for nodes in TYPO3 Neos
<?php
namespace Vendor\Package\TypoScript\FlowQueryOperations;
/* *
* This script belongs to the TYPO3 Flow package "Vendor.Package". *
* *
* It is free software; you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License, either version 3 *
* of the License, or (at your option) any later version. *
* *
* The TYPO3 project - inspiring people to share! *
* */
use TYPO3\Eel\FlowQuery\Operations\AbstractOperation;
use TYPO3\Flow\Annotations as Flow;
use TYPO3\TYPO3CR\Domain\Model\NodeInterface;
use TYPO3\Eel\FlowQuery\FlowQuery;
/**
* Sort operation to sort nodes by their position in the node tree
*
* Use it like this:
*
* ${q(node).children().sortRecursive(['ASC'|'DESC'])}
*/
class SortRecursiveOperation extends AbstractOperation {
/**
* {@inheritdoc}
*
* @var string
*/
static protected $shortName = 'sortRecursive';
/**
* {@inheritdoc}
*
* @var integer
*/
static protected $priority = 100;
/**
* {@inheritdoc}
*
* We can only handle TYPO3CR Nodes.
*
* @param mixed $context
* @return boolean
*/
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];
}
$getIndexPath = function(NodeInterface $node) {
$indexPath = array($node->getIndex());
while ($node = $node->getParent()) {
$indexPath[]= $node->getIndex();
}
return $indexPath;
};
$cmpIndex = function(NodeInterface $a, NodeInterface $b) use ($getIndexPath) {
if ($a == $b) {
return 0;
}
// Compare index path backwards until a difference is found
$aIndexPath = $getIndexPath($a);
$bIndexPath = $getIndexPath($b);
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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment