Skip to content

Commit

Permalink
FEATURE: References on creation and Copy
Browse files Browse the repository at this point in the history
This reworks references so that multiple reference properties can be
set via a single command and also references can be attached to
`CreateNodeAggregateWithNode` which is also used for copying nodes.
  • Loading branch information
kitsunet committed Jun 17, 2024
1 parent 3450b04 commit 1ee4c27
Show file tree
Hide file tree
Showing 46 changed files with 638 additions and 518 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ Feature: Run integrity violation detection regarding reference relations
| Key | Value |
| sourceOriginDimensionSpacePoint | {"language":"de"} |
| sourceNodeAggregateId | "source-nodandaise" |
| referenceName | "referenceProperty" |
| references | [{"target": "anthony-destinode"}] |
| references | {"referenceProperty": [{"target": "anthony-destinode"}]} |
And I detach the following reference relation from its source:
| Key | Value |
| contentStreamId | "cs-identifier" |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
use Neos\ContentRepository\Core\Feature\NodeModification\Dto\SerializedPropertyValues;
use Neos\ContentRepository\Core\Feature\NodeModification\Event\NodePropertiesWereSet;
use Neos\ContentRepository\Core\Feature\NodeMove\Event\NodeAggregateWasMoved;
use Neos\ContentRepository\Core\Feature\NodeReferencing\Dto\NodeReferenceNameToEmpty;
use Neos\ContentRepository\Core\Feature\NodeReferencing\Dto\SerializedNodeReference;
use Neos\ContentRepository\Core\Feature\NodeReferencing\Dto\SerializedNodeReferences;
use Neos\ContentRepository\Core\Feature\NodeReferencing\Event\NodeReferencesWereSet;
use Neos\ContentRepository\Core\Feature\NodeRemoval\Event\NodeAggregateWasRemoved;
use Neos\ContentRepository\Core\Feature\NodeRenaming\Event\NodeAggregateNameWasChanged;
Expand Down Expand Up @@ -434,6 +436,7 @@ private function whenNodeAggregateWithNodeWasCreated(NodeAggregateWithNodeWasCre
$event->originDimensionSpacePoint,
$event->succeedingSiblingsForCoverage,
$event->initialPropertyValues,
$event->nodeReferences,
$event->nodeAggregateClassification,
$event->nodeName,
$eventEnvelope,
Expand Down Expand Up @@ -520,40 +523,52 @@ function (NodeRecord $node) use ($eventEnvelope) {
);

// remove old
try {
$this->dbal->delete($this->tableNames->referenceRelation(), [
'nodeanchorpoint' => $nodeAnchorPoint?->value,
'name' => $event->referenceName->value
]);
} catch (DbalException $e) {
throw new \RuntimeException(sprintf('Failed to remove reference relation: %s', $e->getMessage()), 1716486309, $e);
}

// set new
$position = 0;
/** @var SerializedNodeReference $reference */
foreach ($event->references as $reference) {
$referencePropertiesJson = null;
if ($reference->properties !== null) {
try {
$referencePropertiesJson = \json_encode($reference->properties, JSON_THROW_ON_ERROR | JSON_FORCE_OBJECT);
} catch (\JsonException $e) {
throw new \RuntimeException(sprintf('Failed to JSON-encode reference properties: %s', $e->getMessage()), 1716486271, $e);
}
}
foreach ($event->references->getReferenceNames() as $referenceName) {
try {
$this->dbal->insert($this->tableNames->referenceRelation(), [
'name' => $event->referenceName->value,
'position' => $position,
$this->dbal->delete($this->tableNames->referenceRelation(), [
'nodeanchorpoint' => $nodeAnchorPoint?->value,
'destinationnodeaggregateid' => $reference->targetNodeAggregateId->value,
'properties' => $referencePropertiesJson,
'name' => $referenceName->value
]);
} catch (DbalException $e) {
throw new \RuntimeException(sprintf('Failed to insert reference relation: %s', $e->getMessage()), 1716486309, $e);
throw new \RuntimeException(sprintf('Failed to remove reference relation: %s', $e->getMessage()), 1716486309, $e);
}
}

// set new
$nodeAnchorPoint && $this->writeReferencesForTargetAnchorPoint($event->references, $nodeAnchorPoint);
}
}

private function writeReferencesForTargetAnchorPoint(SerializedNodeReferences $nodeReferences, NodeRelationAnchorPoint $nodeAnchorPoint): void
{
$position = 0;
/** @var NodeReferenceNameToEmpty|SerializedNodeReference $reference */
foreach ($nodeReferences as $reference) {
if ($reference instanceof NodeReferenceNameToEmpty) {
// Reference empty happens separately
continue;
}

$referencePropertiesJson = null;
if ($reference->properties !== null && $reference->properties->count() > 0) {
try {
$referencePropertiesJson = \json_encode($reference->properties, JSON_THROW_ON_ERROR | JSON_FORCE_OBJECT);
} catch (\JsonException $e) {
throw new \RuntimeException(sprintf('Failed to JSON-encode reference properties: %s', $e->getMessage()), 1716486271, $e);
}
$position++;
}
try {
$this->dbal->insert($this->tableNames->referenceRelation(), [
'name' => $reference->referenceName->value,
'position' => $position,
'nodeanchorpoint' => $nodeAnchorPoint?->value,
'destinationnodeaggregateid' => $reference->targetNodeAggregateId->value,
'properties' => $referencePropertiesJson,
]);
} catch (DbalException $e) {
throw new \RuntimeException(sprintf('Failed to insert reference relation: %s', $e->getMessage()), 1716486309, $e);
}
$position++;
}
}

Expand Down Expand Up @@ -779,6 +794,7 @@ private function createNodeWithHierarchy(
OriginDimensionSpacePoint $originDimensionSpacePoint,
InterdimensionalSiblings $coverageSucceedingSiblings,
SerializedPropertyValues $propertyDefaultValuesAndTypes,
SerializedNodeReferences $references,
NodeAggregateClassification $nodeAggregateClassification,
?NodeName $nodeName,
EventEnvelope $eventEnvelope,
Expand Down Expand Up @@ -834,6 +850,8 @@ private function createNodeWithHierarchy(
}
}
}

$this->writeReferencesForTargetAnchorPoint($references, $node->relationAnchorPoint);
}

private function connectHierarchy(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use Neos\ContentRepository\Core\Feature\ContentStreamForking\Command\ForkContentStream;
use Neos\ContentRepository\Core\Feature\NodeCreation\Event\NodeAggregateWithNodeWasCreated;
use Neos\ContentRepository\Core\Feature\NodeModification\Dto\SerializedPropertyValues;
use Neos\ContentRepository\Core\Feature\NodeReferencing\Dto\SerializedNodeReferences;
use Neos\ContentRepository\Core\Feature\RootNodeCreation\Event\RootNodeAggregateWithNodeWasCreated;
use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Command\CreateRootWorkspace;
use Neos\ContentRepository\Core\NodeType\NodeTypeName;
Expand Down Expand Up @@ -142,6 +143,7 @@ private function createHierarchy(
null,
SerializedPropertyValues::createEmpty(),
NodeAggregateClassification::CLASSIFICATION_REGULAR,
SerializedNodeReferences::createEmpty(),
);
$sumSoFar++;
$this->createHierarchy(
Expand Down
Loading

0 comments on commit 1ee4c27

Please sign in to comment.