diff --git a/src/lib/Repository/ContentService.php b/src/lib/Repository/ContentService.php index 2cee84e93a..57509af237 100644 --- a/src/lib/Repository/ContentService.php +++ b/src/lib/Repository/ContentService.php @@ -2528,14 +2528,17 @@ public function deleteTranslationFromDraft(APIVersionInfo $versionInfo, string $ */ public function hideContent(ContentInfo $contentInfo): void { - $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); - if (!$this->permissionResolver->canUser( - 'content', - 'hide', - $contentInfo, - [$locationTarget] - )) { - throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); + // If content is in draft state, mainLocationId is yet not set + if ($contentInfo->mainLocationId !== null) { + $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); + if (!$this->permissionResolver->canUser( + 'content', + 'hide', + $contentInfo, + [$locationTarget] + )) { + throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); + } } $this->repository->beginTransaction(); @@ -2568,14 +2571,17 @@ public function hideContent(ContentInfo $contentInfo): void */ public function revealContent(ContentInfo $contentInfo): void { - $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); - if (!$this->permissionResolver->canUser( - 'content', - 'hide', - $contentInfo, - [$locationTarget] - )) { - throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); + // If content is in draft state, mainLocationId is yet not set + if ($contentInfo->mainLocationId !== null) { + $locationTarget = (new DestinationLocationTarget($contentInfo->mainLocationId, $contentInfo)); + if (!$this->permissionResolver->canUser( + 'content', + 'hide', + $contentInfo, + [$locationTarget] + )) { + throw new UnauthorizedException('content', 'hide', ['contentId' => $contentInfo->id]); + } } $this->repository->beginTransaction(); diff --git a/tests/integration/Core/Repository/ContentServiceTest.php b/tests/integration/Core/Repository/ContentServiceTest.php index b609acec3c..a6e7f73a3d 100644 --- a/tests/integration/Core/Repository/ContentServiceTest.php +++ b/tests/integration/Core/Repository/ContentServiceTest.php @@ -6229,6 +6229,76 @@ function (Location $parentLocation) { $this->assertEquals($hiddenLocations, $hiddenLocationsAfterReveal); } + /** + * @covers \Ibexa\Contracts\Core\Repository\ContentService::hideContent + + * + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\APIInvalidArgumentException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException + */ + public function testHideContentDraft(): void + { + $publishedContent = $this->createContentForHideRevealDraftTests(false); + $location = $this->locationService->loadLocation($publishedContent->contentInfo->mainLocationId); + + $content = $this->contentService->loadContent($publishedContent->contentInfo->id); + self::assertTrue($content->contentInfo->isHidden, 'Content is not hidden'); + self::assertTrue($location->isHidden(), 'Location is visible'); + } + + /** + * @covers \Ibexa\Contracts\Core\Repository\ContentService::revealContent + + * + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + */ + public function testHideAndRevealContentDraft(): void + { + $publishedContent = $this->createContentForHideRevealDraftTests(true); + $location = $this->locationService->loadLocation($publishedContent->contentInfo->mainLocationId); + + $content = $this->contentService->loadContent($publishedContent->contentInfo->id); + self::assertFalse($content->contentInfo->isHidden, 'Content is hidden'); + self::assertFalse($location->isHidden(), 'Location is hidden'); + } + + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\APIInvalidArgumentException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException + */ + private function createContentForHideRevealDraftTests(bool $hideAndRevel): Content + { + $contentTypeService = $this->getRepository()->getContentTypeService(); + + $locationCreateStructs = $this->locationService->newLocationCreateStruct(2); + + $contentType = $contentTypeService->loadContentTypeByIdentifier('folder'); + + $contentCreate = $this->contentService->newContentCreateStruct($contentType, self::ENG_US); + $contentCreate->setField('name', 'Folder to hide'); + + $draft = $this->contentService->createContent( + $contentCreate, + [$locationCreateStructs] + ); + + $this->contentService->hideContent($draft->contentInfo); + if ($hideAndRevel) { + $this->contentService->revealContent($draft->contentInfo); + } + + return $this->contentService->publishVersion($draft->versionInfo); + } + /** * @depends testRevealContent */