em = $entityManager; $this->propertyAccessor = $propertyAccessor; $this->converter = new BBCodeToMarkdownConverter(); parent::__construct(); } protected function configure() { $this ->setDescription('Converts BBCode used in old Part-DB versions to newly used Markdown') ->setHelp('Older versions of Part-DB (<1.0) used BBCode for rich text formatting. Part-DB now uses Markdown which offers more features but is incompatible with BBCode. When you upgrade from an pre 1.0 version you have to run this command to convert your comment fields'); $this->addOption('dry-run', null, null, 'Do not save changes to DB. In combination with -v or -vv you can check what will be changed!'); } /** * Returns a list which entities and which properties need to be checked. * @return array */ protected function getTargetsLists() : array { return [ Part::class => ['description', 'comment'], AttachmentType::class => ['comment'], Storelocation::class => ['comment'], Device::class => ['comment'], Category::class => ['comment'], Manufacturer::class => ['comment'], MeasurementUnit::class => ['comment'], Supplier::class => ['comment'], Currency::class => ['comment'], Group::class => ['comment'], ]; } protected function execute(InputInterface $input, OutputInterface $output) { $io = new SymfonyStyle($input, $output); $targets = $this->getTargetsLists(); //Convert for every class target foreach ($targets as $class => $properties) { $io->section(sprintf('Convert entities of class %s', $class)); $io->note(sprintf( 'Search for entities of type %s that need conversion', $class )); //Determine which entities of this type we need to modify /** @var EntityRepository $repo */ $repo = $this->em->getRepository($class); $qb = $repo->createQueryBuilder('e') ->select('e'); //Add fields criteria foreach ($properties as $key => $property) { $qb->orWhere('e.' . $property . ' LIKE ?' . $key); $qb->setParameter($key, static::BBCODE_CRITERIA); } //Fetch resulting classes $results = $qb->getQuery()->getResult(); $io->note(sprintf('Found %d entities, that need to be converted!', count($results))); //In verbose mode print the names of the entities foreach ($results as $result) { /** @var NamedDBElement $result */ $io->writeln( 'Convert entity: ' . $result->getName() . ' (' . $result->getIDString() . ')', OutputInterface::VERBOSITY_VERBOSE ); foreach ($properties as $property) { //Retrieve bbcode from entity $bbcode = $this->propertyAccessor->getValue($result, $property); //Check if the current property really contains BBCode if (!preg_match(static::BBCODE_REGEX, $bbcode)) { continue; } $io->writeln( 'BBCode (old): ' . str_replace('\n', ' ', substr($bbcode, 0, 255)), OutputInterface::VERBOSITY_VERY_VERBOSE ); $markdown = $this->converter->convert($bbcode); $io->writeln( 'Markdown (new): ' . str_replace('\n', ' ', substr($markdown, 0, 255)), OutputInterface::VERBOSITY_VERY_VERBOSE ); $io->writeln('', OutputInterface::VERBOSITY_VERY_VERBOSE); $this->propertyAccessor->setValue($result, $property, $markdown); } } } //If we are not in dry run, save changes to DB if (!$input->getOption('dry-run')) { $this->em->flush(); $io->success('Changes saved to DB successfully!'); } } }