Skip to content

Commit b6d3e70

Browse files
Merge remote-tracking branch 'origin/4.5' into 4.6
# Conflicts: # phpstan-baseline.neon
2 parents 045cb9e + 4ccc0fa commit b6d3e70

File tree

15 files changed

+543
-39
lines changed

15 files changed

+543
-39
lines changed

phpstan-baseline.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16027,7 +16027,7 @@ parameters:
1602716027

1602816028
-
1602916029
message: "#^Cannot call method fetchAll\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#"
16030-
count: 17
16030+
count: 16
1603116031
path: src/lib/Persistence/Legacy/Content/Gateway/DoctrineDatabase.php
1603216032

1603316033
-

src/contracts/Persistence/Content/Handler.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ public function removeRelation($relationId, $type, ?int $destinationContentId =
283283
/**
284284
* Loads relations from $sourceContentId. Optionally, loads only those with $type and $sourceContentVersionNo.
285285
*
286+
* @deprecated 4.5.7 The "ContentService::loadRelations()" method is deprecated, will be removed in 5.0.
287+
*
286288
* @param mixed $sourceContentId Source Content ID
287289
* @param mixed|null $sourceContentVersionNo Source Content Version, null if not specified
288290
* @param int|null $type {@see \Ibexa\Contracts\Core\Repository\Values\Content\Relation::COMMON,
@@ -294,6 +296,26 @@ public function removeRelation($relationId, $type, ?int $destinationContentId =
294296
*/
295297
public function loadRelations($sourceContentId, $sourceContentVersionNo = null, $type = null);
296298

299+
/**
300+
* Counts all outgoing relations for the given version.
301+
*/
302+
public function countRelations(
303+
int $sourceContentId,
304+
?int $sourceContentVersionNo = null,
305+
?int $type = null
306+
): int;
307+
308+
/**
309+
* @return \Ibexa\Contracts\Core\Persistence\Content\Relation[]
310+
*/
311+
public function loadRelationList(
312+
int $sourceContentId,
313+
int $limit,
314+
int $offset = 0,
315+
?int $sourceContentVersionNo = null,
316+
?int $type = null
317+
): array;
318+
297319
/**
298320
* Counts relations from $destinationContentId only against published versions. Optionally, count only those with $type.
299321
*

src/contracts/Repository/ContentService.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
*/
3131
interface ContentService
3232
{
33+
public const DEFAULT_PAGE_SIZE = 25;
34+
3335
/**
3436
* Loads a content info object.
3537
*
@@ -398,12 +400,36 @@ public function copyContent(ContentInfo $contentInfo, LocationCreateStruct $dest
398400
*
399401
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException if the user is not allowed to read this version
400402
*
401-
* @param \Ibexa\Contracts\Core\Repository\Values\Content\VersionInfo $versionInfo
403+
* @deprecated 4.5.7 The "ContentService::loadRelations()" method is deprecated, will be removed in 5.0.
402404
*
403405
* @return \Ibexa\Contracts\Core\Repository\Values\Content\Relation[]
404406
*/
405407
public function loadRelations(VersionInfo $versionInfo): iterable;
406408

409+
/**
410+
* Loads all outgoing relations for the given version.
411+
*
412+
* If the user is not allowed to read specific version then a returned `RelationList` will contain `UnauthorizedRelationListItem`
413+
*
414+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
415+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
416+
*
417+
* @see \Ibexa\Contracts\Core\Repository\Values\Content\RelationList\Item\UnauthorizedRelationListItem
418+
*/
419+
public function loadRelationList(
420+
VersionInfo $versionInfo,
421+
int $offset = 0,
422+
int $limit = self::DEFAULT_PAGE_SIZE
423+
): RelationList;
424+
425+
/**
426+
* Counts all outgoing relations for the given version.
427+
*
428+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
429+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
430+
*/
431+
public function countRelations(VersionInfo $versionInfo): int;
432+
407433
/**
408434
* Counts all incoming relations for the given content object.
409435
*

src/contracts/Repository/Decorator/ContentServiceDecorator.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ public function loadRelations(VersionInfo $versionInfo): iterable
193193
return $this->innerService->loadRelations($versionInfo);
194194
}
195195

196+
public function countRelations(VersionInfo $versionInfo): int
197+
{
198+
return $this->innerService->countRelations($versionInfo);
199+
}
200+
201+
public function loadRelationList(VersionInfo $versionInfo, int $offset = 0, int $limit = self::DEFAULT_PAGE_SIZE): RelationList
202+
{
203+
return $this->innerService->loadRelationList($versionInfo, $offset, $limit);
204+
}
205+
196206
public function countReverseRelations(ContentInfo $contentInfo): int
197207
{
198208
return $this->innerService->countReverseRelations($contentInfo);

src/lib/Persistence/Cache/ContentHandler.php

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class ContentHandler extends AbstractInMemoryPersistenceHandler implements Conte
3131
private const CONTENT_VERSION_LIST_IDENTIFIER = 'content_version_list';
3232
private const CONTENT_VERSION_INFO_IDENTIFIER = 'content_version_info';
3333
private const CONTENT_VERSION_IDENTIFIER = 'content_version';
34+
private const CONTENT_RELATIONS_COUNT_WITH_VERSION_TYPE_IDENTIFIER = 'content_relations_count_with_by_version_type_suffix';
35+
private const CONTENT_RELATION_IDENTIFIER = 'content_relation';
36+
private const CONTENT_RELATIONS_LIST_IDENTIFIER = 'content_relations_list';
37+
private const CONTENT_RELATIONS_LIST_WITH_VERSION_TYPE_IDENTIFIER = 'content_relations_list_with_by_version_type_suffix';
3438
private const CONTENT_REVERSE_RELATIONS_COUNT_IDENTIFIER = 'content_reverse_relations_count';
3539
private const RELATION_IDENTIFIER = 'relation';
3640

@@ -517,6 +521,97 @@ public function loadRelations($sourceContentId, $sourceContentVersionNo = null,
517521
return $this->persistenceHandler->contentHandler()->loadRelations($sourceContentId, $sourceContentVersionNo, $type);
518522
}
519523

524+
public function countRelations(int $sourceContentId, ?int $sourceContentVersionNo = null, ?int $type = null): int
525+
{
526+
$cacheItem = $this->cache->getItem(
527+
$this->cacheIdentifierGenerator->generateKey(
528+
self::CONTENT_RELATIONS_COUNT_WITH_VERSION_TYPE_IDENTIFIER,
529+
[$sourceContentId, $sourceContentVersionNo, $type],
530+
true
531+
)
532+
);
533+
534+
if ($cacheItem->isHit()) {
535+
$this->logger->logCacheHit(['content' => $sourceContentId, 'version' => $sourceContentVersionNo, 'type' => $type]);
536+
537+
return $cacheItem->get();
538+
}
539+
540+
$this->logger->logCacheMiss(['content' => $sourceContentId, 'version' => $sourceContentVersionNo, 'type' => $type]);
541+
$relationsCount = $this->persistenceHandler->contentHandler()->countRelations(
542+
$sourceContentId,
543+
$sourceContentVersionNo,
544+
$type
545+
);
546+
$cacheItem->set($relationsCount);
547+
$tags = [
548+
$this->cacheIdentifierGenerator->generateTag(
549+
self::CONTENT_IDENTIFIER,
550+
[$sourceContentId]
551+
),
552+
];
553+
554+
$cacheItem->tag($tags);
555+
$this->cache->save($cacheItem);
556+
557+
return $relationsCount;
558+
}
559+
560+
public function loadRelationList(
561+
int $sourceContentId,
562+
int $limit,
563+
int $offset = 0,
564+
?int $sourceContentVersionNo = null,
565+
?int $type = null
566+
): array {
567+
return $this->getListCacheValue(
568+
$this->cacheIdentifierGenerator->generateKey(
569+
self::CONTENT_RELATIONS_LIST_WITH_VERSION_TYPE_IDENTIFIER,
570+
[$sourceContentId, $limit, $offset, $sourceContentVersionNo, $type],
571+
true
572+
),
573+
function () use ($sourceContentId, $limit, $offset, $sourceContentVersionNo, $type): array {
574+
return $this->persistenceHandler->contentHandler()->loadRelationList(
575+
$sourceContentId,
576+
$limit,
577+
$offset,
578+
$sourceContentVersionNo,
579+
$type
580+
);
581+
},
582+
function (Relation $relation): array {
583+
return [
584+
$this->cacheIdentifierGenerator->generateTag(
585+
self::CONTENT_RELATION_IDENTIFIER,
586+
[$relation->destinationContentId]
587+
),
588+
$this->cacheIdentifierGenerator->generateTag(
589+
self::CONTENT_IDENTIFIER,
590+
[$relation->destinationContentId]
591+
),
592+
];
593+
},
594+
function (Relation $relation): array {
595+
return [
596+
$this->cacheIdentifierGenerator->generateKey(self::CONTENT_IDENTIFIER, [$relation->destinationContentId], true),
597+
];
598+
},
599+
function () use ($sourceContentId): array {
600+
return [
601+
$this->cacheIdentifierGenerator->generateTag(
602+
self::CONTENT_RELATIONS_LIST_IDENTIFIER,
603+
[$sourceContentId]
604+
),
605+
$this->cacheIdentifierGenerator->generateTag(
606+
self::CONTENT_IDENTIFIER,
607+
[$sourceContentId]
608+
),
609+
];
610+
},
611+
[$sourceContentId, $limit, $offset, $sourceContentVersionNo, $type]
612+
);
613+
}
614+
520615
/**
521616
* {@inheritdoc}
522617
*/

src/lib/Persistence/Legacy/Content/Gateway.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,29 @@ abstract public function loadRelations(
361361
): array;
362362

363363
/**
364-
* Count number of related to/from $contentId.
364+
* Counts number of related to/from $contentId.
365+
*/
366+
abstract public function countRelations(
367+
int $contentId,
368+
?int $contentVersionNo = null,
369+
?int $relationType = null
370+
): int;
371+
372+
/**
373+
* Loads paginated data of related to/from $contentId.
374+
*
375+
* @return array<array<string, mixed>>
376+
*/
377+
abstract public function listRelations(
378+
int $contentId,
379+
int $limit,
380+
int $offset = 0,
381+
?int $contentVersionNo = null,
382+
?int $relationType = null
383+
): array;
384+
385+
/**
386+
* Counts number of related to/from $contentId.
365387
*/
366388
abstract public function countReverseRelations(int $contentId, ?int $relationType = null): int;
367389

src/lib/Persistence/Legacy/Content/Gateway/DoctrineDatabase.php

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,18 +1387,61 @@ public function loadRelations(
13871387
?int $relationType = null
13881388
): array {
13891389
$query = $this->queryBuilder->createRelationFindQueryBuilder();
1390+
$query = $this->prepareRelationQuery($query, $contentId, $contentVersionNo, $relationType);
1391+
1392+
return $query->execute()->fetchAllAssociative();
1393+
}
1394+
1395+
public function countRelations(
1396+
int $contentId,
1397+
?int $contentVersionNo = null,
1398+
?int $relationType = null
1399+
): int {
1400+
$query = $this->connection->createQueryBuilder();
1401+
$query->select($this->databasePlatform->getCountExpression('l.id'))
1402+
->from(self::CONTENT_RELATION_TABLE, 'l');
1403+
1404+
$query = $this->prepareRelationQuery($query, $contentId, $contentVersionNo, $relationType);
1405+
1406+
return (int)$query->execute()->fetchOne();
1407+
}
1408+
1409+
public function listRelations(
1410+
int $contentId,
1411+
int $limit,
1412+
int $offset = 0,
1413+
?int $contentVersionNo = null,
1414+
?int $relationType = null
1415+
): array {
1416+
$query = $this->queryBuilder->createRelationFindQueryBuilder();
1417+
$query = $this->prepareRelationQuery($query, $contentId, $contentVersionNo, $relationType);
1418+
1419+
$query->setFirstResult($offset)
1420+
->setMaxResults($limit);
1421+
1422+
$query->orderBy('l.id', 'DESC');
1423+
1424+
return $query->execute()->fetchAllAssociative();
1425+
}
1426+
1427+
private function prepareRelationQuery(
1428+
DoctrineQueryBuilder $query,
1429+
int $contentId,
1430+
?int $contentVersionNo = null,
1431+
?int $relationType = null
1432+
): DoctrineQueryBuilder {
13901433
$expr = $query->expr();
13911434
$query
13921435
->innerJoin(
13931436
'l',
1394-
'ezcontentobject',
1395-
'ezcontentobject_to',
1396-
$expr->andX(
1397-
'l.to_contentobject_id = ezcontentobject_to.id',
1398-
'ezcontentobject_to.status = :status'
1437+
self::CONTENT_ITEM_TABLE,
1438+
'c_to',
1439+
$expr->and(
1440+
'l.to_contentobject_id = c_to.id',
1441+
'c_to.status = :status'
13991442
)
14001443
)
1401-
->where(
1444+
->andWhere(
14021445
'l.from_contentobject_id = :content_id'
14031446
)
14041447
->setParameter(
@@ -1409,18 +1452,18 @@ public function loadRelations(
14091452
->setParameter('content_id', $contentId, ParameterType::INTEGER);
14101453

14111454
// source version number
1412-
if (null !== $contentVersionNo) {
1455+
if ($contentVersionNo !== null) {
14131456
$query
14141457
->andWhere('l.from_contentobject_version = :version_no')
14151458
->setParameter('version_no', $contentVersionNo, ParameterType::INTEGER);
14161459
} else {
14171460
// from published version only
14181461
$query
14191462
->innerJoin(
1420-
'ezcontentobject_to',
1421-
'ezcontentobject',
1463+
'c_to',
1464+
self::CONTENT_ITEM_TABLE,
14221465
'c',
1423-
$expr->andX(
1466+
$expr->and(
14241467
'c.id = l.from_contentobject_id',
14251468
'c.current_version = l.from_contentobject_version'
14261469
)
@@ -1442,7 +1485,7 @@ public function loadRelations(
14421485
->setParameter('relation_type', $relationType, ParameterType::INTEGER);
14431486
}
14441487

1445-
return $query->execute()->fetchAll(FetchMode::ASSOCIATIVE);
1488+
return $query;
14461489
}
14471490

14481491
public function countReverseRelations(int $toContentId, ?int $relationType = null): int

src/lib/Persistence/Legacy/Content/Gateway/ExceptionConversion.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,38 @@ public function loadRelations(
392392
}
393393
}
394394

395+
public function countRelations(
396+
int $contentId,
397+
?int $contentVersionNo = null,
398+
?int $relationType = null
399+
): int {
400+
try {
401+
return $this->innerGateway->countRelations($contentId, $contentVersionNo, $relationType);
402+
} catch (DBALException | PDOException $e) {
403+
throw DatabaseException::wrap($e);
404+
}
405+
}
406+
407+
public function listRelations(
408+
int $contentId,
409+
int $limit,
410+
int $offset = 0,
411+
?int $contentVersionNo = null,
412+
?int $relationType = null
413+
): array {
414+
try {
415+
return $this->innerGateway->listRelations(
416+
$contentId,
417+
$limit,
418+
$offset,
419+
$contentVersionNo,
420+
$relationType
421+
);
422+
} catch (DBALException | PDOException $e) {
423+
throw DatabaseException::wrap($e);
424+
}
425+
}
426+
395427
public function countReverseRelations(int $contentId, ?int $relationType = null): int
396428
{
397429
try {

0 commit comments

Comments
 (0)