Home > Net >  Symfony 4.4 Upgrade - DoctrineUpdateCommand no longer called from console command
Symfony 4.4 Upgrade - DoctrineUpdateCommand no longer called from console command

Time:12-17

I am upgrading our Symfony application from version 3.4 to version 4.4, which includes an upgrade of Doctrine from 1.12 to 2.3. I had previously written a class that modified the results to the doctrine:schema:update command, which worked great, but appears not to be working now. The class is below.

To modify doctrine:schema:update, I created a class called DoctrineUpdateCommand, which extended \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand, and placed it in the Command folder of the bundle. This was all that was needed. I referenced this answer to figure out how to do it: How to set up entity (doctrine) for database view in Symfony 2.

We need to override the doctrine:schema:update command because one of our entities refers to a MySQL view instead of a MySQL table. Further, the entity is referenced as both a stand alone entity, and as a many-to-many join. The override class caused the entity and join to be ignored. It also added a sql statement to create the view.

After the upgrade, if I run php console doctrine:schema:update --dump-sql, I get these results:

19:08:16 CRITICAL  [console] Error thrown while running command "doctrine:schema:update --dump-sql". Message: "The table with name 'nest_qa.assignedrole_privilegerole' already exists." ["exception" => Doctrine\DBAL\Schema\SchemaException^ { …},"command" => "doctrine:schema:update --dump-sql","message" => "The table with name 'nest_qa.assignedrole_privilegerole' already exists."]

In SchemaException.php line 112:

  The table with name 'nest_qa.assignedrole_privilegerole' already exists.

I am fairly certain that the extension of the doctrine command is no longer being called, and it's using the default command instead, but I can't figure out how to change that. Any help would be appreciated.

Here is the original class:

<?php 

namespace ApiBundle\Command;

use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Doctrine\ORM\Tools\SchemaTool;

class DoctrineUpdateCommand extends \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand{

    protected $ignoredEntities = array(
        'ApiBundle\Entity\AssignedrolePrivilegerole',
    );
    protected $ignoreAssociationMappings = array(
        'ApiBundle\Entity\Privilegerole' => 'assignedroles',
        'ApiBundle\Entity\Assignedrole' => 'privilegeroles',
    );

    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui) {

        /** @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
        $newMetadatas = array();
        foreach ($metadatas as $metadata) {
            if (array_key_exists($metadata->getName(), $this->ignoreAssociationMappings)) {
                if(array_key_exists($this->ignoreAssociationMappings[$metadata->getName()], $metadata->getAssociationMappings())){
                    unset($metadata->associationMappings[$this->ignoreAssociationMappings[$metadata->getName()]]);
                }
            }
            //If metadata element is not in the ignore array, add it to the new metadata array 
            if (!in_array($metadata->getName(), $this->ignoredEntities)){
                array_push($newMetadatas, $metadata);
            }
        }
        
        parent::executeSchemaCommand($input, $output, $schemaTool, $newMetadatas, $ui);
        $output->writeln("------Create view for assignedrole_privilegerole");
        $output->writeln("CREATE VIEW `assignedrole_privilegerole`  AS  select `Assignedrole`.`id` AS `assignedrole_id`,`Privilegerole`.`id` AS `privilegerole_id` from (`Assignedrole` join `Privilegerole`) where ((`Assignedrole`.`role_id` = `Privilegerole`.`role_id`) and ((`Assignedrole`.`unit_id` = `Privilegerole`.`unit_id`) or `Privilegerole`.`unit_id` in (select `Unittree`.`ancestor_id` from `Unittree` where (`Unittree`.`descendant_id` = `Assignedrole`.`unit_id`)))) ;");
    }

}

CodePudding user response:

Console commands in symfony <4.x were registered by scanning Command folder inside a bundle. Since bundles are obsolete in symfony 4 , you have to define commands in your services definition by tagging the command class, or use DI autoconfiguration.

Option 1: explicitly add console.command tag to the service definition:

services:
    ApiBundle\Command\DoctrineUpdateCommand:
        tags:
            - { name: twig.extension }

Option 2: use DI autoconfiguration:

services:
    ApiBundle\Command\DoctrineUpdateCommand:
        autoconfigure: true

After your class is registered as a console command, it must override the default one.

See symfony docs for more: Console Command

  • Related