Skip to content

Commit

Permalink
FEATURE: Introduce Neos 9 backport of Node access FlowQuery operations
Browse files Browse the repository at this point in the history
  • Loading branch information
mhsdesign committed May 12, 2024
1 parent bf23dff commit 15337f0
Show file tree
Hide file tree
Showing 4 changed files with 291 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
namespace Neos\ContentRepository\Eel\FlowQueryOperations;

/*
* This file is part of the Neos.ContentRepository package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\Eel\FlowQuery\FlowQuery;
use Neos\Eel\FlowQuery\FlowQueryException;
use Neos\Eel\FlowQuery\Operations\AbstractOperation;

/**
* Used to access the Node's identifier of a ContentRepository Node.
*/
class IdOperation extends AbstractOperation
{
/**
* {@inheritdoc}
*
* @var string
*/
protected static $shortName = 'id';

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

/**
* {@inheritdoc}
*
* @var boolean
*/
protected static $final = true;

/**
* {@inheritdoc}
*
* We can only handle ContentRepository Nodes.
*
* @param array<int, mixed> $context $context onto which this operation should be applied (array or array-like object)
* @return boolean
*/
public function canEvaluate($context): bool
{
return (isset($context[0]) && $context[0] instanceof Node);
}

/**
* {@inheritdoc}
*
* @param FlowQuery<int,mixed> $flowQuery the FlowQuery object
* @param array<int,mixed> $arguments the arguments for this operation
* @return mixed
* @throws FlowQueryException
*/
public function evaluate(FlowQuery $flowQuery, array $arguments)
{
if ($arguments !== []) {
throw new FlowQueryException(static::$shortName . '() does not require any argument.', 1715510778);
}
$node = $flowQuery->getContext()[0] ?? null;
if (!$node instanceof Node) {
return null;
}
return $node->nodeAggregateId->value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
namespace Neos\ContentRepository\Eel\FlowQueryOperations;

/*
* This file is part of the Neos.ContentRepository package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\Eel\FlowQuery\FlowQuery;
use Neos\Eel\FlowQuery\FlowQueryException;
use Neos\Eel\FlowQuery\Operations\AbstractOperation;

/**
* Used to access the Node's label of a ContentRepository Node.
*/
class LabelOperation extends AbstractOperation
{
/**
* {@inheritdoc}
*
* @var string
*/
protected static $shortName = 'label';

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

/**
* {@inheritdoc}
*
* @var boolean
*/
protected static $final = true;

/**
* {@inheritdoc}
*
* We can only handle ContentRepository Nodes.
*
* @param array<int, mixed> $context $context onto which this operation should be applied (array or array-like object)
* @return boolean
*/
public function canEvaluate($context): bool
{
return (isset($context[0]) && $context[0] instanceof Node);
}

/**
* {@inheritdoc}
*
* @param FlowQuery<int,mixed> $flowQuery the FlowQuery object
* @param array<int,mixed> $arguments the arguments for this operation
* @return mixed
* @throws FlowQueryException
*/
public function evaluate(FlowQuery $flowQuery, array $arguments)
{
if ($arguments !== []) {
throw new FlowQueryException(static::$shortName . '() does not require any argument.', 1715510778);
}
$node = $flowQuery->getContext()[0] ?? null;
if (!$node instanceof Node) {
return null;
}
return $node->getLabel();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
namespace Neos\ContentRepository\Eel\FlowQueryOperations;

/*
* This file is part of the Neos.ContentRepository package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Eel\FlowQuery\FlowQuery;
use Neos\Eel\FlowQuery\FlowQueryException;
use Neos\Eel\FlowQuery\Operations\AbstractOperation;
use Neos\Flow\Annotations as Flow;
use Neos\Neos\Domain\Service\NodeTypeNameFactory;

/**
* Used to access the NodeTypeName of a ContentRepository Node.
*/
class NodeTypeNameOperation extends AbstractOperation
{
/**
* {@inheritdoc}
*
* @var string
*/
protected static $shortName = 'nodeTypeName';

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

/**
* {@inheritdoc}
*
* @var boolean
*/
protected static $final = true;

/**
* @Flow\Inject
*/
protected ContentRepositoryRegistry $contentRepositoryRegistry;

/**
* {@inheritdoc}
*
* We can only handle ContentRepository Nodes.
*
* @param array<int, mixed> $context $context onto which this operation should be applied (array or array-like object)
* @return boolean
*/
public function canEvaluate($context): bool
{
return (isset($context[0]) && $context[0] instanceof Node);
}

/**
* {@inheritdoc}
*
* @param FlowQuery<int,mixed> $flowQuery the FlowQuery object
* @param array<int,mixed> $arguments the arguments for this operation
* @return mixed
* @throws FlowQueryException
*/
public function evaluate(FlowQuery $flowQuery, array $arguments)
{
if ($arguments !== []) {
throw new FlowQueryException(static::$shortName . '() does not require any argument.', 1715510778);
}
$node = $flowQuery->getContext()[0] ?? null;
if (!$node instanceof Node) {
return null;
}

$contentRepository = $this->contentRepositoryRegistry->get($node->subgraphIdentity->contentRepositoryId);

return $contentRepository->getNodeTypeManager()->hasNodeType($node->nodeTypeName)
? $node->nodeType->name
: NodeTypeNameFactory::forFallback()->value;
}
}
47 changes: 47 additions & 0 deletions Neos.Neos/Tests/Behavior/Features/Fusion/FlowQuery.feature
Original file line number Diff line number Diff line change
Expand Up @@ -395,3 +395,50 @@ Feature: Tests for the "Neos.ContentRepository" Flow Query methods.
removeNode: a
nothingToRemove: a1a4,a1a4,a1a4
"""

Scenario: Node accessors (final Node access operations)
When the Fusion context node is "a1"
When I execute the following Fusion code:
"""fusion
test = Neos.Fusion:DataStructure {
property = ${q(node).property('title')}
identifier = ${q(node).id()}
label = ${q(node).label()}
nodeTypeName = ${q(node).nodeTypeName()}
@process.render = ${Json.stringify(value, ['JSON_PRETTY_PRINT'])}
}
"""
Then I expect the following Fusion rendering result:
"""
{
"property": "Node a1",
"identifier": "a1",
"label": "Neos.Neos:Test.DocumentType1 (a1)",
"nodeTypeName": "Neos.Neos:Test.DocumentType1"
}
"""
# changing the node type config will invoke the Neos.Neos:FallbackNode handling
When I have the following NodeTypes configuration:
"""yaml
'unstructured': {}
'Neos.Neos:FallbackNode': {}
"""
When I execute the following Fusion code:
"""fusion
test = Neos.Fusion:DataStructure {
property = ${q(node).property('title')}
identifier = ${q(node).id()}
label = ${q(node).label()}
nodeTypeName = ${q(node).nodeTypeName()}
@process.render = ${Json.stringify(value, ['JSON_PRETTY_PRINT'])}
}
"""
Then I expect the following Fusion rendering result:
"""
{
"property": "Node a1",
"identifier": "a1",
"label": "Neos.Neos:FallbackNode (a1)",
"nodeTypeName": "Neos.Neos:FallbackNode"
}
"""

0 comments on commit 15337f0

Please sign in to comment.