diff --git a/src/lib/Persistence/Legacy/Content/UrlAlias/Gateway/DoctrineDatabase.php b/src/lib/Persistence/Legacy/Content/UrlAlias/Gateway/DoctrineDatabase.php index 1b708c059b..88fa221b2f 100644 --- a/src/lib/Persistence/Legacy/Content/UrlAlias/Gateway/DoctrineDatabase.php +++ b/src/lib/Persistence/Legacy/Content/UrlAlias/Gateway/DoctrineDatabase.php @@ -603,7 +603,7 @@ public function insertRow(array $values): int $values['is_original'] = 1; } if ($values['action'] === self::NOP_ACTION) { - $values['is_original'] = 0; + $values['is_original'] = 1; } $query = $this->connection->createQueryBuilder(); diff --git a/src/lib/Persistence/Legacy/Content/UrlAlias/Handler.php b/src/lib/Persistence/Legacy/Content/UrlAlias/Handler.php index b841ce4bac..a518739f7d 100644 --- a/src/lib/Persistence/Legacy/Content/UrlAlias/Handler.php +++ b/src/lib/Persistence/Legacy/Content/UrlAlias/Handler.php @@ -231,11 +231,9 @@ private function internalPublishUrlAliasForLocation( } // Row exists, check if it is reusable. There are 3 cases when this is possible: - // 1. NOP entry - // 2. existing location or custom alias entry - // 3. history entry + // 1. existing location or custom alias entry + // 2. history entry if ( - $row['action'] === Gateway::NOP_ACTION || $row['action'] === $action || (int)$row['is_original'] === 0 ) { diff --git a/tests/integration/Core/Repository/URLAliasServiceTest.php b/tests/integration/Core/Repository/URLAliasServiceTest.php index 5f1392bbf9..595796090c 100644 --- a/tests/integration/Core/Repository/URLAliasServiceTest.php +++ b/tests/integration/Core/Repository/URLAliasServiceTest.php @@ -1487,6 +1487,55 @@ public function testOverrideHistoryUrlAliasAtTheSameLocation(): void self::assertFalse($newAlias->isHistory); } + public function testRenamingParentContentDoesntBreakChildAlias(): void + { + $repository = $this->getRepository(); + $urlAliasService = $repository->getURLAliasService(); + $contentService = $repository->getContentService(); + + $languageCode = 'eng-GB'; + + // 1. Create parent folder + $folder = $this->createFolder([$languageCode => 'a'], 2); + $folderLocationId = $folder->contentInfo->getMainLocationId(); + + // 2. Create child folder + $child = $this->createFolder([$languageCode => 'b'], $folderLocationId); + $childLocation = $child->getVersionInfo()->getContentInfo()->getMainLocation(); + + self::assertInstanceOf(Location::class, $childLocation); + + $childLocationId = $childLocation->id; + + // 3. Create custom URL alias for child folder + $urlAliasService->createUrlAlias($childLocation, '/c/b', $languageCode); + $lookup = $urlAliasService->lookup('/c/b'); + + self::assertSame('/c/b', $lookup->path); + self::assertSame($childLocationId, $lookup->destination); + + // 4. Rename "A" to "C" + $folderDraft = $contentService->createContentDraft($folder->contentInfo); + $folderUpdateStruct = $contentService->newContentUpdateStruct(); + $folderUpdateStruct->setField('name', 'c'); + $renamedFolder = $contentService->updateContent($folderDraft->getVersionInfo(), $folderUpdateStruct); + $contentService->publishVersion($renamedFolder->getVersionInfo()); + + // Loading aliases shouldn't throw a `BadStateException` + $childLocationAliases = $urlAliasService->listLocationAliases($childLocation); + $childLocationAliasesUnpacked = iterator_to_array($childLocationAliases); + + self::assertCount(1, $childLocationAliasesUnpacked); + self::assertSame('/c/b', $childLocationAliasesUnpacked[0]->path); + + // Renamed content should have '/c2' path alias + $lookupRenamed = $urlAliasService->lookup('c2'); + $originalLookup = $urlAliasService->lookup('/c/b'); + + self::assertSame($childLocationId, $originalLookup->destination); + self::assertSame('/c2', $lookupRenamed->path); + } + /** * Lookup given URL and check if it is archived and points to the given Location Id. *