How to access the EntityManager in a Symfony Single Command Application?

452 Views Asked by At

I'm working on a Symfony Single Command Application. I'm using Doctrine to manage entities.

I created the entity configuration using the Symfony CLI and now I'm not sure how I can get access to the EM from within the run method.

Should I create a new subclass of SingleCommandApplication for this?

2

There are 2 best solutions below

2
yivi On BEST ANSWER

If you are truly using a Single Command Application, you'll have to configure Doctrine on your own within the setCode() method. E.g. following these instructions.

(new SingleCommandApplication())
    ->setName('My Super Command') // Optional
    ->setVersion('1.0.0') // Optional
    ->addArgument('foo', InputArgument::OPTIONAL, 'The directory')
    ->addOption('bar', null, InputOption::VALUE_REQUIRED)
    ->setCode(function (InputInterface $input, OutputInterface $output) {

        $paths = array("/path/to/entity-files");
        $isDevMode = false;

        // the connection configuration
        $dbParams = [
            'driver'   => 'pdo_mysql',
            'user'     => 'db_user',
            'password' => 'very_secret',
            'dbname'   => 'foo',
        ];

        $config = Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);
        $em     = Doctrine\ORM\EntityManager::create($dbParams, $config);

        // output arguments and options
    })
    ->run();

On a single command application you do not have "bundles" as such, since you are operating outside of the Framework bundle, and generally you wouldn't have access to dependency injection either.

(If you wanted DI, you'd probably have something like this while calling the setDefaultCommand() method on the instantiated Application object, but you'd still need to instantiate the Doctrine connection "manually", even if you are doing on a different service to be injected).

0
Ingo On

Since i just had that question and found this answer here is another way to do it (using php8.1 and symfony 6.2).

I created a Command like described here: https://symfony.com/doc/current/console.html

and just injected the entitymanager via construct and autowiring.

# src/Command/MyCommand

#[AsCommand(name: 'app:my-command',description: 'My Command',hidden: false)]
class HeartbeatCronCommand extends Command
{
    protected static $defaultDescription = 'does stuff';
    protected $entityManager;
    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
        parent::__construct();
    }
    protected function configure(): void
    {
        $this
            ->setHelp('Help');
    }
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $client = $this->entityManager->getRepository(Client::class)->findOneByName('test'); # just an example
        return Command::SUCCESS;
    }
}