diff --git a/Document/Subscriber/RoutableSubscriber.php b/Document/Subscriber/RoutableSubscriber.php index 36cde909..2ac29107 100644 --- a/Document/Subscriber/RoutableSubscriber.php +++ b/Document/Subscriber/RoutableSubscriber.php @@ -43,6 +43,8 @@ class RoutableSubscriber implements EventSubscriberInterface { public const ROUTE_FIELD = 'routePath'; + public const ROUTE_FIELD_NAME = self::ROUTE_FIELD . 'Name'; + public const ROUTES_PROPERTY = 'suluRoutes'; public const TAG_NAME = 'sulu_article.article_route'; @@ -308,6 +310,7 @@ private function updateRoute(RoutablePageBehavior $document): void $node = $this->documentInspector->getNode($document); $node->setProperty($propertyName, $route->getPath()); + $node->setProperty($this->propertyEncoder->localizedContentName(self::ROUTE_FIELD_NAME, (string) $locale), $propertyName); } private function updateChildRoutes(ChildrenBehavior $document): void diff --git a/Resources/phpcr-migrations/Version202407111600.php b/Resources/phpcr-migrations/Version202407111600.php new file mode 100644 index 00000000..1d996f34 --- /dev/null +++ b/Resources/phpcr-migrations/Version202407111600.php @@ -0,0 +1,137 @@ +container = $container; + } + + public function up(SessionInterface $session) + { + $this->propertyEncoder = $this->container->get('sulu_document_manager.property_encoder'); + $this->metadataFactory = $this->container->get('sulu_page.structure.factory'); + + $liveSession = $this->container->get('sulu_document_manager.live_session'); + $this->upgrade($liveSession); + $this->upgrade($session); + + $liveSession->save(); + $session->save(); + } + + public function down(SessionInterface $session) + { + $this->propertyEncoder = $this->container->get('sulu_document_manager.property_encoder'); + $this->metadataFactory = $this->container->get('sulu_page.structure.factory'); + + $liveSession = $this->container->get('sulu_document_manager.live_session'); + $this->downgrade($liveSession); + $this->downgrade($session); + + $liveSession->save(); + $session->save(); + } + + private function upgrade(SessionInterface $session): void + { + $queryManager = $session->getWorkspace()->getQueryManager(); + $localizations = $this->container->get('sulu_core.webspace.webspace_manager')->getAllLocalizations(); + + $query = 'SELECT * FROM [nt:unstructured] WHERE ([jcr:mixinTypes] = "sulu:article" OR [jcr:mixinTypes] = "sulu:articlepage")'; + $rows = $queryManager->createQuery($query, 'JCR-SQL2')->execute(); + + /** @var Localization $localization */ + foreach ($localizations as $localization) { + $locale = $localization->getLocale(); + $templateKey = $this->propertyEncoder->localizedContentName('template', $locale); + + /** @var Row $row */ + foreach ($rows as $row) { + $node = $row->getNode(); + $structureType = $node->getPropertyValue($templateKey); + $routePathPropertyName = $this->getRoutePathPropertyName($structureType, $locale); + + $propertyName = $this->propertyEncoder->localizedContentName(RoutableSubscriber::ROUTE_FIELD_NAME, $locale); + $node->setProperty($propertyName, $routePathPropertyName); + } + } + } + + private function downgrade(SessionInterface $session) + { + $queryManager = $session->getWorkspace()->getQueryManager(); + $localizations = $this->container->get('sulu_core.webspace.webspace_manager')->getAllLocalizations(); + + $query = 'SELECT * FROM [nt:unstructured] WHERE ([jcr:mixinTypes] = "sulu:article" OR [jcr:mixinTypes] = "sulu:articlepage")'; + $rows = $queryManager->createQuery($query, 'JCR-SQL2')->execute(); + + /** @var Localization $localization */ + foreach ($localizations as $localization) { + $locale = $localization->getLocale(); + + /** @var Row $row */ + foreach ($rows as $row) { + $node = $row->getNode(); + $propertyName = $this->propertyEncoder->localizedContentName(RoutableSubscriber::ROUTE_FIELD_NAME, $locale); + $node->setProperty($propertyName, null); + } + } + } + + private function getRoutePathPropertyName(string $structureType, string $locale): string + { + $metadata = $this->metadataFactory->getStructureMetadata('article', $structureType); + + if ($metadata->hasPropertyWithTagName(RoutableSubscriber::TAG_NAME)) { + return $this->getPropertyName($locale, $metadata->getPropertyByTagName(RoutableSubscriber::TAG_NAME)->getName()); + } + + return $this->getPropertyName($locale, RoutableSubscriber::ROUTE_FIELD); + } + + private function getPropertyName(string $locale, string $field): string + { + return $this->propertyEncoder->localizedSystemName($field, $locale); + } +} diff --git a/Tests/Unit/Document/Subscriber/RoutableSubscriberTest.php b/Tests/Unit/Document/Subscriber/RoutableSubscriberTest.php index bd18f2aa..df560e3e 100644 --- a/Tests/Unit/Document/Subscriber/RoutableSubscriberTest.php +++ b/Tests/Unit/Document/Subscriber/RoutableSubscriberTest.php @@ -159,6 +159,7 @@ public function testHandlePersist() $this->metadataFactory->getStructureMetadata('article', 'default')->willReturn($metadata->reveal()); $this->propertyEncoder->localizedSystemName('routePath', 'de')->willReturn('i18n:de-routePath'); + $this->propertyEncoder->localizedContentName('routePathName', 'de')->willReturn('i18n:de-routePathName'); $children = [ $this->prophesize(RoutablePageBehavior::class), @@ -200,8 +201,11 @@ public function testHandlePersist() $children[2]->setRoutePath('/test-3')->shouldBeCalled(); $nodes[0]->setProperty('i18n:de-routePath', '/test-1')->shouldBeCalled(); + $nodes[0]->setProperty('i18n:de-routePathName', 'i18n:de-routePath')->shouldBeCalled(); $nodes[1]->setProperty('i18n:de-routePath', '/test-2')->shouldBeCalled(); + $nodes[1]->setProperty('i18n:de-routePathName', 'i18n:de-routePath')->shouldBeCalled(); $nodes[2]->setProperty('i18n:de-routePath', '/test-3')->shouldBeCalled(); + $nodes[2]->setProperty('i18n:de-routePathName', 'i18n:de-routePath')->shouldBeCalled(); $this->routableSubscriber->handlePersist($event->reveal()); } @@ -360,6 +364,7 @@ public function testHandleReorder() $this->metadataFactory->getStructureMetadata('article', 'default')->willReturn($metadata->reveal()); $this->propertyEncoder->localizedSystemName('routePath', 'de')->willReturn('i18n:de-routePath'); + $this->propertyEncoder->localizedContentName('routePathName', 'de')->willReturn('i18n:de-routePathName'); $children = [ $this->prophesize(RoutablePageBehavior::class), @@ -401,8 +406,11 @@ public function testHandleReorder() $children[2]->setRoutePath('/test-3')->shouldBeCalled(); $nodes[0]->setProperty('i18n:de-routePath', '/test-1')->shouldBeCalled(); + $nodes[0]->setProperty('i18n:de-routePathName', 'i18n:de-routePath')->shouldBeCalled(); $nodes[1]->setProperty('i18n:de-routePath', '/test-2')->shouldBeCalled(); + $nodes[1]->setProperty('i18n:de-routePathName', 'i18n:de-routePath')->shouldBeCalled(); $nodes[2]->setProperty('i18n:de-routePath', '/test-3')->shouldBeCalled(); + $nodes[2]->setProperty('i18n:de-routePathName', 'i18n:de-routePath')->shouldBeCalled(); $this->routableSubscriber->handleReorder($event->reveal()); }