Skip to content

Commit

Permalink
TASK: Adjust to split up references and properties
Browse files Browse the repository at this point in the history
  • Loading branch information
mhsdesign authored and markusguenther committed Dec 16, 2023
1 parent 112813d commit 50d6e20
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 80 deletions.
42 changes: 19 additions & 23 deletions Classes/Domain/Model/Changes/Property.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,8 @@ public function canApply(): bool
}
$nodeType = $this->subject->nodeType;
$propertyName = $this->getPropertyName();
$nodeTypeProperties = $nodeType->getProperties();

return isset($nodeTypeProperties[$propertyName]);
return $nodeType->hasProperty($propertyName) || $nodeType->hasReference($propertyName);
}

/**
Expand All @@ -153,26 +152,16 @@ public function apply(): void
if ($this->canApply() && !is_null($subject) && !is_null($propertyName)) {
$contentRepository = $this->contentRepositoryRegistry->get($subject->subgraphIdentity->contentRepositoryId);

$propertyType = $this->getNodeType($subject)->getPropertyType($propertyName);

// Use extra commands for reference handling
if ($propertyType === 'reference' || $propertyType === 'references') {
if ($this->getNodeType($subject)->hasReference($propertyName)) {
// Use extra commands for reference handling
$value = $this->getValue();

$destinationNodeAggregateIds = [];
if ($propertyType === 'reference') {
if (is_string($value) && !empty($value)) {
$destinationNodeAggregateIds[] = $value;
}
}

if ($propertyType === 'references') {
/** @var array<int,string> $values */
$values = $value;
if (is_array($values)) {
foreach ($values as $singleNodeAggregateId) {
$destinationNodeAggregateIds[] = $singleNodeAggregateId;
}
}
if (is_string($value) && !empty($value)) {
$destinationNodeAggregateIds = [$value];
} elseif (is_array($value)) {
$destinationNodeAggregateIds = $value;
}

