Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EZP-30968: Added method to count the number of content's reverse relations #2774

Merged
merged 1 commit into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions eZ/Publish/API/Repository/ContentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,15 @@ public function copyContent(ContentInfo $contentInfo, LocationCreateStruct $dest
*/
public function loadRelations(VersionInfo $versionInfo);

/**
* Counts all incoming relations for the given content object.
*
* @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
*
* @return int The number of reverse relations ({@link Relation})
*/
public function countReverseRelations(ContentInfo $contentInfo): int;

/**
* Loads all incoming relations for a content object.
*
Expand Down
88 changes: 88 additions & 0 deletions eZ/Publish/API/Repository/Tests/ContentServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3490,6 +3490,59 @@ public function testLoadRelationsSkipsDraftContent()
);
}

/**
* Test for the countReverseRelations() method.
*
* @covers \eZ\Publish\API\Repository\ContentService::countReverseRelations
*/
public function testCountReverseRelations(): void
{
$contentWithReverseRelations = $this->createContentWithReverseRelations([
$this->contentService->createContentDraft(
$this->createFolder([self::ENG_GB => 'Foo'], 2)->contentInfo
),
$this->contentService->createContentDraft(
$this->createFolder([self::ENG_GB => 'Bar'], 2)->contentInfo
),
]);

$contentInfo = $contentWithReverseRelations->content->getVersionInfo()->getContentInfo();

$this->assertEquals(2, $this->contentService->countReverseRelations($contentInfo));
}

/**
* Test for the countReverseRelations() method.
*
* @covers \eZ\Publish\API\Repository\ContentService::countReverseRelations
*/
public function testCountReverseRelationsReturnsZeroByDefault(): void
{
$draft = $this->createContentDraftVersion1();

$this->assertSame(0, $this->contentService->countReverseRelations($draft->getVersionInfo()->getContentInfo()));
}

/**
* Test for the countReverseRelations() method.
*
* @covers \eZ\Publish\API\Repository\ContentService::countReverseRelations
*/
public function testCountReverseRelationsForUnauthorizedUser(): void
{
$contentWithReverseRelations = $this->createContentWithReverseRelations([
$this->contentService->createContentDraft(
$this->createFolder([self::ENG_GB => 'Foo'], 2)->contentInfo
),
]);
$mediaUser = $this->createMediaUserVersion1();
$this->permissionResolver->setCurrentUserReference($mediaUser);

$contentInfo = $contentWithReverseRelations->content->contentInfo;

$this->assertSame(0, $this->contentService->countReverseRelations($contentInfo));
}

/**
* Test for the loadReverseRelations() method.
*
Expand Down Expand Up @@ -6164,4 +6217,39 @@ private function createUserWithVersionReadLimitations(array $limitationValues =
]
);
}

/**
* @param \eZ\Publish\API\Repository\Values\Content\Content[] $drafts
*
* @throws \eZ\Publish\API\Repository\Exceptions\BadStateException
* @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
*
* @return object
*/
private function createContentWithReverseRelations(array $drafts)
alongosz marked this conversation as resolved.
Show resolved Hide resolved
{
$contentWithReverseRelations = new class() {
/** @var \eZ\Publish\API\Repository\Values\Content\Content */
public $content;

/** @var \eZ\Publish\API\Repository\Values\Content\Content[] */
public $reverseRelations;
};
$content = $this->createContentVersion1();
$versionInfo = $content->getVersionInfo();
$contentInfo = $versionInfo->getContentInfo();
$contentWithReverseRelations->content = $content;

/** @var \eZ\Publish\API\Repository\Values\Content\Content $draft */
foreach ($drafts as $draft) {
$this->contentService->addRelation(
$draft->getVersionInfo(),
$contentInfo
);

$contentWithReverseRelations->reverseRelations[] = $this->contentService->publishVersion($draft->getVersionInfo());
}

return $contentWithReverseRelations;
}
}
10 changes: 10 additions & 0 deletions eZ/Publish/Core/Persistence/Cache/ContentHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,16 @@ public function loadRelations($sourceContentId, $sourceContentVersionNo = null,
return $this->persistenceHandler->contentHandler()->loadRelations($sourceContentId, $sourceContentVersionNo, $type);
}

/**
* {@inheritdoc}
*/
public function countReverseRelations(int $destinationContentId, ?int $type = null): int
{
$this->logger->logCall(__METHOD__, ['content' => $destinationContentId, 'type' => $type]);

return $this->persistenceHandler->contentHandler()->countReverseRelations($destinationContentId, $type);
}

/**
* {@inheritdoc}
*/
Expand Down
10 changes: 10 additions & 0 deletions eZ/Publish/Core/Persistence/Legacy/Content/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,16 @@ abstract public function deleteContent($contentId);
*/
abstract public function loadRelations($contentId, $contentVersionNo = null, $relationType = null);

/**
* Counts number of related to/from $contentId.
*
* @param int $contentId
* @param int|null $relationType
*
* @return int
*/
abstract public function countReverseRelations(int $contentId, ?int $relationType = null): int;

