diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1de670ba..c09c6edb 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -84,24 +84,6 @@ parameters: count: 1 path: src/Command/LoadDataFixturesDoctrineODMCommand.php - - - message: '#^Method Psr\\Log\\AbstractLogger@anonymous/src/Command/LoadDataFixturesDoctrineODMCommand\.php\:88\:\:log\(\) has parameter \$message with no type specified\.$#' - identifier: missingType.parameter - count: 1 - path: src/Command/LoadDataFixturesDoctrineODMCommand.php - - - - message: '#^Parameter \#1 \$dm of class Doctrine\\Common\\DataFixtures\\Executor\\MongoDBExecutor constructor expects Doctrine\\ODM\\MongoDB\\DocumentManager, Doctrine\\Persistence\\ObjectManager given\.$#' - identifier: argument.type - count: 1 - path: src/Command/LoadDataFixturesDoctrineODMCommand.php - - - - message: '#^Parameter \#1 \$dm of class Doctrine\\Common\\DataFixtures\\Purger\\MongoDBPurger constructor expects Doctrine\\ODM\\MongoDB\\DocumentManager\|null, Doctrine\\Persistence\\ObjectManager given\.$#' - identifier: argument.type - count: 1 - path: src/Command/LoadDataFixturesDoctrineODMCommand.php - - message: '#^Parameter \#1 \$application of static method Doctrine\\Bundle\\MongoDBBundle\\Command\\DoctrineODMCommand\:\:setApplicationDocumentManager\(\) expects Symfony\\Bundle\\FrameworkBundle\\Console\\Application, Symfony\\Component\\Console\\Application\|null given\.$#' identifier: argument.type diff --git a/src/Command/LoadDataFixturesDoctrineODMCommand.php b/src/Command/LoadDataFixturesDoctrineODMCommand.php index 1e5a60e2..dd5d5816 100644 --- a/src/Command/LoadDataFixturesDoctrineODMCommand.php +++ b/src/Command/LoadDataFixturesDoctrineODMCommand.php @@ -7,7 +7,9 @@ use Doctrine\Bundle\MongoDBBundle\Loader\SymfonyFixturesLoaderInterface; use Doctrine\Bundle\MongoDBBundle\ManagerRegistry; use Doctrine\Common\DataFixtures\Executor\MongoDBExecutor; +use Doctrine\Common\DataFixtures\Purger\MongoDBPurgeMode; use Doctrine\Common\DataFixtures\Purger\MongoDBPurger; +use Doctrine\ODM\MongoDB\DocumentManager; use Psr\Log\AbstractLogger; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -15,6 +17,8 @@ use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle; +use function assert; +use function class_exists; use function implode; use function sprintf; @@ -38,6 +42,7 @@ protected function configure(): void ->addOption('group', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Only load fixtures that belong to this group (use with --services)') ->addOption('append', null, InputOption::VALUE_NONE, 'Append the data fixtures instead of flushing the database first.') ->addOption('dm', null, InputOption::VALUE_REQUIRED, 'The document manager to use for this command.') + ->addOption('purge-with-delete', null, InputOption::VALUE_NONE, 'Purge the database using deleteMany() instead of dropping and recreating the collections.') ->setHelp(<<<'EOT' The doctrine:mongodb:fixtures:load command loads data fixtures from your application: @@ -50,6 +55,10 @@ protected function configure(): void You can also choose to load only fixtures that live in a certain group: php %command.full_name% --group=group1 + +If the collection uses search indexes or encryption, you can use the --purge-with-delete option to keep the collections instead of dropping them when purging the database: + + php %command.full_name% --purge-with-delete EOT ); } @@ -57,6 +66,8 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { $dm = $this->getManagerRegistry()->getManager($input->getOption('dm')); + assert($dm instanceof DocumentManager); + $ui = new SymfonyStyle($input, $output); if ($input->isInteractive() && ! $input->getOption('append')) { @@ -82,15 +93,28 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 1; } - $purger = new MongoDBPurger($dm); - $executor = new MongoDBExecutor($dm, $purger); + $purger = new MongoDBPurger($dm); + if ($input->getOption('purge-with-delete')) { + if (! class_exists(MongoDBPurgeMode::class)) { + $ui->error('The --purge-with-delete option requires doctrine/data-fixtures >= 2.1.0.'); + return self::INVALID; + } + + // @phpstan-ignore method.notFound + $purger->setPurgeMode(MongoDBPurgeMode::Delete); + } + + $executor = new MongoDBExecutor($dm, $purger); $executor->setLogger(new class ($output) extends AbstractLogger { public function __construct(private OutputInterface $output) { } - /** {@inheritDoc} */ + /** + * @inheritdoc + * @phpstan-ignore missingType.parameter + */ public function log($level, $message, array $context = []): void { $this->output->writeln(sprintf(' > %s', $message)); diff --git a/tests/Command/LoadDataFixturesDoctrineODMCommandTest.php b/tests/Command/LoadDataFixturesDoctrineODMCommandTest.php index e4552a42..4d5dc3f5 100644 --- a/tests/Command/LoadDataFixturesDoctrineODMCommandTest.php +++ b/tests/Command/LoadDataFixturesDoctrineODMCommandTest.php @@ -5,10 +5,13 @@ namespace Doctrine\Bundle\MongoDBBundle\Tests\Command; use Doctrine\Bundle\MongoDBBundle\Command\LoadDataFixturesDoctrineODMCommand; +use Doctrine\Common\DataFixtures\Purger\MongoDBPurgeMode; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Console\Tester\CommandTester; +use function class_exists; + class LoadDataFixturesDoctrineODMCommandTest extends KernelTestCase { private LoadDataFixturesDoctrineODMCommand $command; @@ -60,6 +63,22 @@ public function testExecute(): void $commandTester->execute([], ['interactive' => false]); $output = $commandTester->getDisplay(); + $this->assertStringContainsString('purging database', $output); + $this->assertStringContainsString('loading Doctrine\Bundle\MongoDBBundle\Tests\Fixtures\CommandBundle\DataFixtures\UserFixtures', $output); + $this->assertStringContainsString('loading Doctrine\Bundle\MongoDBBundle\Tests\Fixtures\CommandBundle\DataFixtures\OtherFixtures', $output); + } + + public function testExecutePurgeWithDelete(): void + { + if (! class_exists(MongoDBPurgeMode::class)) { + $this->markTestSkipped('The --purge-with-delete option requires doctrine/data-fixtures >= 2.1.0.'); + } + + $commandTester = new CommandTester($this->command); + $commandTester->execute(['--purge-with-delete' => true], ['interactive' => false]); + + $output = $commandTester->getDisplay(); + $this->assertStringContainsString('purging database', $output); $this->assertStringContainsString('loading Doctrine\Bundle\MongoDBBundle\Tests\Fixtures\CommandBundle\DataFixtures\UserFixtures', $output); $this->assertStringContainsString('loading Doctrine\Bundle\MongoDBBundle\Tests\Fixtures\CommandBundle\DataFixtures\OtherFixtures', $output); }