Skip to content

Commit

Permalink
TASK: Harden uriPathProjection against empty string `uriPathSegment…
Browse files Browse the repository at this point in the history
…` and unsetting of `uriPathSegment`
  • Loading branch information
mficzel committed Jan 14, 2025
1 parent 64d52a7 commit 9208c23
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use Neos\ContentRepository\Core\Projection\ProjectionStatus;
use Neos\ContentRepository\Core\Projection\WithMarkStaleInterface;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepository\Core\SharedModel\Node\PropertyName;
use Neos\EventStore\Model\EventEnvelope;
use Neos\Neos\Domain\Model\SiteNodeName;
use Neos\Neos\FrontendRouting\Exception\NodeNotFoundException;
Expand Down Expand Up @@ -209,7 +210,7 @@ private function whenNodeAggregateWithNodeWasCreated(NodeAggregateWithNodeWasCre
}

$propertyValues = $event->initialPropertyValues->getPlainValues();
$uriPathSegment = $propertyValues['uriPathSegment'] ?? $event->nodeAggregateId->value;
$uriPathSegment = ($propertyValues['uriPathSegment'] ?? '') ?: $event->nodeAggregateId->value;

$shortcutTarget = null;
if ($documentTypeClassification === DocumentTypeClassification::CLASSIFICATION_SHORTCUT) {
Expand Down Expand Up @@ -494,8 +495,10 @@ private function whenNodePropertiesWereSet(NodePropertiesWereSet $event, EventEn
return;
}
$newPropertyValues = $event->propertyValues->getPlainValues();
$unsetPropertyNames = array_map(fn(PropertyName $propertyName) => $propertyName->value, $event->propertiesToUnset->getIterator());

Check failure on line 498 in Neos.Neos/Classes/FrontendRouting/Projection/DocumentUriPathProjection.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 Test linting-unit-functionaltests-mysql (deps: highest)

Parameter #2 $array of function array_map expects array, Traversable<int, Neos\ContentRepository\Core\SharedModel\Node\PropertyName> given.

Check failure on line 498 in Neos.Neos/Classes/FrontendRouting/Projection/DocumentUriPathProjection.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 Test linting-unit-functionaltests-mysql (deps: highest)

Parameter #2 $array of function array_map expects array, Traversable<int, Neos\ContentRepository\Core\SharedModel\Node\PropertyName> given.
if (
!isset($newPropertyValues['uriPathSegment'])
&& !in_array('uriPathSegment', $unsetPropertyNames)
&& !isset($newPropertyValues['targetMode'])
&& !isset($newPropertyValues['target'])
) {
Expand Down Expand Up @@ -529,12 +532,12 @@ private function whenNodePropertiesWereSet(NodePropertiesWereSet $event, EventEn
);
}

if (!isset($newPropertyValues['uriPathSegment'])) {
if (!isset($newPropertyValues['uriPathSegment']) && !in_array('uriPathSegment', $unsetPropertyNames)) {
continue;
}
$oldUriPath = $node->getUriPath();
$uriPathSegments = explode('/', $oldUriPath);
$uriPathSegments[array_key_last($uriPathSegments)] = $newPropertyValues['uriPathSegment'];
$uriPathSegments[array_key_last($uriPathSegments)] = ($newPropertyValues['uriPathSegment'] ?? '') ?: $event->nodeAggregateId;
$newUriPath = implode('/', $uriPathSegments);

$this->updateNodeQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,47 @@ Feature: Routing functionality if path segments are missing like during tethered
| propertyValues | {"uriPathSegment": "earl-documentbourgh-updated"} |
And I am on URL "/"
Then the node "earl-o-documentbourgh" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/sir-david-nodenborough/earl-documentbourgh-updated"

Scenario: Add empty uri path segment on first level
When the command SetNodeProperties is executed with payload:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| originDimensionSpacePoint | {} |
| propertyValues | {"uriPathSegment": ""} |
And I am on URL "/"
Then the node "sir-david-nodenborough" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/sir-david-nodenborough"
And the node "earl-o-documentbourgh" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/sir-david-nodenborough/earl-o-documentbourgh"

Scenario: Uri path segment is unset after having been set before
When the command SetNodeProperties is executed with payload:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| originDimensionSpacePoint | {} |
| propertyValues | {"uriPathSegment": "david-nodenborough-updated"} |
And I am on URL "/"
Then the node "sir-david-nodenborough" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/david-nodenborough-updated"
And the node "earl-o-documentbourgh" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/david-nodenborough-updated/earl-o-documentbourgh"
When the command SetNodeProperties is executed with payload:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| originDimensionSpacePoint | {} |
| propertiesToUnset | ["uriPathSegment"] |
Then the node "sir-david-nodenborough" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/sir-david-nodenborough"
And the node "earl-o-documentbourgh" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/sir-david-nodenborough/earl-o-documentbourgh"

Scenario: Uri path segment is set to empty string having been set before
When the command SetNodeProperties is executed with payload:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| originDimensionSpacePoint | {} |
| propertyValues | {"uriPathSegment": "david-nodenborough-updated"} |
And I am on URL "/"
Then the node "sir-david-nodenborough" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/david-nodenborough-updated"
And the node "earl-o-documentbourgh" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/david-nodenborough-updated/earl-o-documentbourgh"
When the command SetNodeProperties is executed with payload:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| originDimensionSpacePoint | {} |
| propertyValues | {"uriPathSegment": ""} |
Then the node "sir-david-nodenborough" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/sir-david-nodenborough"
And the node "earl-o-documentbourgh" in content stream "cs-identifier" and dimension "{}" should resolve to URL "/sir-david-nodenborough/earl-o-documentbourgh"

0 comments on commit 9208c23

Please sign in to comment.