Last active
February 14, 2022 08:44
-
-
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
This file contains hidden or 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 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