Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Improve Node and Node interfaces rewrites #95

Merged
merged 4 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion config/set/contentrepository-90.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@
use Neos\Rector\ContentRepository90\Rules\NodeGetDepthRector;
use Neos\Rector\ContentRepository90\Rules\NodeGetDimensionsRector;
use Neos\Rector\ContentRepository90\Rules\NodeGetIdentifierRector;
use Neos\Rector\ContentRepository90\Rules\NodeGetNodeTypeGetNameRector;
use Neos\Rector\ContentRepository90\Rules\NodeGetNodeTypeRector;
use Neos\Rector\ContentRepository90\Rules\NodeGetParentRector;
use Neos\Rector\ContentRepository90\Rules\NodeGetPathRector;
use Neos\Rector\ContentRepository90\Rules\NodeGetPropertyNamesRector;
use Neos\Rector\ContentRepository90\Rules\NodeIsHiddenInIndexRector;
use Neos\Rector\ContentRepository90\Rules\NodeIsHiddenRector;
use Neos\Rector\ContentRepository90\Rules\NodeLabelGeneratorRector;
Expand Down Expand Up @@ -89,12 +92,14 @@
$services->set(\Neos\Rector\Core\YamlProcessing\YamlFileProcessor::class);
$rectorConfig->disableParallel(); // parallel does not work for non-PHP-Files, so we need to disable it - see https://github.com/rectorphp/rector-src/pull/2597#issuecomment-1190120688

$rectorConfig->autoloadPaths([__DIR__ . '/../../src/ContentRepository90/Legacy']);

$rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
\Neos\ContentRepository\Domain\Model\Node::class => NodeLegacyStub::class,
\Neos\ContentRepository\Domain\Model\NodeInterface::class => NodeLegacyStub::class,
\Neos\ContentRepository\Domain\Projection\Content\NodeInterface::class => NodeLegacyStub::class,
\Neos\ContentRepository\Domain\Projection\Content\TraversableNodeInterface::class => NodeLegacyStub::class,

\Neos\ContentRepository\Domain\Projection\Content\TraversableNodes::class => \Neos\ContentRepository\Core\Projection\ContentGraph\Nodes::class,

\Neos\ContentRepository\Domain\Service\Context::class => LegacyContextStub::class,
Expand Down Expand Up @@ -136,27 +141,35 @@
* Neos\ContentRepository\Domain\Model\NodeInterface
*/
// setName
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'setName', '!! Node::setName() is not supported by the new CR. Use the "ChangeNodeAggregateName" command to change the node name.');
// getName
$methodCallToPropertyFetches[] = new MethodCallToPropertyFetch(NodeLegacyStub::class, 'getName', 'nodeName');
$fusionFlowQueryPropertyToComments[] = new FusionFlowQueryNodePropertyToWarningComment('_name', 'Line %LINE: !! You very likely need to rewrite "q(VARIABLE).property("_name")" to "VARIABLE.nodeName". We did not auto-apply this migration because we cannot be sure whether the variable is a Node.');
// getLabel
$rectorConfig->rule(FusionNodeLabelRector::class);
$rectorConfig->rule(NodeLabelGeneratorRector::class);
// setProperty
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'setProperty', '!! Node::setProperty() is not supported by the new CR. Use the "SetNodeProperties" command to change property values.');
// hasProperty -> compatible with ES CR Node (nothing to do)
// getProperty -> compatible with ES CR Node (nothing to do)
// removeProperty
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'removeProperty', '!! Node::setProperty() is not supported by the new CR. Use the "SetNodeProperties" command to remove a property values.');
// getProperties -> PropertyCollectionInterface
$methodCallToPropertyFetches[] = new MethodCallToPropertyFetch(NodeLegacyStub::class, 'getProperties', 'properties');
// getPropertyNames
$rectorConfig->rule(NodeGetPropertyNamesRector::class);
// setContentObject -> DEPRECATED / NON-FUNCTIONAL
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'setContentObject', '!! Node::setContentObject() is not supported by the new CR. Referencing objects can be done by storing them in Node::properties (and the serialization/deserialization is extensible).');
// getContentObject -> DEPRECATED / NON-FUNCTIONAL
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'getContentObject', '!! Node::getContentObject() is not supported by the new CR. Referencing objects can be done by storing them in Node::properties (and the serialization/deserialization is extensible).');
// unsetContentObject -> DEPRECATED / NON-FUNCTIONAL
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'unsetContentObject', '!! Node::unsetContentObject() is not supported by the new CR. Referencing objects can be done by storing them in Node::properties (and the serialization/deserialization is extensible).');
// setNodeType
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'setNodeType', '!! Node::setNodeType() is not supported by the new CR. Use the "ChangeNodeAggregateType" command to change nodetype.');
// getNodeType: NodeType
// PHP: shortcut to Node->nodeTypeName->value
$rectorConfig->rule(NodeGetNodeTypeGetNameRector::class);
$rectorConfig->rule(NodeGetNodeTypeRector::class);
// Fusion: node.nodeType -> Neos.Node.nodeType(node)
// Fusion: node.nodeType.name -> node.nodeTypeName
$rectorConfig->rule(FusionNodeNodeTypeRector::class);
Expand All @@ -176,6 +189,7 @@
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'getHiddenAfterDateTime', '!! Node::getHiddenAfterDateTime() is not supported by the new CR. Timed publishing will be implemented not on the read model, but by dispatching commands at a given time.');
$rectorConfig->rule(FusionNodeHiddenAfterDateTimeRector::class);
// setHiddenInIndex
$methodCallToWarningComments[] = new MethodCallToWarningComment(NodeLegacyStub::class, 'setHiddenInIndex', '!! Node::setHiddenInIndex() is not supported by the new CR. Use the "SetNodeProperties" command to change the property value for "hiddenInMenu".');
// isHiddenInIndex
$rectorConfig->rule(NodeIsHiddenInIndexRector::class);
// Fusion: .hiddenInIndex -> node.properties._hiddenInIndex
Expand Down Expand Up @@ -462,7 +476,9 @@

