Skip to content

Commit

Permalink
Merge pull request #7 from mateuszbieniek/remove-orphaned-block-relat…
Browse files Browse the repository at this point in the history
…ed-records

Extend 'page-fieldtype-cleanup' command to remove leftovers
  • Loading branch information
mateuszbieniek authored Jan 20, 2022
2 parents 43a33a9 + e61aed4 commit 1e3a144
Show file tree
Hide file tree
Showing 4 changed files with 284 additions and 9 deletions.
75 changes: 66 additions & 9 deletions src/bundle/Command/PageFieldTypeCleanupCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace MateuszBieniek\EzPlatformDatabaseHealthCheckerBundle\Command;

use Exception;
use eZ\Publish\API\Repository\Repository;
use MateuszBieniek\EzPlatformDatabaseHealthChecker\Persistence\Legacy\Content\Gateway\PageFieldTypeGatewayInterface as Gateway;
use Symfony\Bundle\MakerBundle\Validator;
use Symfony\Component\Console\Command\Command;
Expand All @@ -22,9 +24,13 @@ class PageFieldTypeCleanupCommand extends Command
/** @var Gateway */
private $gateway;

public function __construct(Gateway $gateway)
/** @var \eZ\Publish\API\Repository\Repository */
private $repository;

public function __construct(Gateway $gateway, Repository $repository)
{
$this->gateway = $gateway;
$this->repository = $repository;

parent::__construct();
}
Expand Down Expand Up @@ -90,33 +96,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$limit = (int) $helper->ask($input, $output, $question);

if ($this->countOrphanedPageRelations() <= 0) {
return 0;
}

$this->countOrphanedPageRelations();
$this->deleteOrphanedPageRelations($limit);

$this->io->success('Done');

return 0;
}

private function countOrphanedPageRelations(): int
private function countOrphanedPageRelations(): void
{
$count = $this->gateway->countOrphanedPageRelations();

$count <= 0
? $this->io->success('Found: 0')
: $this->io->caution(sprintf('Found: %d orphaned pages', $count));

return $count;
}

private function deleteOrphanedPageRelations(int $limit): void
{
if (!$this->io->confirm(
sprintf('Are you sure that you want to proceed? The maximum number of pages that will be cleaned
in this iteration is equal to %d.', $limit),
in this iteration is equal to %d. If the number is equal to 0 you can still continue to run the remaining
cleaning methods.', $limit),
false)
) {
return;
Expand All @@ -132,5 +134,60 @@ private function deleteOrphanedPageRelations(int $limit): void
$this->gateway->removePage((int) $records[$i]);
}
}

$this->deleteUnrelatedLeftovers($limit);
}

private function deleteUnrelatedLeftovers(int $limit): void
{
$this->io->info('Orphaned blocks and related items which cannot be deleted using the standard procedure will be searched for now.');

$orphanedBlocks = $this->gateway->getOrphanedBlockIds($limit);
$orphanedAttributes = $this->gateway->getOrphanedAttributeIds($orphanedBlocks);

$this->io->caution(sprintf('Found %d orphaned blocks within the chosen limit.', count($orphanedBlocks)));

$this->io->caution(sprintf('Found %d orphaned attributes related to the found blocks.', count($orphanedAttributes)));

if (!$this->io->confirm('Are you sure that you want to proceed? The block-related records will be now removed.', false)) {
return;
}

$this->repository->beginTransaction();

try {
$progressBar = $this->io->createProgressBar(6);

$this->io->info('Removing orphaned ezpage_map_attributes_blocks records');
$this->gateway->removeOrphanedBlockAttributes($orphanedAttributes);
$progressBar->advance();

$this->io->info('Removing orphaned ezpage_attributes records');
$this->gateway->removeOrphanedAttributes($orphanedAttributes);
$progressBar->advance();

$this->io->info('Removing orphaned ezpage_blocks_design records');
$this->gateway->removeOrphanedBlockDesigns($orphanedBlocks);
$progressBar->advance();

$this->io->info('Removing orphaned ezpage_blocks_visibility records');
$this->gateway->removeOrphanedBlockVisibilities($orphanedBlocks);
$progressBar->advance();

$this->io->info('Removing orphaned ezpage_blocks records');
$this->gateway->removeOrphanedBlocks($orphanedBlocks);
$progressBar->advance();

$this->io->info('Removing orphaned ezpage_map_blocks_zones records');
$this->gateway->removeOrphanedBlocksZones($orphanedBlocks);
$progressBar->advance();

$this->io->newLine();

$this->repository->commit();
} catch (Exception $e) {
$this->repository->rollback();
throw $e;
}
}
}
1 change: 1 addition & 0 deletions src/bundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ services:
MateuszBieniek\EzPlatformDatabaseHealthCheckerBundle\Command\PageFieldTypeCleanupCommand:
arguments:
$gateway: '@MateuszBieniek\EzPlatformDatabaseHealthChecker\Persistence\Legacy\Content\Gateway\PageFieldTypeDoctrineDatabase'
$repository: '@ezpublish.api.repository'
tags:
- { name: 'console.command', command: 'ezplatform:page-fieldtype-cleanup' }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,180 @@ public function removePage(int $pageId): void
$this->pageFieldTypeGateway->removeZone((int) $zone['id']);
}
}

