diff --git a/eZ/Publish/API/Repository/Tests/LocationServiceTest.php b/eZ/Publish/API/Repository/Tests/LocationServiceTest.php index fae805308e..632745077c 100644 --- a/eZ/Publish/API/Repository/Tests/LocationServiceTest.php +++ b/eZ/Publish/API/Repository/Tests/LocationServiceTest.php @@ -131,6 +131,50 @@ public function testCreateLocation() ]; } + /** + * Test for the createLocation() method. + * + * @see \eZ\Publish\API\Repository\LocationService::createLocation() + * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation + * @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testHideContent + */ + public function testCreateLocationChecksContentVisibility() + { + $repository = $this->getRepository(); + + $contentId = $this->generateId('object', 41); + $parentLocationId = $this->generateId('location', 5); + /* BEGIN: Use Case */ + // $contentId is the ID of an existing content object + // $parentLocationId is the ID of an existing location + $contentService = $repository->getContentService(); + $locationService = $repository->getLocationService(); + + // ContentInfo for "How to use eZ Publish" + $contentInfo = $contentService->loadContentInfo($contentId); + $contentService->hideContent($contentInfo); + + $locationCreate = $locationService->newLocationCreateStruct($parentLocationId); + $locationCreate->priority = 23; + $locationCreate->hidden = false; + $locationCreate->remoteId = 'sindelfingen'; + $locationCreate->sortField = Location::SORT_FIELD_NODE_ID; + $locationCreate->sortOrder = Location::SORT_ORDER_DESC; + + $location = $locationService->createLocation( + $contentInfo, + $locationCreate + ); + /* END: Use Case */ + + $this->assertInstanceOf( + '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location', + $location + ); + + $this->assertTrue($location->invisible); + } + /** * Test for the createLocation() method with utilizing default ContentType sorting options. * diff --git a/eZ/Publish/API/Repository/Values/Content/Location.php b/eZ/Publish/API/Repository/Values/Content/Location.php index 5ff774c813..e76e8dcf1f 100644 --- a/eZ/Publish/API/Repository/Values/Content/Location.php +++ b/eZ/Publish/API/Repository/Values/Content/Location.php @@ -20,7 +20,7 @@ * @property-read int $id the id of the location * @property-read int $priority Position of the Location among its siblings when sorted using priority * @property-read bool $hidden Indicates that the Location entity is hidden (explicitly or hidden by content). - * @property-read bool $invisible Indicates that the Location is implicitly marked as hidden by a parent location + * @property-read bool $invisible Indicates that the Location is not visible, being either marked as hidden itself, or implicitly hidden by its Content or an ancestor Location * @property-read bool $explicitlyHidden Indicates that the Location entity has been explicitly marked as hidden. * @property-read string $remoteId a global unique id of the content object * @property-read int $parentLocationId the id of the parent location @@ -121,8 +121,8 @@ abstract class Location extends ValueObject protected $hidden; /** - * Indicates that the Location is implicitly marked as hidden by a parent - * location. + * Indicates that the Location is not visible, being either marked as hidden itself, + * or implicitly hidden by its Content or an ancestor Location. * * @var bool */ diff --git a/eZ/Publish/Core/Repository/ContentService.php b/eZ/Publish/Core/Repository/ContentService.php index f42e3729f5..94991279c6 100644 --- a/eZ/Publish/Core/Repository/ContentService.php +++ b/eZ/Publish/Core/Repository/ContentService.php @@ -808,7 +808,8 @@ protected function buildSPILocationCreateStructs(array $locationCreateStructs): $mainLocation, // For Content draft contentId and contentVersionNo are set in ContentHandler upon draft creation null, - null + null, + false ); // First Location in the list will be created as main Location diff --git a/eZ/Publish/Core/Repository/LocationService.php b/eZ/Publish/Core/Repository/LocationService.php index fad539a777..dc4ed4a6fe 100644 --- a/eZ/Publish/Core/Repository/LocationService.php +++ b/eZ/Publish/Core/Repository/LocationService.php @@ -483,7 +483,8 @@ public function createLocation(ContentInfo $contentInfo, LocationCreateStruct $l $parentLocation, $contentInfo->mainLocationId ?? true, $contentInfo->id, - $contentInfo->currentVersionNo + $contentInfo->currentVersionNo, + $contentInfo->isHidden ); $this->repository->beginTransaction(); diff --git a/eZ/Publish/Core/Repository/Mapper/ContentDomainMapper.php b/eZ/Publish/Core/Repository/Mapper/ContentDomainMapper.php index 6bf5aebfae..35b6520a9d 100644 --- a/eZ/Publish/Core/Repository/Mapper/ContentDomainMapper.php +++ b/eZ/Publish/Core/Repository/Mapper/ContentDomainMapper.php @@ -673,6 +673,7 @@ public function buildLocationDomainObjectsOnSearchResult(SearchResult $result, a * @param mixed $mainLocation * @param mixed $contentId * @param mixed $contentVersionNo + * @param bool $isContentHidden * * @return \eZ\Publish\SPI\Persistence\Content\Location\CreateStruct */ @@ -681,7 +682,8 @@ public function buildSPILocationCreateStruct( APILocation $parentLocation, $mainLocation, $contentId, - $contentVersionNo + $contentVersionNo, + bool $isContentHidden ) { if (!$this->isValidLocationPriority($locationCreateStruct->priority)) { throw new InvalidArgumentValue('priority', $locationCreateStruct->priority, 'LocationCreateStruct'); @@ -723,10 +725,10 @@ public function buildSPILocationCreateStruct( 'priority' => $locationCreateStruct->priority, 'hidden' => $locationCreateStruct->hidden, // If we declare the new Location as hidden, it is automatically invisible - // Otherwise it picks up visibility from parent Location + // Otherwise it picks up visibility from parent Location and Content // Note: There is no need to check for hidden status of parent, as hidden Location // is always invisible as well - 'invisible' => ($locationCreateStruct->hidden === true || $parentLocation->invisible), + 'invisible' => ($locationCreateStruct->hidden === true || $parentLocation->invisible || $isContentHidden), 'remoteId' => $remoteId, 'contentId' => $contentId, 'contentVersion' => $contentVersionNo, diff --git a/eZ/Publish/Core/Repository/Tests/Service/Mock/ContentTest.php b/eZ/Publish/Core/Repository/Tests/Service/Mock/ContentTest.php index 30a6865ad6..42d98c5b4d 100644 --- a/eZ/Publish/Core/Repository/Tests/Service/Mock/ContentTest.php +++ b/eZ/Publish/Core/Repository/Tests/Service/Mock/ContentTest.php @@ -2659,7 +2659,8 @@ public function testCreateContentWithLocations() $this->equalTo($parentLocation), $this->equalTo(true), $this->equalTo(null), - $this->equalTo(null) + $this->equalTo(null), + $this->equalTo(false) )->will($this->returnValue($spiLocationCreateStruct)); $domainMapperMock->expects($this->at(2)) @@ -2669,7 +2670,8 @@ public function testCreateContentWithLocations() $this->equalTo($parentLocation), $this->equalTo(false), $this->equalTo(null), - $this->equalTo(null) + $this->equalTo(null), + $this->equalTo(false) )->will($this->returnValue($spiLocationCreateStruct)); $spiContentCreateStruct = new SPIContentCreateStruct( @@ -2869,7 +2871,8 @@ function ($object) use ($that, $contentCreateStruct) { $this->equalTo($parentLocation), $this->equalTo(true), $this->equalTo(null), - $this->equalTo(null) + $this->equalTo(null), + $this->equalTo(false) )->will($this->returnValue($spiLocationCreateStruct)); $fieldTypeMock = $this->createMock(SPIFieldType::class);