diff --git a/src/Command/LoadDataFixturesCommand.php b/src/Command/LoadDataFixturesCommand.php index 0b82523..d2f6507 100644 --- a/src/Command/LoadDataFixturesCommand.php +++ b/src/Command/LoadDataFixturesCommand.php @@ -4,160 +4,99 @@ use Doctrine\Common\DataFixtures\Executor\ORMExecutor; use Doctrine\Common\DataFixtures\Purger\ORMPurger; -use Doctrine\ORM\EntityManager; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\Persistence\ManagerRegistry; -use InvalidArgumentException; use Nettrine\Fixtures\Loader\FixturesLoader; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Style\SymfonyStyle; /** - * @see http://symfony.com/doc/2.2/bundles/DoctrineFixturesBundle/index.html + * Load data fixtures from bundles. + * + * @see https://github.com/doctrine/DoctrineFixturesBundle/blob/3.5.x/Command/LoadDataFixturesDoctrineCommand.php */ +#[AsCommand(name: 'doctrine:fixtures:load')] class LoadDataFixturesCommand extends Command { - /** @var FixturesLoader */ - private $loader; + private FixturesLoader $fixturesLoader; - /** @var ManagerRegistry */ - private $managerRegistry; + private ManagerRegistry $managerRegistry; - /** @var string */ - protected static $defaultName = 'doctrine:fixtures:load'; - - public function __construct(FixturesLoader $loader, ManagerRegistry $managerRegistry) + public function __construct(FixturesLoader $fixturesLoader, ManagerRegistry $managerRegistry) { parent::__construct(); - $this->loader = $loader; + + $this->fixturesLoader = $fixturesLoader; $this->managerRegistry = $managerRegistry; } - /** - * Configures the current command. - */ protected function configure(): void { $this - ->setName(static::$defaultName) - ->setDescription('Load data fixtures to your database.') - ->addOption( - 'fixtures', - null, - InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, - 'The directory to load data fixtures from.' - ) - ->addOption( - 'append', - null, - InputOption::VALUE_NONE, - 'Append the data fixtures instead of deleting all data from the database first.' - ) + ->setDescription('Load data fixtures to your database') + ->addOption('append', null, InputOption::VALUE_NONE, 'Append the data fixtures instead of deleting all data from the database first.') ->addOption('em', null, InputOption::VALUE_REQUIRED, 'The entity manager to use for this command.') - ->addOption( - 'purge-with-truncate', - null, - InputOption::VALUE_NONE, - 'Purge data by using a database-level TRUNCATE statement' - ) - // ->addOption('multiple-transactions', NULL, InputOption::VALUE_NONE, - // 'Use one transaction per fixture file instead of a single transaction for all') - ->setHelp(' -The doctrine:fixtures:load command loads data fixtures from your config: + ->addOption('purge-with-truncate', null, InputOption::VALUE_NONE, 'Purge data by using a database-level TRUNCATE statement') + ->setHelp(<<<'EOT' +The %command.name% command loads data fixtures from your application: + + php %command.full_name% - doctrine:fixtures:load +Fixtures are services that are tagged with doctrine.fixture.orm. -You can also optionally specify the path to fixtures with the --fixtures option: +If you want to append the fixtures instead of flushing the database first you can use the --append option: - doctrine:fixtures:load --fixtures=/path/to/fixtures1 --fixtures=/path/to/fixtures2 + php %command.full_name% --append -If you want to append the fixtures instead of flushing the database first you can use the --append option: +By default Doctrine Data Fixtures uses DELETE statements to drop the existing rows from the database. +If you want to use a TRUNCATE statement instead you can use the --purge-with-truncate flag: - doctrine:fixtures:load --append + php %command.full_name% --purge-with-truncate -By default Doctrine Data Fixtures uses DELETE statements to drop the existing rows from -the database. If you want to use a TRUNCATE statement instead you can use the --purge-with-truncate flag: +To execute only fixtures that live in a certain group, use: - doctrine:fixtures:load --purge-with-truncate -'); + php %command.full_name% --group=group1 + +EOT + ); } protected function execute(InputInterface $input, OutputInterface $output): int { - /** @var string|null $em */ - $em = $input->getOption('em'); - - /** @var EntityManager $em */ - $em = $this->managerRegistry->getManager($em); - - $append = $input->getOption('append'); - if ($input->isInteractive() && $append !== null && $append !== '') { - if (!$this->askConfirmation( - $input, - $output, - 'Careful, database will be purged. Do you want to continue y/N ?', - false - ) - ) { - return 1; - } - } + $ui = new SymfonyStyle($input, $output); - $dirOrFile = $input->getOption('fixtures'); - if ($dirOrFile !== null && $dirOrFile !== '' && !(is_array($dirOrFile) && count($dirOrFile) === 0)) { - $paths = is_array($dirOrFile) ? $dirOrFile : [$dirOrFile]; - $this->loader->loadPaths($paths); - } else { - $this->loader->load(); - $paths = $this->loader->getPaths(); + $em = $this->managerRegistry->getManager(is_string($input->getOption('em')) ? $input->getOption('em') : null); + assert($em instanceof EntityManagerInterface); + + if ($input->getOption('append') !== null) { + if (!$ui->confirm(sprintf('Careful, database "%s" will be purged. Do you want to continue?', $em->getConnection()->getDatabase()), !$input->isInteractive())) { + return 0; + } } - $fixtures = $this->loader->getFixtures(); + $fixtures = $this->fixturesLoader->getFixtures(); if ($fixtures === []) { - throw new InvalidArgumentException( - sprintf( - 'Could not find any fixtures to load in: %s', - "\n\n- " . implode("\n- ", $paths) - ) - ); + $ui->error('Could not find any fixture services to load.'); + + return 1; } $purgeTruncate = $input->getOption('purge-with-truncate'); $purger = new ORMPurger($em); - $purger->setPurgeMode($purgeTruncate !== null && $purgeTruncate ? ORMPurger::PURGE_MODE_TRUNCATE : ORMPurger::PURGE_MODE_DELETE); + $purger->setPurgeMode($purgeTruncate !== null ? ORMPurger::PURGE_MODE_TRUNCATE : ORMPurger::PURGE_MODE_DELETE); $executor = new ORMExecutor($em, $purger); - $executor->setLogger(function ($message) use ($output): void { - $output->writeln(sprintf(' > %s', $message)); + $executor->setLogger(static function ($message) use ($ui): void { + $ui->text(sprintf(' > %s', $message)); }); - $executor->execute($fixtures, (bool) $append); - //$executor->execute($fixtures, $input->getOption('append'), $input->getOption('multiple-transactions')); + $executor->execute($fixtures, $input->getOption('append') !== null); return 0; } - private function askConfirmation( - InputInterface $input, - OutputInterface $output, - string $question, - bool $default - ): bool - { - $set = $this->getHelperSet(); - - if ($set === null) { - return false; - } - - /** @var QuestionHelper $questionHelper */ - $questionHelper = $set->get('question'); - $question = new ConfirmationQuestion($question, $default); - - return (bool) $questionHelper->ask($input, $output, $question); - } - }