$commandResult = $contentRepository->handle(
Expand Down Expand Up @@ -278,8 +267,12 @@ public function apply(): void
$updateNodeInfo->setNode($node);
$this->feedbackCollection->add($updateNodeInfo);

$reloadIfChangedConfigurationPath = sprintf('properties.%s.ui.reloadIfChanged', $propertyName);
if (!$this->getIsInline() && $this->getNodeType($node)->getConfiguration($reloadIfChangedConfigurationPath)) {
if (!$this->getIsInline()
&& (
$this->getNodeType($node)->hasConfiguration(sprintf('properties.%s.ui.reloadIfChanged', $propertyName))
|| $this->getNodeType($node)->hasConfiguration(sprintf('references.%s.ui.reloadIfChanged', $propertyName))
)
) {
if ($this->getNodeDomAddress() && $this->getNodeDomAddress()->getFusionPath()
&& $parentNode
&& $this->getNodeType($parentNode)->isOfType('Neos.Neos:ContentCollection')) {
Expand All @@ -292,9 +285,12 @@ public function apply(): void
}
}

$reloadPageIfChangedConfigurationPath = sprintf('properties.%s.ui.reloadPageIfChanged', $propertyName);
if (!$this->getIsInline()
&& $this->getNodeType($node)->getConfiguration($reloadPageIfChangedConfigurationPath)) {
&& (
$this->getNodeType($node)->hasConfiguration(sprintf('properties.%s.ui.reloadPageIfChanged', $propertyName))
|| $this->getNodeType($node)->hasConfiguration(sprintf('references.%s.ui.reloadPageIfChanged', $propertyName))
)
) {
$this->reloadDocument($node);
}
}
Expand Down
13 changes: 4 additions & 9 deletions Classes/Domain/Service/NodePropertyConversionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ class NodePropertyConversionService
*/
public function convert(NodeType $nodeType, string $propertyName, string|array|null $rawValue): mixed
{
// WORKAROUND: $nodeType->getPropertyType() is missing the "initialize" call,
// so we need to trigger another method beforehand.
$nodeType->getFullConfiguration();
if ($nodeType->hasReference($propertyName)) {
throw new \Exception("not implemented here, must be handled outside.");
}

$propertyType = $nodeType->getPropertyType($propertyName);

if (is_null($rawValue)) {
Expand All @@ -57,12 +58,6 @@ public function convert(NodeType $nodeType, string $propertyName, string|array|n
case 'string':
return $rawValue;

case 'reference':
throw new \Exception("not implemented here, must be handled outside.");

case 'references':
throw new \Exception("not implemented here, must be handled outside.");

case 'DateTime':
return $this->convertDateTime($rawValue);

Expand Down
86 changes: 39 additions & 47 deletions Classes/Domain/Service/NodePropertyConverterService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use Neos\ContentRepository\Core\NodeType\NodeType;
use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindReferencesFilter;
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\ContentRepository\Core\Projection\ContentGraph\References;
use Neos\ContentRepository\Core\Projection\NodeHiddenState\NodeHiddenStateFinder;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Flow\Annotations as Flow;
Expand All @@ -40,6 +39,7 @@
* THIS IS DIRTY CODE. In the longer run, the neos UI should work DIRECTLY with serialized properties
* instead of the objects.
*
* @internal
* @Flow\Scope("singleton")
*/
class NodePropertyConverterService
Expand Down Expand Up @@ -99,14 +99,40 @@ public function injectThrowableStorage(ThrowableStorageInterface $throwableStora
$this->throwableStorage = $throwableStorage;
}

/**
* @return list<string>|string|null
*/
private function getReference(Node $node, string $referenceName): array|string|null
{
$subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
$references = $subgraph->findReferences(
$node->nodeAggregateId,
FindReferencesFilter::create(referenceName: $referenceName)
);

$referenceIdentifiers = [];
foreach ($references as $reference) {
$referenceIdentifiers[] = $reference->node->nodeAggregateId->value;
}

$maxItems = $this->getNodeType($node)->getReferences()[$referenceName]['constraints']['maxItems'] ?? null;

if ($maxItems === 1) {
// special handling to simulate old single reference behaviour.
// todo should be adjusted in the ui
if (count($referenceIdentifiers) === 0) {
return null;
} else {
return reset($referenceIdentifiers);
}
}
return $referenceIdentifiers;
}

/**
* Get a single property reduced to a simple type (no objects) representation
*
* @param Node $node
* @param string $propertyName
* @return mixed
*/
public function getProperty(Node $node, $propertyName)
private function getProperty(Node $node, string $propertyName): mixed
{
if ($propertyName === '_hidden') {
$contentRepository = $this->contentRepositoryRegistry->get($node->subgraphIdentity->contentRepositoryId);
Expand All @@ -118,38 +144,14 @@ public function getProperty(Node $node, $propertyName)
$node->nodeAggregateId
)->isHidden;
}
$propertyType = $this->getNodeType($node)->getPropertyType($propertyName);

// We handle "reference" and "references" differently than other properties;
// because we need to use another API for querying these references.
if ($propertyType === 'reference') {
$subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
$referenceIdentifiers = $this->toNodeIdentifierStrings(
$subgraph->findReferences(
$node->nodeAggregateId,
FindReferencesFilter::create(referenceName: $propertyName)
)
);
if (count($referenceIdentifiers) === 0) {
return null;
} else {
return reset($referenceIdentifiers);
}
} elseif ($propertyType === 'references') {
$subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
$references = $subgraph->findReferences(
$node->nodeAggregateId,
FindReferencesFilter::create(referenceName: $propertyName)
);

return $this->toNodeIdentifierStrings($references);
// Here, the normal property access logic starts.
} elseif ($propertyName[0] === '_' && $propertyName !== '_hiddenInIndex') {
if ($propertyName[0] === '_' && $propertyName !== '_hiddenInIndex') {
$propertyValue = ObjectAccess::getProperty($node, ltrim($propertyName, '_'));
} else {
$propertyValue = $node->getProperty($propertyName);
}

$propertyType = $this->getNodeType($node)->getPropertyType($propertyName);
try {
$convertedValue = $this->convertValue($propertyValue, $propertyType);
} catch (PropertyException $exception) {
Expand All @@ -175,35 +177,25 @@ public function getProperty(Node $node, $propertyName)
}

/**
* @return array<int,string>
*/
private function toNodeIdentifierStrings(References $references): array
{
$identifiers = [];
foreach ($references as $reference) {
$identifiers[] = $reference->node->nodeAggregateId->value;
}
return $identifiers;
}

/**
* Get all properties reduced to simple type (no objects) representations in an array
* Get all properties and references stuff reduced to simple type (no objects) representations in an array
*
* @param Node $node
* @return array<string,mixed>
*/
public function getPropertiesArray(Node $node)
{
$properties = [];
foreach ($this->getNodeType($node)->getProperties() as $propertyName => $propertyConfiguration) {
foreach ($this->getNodeType($node)->getProperties() as $propertyName => $_) {
if ($propertyName[0] === '_' && $propertyName[1] === '_') {
// skip fully-private properties
continue;
}

$properties[$propertyName] = $this->getProperty($node, $propertyName);
}

foreach ($this->getNodeType($node)->getReferences() as $referenceName => $_) {
$properties[$referenceName] = $this->getReference($node, $referenceName);
}
return $properties;
}

Expand Down
1 change: 1 addition & 0 deletions Classes/Fusion/Helper/NodeInfoHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use Neos\Neos\Utility\NodeTypeWithFallbackProvider;

/**
* @internal
* @Flow\Scope("singleton")
*/
class NodeInfoHelper implements ProtectedContextAwareInterface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function handle(CreateNodeAggregateWithNode $command, array $data, Conten
continue;
}
$propertyValue = $data[$propertyName];
if ($propertyType !== 'references' && $propertyType !== 'reference' && $propertyType !== TypeHandling::getTypeForValue($propertyValue)) {
if (!$nodeType->hasReference($propertyName) && $propertyType !== TypeHandling::getTypeForValue($propertyValue)) {
$propertyValue = $this->propertyMapper->convert($propertyValue, $propertyType, $propertyMappingConfiguration);
}

Expand Down

0 comments on commit 50d6e20

Please sign in to comment.