Команда Symfony добавляет параметр на основе аргумента

я хотел бы добавить параметры на основе аргумента в моей команде импорта. Я думал, что это может сработать, чтобы добавить их в взаимодействие(), но когда я запускаю

bin/console app:import test --supplier=5

я получил

[Symfony\Component\Console\Exception\RuntimeException]
Параметр "--supplier" не существует.

Я знаю, что мог бы использовать вопросы, но я бы предпочел варианты, потому что это избавляет меня от необходимости периодически запускать команду импорта! Вот моя команда:

class ImportCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this
            ->setName('app:import')
            ->addArgument('importKey', InputArgument::REQUIRED)
        ;
    }

    protected function interact(InputInterface $input, OutputInterface $output)
    {
        $key = $input->getArgument('importKey');


        // this will be handled in
        // $importProvider = $this->getContainer()->get('app.import.provider');
        // $importer = $importProvider->getImport($key);
        // $importer->configureCommand($input, $output, $this);
        // but for simplicity's sake
        if($key == 'test')
        {
            $this->addOption('supplier', null,InputOption::VALUE_REQUIRED);
        }


    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {

        $supplier = $input->getOption('supplier');

        $output->writeln("your provided suplier id is '$supplier'");
    }
}

person Brucie Alpha    schedule 26.08.2017    source источник


Ответы (2)


команда необязательных аргументов symfony

<?php
 namespace sandboxBundle\Command;

 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;

 // Add the required classes
 use Symfony\Component\Console\Input\InputDefinition;
 use Symfony\Component\Console\Input\InputOption;


 class TestCommand extends Command
  {
      protected function configure()
       {
        $this
           // the name of the command (the part after "bin/console")
          ->setName('app:print-lines')
           // the short description shown while running "php bin/console list"
         ->setHelp("This command allows you to print some text in the console")
         // the full command description shown when running the command with
         ->setDescription('Prints some text into the console with given parameters.')
        // Set options
          ->setDefinition(
            new InputDefinition(array(
                new InputOption('firstline', 'a', InputOption::VALUE_REQUIRED,"The first line to be printed","Default First Line Value"),
                new InputOption('secondline', 'b', InputOption::VALUE_OPTIONAL,"The second line to be printed","Default First Line Value"),
            ))
        )
    ;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
    // outputs multiple lines to the console (adding "\n" at the end of each line)
    $output->writeln([
        'My Third Symfony command',// A line
        '============',// Another line
        '',// Empty line
    ]);

    $firstLine = $input->getOption('firstline');
    $secondline = $input->getOption('secondline');

    $output->writeln("First line value : ".$firstLine);

    if($secondline){
        $output->writeln("Second line value : ".$secondline);
    }

    // Instead of retrieve line per line every option, you can get an array of all the providen options :
    //$output->writeln(json_encode($input->getOptions()));
}
}
person Robert    schedule 26.08.2017
comment
это не соответствует моим требованиям, потому что первая и вторая строки определены в configure(), где мы не знаем ключ импорта. - person Brucie Alpha; 26.08.2017
comment
вы можете попробовать addArgument('supplier', InputArgument::OPTIONAL) - person Robert; 26.08.2017
comment
это ничего не меняет, потому что взаимодействие() вызывается после привязки ввода... я придумал решение и опубликую его сейчас... но все равно спасибо - person Brucie Alpha; 26.08.2017

я нашел решение... скорее всего не самое лучшее, но оно работает

решение — скопируйте класс Command, объявите его абстрактным и дайте ему расширить старую команду — скопируйте ContainerAwareCommand и дайте ему расширить вашу новую команду — добавьте код в новую команду

public function notIgnoreValidationErrors()
{
    $this->ignoreValidationErrors = false;
}

protected function configureAdditionalInput(InputInterface $input, OutputInterface $output)
{
}

-изменить запуск() на

public function run(InputInterface $input, OutputInterface $output)
{
    // force the creation of the synopsis before the merge with the app definition
    $this->getSynopsis(true);
    $this->getSynopsis(false);

    // add the application arguments and options
    $this->mergeApplicationDefinition();

    // bind the input against the command specific arguments/options
    try {
        $input->bind($this->definition);
    } catch (ExceptionInterface $e) {
        if (!$this->ignoreValidationErrors) {
            throw $e;
        }
    }

    $this->configureAdditionalInput($input, $output);

    // bind the input against the command specific arguments/options
    try {
        $input->bind($this->definition);
    } catch (ExceptionInterface $e) {
        if (!$this->ignoreValidationErrors) {
            throw $e;
        }
    }

    $this->initialize($input, $output);

    if (null !== $this->processTitle) {
        if (function_exists('cli_set_process_title')) {
            if (false === @cli_set_process_title($this->processTitle)) {
                if ('Darwin' === PHP_OS) {
                    $output->writeln('<comment>Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.</comment>');
                } else {
                    $error = error_get_last();
                    trigger_error($error['message'], E_USER_WARNING);
                }
            }
        } elseif (function_exists('setproctitle')) {
            setproctitle($this->processTitle);
        } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
            $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
        }
    }

    if ($input->isInteractive()) {
        $this->interact($input, $output);
    }

    // The command name argument is often omitted when a command is executed directly with its run() method.
    // It would fail the validation if we didn't make sure the command argument is present,
    // since it's required by the application.
    if ($input->hasArgument('command') && null === $input->getArgument('command')) {
        $input->setArgument('command', $this->getName());
    }

    $input->validate();

    if ($this->code) {
        $statusCode = call_user_func($this->code, $input, $output);
    } else {
        $statusCode = $this->execute($input, $output);
    }

    return is_numeric($statusCode) ? (int) $statusCode : 0;
}

- измените свою команду на (ContainerAwareCommand - ваш новый класс)

class ImportCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this
            ->setName('app:import')
            ->addArgument('importKey', InputArgument::REQUIRED)
        ;
        $this->ignoreValidationErrors();
    }

    protected function configureAdditionalInput(InputInterface $input, OutputInterface $output)
    {
        $key = $input->getArgument('importKey');

        $this->notIgnoreValidationErrors();

        // this will be handled in
        // $importProvider = $this->getContainer()->get('app.import');
        // $importer = $importProvider->getImport($key);
        // $importer->configureCommand($input, $output, $this);
        if($key == 'test')
        {
            $this->addOption('supplier', null,InputOption::VALUE_REQUIRED);
        }
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {

        $supplier = $input->getOption('supplier');

        $output->writeln("your provided suplier id is '$supplier'");
    }
}

теперь запустите команду

bin/console app:import test --supplier=5

предоставленный вами идентификатор поставщика равен «5»

person Brucie Alpha    schedule 26.08.2017