Skip to content

Commit 02200e6

Browse files
authored
IBX-8418: Fixed removing orphaned drafts when trashing or deleting its ancestors (#439)
For more details see https://issues.ibexa.co/browse/IBX-8418 and #439 Key changes: * Fixed removing orphaned draft when trashing or deleting its parent or ancestor location
1 parent 9e313d2 commit 02200e6

File tree

16 files changed

+284
-15
lines changed

16 files changed

+284
-15
lines changed

phpstan-baseline.neon

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19010,11 +19010,6 @@ parameters:
1901019010
count: 1
1901119011
path: src/lib/Persistence/Legacy/User/Mapper.php
1901219012

19013-
-
19014-
message: "#^array\\|string does not accept array\\<int, mixed\\>\\.$#"
19015-
count: 1
19016-
path: src/lib/Persistence/Legacy/User/Mapper.php
19017-
1901819013
-
1901919014
message: "#^Method Ibexa\\\\Core\\\\Persistence\\\\Legacy\\\\User\\\\Role\\\\Gateway\\:\\:addPolicyLimitations\\(\\) has parameter \\$limitations with no value type specified in iterable type array\\.$#"
1902019015
count: 1
@@ -27090,23 +27085,18 @@ parameters:
2709027085
count: 5
2709127086
path: tests/integration/Core/Repository/ContentServiceTest.php
2709227087

27093-
-
27094-
message: "#^Cannot access offset 0 on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\Relation\\>\\.$#"
27095-
count: 12
27096-
path: tests/integration/Core/Repository/ContentServiceTest.php
27097-
2709827088
-
2709927089
message: "#^Cannot access offset 0 on iterable\\<Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\VersionInfo\\>\\.$#"
2710027090
count: 7
2710127091
path: tests/integration/Core/Repository/ContentServiceTest.php
2710227092

2710327093
-
27104-
message: "#^Cannot access offset 0 on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\VersionInfo\\>\\.$#"
27105-
count: 4
27094+
message: "#^Cannot access offset 0 on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\Relation\\>\\.$#"
27095+
count: 12
2710627096
path: tests/integration/Core/Repository/ContentServiceTest.php
2710727097

2710827098
-
27109-
message: "#^Cannot access offset 1 on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\Relation\\>\\.$#"
27099+
message: "#^Cannot access offset 0 on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\VersionInfo\\>\\.$#"
2711027100
count: 4
2711127101
path: tests/integration/Core/Repository/ContentServiceTest.php
2711227102

@@ -27115,6 +27105,11 @@ parameters:
2711527105
count: 2
2711627106
path: tests/integration/Core/Repository/ContentServiceTest.php
2711727107

27108+
-
27109+
message: "#^Cannot access offset 1 on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\Relation\\>\\.$#"
27110+
count: 4
27111+
path: tests/integration/Core/Repository/ContentServiceTest.php
27112+
2711827113
-
2711927114
message: "#^Cannot access offset 1 on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\VersionInfo\\>\\.$#"
2712027115
count: 1
@@ -27141,12 +27136,12 @@ parameters:
2714127136
path: tests/integration/Core/Repository/ContentServiceTest.php
2714227137

2714327138
-
27144-
message: "#^Cannot access offset mixed on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\ContentInfo\\>\\.$#"
27139+
message: "#^Cannot access offset int on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\VersionInfo\\>\\.$#"
2714527140
count: 1
2714627141
path: tests/integration/Core/Repository/ContentServiceTest.php
2714727142

2714827143
-
27149-
message: "#^Cannot access offset int on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\VersionInfo\\>\\.$#"
27144+
message: "#^Cannot access offset mixed on iterable\\<int, Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\Values\\\\Content\\\\ContentInfo\\>\\.$#"
2715027145
count: 1
2715127146
path: tests/integration/Core/Repository/ContentServiceTest.php
2715227147

src/contracts/Persistence/Content/Location/Handler.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ public function create(CreateStruct $location);
215215
*/
216216
public function removeSubtree($locationId);
217217

218+
/**
219+
* Removes all draft contents that have no location assigned to them under the given parent location.
220+
*/
221+
public function deleteChildrenDrafts(int $locationId): void;
222+
218223
/**
219224
* Set section on all content objects in the subtree.
220225
* Only main locations will be updated.

src/contracts/Test/IbexaKernelTestTrait.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Ibexa\Contracts\Core\Repository\RoleService;
2020
use Ibexa\Contracts\Core\Repository\SearchService;
2121
use Ibexa\Contracts\Core\Repository\SectionService;
22+
use Ibexa\Contracts\Core\Repository\TrashService;
2223
use Ibexa\Contracts\Core\Repository\URLAliasService;
2324
use Ibexa\Contracts\Core\Repository\UserService;
2425
use Ibexa\Contracts\Core\Test\Persistence\Fixture\FixtureImporter;
@@ -169,6 +170,11 @@ protected static function getUrlAliasService(): URLAliasService
169170
return self::getServiceByClassName(URLAliasService::class);
170171
}
171172

173+
protected static function getTrashService(): TrashService
174+
{
175+
return self::getServiceByClassName(TrashService::class);
176+
}
177+
172178
protected static function setAnonymousUser(): void
173179
{
174180
$anonymousUserId = 10;

src/contracts/Test/IbexaTestKernel.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class IbexaTestKernel extends Kernel implements IbexaTestKernelInterface
9292
Repository\TokenService::class,
9393
Repository\URLAliasService::class,
9494
Repository\BookmarkService::class,
95+
Repository\TrashService::class,
9596
Handler::class,
9697
];
9798

src/lib/Persistence/Cache/LocationHandler.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,20 @@ public function removeSubtree($locationId)
415415
return $return;
416416
}
417417

418+
public function deleteChildrenDrafts(int $locationId): void
419+
{
420+
$this->logger->logCall(__METHOD__, ['location' => $locationId]);
421+
422+
$this->persistenceHandler->locationHandler()->deleteChildrenDrafts($locationId);
423+
424+
$this->cache->invalidateTags([
425+
$this->cacheIdentifierGenerator->generateTag(
426+
self::LOCATION_PATH_IDENTIFIER,
427+
[$locationId],
428+
),
429+
]);
430+
}
431+
418432
/**
419433
* {@inheritdoc}
420434
*/

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ public function deleteContent($contentId)
650650
$this->removeRawContent($contentId);
651651
} else {
652652
foreach ($contentLocations as $locationId) {
653+
$this->treeHandler->deleteChildrenDrafts($locationId);
653654
$this->treeHandler->removeSubtree($locationId);
654655
}
655656
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ abstract public function loadParentLocationsDataForDraftContent(int $contentId):
111111
*/
112112
abstract public function getSubtreeContent(int $sourceId, bool $onlyIds = false): array;
113113

114+
/**
115+
* Finds draft contents created under the given parent location.
116+
*
117+
* @return array<int>
118+
*/
119+
abstract public function getSubtreeChildrenDraftContentIds(int $sourceId): array;
120+
114121
abstract public function getSubtreeSize(string $path): int;
115122

116123
/**

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,29 @@ public function getSubtreeContent(int $sourceId, bool $onlyIds = false): array
237237
: $results;
238238
}
239239

240+
/**
241+
* @return array<int>
242+
*
243+
* @throws \Doctrine\DBAL\Exception
244+
* @throws \Doctrine\DBAL\Driver\Exception
245+
*/
246+
public function getSubtreeChildrenDraftContentIds(int $sourceId): array
247+
{
248+
$query = $this->connection->createQueryBuilder();
249+
$query
250+
->select('contentobject_id')
251+
->from('eznode_assignment', 'n')
252+
->innerJoin('n', 'ezcontentobject', 'c', 'n.contentobject_id = c.id')
253+
->andWhere('n.parent_node = :parentNode')
254+
->andWhere('c.status = :status')
255+
->setParameter(':parentNode', $sourceId, ParameterType::INTEGER)
256+
->setParameter(':status', ContentInfo::STATUS_DRAFT, ParameterType::INTEGER);
257+
258+
$statement = $query->execute();
259+
260+
return $statement->fetchFirstColumn();
261+
}
262+
240263
public function getSubtreeSize(string $path): int
241264
{
242265
$query = $this->createNodeQueryBuilder([$this->dbPlatform->getCountExpression('node_id')]);

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ public function getSubtreeContent(int $sourceId, bool $onlyIds = false): array
106106
}
107107
}
108108

109+
/**
110+
* @return array<int>
111+
*/
112+
public function getSubtreeChildrenDraftContentIds(int $sourceId): array
113+
{
114+
try {
115+
return $this->innerGateway->getSubtreeChildrenDraftContentIds($sourceId);
116+
} catch (PDOException $e) {
117+
throw DatabaseException::wrap($e);
118+
}
119+
}
120+
109121
public function getSubtreeSize(string $path): int
110122
{
111123
try {

src/lib/Persistence/Legacy/Content/Location/Handler.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,11 @@ public function removeSubtree($locationId)
546546
$this->treeHandler->removeSubtree($locationId);
547547
}
548548

549+
public function deleteChildrenDrafts(int $locationId): void
550+
{
551+
$this->treeHandler->deleteChildrenDrafts($locationId);
552+
}
553+
549554
/**
550555
* Set section on all content objects in the subtree.
551556
*

0 commit comments

Comments
 (0)