// We can only add one rule per class name. As workaround, we need to alias the RenameClassRector, so we are able to
// add this rule twice.
class_alias(RenameClassRector::class, \Alias\RenameClassRectorLegacy::class);
if (!class_exists(\Alias\RenameClassRectorLegacy::class)){
class_alias(RenameClassRector::class, \Alias\RenameClassRectorLegacy::class);
}
$rectorConfig->ruleWithConfiguration(\Alias\RenameClassRectorLegacy::class, [
NodeLegacyStub::class => Node::class,
]);
Expand Down
106 changes: 92 additions & 14 deletions docs/rules_overview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 58 Rules Overview
# 61 Rules Overview

## ContentDimensionCombinatorGetAllAllowedCombinationsRector

Expand Down Expand Up @@ -1319,7 +1319,7 @@ return static function (RectorConfig $rectorConfig): void {
{
- $parentNode = $node->findParentNode();
+ $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
+ $parentNode = $subgraph->findParentNode($node->nodeAggregateId);
+ $parentNode = $subgraph->findParentNode($node->aggregateId);
}
}

Expand Down Expand Up @@ -1347,7 +1347,7 @@ return static function (RectorConfig $rectorConfig): void {
+ $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
+ // TODO 9.0 migration: Try to remove the iterator_to_array($nodes) call.
+
+ foreach (iterator_to_array($subgraph->findChildNodes($node->nodeAggregateId, \Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter::create(pagination: ['limit' => 10, 'offset' => 100]))) as $node) {
+ foreach (iterator_to_array($subgraph->findChildNodes($node->aggregateId, \Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter::create(pagination: ['limit' => 10, 'offset' => 100]))) as $node) {
}
}
}
Expand Down Expand Up @@ -1426,7 +1426,7 @@ return static function (RectorConfig $rectorConfig): void {
{
- return $node->getDepth();
+ $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
+ return $subgraph->findNodePath($node->nodeAggregateId)->getDepth();
+ return $subgraph->findNodePath($node->aggregateId)->getDepth();
}
}

Expand Down Expand Up @@ -1480,7 +1480,62 @@ return static function (RectorConfig $rectorConfig): void {
- $nodeIdentifier = $node->getIdentifier();
+ // TODO 9.0 migration: Check if you could change your code to work with the NodeAggregateId value object instead.
+
+ $nodeIdentifier = $node->nodeAggregateId->value;
+ $nodeIdentifier = $node->aggregateId->value;
}
}

