Skip to content

Instantly share code, notes, and snippets.

@jobee
Last active February 14, 2022 08:44
Show Gist options
  • Save jobee/60f2c8de7b5e2de8e5a462fba83075c6 to your computer and use it in GitHub Desktop.
Save jobee/60f2c8de7b5e2de8e5a462fba83075c6 to your computer and use it in GitHub Desktop.
A FlowQuery operation which applies an extra filter to consider parent nodes visibility
<?php
namespace Your\Package\Eel\FlowQueryOperations;
use Neos\ContentRepository\Domain\Projection\Content\TraversableNodeInterface;
use Neos\ContentRepository\Exception\NodeException;
use Neos\Eel\FlowQuery\FlowQuery;
use Neos\Eel\FlowQuery\FlowQueryException;
use Neos\Eel\FlowQuery\Operations\AbstractOperation;
use Neos\Flow\Annotations as Flow;
use Neos\ContentRepository\Domain\Model\NodeInterface;
/**
* FlowQuery operation which applies an extra filter to consider parent nodes visibility
* Why is this needed? The .find(...) operation won't respect parent nodes visibility.
* Use .find(...).considerParentsVisibility() in your Flow query to apply this extra filter.
*/
class ConsiderParentsVisibilityOperation extends AbstractOperation
{
/**
* {@inheritdoc}
*/
protected static $shortName = 'considerParentsVisibility';
/**
* {@inheritdoc}
*/
protected static $priority = 100;
/**
* {@inheritdoc}
*
* We can only handle CR Nodes.
*/
public function canEvaluate($context)
{
return (!isset($context[0]) || ($context[0] instanceof NodeInterface));
}
/**
* {@inheritdoc}
*
* @param array $arguments The arguments for this operation.
*
* @return void
* @throws FlowQueryException
*/
public function evaluate(FlowQuery $flowQuery, array $arguments)
{
if (isset($arguments[0])) {
throw new FlowQueryException('considerParentsVisibility() expects no arguments', 1644566246);
}
$visibleNodes = [];
foreach ($flowQuery->getContext() as $contextNode) {
if ($this->hasInvisibleParent($contextNode))
continue;
$visibleNodes[] = $contextNode;
}
$flowQuery->setContext($visibleNodes);
}
/**
* @param TraversableNodeInterface $contextNode
* @return boolean
*/
protected function hasInvisibleParent(TraversableNodeInterface $contextNode)
{
$node = $contextNode;
$result = false;
do {
try {
$node = $node->findParentNode();
} catch (NodeException $exception) {
// TODO: Remember invisible path to exit do-while as early as possible for subsequent calls
if (!$node->isRoot())
$result = true;
break;
}
} while (true);
return $result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment