From 8c4f65884147ae08731a229c5a5443cba50aeecc Mon Sep 17 00:00:00 2001 From: Adrian Cerdeira Date: Thu, 10 Jul 2025 10:42:24 +0200 Subject: [PATCH 1/3] TASK: Neos 9 Compatibility with rector --- Classes/Migration/Transformation/PropertyValueToLowercase.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/Migration/Transformation/PropertyValueToLowercase.php b/Classes/Migration/Transformation/PropertyValueToLowercase.php index dde1f30..58f823a 100644 --- a/Classes/Migration/Transformation/PropertyValueToLowercase.php +++ b/Classes/Migration/Transformation/PropertyValueToLowercase.php @@ -7,7 +7,8 @@ use Neos\ContentRepository\Domain\Model\NodeData; use Neos\ContentRepository\Migration\Transformations\AbstractTransformation; -class PropertyValueToLowercase extends AbstractTransformation +// TODO 9.0 migration: You need to convert your AbstractTransformation to an implementation of Neos\ContentRepository\NodeMigration\Transformation\TransformationFactoryInterface +class PropertyValueToLowercase { private string $propertyName; From ef17b375c0a8d753983cd26010eb38c606ca1926 Mon Sep 17 00:00:00 2001 From: Adrian Cerdeira Date: Thu, 17 Jul 2025 07:32:22 +0200 Subject: [PATCH 2/3] feat: resolve todos and create custom transformation (who cannot be used at the moment) --- .../PropertyValueToLowercase.php | 79 ++++++++++++------- .../Version20250124153030.yaml | 29 +++---- README.md | 22 +++--- composer.json | 2 +- 4 files changed, 74 insertions(+), 58 deletions(-) diff --git a/Classes/Migration/Transformation/PropertyValueToLowercase.php b/Classes/Migration/Transformation/PropertyValueToLowercase.php index 58f823a..dfa6445 100644 --- a/Classes/Migration/Transformation/PropertyValueToLowercase.php +++ b/Classes/Migration/Transformation/PropertyValueToLowercase.php @@ -4,39 +4,58 @@ namespace Flowpack\SeoRouting\Migration\Transformation; -use Neos\ContentRepository\Domain\Model\NodeData; -use Neos\ContentRepository\Migration\Transformations\AbstractTransformation; - -// TODO 9.0 migration: You need to convert your AbstractTransformation to an implementation of Neos\ContentRepository\NodeMigration\Transformation\TransformationFactoryInterface -class PropertyValueToLowercase +use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; +use Neos\ContentRepository\Core\Projection\ContentGraph\Node; +use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; +use Neos\ContentRepository\NodeMigration\Transformation\NodeBasedTransformationInterface; +use Neos\ContentRepository\Core\ContentRepository; +use Neos\ContentRepository\Core\Feature\NodeModification\Command\SetNodeProperties; +use Neos\ContentRepository\Core\Feature\NodeModification\Dto\PropertyValuesToWrite; +use Neos\ContentRepository\NodeMigration\Transformation\GlobalTransformationInterface; +use Neos\ContentRepository\NodeMigration\Transformation\TransformationFactoryInterface; +use Neos\ContentRepository\NodeMigration\Transformation\TransformationStep; + +/** + * Transforms a specified property value of a node to lowercase. + */ +class PropertyValueToLowercase implements TransformationFactoryInterface { - private string $propertyName; - - public function setProperty(string $propertyName): void - { - $this->propertyName = $propertyName; - } - - /** - * @inheritDoc - */ - public function isTransformable(NodeData $node) - { - return $node->hasProperty($this->propertyName); - } - /** - * @inheritDoc + * @param array $settings */ - public function execute(NodeData $node) + public function build(array $settings, ContentRepository $contentRepository): GlobalTransformationInterface|NodeBasedTransformationInterface { - $currentPropertyValue = $node->getProperty($this->propertyName); - if (! is_string($currentPropertyValue)) { - return $node; - } - $newPropertyValue = strtolower($currentPropertyValue); - $node->setProperty($this->propertyName, $newPropertyValue); - - return $node; + return new class( + $settings['property'] + ) implements NodeBasedTransformationInterface { + + private string $propertyName; + + public function __construct(string $propertyName) + { + $this->propertyName = $propertyName; + } + + public function execute(Node $node, DimensionSpacePoint $coveredDimensionSpacePoints, WorkspaceName $workspaceNameForWriting): TransformationStep + { + $currentProperty = $node->getProperty($this->propertyName); + + if ($currentProperty !== null && is_string($currentProperty)) { + $value = strtolower($currentProperty); + return TransformationStep::fromCommand( + SetNodeProperties::create( + $workspaceNameForWriting, + $node->aggregateId, + $node->originDimensionSpacePoint, + PropertyValuesToWrite::fromArray([ + $this->propertyName => $value, + ]) + ) + ); + } + + return TransformationStep::createEmpty(); + } + }; } } diff --git a/Migrations/ContentRepository/Version20250124153030.yaml b/Migrations/ContentRepository/Version20250124153030.yaml index a17f8d7..991e8c2 100644 --- a/Migrations/ContentRepository/Version20250124153030.yaml +++ b/Migrations/ContentRepository/Version20250124153030.yaml @@ -1,16 +1,13 @@ -up: - comments: 'Transforms all uriPathSegment values to lowercase' - warnings: 'As this migration removes the distinction between uppercase and lowercase it might not be cleanly undone by the down migration.' - migration: - - filters: - - type: 'NodeType' - settings: - nodeType: 'Neos.Neos:Document' - withSubTypes: TRUE - transformations: - - type: 'Flowpack\SeoRouting\Migration\Transformation\PropertyValueToLowercase' - settings: - property: 'uriPathSegment' - -down: - comments: 'No down migration available' +comments: "Transforms all uriPathSegment values to lowercase" +warnings: "As this migration removes the distinction between uppercase and lowercase it might not be cleanly undone by the down migration." +migration: + - filters: + - type: "NodeType" + settings: + nodeType: "Neos.Neos:Document" + withSubTypes: TRUE + # Custom transformation not possible in Neos < 9.0: https://neos-project.slack.com/archives/C04V4C6B0/p1752678184783919 + # transformations: + # - type: 'Flowpack\SeoRouting\Migration\Transformation\PropertyValueToLowercase' + # settings: + # property: "uriPathSegment" diff --git a/README.md b/README.md index 5770e5f..d6050f0 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ -* [Flowpack.SeoRouting](#flowpackseorouting) - * [Sponsoring](#sponsoring) - * [Introduction](#introduction) - * [Features](#features) - * [Installation](#installation) - * [Configuration](#configuration) - * [Standard Configuration](#standard-configuration) - * [Trailing slash mode](#trailing-slash-mode) - * [Blocklist for redirects](#blocklist-for-redirects) - * [Thank you](#thank-you) +- [Flowpack.SeoRouting](#flowpackseorouting) + - [Sponsoring](#sponsoring) + - [Introduction](#introduction) + - [Features](#features) + - [Installation](#installation) + - [Configuration](#configuration) + - [Standard Configuration](#standard-configuration) + - [Trailing slash mode](#trailing-slash-mode) + - [Blocklist for redirects](#blocklist-for-redirects) + - [Thank you](#thank-you) @@ -46,7 +46,7 @@ Just require it via composer: If you want to use the *toLowerCase* feature you should execute the migration that comes with this package: -`./flow node:migrate 20250124153030 --confirmation true` +`./flow nodemigration:execute 20250124153030 --force` This migration transforms all the URLs of all your nodes to lowercase. It's irreversible. diff --git a/composer.json b/composer.json index cbf61e9..10822a0 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "require": { "guzzlehttp/psr7": "^2.0", "php": "^8.1", - "neos/neos": "^8.3|^9.0" + "neos/neos": "^9.0" }, "require-dev": { "phpstan/phpstan": "^2.1", From 4357c1e9770c01e6e1bc810178ffe1d3c8ed2afa Mon Sep 17 00:00:00 2001 From: Adrian Cerdeira Date: Thu, 17 Jul 2025 09:24:37 +0200 Subject: [PATCH 3/3] fix: property value migration and add into settings custom transformation --- .../Transformation/PropertyValueToLowercase.php | 6 +++--- Configuration/Settings.yaml | 5 +++++ Migrations/ContentRepository/Version20250124153030.yaml | 9 ++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Classes/Migration/Transformation/PropertyValueToLowercase.php b/Classes/Migration/Transformation/PropertyValueToLowercase.php index dfa6445..5a329a4 100644 --- a/Classes/Migration/Transformation/PropertyValueToLowercase.php +++ b/Classes/Migration/Transformation/PropertyValueToLowercase.php @@ -4,7 +4,7 @@ namespace Flowpack\SeoRouting\Migration\Transformation; -use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; +use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\ContentRepository\NodeMigration\Transformation\NodeBasedTransformationInterface; @@ -36,12 +36,12 @@ public function __construct(string $propertyName) $this->propertyName = $propertyName; } - public function execute(Node $node, DimensionSpacePoint $coveredDimensionSpacePoints, WorkspaceName $workspaceNameForWriting): TransformationStep - { + public function execute(Node $node, DimensionSpacePointSet $coveredDimensionSpacePoints, WorkspaceName $workspaceNameForWriting): TransformationStep { $currentProperty = $node->getProperty($this->propertyName); if ($currentProperty !== null && is_string($currentProperty)) { $value = strtolower($currentProperty); + return TransformationStep::fromCommand( SetNodeProperties::create( $workspaceNameForWriting, diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml index 77ff9d2..7526d74 100644 --- a/Configuration/Settings.yaml +++ b/Configuration/Settings.yaml @@ -15,3 +15,8 @@ Neos: middlewares: 'after routing': middleware: 'Flowpack\SeoRouting\RoutingMiddleware' + + ContentRepositoryRegistry: + nodeMigration: + transformationFactories: + PropertyValueToLowercase: Flowpack\SeoRouting\Migration\Transformation\PropertyValueToLowercase diff --git a/Migrations/ContentRepository/Version20250124153030.yaml b/Migrations/ContentRepository/Version20250124153030.yaml index 991e8c2..8792187 100644 --- a/Migrations/ContentRepository/Version20250124153030.yaml +++ b/Migrations/ContentRepository/Version20250124153030.yaml @@ -6,8 +6,7 @@ migration: settings: nodeType: "Neos.Neos:Document" withSubTypes: TRUE - # Custom transformation not possible in Neos < 9.0: https://neos-project.slack.com/archives/C04V4C6B0/p1752678184783919 - # transformations: - # - type: 'Flowpack\SeoRouting\Migration\Transformation\PropertyValueToLowercase' - # settings: - # property: "uriPathSegment" + transformations: + - type: 'PropertyValueToLowercase' + settings: + property: "uriPathSegment"