?>
```

<br>

## NodeGetNodeTypeGetNameRector

`"NodeInterface::getNodeType()->getName()"` will be rewritten

- class: [`Neos\Rector\ContentRepository90\Rules\NodeGetNodeTypeGetNameRector`](../src/ContentRepository90/Rules/NodeGetNodeTypeGetNameRector.php)

```diff
<?php

use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

class SomeClass
{
public function run(NodeLegacyStub $node)
{
$nodeType = $node->getNodeType();
$nodeTypeName = $nodeType->getName();

- $nodeTypeName = $node->getNodeType()->getName();
+ $nodeTypeName = $node->nodeTypeName->value;
}
}

?>
```

<br>

## NodeGetNodeTypeRector

`"NodeInterface::getNodeType()"` will be rewritten

- class: [`Neos\Rector\ContentRepository90\Rules\NodeGetNodeTypeRector`](../src/ContentRepository90/Rules/NodeGetNodeTypeRector.php)

```diff
<?php

use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

class SomeClass
{
public function run(NodeLegacyStub $node)
{
- $nodeType = $node->getNodeType();
+ // TODO 9.0 migration: Make this code aware of multiple Content Repositories.
+ $contentRepository = $this->contentRepositoryRegistry->get(\Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId::fromString('default'));
+ $nodeType = $contentRepository->getNodeTypeManager()->getNodeType($node->nodeTypeName);
dlubitz marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand All @@ -1506,7 +1561,7 @@ return static function (RectorConfig $rectorConfig): void {
{
- return $node->getParent();
+ $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
+ return $subgraph->findParentNode($node->nodeAggregateId);
+ return $subgraph->findParentNode($node->aggregateId);
}
}

Expand Down Expand Up @@ -1534,7 +1589,32 @@ return static function (RectorConfig $rectorConfig): void {
+ $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
+ // TODO 9.0 migration: Try to remove the (string) cast and make your code more type-safe.
+
+ return (string) $subgraph->findNodePath($node->nodeAggregateId);
+ return (string) $subgraph->findNodePath($node->aggregateId);
}
}

?>
```

<br>

## NodeGetPropertyNamesRector

"$nodeType->allowsGrandchildNodeType($parentNodeName, `$nodeType)"` will be rewritten.

- class: [`Neos\Rector\ContentRepository90\Rules\NodeGetPropertyNamesRector`](../src/ContentRepository90/Rules/NodeGetPropertyNamesRector.php)

