From b8cd3eab4a3b985a1c0fd499b99d892188e253ee Mon Sep 17 00:00:00 2001 From: slaci Date: Fri, 2 Mar 2018 10:29:28 +0100 Subject: [PATCH] EZP-28883: Removing Translation from Draft corrupts all Url Aliases for the removed Translation (#2262) * EZP-28883: Fixed wrong SQL query constraints * EZP-28883: Created integration test * EZP-28883: Replaced Generator with array to avoid endless loop Possible reason: It seems that SQLite driver executes query multiple times which in conjunction with other operations in the transaction creates an endless loop. --- .../Repository/Tests/ContentServiceTest.php | 64 +++++++++++++++++++ .../UrlAlias/Gateway/DoctrineDatabase.php | 8 +-- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/eZ/Publish/API/Repository/Tests/ContentServiceTest.php b/eZ/Publish/API/Repository/Tests/ContentServiceTest.php index ae252541836..b78e7f8ce55 100644 --- a/eZ/Publish/API/Repository/Tests/ContentServiceTest.php +++ b/eZ/Publish/API/Repository/Tests/ContentServiceTest.php @@ -5414,6 +5414,11 @@ public function providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing * @dataProvider providerForDeleteTranslationFromDraftRemovesUrlAliasOnPublishing * * @param string[] $fieldValues translated field values + * + * @throws \eZ\Publish\API\Repository\Exceptions\BadStateException + * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException + * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException + * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException */ public function testDeleteTranslationFromDraftRemovesUrlAliasOnPublishing(array $fieldValues) { @@ -5476,6 +5481,65 @@ public function testDeleteTranslationFromDraftRemovesUrlAliasOnPublishing(array } } + /** + * Test that URL aliases for deleted Translations are properly archived. + */ + public function testDeleteTranslationFromDraftArchivesUrlAliasOnPublishing() + { + $repository = $this->getRepository(); + $contentService = $repository->getContentService(); + $urlAliasService = $repository->getURLAliasService(); + + $content = $contentService->publishVersion( + $this->createMultilingualContentDraft( + 'folder', + 2, + 'eng-US', + [ + 'name' => [ + 'eng-GB' => 'BritishEnglishContent', + 'eng-US' => 'AmericanEnglishContent', + ], + ] + )->versionInfo + ); + + $unrelatedContent = $contentService->publishVersion( + $this->createMultilingualContentDraft( + 'folder', + 2, + 'eng-US', + [ + 'name' => [ + 'eng-GB' => 'AnotherBritishContent', + 'eng-US' => 'AnotherAmericanContent', + ], + ] + )->versionInfo + ); + + $urlAlias = $urlAliasService->lookup('/BritishEnglishContent'); + self::assertFalse($urlAlias->isHistory); + self::assertEquals($urlAlias->path, '/BritishEnglishContent'); + self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId); + + $draft = $contentService->deleteTranslationFromDraft( + $contentService->createContentDraft($content->contentInfo)->versionInfo, + 'eng-GB' + ); + $content = $contentService->publishVersion($draft->versionInfo); + + $urlAlias = $urlAliasService->lookup('/BritishEnglishContent'); + self::assertTrue($urlAlias->isHistory); + self::assertEquals($urlAlias->path, '/BritishEnglishContent'); + self::assertEquals($urlAlias->destination, $content->contentInfo->mainLocationId); + + $unrelatedUrlAlias = $urlAliasService->lookup('/AnotherBritishContent'); + self::assertFalse($unrelatedUrlAlias->isHistory); + self::assertEquals($unrelatedUrlAlias->path, '/AnotherBritishContent'); + self::assertEquals($unrelatedUrlAlias->destination, $unrelatedContent->contentInfo->mainLocationId); + } + /** * Test deleting a Translation from Draft which has single Translation throws BadStateException. * diff --git a/eZ/Publish/Core/Persistence/Legacy/Content/UrlAlias/Gateway/DoctrineDatabase.php b/eZ/Publish/Core/Persistence/Legacy/Content/UrlAlias/Gateway/DoctrineDatabase.php index a70b555e09c..b541d14b145 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Content/UrlAlias/Gateway/DoctrineDatabase.php +++ b/eZ/Publish/Core/Persistence/Legacy/Content/UrlAlias/Gateway/DoctrineDatabase.php @@ -1250,14 +1250,14 @@ private function loadLocationEntriesMatchingMultipleLanguages($locationId, array ->from($this->table) ->where('action = :action') // fetch rows matching any of the given Languages - ->where('lang_mask & :languageMask <> 0') + ->andWhere('lang_mask & :languageMask <> 0') ->setParameter(':action', 'eznode:' . $locationId) ->setParameter(':languageMask', $languageMask) ; $statement = $query->execute(); - while (false !== ($row = $statement->fetch(\PDO::FETCH_ASSOC))) { - yield $row; - } + $rows = $statement->fetchAll(\PDO::FETCH_ASSOC); + + return $rows ?: []; } }