phpsymfonyoauthsymfony-console

extend a symfony bundle command


For a project, I am using the league/oauth2-server-bundle. This bundle has a command league:oauth:create-client that creates a client in the database.

In this project, I have a ClientConfiguration entity linked to the bundle's Client entity, which allows adding additional configuration.

I would like to be able to "extend" the bundle's create-client command. I want to keep all the options and arguments configuration from the base CreateClientCommand class to create the client but also add options for the additional configuration.

I can't directly extends the CreateClientCommand from the bundle because it's a final class.

i tried by injecting the base command and copy it's definition in my new command

class CreateClientWithConfiguration extends Command {


    function __construct(private readonly CreateClientCommand $createClientCommand)
    {
        parent::__construct();
    }
    
    protected function configure(): void
    {
        $this->setDefinition($this->createClientCommand->getDefinition());
        $this->setDescription('This create a new oAuth client with additionnal configuration')
            ->setName('oauth:create-client-configuration')
            // add custom options
            ;

    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $options = [];
        foreach($input->getOptions() as $key => $option){
            $options["--".$key] = $option;
        }

        $arrayInput = array_merge(['command' => 'league:oauth:create-client'],$input->getArguments(),$options);

        $createClientInput = new ArrayInput($arrayInput);
    
        $returnCode = $this->getApplication()->doRun($createClientInput, $output);

        // do other stuffs
     }
}

but the $options array contains all options like --version and it's automatically detected when using doRun() even if the option value is off and it directly stop the execution :

    public function doRun(InputInterface $input, OutputInterface $output)
    {
        if (true === $input->hasParameterOption(['--version', '-V'], true)) {
            $output->writeln($this->getLongVersion());

            return 0;
        }
        // ...
    }

Is there a clean way to do this without manually copy the arguments and options of CreateClientCommand ?


Solution

  • I think that you have to manually create the options and arguments array that you pass to the create-client command. Of course, this means that whenever the "base command" adds a new option or argument, then you will have to update your code, but maybe that doesn't happen that often.