```diff
<?php

use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

class SomeClass
{
public function run(NodeLegacyStub $node)
{
- $propertyNames = $node->getPropertyNames();
+ $propertyNames = array_keys(iterator_to_array($node->properties));
}
}

Expand Down Expand Up @@ -1645,7 +1725,7 @@ return static function (RectorConfig $rectorConfig): void {
+ $contentRepository = $this->contentRepositoryRegistry->get(\Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId::fromString('default'));

- $grandParentsNodeType->allowsGrandchildNodeType($parentNodeName, $nodeType);
+ $contentRepository->getNodeTypeManager()->isNodeTypeAllowedAsChildToTetheredNode($grandParentsNodeType, \Neos\ContentRepository\Core\SharedModel\Node\NodeName::fromString($parentNodeName), $nodeType);
+ $contentRepository->getNodeTypeManager()->isNodeTypeAllowedAsChildToTetheredNode($grandParentsNodeType->name, \Neos\ContentRepository\Core\SharedModel\Node\NodeName::fromString($parentNodeName), $nodeType->name);
}
}

Expand All @@ -1667,15 +1747,13 @@ return static function (RectorConfig $rectorConfig): void {

class SomeClass
{
+ #[\Neos\Flow\Annotations\Inject]
+ protected \Neos\ContentRepositoryRegistry\ContentRepositoryRegistry $contentRepositoryRegistry;
public function run(NodeLegacyStub $node)
{
$nodeType = $node->getNodeType();
- $childNodes = $nodeType->getAutoCreatedChildNodes();
+ // TODO 9.0 migration: Make this code aware of multiple Content Repositories.
+ $contentRepository = $this->contentRepositoryRegistry->get(\Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId::fromString('default'));
+ $childNodes = $contentRepository->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType);
+ // TODO 9.0 migration: NodeType::tetheredNodeTypeDefinitions() is not a 1:1 replacement of NodeType::getAutoCreatedChildNodes(). You need to change your code to work with new TetheredNodeTypeDefinition object.
+
+ $childNodes = $nodeType->tetheredNodeTypeDefinitions;
}
}

Expand Down Expand Up @@ -1732,7 +1810,7 @@ return static function (RectorConfig $rectorConfig): void {
- $type = $nodeType->getTypeOfAutoCreatedChildNode($nodeName);
+ // TODO 9.0 migration: Make this code aware of multiple Content Repositories.
+ $contentRepository = $this->contentRepositoryRegistry->get(\Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId::fromString('default'));
+ $type = $contentRepository->getNodeTypeManager()->getTypeOfTetheredNode($nodeType, $nodeName);
+ $type = $contentRepository->getNodeTypeManager()->getNodeType($nodeType->tetheredNodeTypeDefinitions->get($nodeName));
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/ContentRepository90/Legacy/Node.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Neos\ContentRepository\Domain\Model;

use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

/**
* @deprecated
*/
class Node extends NodeLegacyStub
{

}
13 changes: 13 additions & 0 deletions src/ContentRepository90/Legacy/NodeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Neos\ContentRepository\Domain\Model;

use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

/**
* @deprecated
*/
class NodeInterface extends NodeLegacyStub
{

}
29 changes: 29 additions & 0 deletions src/ContentRepository90/Legacy/NodeLegacyStub.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
namespace Neos\Rector\ContentRepository90\Legacy;

use Neos\ContentRepository\Core\NodeType\NodeType;
use Neos\ContentRepository\Domain\NodeAggregate\NodeName;
use Neos\ContentRepository\Domain\NodeType\NodeTypeConstraints;
use Neos\ContentRepository\Domain\Projection\Content\TraversableNodes;

/**
* @deprecated
Expand All @@ -21,4 +24,30 @@ public function getNodeType(): NodeType {
public function getParent(): NodeLegacyStub {
return new NodeLegacyStub();
}

public function findParentNode(): NodeLegacyStub {
return new NodeLegacyStub();
}

public function findNamedChildNode(NodeName $nodeName): NodeLegacyStub
{
return new NodeLegacyStub();
}

public function getNode(): NodeLegacyStub {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this thing contains the signature of the original node interface and some of the "forward compatible" changes of the traversable thing ... but this is just a helper during running the migration right? These methods like all the find* and get* would be the todo to be migrated right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, correct. This is just to enable rector to determine the return type of methods, which not exists anymore.

return new NodeLegacyStub();
}

public function findChildNodes(NodeTypeConstraints $nodeTypeConstraints = null, int $limit = null, int $offset = null): TraversableNodes {
return new TraversableNodes();
}

public function findReferencedNodes(): TraversableNodes {
return new TraversableNodes();
}

public function findNamedReferencedNodes(PropertyName $edgeName): TraversableNodes {
return new TraversableNodes();
}

}
13 changes: 13 additions & 0 deletions src/ContentRepository90/Legacy/TraversableNodeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Neos\ContentRepository\Domain\Projection\Content;

use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;

/**
* @deprecated
*/
class TraversableNodeInterface extends NodeLegacyStub
{

}
27 changes: 27 additions & 0 deletions src/ContentRepository90/Legacy/TraversableNodes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Neos\ContentRepository\Domain\Projection\Content;

use Neos\ContentRepository\Domain\Projection\Content\TraversableNodeInterface;
use Neos\Rector\ContentRepository90\Legacy\NodeLegacyStub;
use Traversable;

/**
* @implements \IteratorAggregate<int, TraversableNodeInterface>
* @deprecated
*/
class TraversableNodes implements \IteratorAggregate, \Countable
{

/**
* @return TraversableNodeInterface[]|\ArrayIterator<TraversableNodeInterface>
*/
public function getIterator(): Traversable
{
return new \ArrayIterator();
}

public function count(): int
{
}
}
Loading
Loading