/**
* Loads data of related to/from $contentId.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1940,6 +1940,45 @@ public function loadRelations($contentId, $contentVersionNo = null, $relationTyp
return $statement->fetchAll(\PDO::FETCH_ASSOC);
}

/**
* {@inheritdoc}
*/
public function countReverseRelations(int $toContentId, ?int $relationType = null): int
{
$platform = $this->connection->getDatabasePlatform();
$query = $this->connection->createQueryBuilder();
$expr = $query->expr();
$query
->select($platform->getCountExpression('l.id'))
->from('ezcontentobject_link', 'l')
->innerJoin(
'l',
'ezcontentobject',
'c',
$expr->andX(
$expr->eq('l.from_contentobject_id', 'c.id'),
$expr->eq('l.from_contentobject_version', 'c.current_version'),
$expr->eq('c.status', 1)
)
)
->where(
$expr->eq('l.to_contentobject_id', ':toContentId')
)
->setParameter(':toContentId', $toContentId, ParameterType::INTEGER);

// relation type
if ($relationType !== null) {
$query->andWhere(
$expr->gt(
$platform->getBitAndComparisonExpression('l.relation_type', $relationType),
0
)
);
}

return (int) $query->execute()->fetchColumn();
}

/**
* Loads data that related to $toContentId.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,18 @@ public function loadRelations($contentId, $contentVersionNo = null, $relationTyp
}
}

/**
* {@inheritdoc}
*/
public function countReverseRelations(int $contentId, ?int $relationType = null): int
{
try {
return $this->innerGateway->countReverseRelations($contentId, $relationType);
} catch (DBALException | PDOException $e) {
throw new RuntimeException('Database error', 0, $e);
}
}

/**
* Loads data of related to/from $contentId.
*
Expand Down
8 changes: 8 additions & 0 deletions eZ/Publish/Core/Persistence/Legacy/Content/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,14 @@ public function loadRelations($sourceContentId, $sourceContentVersionNo = null,
);
}

/**
* {@inheritdoc}
*/
public function countReverseRelations(int $destinationContentId, ?int $type = null): int
{
return $this->contentGateway->countReverseRelations($destinationContentId, $type);
}

/**
* Loads relations from $contentId. Optionally, loads only those with $type.
*
Expand Down
8 changes: 8 additions & 0 deletions eZ/Publish/Core/REST/Client/ContentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,14 @@ public function loadRelations(VersionInfo $versionInfo)
throw new \Exception('@todo: Implement.');
}

/**
* {@inheritdoc}
*/
public function countReverseRelations(ContentInfo $contentInfo): int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remember to drop it on merge up.

{
throw new \Exception('@todo: Implement.');
}

/**
* Loads all incoming relations for a content object.
*
Expand Down
14 changes: 14 additions & 0 deletions eZ/Publish/Core/Repository/ContentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -1943,6 +1943,20 @@ public function loadRelations(APIVersionInfo $versionInfo)
return $relations;
}

/**
* {@inheritdoc}
*/
public function countReverseRelations(ContentInfo $contentInfo): int
{
if (!$this->repository->canUser('content', 'reverserelatedlist', $contentInfo)) {
return 0;
alongosz marked this conversation as resolved.
Show resolved Hide resolved
}

return $this->persistenceHandler->contentHandler()->countReverseRelations(
$contentInfo->id
);
}

/**
* Loads all incoming relations for a content object.
*
Expand Down
8 changes: 8 additions & 0 deletions eZ/Publish/Core/Repository/SiteAccessAware/ContentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ public function loadRelations(VersionInfo $versionInfo)
return $this->service->loadRelations($versionInfo);
}

/**
* {@inheritdoc}
*/
public function countReverseRelations(ContentInfo $contentInfo): int
{
return $this->service->countReverseRelations($contentInfo);
}

public function loadReverseRelations(ContentInfo $contentInfo)
{
return $this->service->loadReverseRelations($contentInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public function providerForPassTroughMethods()

['loadRelations', [$versionInfo]],

['countReverseRelations', [$contentInfo]],

['loadReverseRelations', [$contentInfo]],

['addRelation', [$versionInfo, $contentInfo]],
Expand Down
8 changes: 8 additions & 0 deletions eZ/Publish/Core/SignalSlot/ContentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,14 @@ public function loadRelations(VersionInfo $versionInfo)
return $this->service->loadRelations($versionInfo);
}

/**
* {@inheritdoc}
*/
public function countReverseRelations(ContentInfo $contentInfo): int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remember to drop it on merge up.

{
return $this->service->countReverseRelations($contentInfo);
}

/**
* Loads all incoming relations for a content object.
*
Expand Down
6 changes: 6 additions & 0 deletions eZ/Publish/Core/SignalSlot/Tests/ContentServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ public function serviceProvider()
$relations,
0,
],
[
'countReverseRelations',
[$contentInfo],
0,
0,
],
[
'loadReverseRelations',
[$contentInfo],
Expand Down
10 changes: 10 additions & 0 deletions eZ/Publish/SPI/Persistence/Content/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,16 @@ public function removeRelation($relationId, $type);
*/
public function loadRelations($sourceContentId, $sourceContentVersionNo = null, $type = null);

/**
* Counts relations from $destinationContentId only against published versions. Optionally, count only those with $type.
*
* @param int $destinationContentId Destination Content ID
* @param int|null $type The relation type bitmask {@see \eZ\Publish\API\Repository\Values\Content\Relation}
*
* @return int
*/
public function countReverseRelations(int $destinationContentId, ?int $type = null): int;

/**
* Loads relations from $contentId. Optionally, loads only those with $type.
*
Expand Down