Skip to content

Commit

Permalink
IBX-3957: Made NOP URL aliases not reusable and original (#350)
Browse files Browse the repository at this point in the history
For more details see https://issues.ibexa.co/browse/IBX-3957 and #350

Breaking change: if there exists a custom URL alias having a path "/a/b" where "a" is a virtual (NOP) entry - not pointing to any content - renaming or creating another content on the same level using a colliding name - "a" in this case - will result in actually creating "/a2" entry, as "/a" is already taken by "/a/b" path.
  • Loading branch information
barw4 authored May 17, 2024
1 parent 3278641 commit 2964324
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 2 additions & 4 deletions src/lib/Persistence/Legacy/Content/UrlAlias/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
) {
Expand Down
49 changes: 49 additions & 0 deletions tests/integration/Core/Repository/URLAliasServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down

0 comments on commit 2964324

Please sign in to comment.