From b5fe9ad828dbf6a645afb8ea5e9407ebf54255f6 Mon Sep 17 00:00:00 2001 From: Bartek Wajda Date: Tue, 7 May 2024 14:42:00 +0200 Subject: [PATCH] IBX-6494: Fixed copying of non-translatable fields to later versions For more details see https://issues.ibexa.co/browse/IBX-6494 and https://github.com/ezsystems/ezplatform-kernel/pull/394 Key changes: * Fixed copying of non-translatable fields to later versions * [Tests] Added integration test coverage for the use case --- eZ/Publish/Core/Repository/ContentService.php | 18 +-- ...slatableFieldsFromPublishedVersionTest.php | 125 ++++++++++++++++-- 2 files changed, 122 insertions(+), 21 deletions(-) diff --git a/eZ/Publish/Core/Repository/ContentService.php b/eZ/Publish/Core/Repository/ContentService.php index c64d49ced0..3ef2ad3bdd 100644 --- a/eZ/Publish/Core/Repository/ContentService.php +++ b/eZ/Publish/Core/Repository/ContentService.php @@ -1517,16 +1517,12 @@ protected function copyNonTranslatableFieldsFromPublishedVersion(APIContent $cur $publishedContent = $this->internalLoadContentById($versionInfo->getContentInfo()->getId()); $publishedVersionInfo = $publishedContent->getVersionInfo(); - if ( - !$publishedVersionInfo->isPublished() - || ($versionInfo->versionNo >= $publishedVersionInfo->versionNo) - ) { + if (!$publishedVersionInfo->isPublished()) { return; } - $publishedContentFieldsInMainLanguage = $publishedContent->getFieldsByLanguage( - $publishedContent->getVersionInfo()->getContentInfo()->getMainLanguageCode() - ); + $mainLanguageCode = $publishedContent->getVersionInfo()->getContentInfo()->getMainLanguageCode(); + $publishedContentFieldsInMainLanguage = $publishedContent->getFieldsByLanguage($mainLanguageCode); $fieldValues = []; $persistenceFields = []; @@ -1545,7 +1541,13 @@ protected function copyNonTranslatableFieldsFromPublishedVersion(APIContent $cur $fieldDefinition->fieldTypeIdentifier ); - $newValue = $publishedContentFieldsInMainLanguage[$field->fieldDefIdentifier]->getValue(); + $newValue = ( + $versionInfo->versionNo >= $publishedVersionInfo->versionNo + && $versionInfo->initialLanguageCode === $mainLanguageCode + ) + ? $field->getValue() + : $publishedContentFieldsInMainLanguage[$field->fieldDefIdentifier]->getValue(); + $fieldValues[$fieldDefinition->identifier][$field->languageCode] = $newValue; $persistenceFields[] = new SPIField( diff --git a/tests/integration/Core/Repository/ContentService/CopyNonTranslatableFieldsFromPublishedVersionTest.php b/tests/integration/Core/Repository/ContentService/CopyNonTranslatableFieldsFromPublishedVersionTest.php index 84cb799036..a38d527797 100644 --- a/tests/integration/Core/Repository/ContentService/CopyNonTranslatableFieldsFromPublishedVersionTest.php +++ b/tests/integration/Core/Repository/ContentService/CopyNonTranslatableFieldsFromPublishedVersionTest.php @@ -9,6 +9,7 @@ namespace Ibexa\Tests\Integration\Core\Repository\ContentService; use DateTime; +use eZ\Publish\API\Repository\Values\Content\Content; use eZ\Publish\API\Repository\Values\ContentType\FieldDefinitionCreateStruct; use eZ\Publish\Core\Repository\Values\Content\ContentUpdateStruct; use Ibexa\Tests\Integration\Core\RepositoryTestCase; @@ -31,21 +32,9 @@ public function testCopyNonTranslatableFieldsFromPublishedVersionToDraft(): void $this->createNonTranslatableContentType(); $contentService = self::getContentService(); - $contentTypeService = self::getContentTypeService(); - $locationService = self::getLocationService(); // Creating start content in eng-US language - $contentType = $contentTypeService->loadContentTypeByIdentifier(self::CONTENT_TYPE_IDENTIFIER); - $mainLanguageCode = self::ENG_US; - $contentCreateStruct = $contentService->newContentCreateStruct($contentType, $mainLanguageCode); - $contentCreateStruct->setField('title', 'Test title'); - - $contentDraft = $contentService->createContent( - $contentCreateStruct, - [ - $locationService->newLocationCreateStruct(2), - ] - ); + $contentDraft = $this->createEngDraft(); $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo()); // Creating a draft in ger-DE language with the only field updated being 'title' @@ -84,6 +73,116 @@ public function testCopyNonTranslatableFieldsFromPublishedVersionToDraft(): void self::assertSame($expectedBodyValue, $bodyFieldValue->text); } + /** + * @throws \eZ\Publish\API\Repository\Exceptions\Exception + */ + public function testCopyNonTranslatableFieldsTwoParallelDrafts(): void + { + $this->createNonTranslatableContentType(); + + $contentService = self::getContentService(); + + // Creating start content in eng-US language + $contentDraft = $this->createEngDraft(); + $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo()); + + // Creating two drafts at the same time + $usDraft = $contentService->createContentDraft($publishedContent->contentInfo); + $gerDraft = $contentService->createContentDraft($publishedContent->contentInfo); + + // Publishing the draft in eng-US language + $contentUpdateStruct = new ContentUpdateStruct([ + 'initialLanguageCode' => self::ENG_US, + 'fields' => $usDraft->getFields(), + ]); + $contentUpdateStruct->setField('title', 'Title v2', self::ENG_US); + $contentUpdateStruct->setField('body', 'Nontranslatable body v2', self::ENG_US); + $usContent = $contentService->updateContent($usDraft->getVersionInfo(), $contentUpdateStruct); + $contentService->publishVersion($usContent->getVersionInfo()); + + // Publishing the draft in ger-DE language + $contentUpdateStruct = new ContentUpdateStruct([ + 'initialLanguageCode' => self::GER_DE, + 'fields' => $gerDraft->getFields(), + ]); + $contentUpdateStruct->setField('title', 'Title ger', self::GER_DE); + $gerContent = $contentService->updateContent($gerDraft->getVersionInfo(), $contentUpdateStruct); + $contentService->publishVersion($gerContent->getVersionInfo()); + + // Loading main content + $mainPublishedContent = $contentService->loadContent($gerContent->id); + $bodyFieldValue = $mainPublishedContent->getField('body')->getValue(); + + self::assertSame('Nontranslatable body v2', $bodyFieldValue->text); + } + + /** + * @throws \eZ\Publish\API\Repository\Exceptions\Exception + */ + public function testCopyNonTranslatableFieldsOverridesNonMainLanguageDrafts(): void + { + $this->createNonTranslatableContentType(); + + $contentService = self::getContentService(); + + // Creating start content in eng-US language + $contentDraft = $this->createEngDraft(); + $publishedContent = $contentService->publishVersion($contentDraft->getVersionInfo()); + + // Creating a draft in ger-DE language with the only field updated being 'title' + $gerDraft = $contentService->createContentDraft($publishedContent->contentInfo); + + $contentUpdateStruct = new ContentUpdateStruct([ + 'initialLanguageCode' => self::GER_DE, + 'fields' => $contentDraft->getFields(), + ]); + + $contentUpdateStruct->setField('title', 'Folder GER', self::GER_DE); + $gerContent = $contentService->updateContent($gerDraft->getVersionInfo(), $contentUpdateStruct); + $publishedContent = $contentService->publishVersion($gerContent->getVersionInfo()); + + // Updating non-translatable field in eng-US language (allowed) and publishing it + $engContent = $contentService->createContentDraft($publishedContent->contentInfo); + + $contentUpdateStruct = new ContentUpdateStruct([ + 'initialLanguageCode' => self::ENG_US, + 'fields' => $contentDraft->getFields(), + ]); + + $expectedBodyValue = 'Non-translatable value'; + $contentUpdateStruct->setField('title', 'Title v2', self::ENG_US); + $contentUpdateStruct->setField('body', $expectedBodyValue, self::ENG_US); + + $engContent = $contentService->updateContent($engContent->getVersionInfo(), $contentUpdateStruct); + $contentService->publishVersion($engContent->getVersionInfo()); + + // Loading content in ger-DE language + $mainPublishedContent = $contentService->loadContent($engContent->id, ['ger-DE']); + $bodyFieldValue = $mainPublishedContent->getField('body')->getValue(); + + self::assertSame($expectedBodyValue, $bodyFieldValue->text); + } + + private function createEngDraft(): Content + { + $contentService = self::getContentService(); + $contentTypeService = self::getContentTypeService(); + $locationService = self::getLocationService(); + + $contentType = $contentTypeService->loadContentTypeByIdentifier(self::CONTENT_TYPE_IDENTIFIER); + $mainLanguageCode = self::ENG_US; + $contentCreateStruct = $contentService->newContentCreateStruct($contentType, $mainLanguageCode); + $contentCreateStruct->setField('title', 'Test title'); + $contentCreateStruct->setField('body', 'Test body'); + + return $contentService->createContent( + $contentCreateStruct, + [ + $locationService->newLocationCreateStruct(2), + ] + ); + } + private function createNonTranslatableContentType(): void { $permissionResolver = self::getPermissionResolver();