/**
* @inheritDoc
*/
public function getOrphanedBlockIds(int $limit): array
{
//fetching the first set via ezpage_map_blocks_zones table
$zonesQuery = $this->connection->createQueryBuilder();
$zonesQuery = $zonesQuery->select('id')
->from('ezpage_zones')
->getSQL();

$orphanedBlocksQuery = $this->connection->createQueryBuilder();
$orphanedBlocksQuery->select('block_id')
->from('ezpage_map_blocks_zones', 'bz')
->where(
$orphanedBlocksQuery->expr()->notIn(
'zone_id',
$zonesQuery
)
)
->setMaxResults($limit);

$firstResult = $orphanedBlocksQuery->execute()->fetchAll(FetchMode::COLUMN);

//fetching the second set via ezpage_map_zones_pages table
$pagesQuery = $this->connection->createQueryBuilder();
$pagesQuery = $pagesQuery->select('id')
->from('ezpage_pages')
->getSQL();

$secondZonesQuery = $this->connection->createQueryBuilder();
$secondZonesQuery->select('zone_id')
->from('ezpage_map_zones_pages', 'zp')
->where(
$secondZonesQuery->expr()->notIn(
'page_id',
$pagesQuery
)
);

$secondOrphanedBlocksQuery = $this->connection->createQueryBuilder();
$secondOrphanedBlocksQuery->select('block_id')
->from('ezpage_map_blocks_zones', 'bz')
->where(
$secondOrphanedBlocksQuery->expr()->in(
'zone_id',
$secondZonesQuery->getSQL()
)
)
->setMaxResults($limit);

$secondResult = $secondOrphanedBlocksQuery->execute()->fetchAll(FetchMode::COLUMN);

return array_unique(array_merge($firstResult, $secondResult));
}

/**
* @inheritDoc
*/
public function getOrphanedAttributeIds(array $blockIds): array
{
$orphanedAttributesQuery = $this->connection->createQueryBuilder();
$orphanedAttributesQuery->select('attribute_id')
->from('ezpage_map_attributes_blocks')
->where(
$orphanedAttributesQuery->expr()->in(
'block_id',
$orphanedAttributesQuery->createPositionalParameter($blockIds, Connection::PARAM_INT_ARRAY)
)
);

return $orphanedAttributesQuery->execute()->fetchAll(FetchMode::COLUMN);
}

/**
* @inheritDoc
*/
public function removeOrphanedBlockAttributes(array $attributeIds): void
{
$query = $this->connection->createQueryBuilder();
$query->delete('ezpage_map_attributes_blocks')
->where(
$query->expr()->in(
'attribute_id',
$query->createPositionalParameter($attributeIds, Connection::PARAM_INT_ARRAY)
)
);

$query->execute();
}

/**
* @inheritDoc
*/
public function removeOrphanedAttributes(array $attributeIds): void
{
$query = $this->connection->createQueryBuilder();
$query->delete('ezpage_attributes')
->where(
$query->expr()->in(
'id',
$query->createPositionalParameter($attributeIds, Connection::PARAM_INT_ARRAY)
)
);

$query->execute();
}

/**
* @inheritDoc
*/
public function removeOrphanedBlockDesigns(array $blockIds): void
{
$query = $this->connection->createQueryBuilder();
$query->delete('ezpage_blocks_design')
->where(
$query->expr()->in(
'block_id',
$query->createPositionalParameter($blockIds, Connection::PARAM_INT_ARRAY)
)
);

$query->execute();
}

/**
* @inheritDoc
*/
public function removeOrphanedBlockVisibilities(array $blockIds): void
{
$query = $this->connection->createQueryBuilder();
$query->delete('ezpage_blocks_visibility')
->where(
$query->expr()->in(
'block_id',
$query->createPositionalParameter($blockIds, Connection::PARAM_INT_ARRAY)
)
);

$query->execute();
}

/**
* @inheritDoc
*/
public function removeOrphanedBlocksZones(array $blockIds): void
{
$query = $this->connection->createQueryBuilder();
$query->delete('ezpage_map_blocks_zones')
->where(
$query->expr()->in(
'block_id',
$query->createPositionalParameter($blockIds, Connection::PARAM_INT_ARRAY)
)
);

$query->execute();
}

/**
* @inheritDoc
*/
public function removeOrphanedBlocks(array $blockIds): void
{
$query = $this->connection->createQueryBuilder();
$query->delete('ezpage_blocks')
->where(
$query->expr()->in(
'id',
$query->createPositionalParameter($blockIds, Connection::PARAM_INT_ARRAY)
)
);

$query->execute();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,45 @@ interface PageFieldTypeGatewayInterface
public function countOrphanedPageRelations(): int;

public function getOrphanedPageRelations(int $limit): array;

/**
* @return int[]
*/
public function getOrphanedBlockIds(int $limit): array;

/**
* @param int[] $blockIds
* @return int[]
*/
public function getOrphanedAttributeIds(array $blockIds): array;

/**
* @param int[] $attributeIds
*/
public function removeOrphanedBlockAttributes(array $attributeIds): void;

/**
* @param int[] $attributeIds
*/
public function removeOrphanedAttributes(array $attributeIds): void;

/**
* @param int[] $blockIds
*/
public function removeOrphanedBlockDesigns(array $blockIds): void;

/**
* @param int[] $blockIds
*/
public function removeOrphanedBlockVisibilities(array $blockIds): void;

/**
* @param int[] $blockIds
*/
public function removeOrphanedBlocksZones(array $blockIds): void;

/**
* @param int[] $blockIds
*/
public function removeOrphanedBlocks(array $blockIds): void;
}

0 comments on commit 1e3a144

Please sign in to comment.