diff --git a/bundle/Command/ConvertXmlTextToRichTextCommand.php b/bundle/Command/ConvertXmlTextToRichTextCommand.php index 08dd1853..b42785df 100644 --- a/bundle/Command/ConvertXmlTextToRichTextCommand.php +++ b/bundle/Command/ConvertXmlTextToRichTextCommand.php @@ -13,6 +13,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Console\Helper\ProgressBar; use eZ\Publish\Core\FieldType\XmlText\Value; use eZ\Publish\Core\FieldType\XmlText\Converter\RichText as RichTextConverter; use Symfony\Component\Debug\Exception\ContextErrorException; @@ -60,6 +61,15 @@ class ConvertXmlTextToRichTextCommand extends ContainerAwareCommand */ protected $processes = []; + /** + * @var bool + */ + protected $hasProgressBar; + + /** + * @var \Symfony\Component\Console\Helper\ProgressBar + */ + protected $progressBar; /** * @var int */ @@ -164,6 +174,12 @@ protected function configure() This option is needed if you have an existing ezplatform database which was converted with an earlier version of\n 'ezxmltext:convert-to-richtext' which did not convert embedded images correctly." ) + ->addOption( + 'no-progress', + null, + InputOption::VALUE_NONE, + 'Disable the progress bar.' + ) ->addOption( 'user', 'u', @@ -184,6 +200,8 @@ protected function execute(InputInterface $input, OutputInterface $output) } } + $this->hasProgressBar = !$input->getOption('no-progress'); + $testContentId = $input->getOption('test-content-object'); if ($testContentId !== null && $this->maxConcurrency !== 1) { throw new RuntimeException('Multi concurrency is not supported together with the --test-content-object option'); @@ -380,6 +398,7 @@ protected function fixEmbeddedImages($dryRun, $contentId, OutputInterface $outpu $count = $this->gateway->getRowCountOfContentObjectAttributes('ezrichtext', $contentId); $output->writeln("Found $count field rows to convert."); + $this->progressBarStart($output, $count); $offset = 0; $totalCount = 0; @@ -430,19 +449,26 @@ protected function fixEmbeddedImages($dryRun, $contentId, OutputInterface $outpu ); } } + $this->progressBarAdvance($offset); $offset += self::MAX_OBJECTS_PER_CHILD; } while ($offset + self::MAX_OBJECTS_PER_CHILD <= $count); + $this->progressBarFinish(); - $output->writeln("Updated ezembed tags in $totalCount field(s)"); + $output->writeln("\nUpdated ezembed tags in $totalCount field(s)"); } protected function waitForAvailableProcessSlot(OutputInterface $output) { - if (count($this->processes) >= $this->maxConcurrency) { + if (!$this->processSlotAvailable()) { $this->waitForChild($output); } } + protected function processSlotAvailable() + { + return count($this->processes) < $this->maxConcurrency; + } + protected function waitForChild(OutputInterface $output) { $childEnded = false; @@ -602,30 +628,64 @@ protected function convertFields($dryRun, $contentId, $checkDuplicateIds, $check $this->writeCustomTagLog(); } + protected function progressBarStart(OutputInterface $output, $count) + { + if ($this->hasProgressBar) { + $this->progressBar = new ProgressBar($output, $count); + $this->progressBar->start(); + } + } + + protected function progressBarAdvance($step) + { + if ($this->hasProgressBar) { + $this->progressBar->advance($step); + } + } + + protected function progressBarFinish() + { + if ($this->hasProgressBar) { + $this->progressBar->finish(); + } + } + protected function processFields($dryRun, $checkDuplicateIds, $checkIdValues, OutputInterface $output) { $count = $this->gateway->getRowCountOfContentObjectAttributes('ezxmltext', null); $output->writeln("Found $count field rows to convert."); + if ($count < self::MAX_OBJECTS_PER_CHILD * $this->maxConcurrency && $this->maxConcurrency > 1) { + $objectsPerChild = (int) ceil($count / $this->maxConcurrency); + } else { + $objectsPerChild = self::MAX_OBJECTS_PER_CHILD; + } $offset = 0; $fork = $this->maxConcurrency > 1; + $this->progressBarStart($output, $count); do { - $limit = self::MAX_OBJECTS_PER_CHILD; + $limit = $objectsPerChild; if ($fork) { + $processSlotAvailable = $this->processSlotAvailable(); $this->waitForAvailableProcessSlot($output); + if (!$processSlotAvailable) { + $this->progressBarAdvance($objectsPerChild); + } $process = $this->createChildProcess($dryRun, $checkDuplicateIds, $checkIdValues, $offset, $limit, $output); $this->processes[$process->getPid()] = ['offset' => $offset, 'limit' => $limit, 'process' => $process]; } else { $this->convertFields($dryRun, null, $checkDuplicateIds, $checkIdValues, $offset, $limit); } - $offset += self::MAX_OBJECTS_PER_CHILD; - } while ($offset + self::MAX_OBJECTS_PER_CHILD <= $count); + $offset += $objectsPerChild; + } while ($offset + $objectsPerChild <= $count); while (count($this->processes) > 0) { $this->waitForChild($output); + $this->progressBarAdvance($objectsPerChild); } - $output->writeln("Converted $count ezxmltext fields to richtext"); + $this->progressBarFinish(); + $output->writeln("\nConverted $count ezxmltext fields to richtext"); } protected function createDocument($xmlString)