Skip to content

Commit

Permalink
IBX-8418: Remove drafts when trashing its parent or ancestor location
Browse files Browse the repository at this point in the history
  • Loading branch information
barw4 committed Jul 2, 2024
1 parent 4ef331b commit d737438
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/contracts/Persistence/Content/Location/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ public function create(CreateStruct $location);
*/
public function removeSubtree($locationId);

/**
* Removes all draft contents that have no location assigned to them under the given parent location.
*/
public function deleteChildrenDrafts(int $locationId): void;

/**
* Set section on all content objects in the subtree.
* Only main locations will be updated.
Expand Down
14 changes: 14 additions & 0 deletions src/lib/Persistence/Cache/LocationHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,20 @@ public function removeSubtree($locationId)
return $return;
}

public function deleteChildrenDrafts(int $locationId): void
{
$this->logger->logCall(__METHOD__, ['location' => $locationId]);

$this->persistenceHandler->locationHandler()->deleteChildrenDrafts($locationId);

$this->cache->invalidateTags([
$this->cacheIdentifierGenerator->generateTag(
self::LOCATION_PATH_IDENTIFIER,
[$locationId],
),
]);
}

/**
* {@inheritdoc}
*/
Expand Down
7 changes: 7 additions & 0 deletions src/lib/Persistence/Legacy/Content/Location/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ abstract public function loadParentLocationsDataForDraftContent(int $contentId):
*/
abstract public function getSubtreeContent(int $sourceId, bool $onlyIds = false): array;

/**
* Finds draft contents created under the given parent location.
*
* @return array<int>
*/
abstract public function getSubtreeChildrenDraftContentIds(int $sourceId): array;

abstract public function getSubtreeSize(string $path): int;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\DBAL\Result;
use Ibexa\Contracts\Core\Persistence\Content\ContentInfo;
use Ibexa\Contracts\Core\Persistence\Content\Location;
use Ibexa\Contracts\Core\Persistence\Content\Location\CreateStruct;
Expand Down Expand Up @@ -237,6 +238,29 @@ public function getSubtreeContent(int $sourceId, bool $onlyIds = false): array
: $results;
}

/**
* @return array<int>
*
* @throws \Doctrine\DBAL\Exception
* @throws \Doctrine\DBAL\Driver\Exception
*/
public function getSubtreeChildrenDraftContentIds(int $sourceId): array
{
$query = $this->connection->createQueryBuilder();
$query
->select('contentobject_id')
->from('eznode_assignment', 'n')
->innerJoin('n', 'ezcontentobject', 'c', 'n.contentobject_id = c.id')
->andWhere('n.parent_node = :parentNode')
->andWhere('c.status = :status')
->setParameter(':parentNode', $sourceId, ParameterType::INTEGER)
->setParameter(':status', ContentInfo::STATUS_DRAFT, ParameterType::INTEGER);

$statement = $query->execute();

return $statement instanceof Result ? $statement->fetchFirstColumn() : [];
}

public function getSubtreeSize(string $path): int
{
$query = $this->createNodeQueryBuilder([$this->dbPlatform->getCountExpression('node_id')]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ public function getSubtreeContent(int $sourceId, bool $onlyIds = false): array
}
}

/**
* @return array<int>
*/
public function getSubtreeChildrenDraftContentIds(int $sourceId): array
{
try {
return $this->innerGateway->getSubtreeChildrenDraftContentIds($sourceId);
} catch (PDOException $e) {
throw DatabaseException::wrap($e);
}
}

public function getSubtreeSize(string $path): int
{
try {
Expand Down
5 changes: 5 additions & 0 deletions src/lib/Persistence/Legacy/Content/Location/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,11 @@ public function removeSubtree($locationId)
$this->treeHandler->removeSubtree($locationId);
}

public function deleteChildrenDrafts(int $locationId): void
{
$this->treeHandler->deleteChildrenDrafts($locationId);
}

/**
* Set section on all content objects in the subtree.
*
Expand Down
20 changes: 20 additions & 0 deletions src/lib/Persistence/Legacy/Content/TreeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,26 @@ public function removeSubtree($locationId)
$this->locationGateway->deleteNodeAssignment($contentId);
}

/**
* Removes draft contents assigned to the given parent location and its descendant locations.
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
*/
public function deleteChildrenDrafts(int $locationId): void
{
$subLocations = $this->locationGateway->getChildren($locationId);
foreach ($subLocations as $subLocation) {
$this->deleteChildrenDrafts($subLocation['node_id']);
}

// Fetch child draft content ids
$subtreeChildrenDraftIds = $this->locationGateway->getSubtreeChildrenDraftContentIds($locationId);

foreach ($subtreeChildrenDraftIds as $contentId) {
$this->removeRawContent($contentId);
}
}

/**
* Set section on all content objects in the subtree.
*
Expand Down
1 change: 1 addition & 0 deletions src/lib/Repository/TrashService.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ public function trash(Location $location): ?APITrashItem

$this->repository->beginTransaction();
try {
$this->persistenceHandler->locationHandler()->deleteChildrenDrafts($location->id);
$spiTrashItem = $this->persistenceHandler->trashHandler()->trashSubtree($location->id);
$this->persistenceHandler->urlAliasHandler()->locationDeleted($location->id);
$this->repository->commit();
Expand Down

0 comments on commit d737438

Please sign in to comment.