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

Extend 'page-fieldtype-cleanup' command to remove leftovers #7

Merged
merged 3 commits into from
Jan 20, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
71 changes: 66 additions & 5 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,11 +96,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int

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

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

$this->deleteOrphanedPageRelations($limit);
if ($count) {
$this->deleteOrphanedPageRelations($limit);
}

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

Expand Down Expand Up @@ -132,5 +138,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;
}