Переопределить команды консоли symfony2?

Можно ли переопределить команды приложения / консоли symfony2? Например, в FOS UserBundle я хотел бы добавить еще несколько полей, которые он запрашивает, когда он создает пользователя с консолью, создавая пользовательскую команду. Возможно ли это, или мне нужно создать собственную консольную команду в моем собственном пакете?

Весь процесс добавления в команду дополнительных полей:

1. В вашем классе AcmeDemoBundle вы должны установить FOSUser как родительский:

<?php namespace Acme\UserBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; class AcmeUserBundle extends Bundle { public function getParent() { return 'FOSUserBundle'; } } 

2. Когда вы сделаете это, вы можете воссоздать CreateUserCommand в своем комплекте:

 <?php namespace Acme\UserBundle\Command; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use FOS\UserBundle\Model\User; /** * @author Matthieu Bontemps <matthieu@knplabs.com> * @author Thibault Duplessis <thibault.duplessis@gmail.com> * @author Luis Cordova <cordoval@gmail.com> */ class CreateUserCommand extends ContainerAwareCommand { /** * @see Command */ protected function configure() { $this ->setName('fos:user:create') ->setDescription('Create a user.') ->setDefinition(array( new InputArgument('username', InputArgument::REQUIRED, 'The username'), new InputArgument('email', InputArgument::REQUIRED, 'The email'), new InputArgument('password', InputArgument::REQUIRED, 'The password'), new InputArgument('name', InputArgument::REQUIRED, 'The name'), new InputOption('super-admin', null, InputOption::VALUE_NONE, 'Set the user as super admin'), new InputOption('inactive', null, InputOption::VALUE_NONE, 'Set the user as inactive'), )) ->setHelp(<<<EOT The <info>fos:user:create</info> command creates a user: <info>php app/console fos:user:create matthieu</info> This interactive shell will ask you for an email and then a password. You can alternatively specify the email and password as the second and third arguments: <info>php app/console fos:user:create matthieu matthieu@example.com mypassword</info> You can create a super admin via the super-admin flag: <info>php app/console fos:user:create admin --super-admin</info> You can create an inactive user (will not be able to log in): <info>php app/console fos:user:create thibault --inactive</info> EOT ); } /** * @see Command */ protected function execute(InputInterface $input, OutputInterface $output) { $username = $input->getArgument('username'); $email = $input->getArgument('email'); $password = $input->getArgument('password'); $name = $input->getArgument('name'); $inactive = $input->getOption('inactive'); $superadmin = $input->getOption('super-admin'); $manipulator = $this->getContainer()->get('acme.util.user_manipulator'); $manipulator->create($username, $password, $email, $name, !$inactive, $superadmin); $output->writeln(sprintf('Created user <comment>%s</comment>', $username)); } /** * @see Command */ protected function interact(InputInterface $input, OutputInterface $output) { if (!$input->getArgument('username')) { $username = $this->getHelper('dialog')->askAndValidate( $output, 'Please choose a username:', function($username) { if (empty($username)) { throw new \Exception('Username can not be empty'); } return $username; } ); $input->setArgument('username', $username); } if (!$input->getArgument('email')) { $email = $this->getHelper('dialog')->askAndValidate( $output, 'Please choose an email:', function($email) { if (empty($email)) { throw new \Exception('Email can not be empty'); } return $email; } ); $input->setArgument('email', $email); } if (!$input->getArgument('password')) { $password = $this->getHelper('dialog')->askAndValidate( $output, 'Please choose a password:', function($password) { if (empty($password)) { throw new \Exception('Password can not be empty'); } return $password; } ); $input->setArgument('password', $password); } if (!$input->getArgument('name')) { $name = $this->getHelper('dialog')->askAndValidate( $output, 'Please choose a name:', function($name) { if (empty($name)) { throw new \Exception('Name can not be empty'); } return $name; } ); $input->setArgument('name', $name); } } } 

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

3. Создайте свой собственный UserManipulator:

 <?php namespace Acme\UserBundle\Util; use FOS\UserBundle\Model\UserManagerInterface; /** * Executes some manipulations on the users * * @author Christophe Coevoet <stof@notk.org> * @author Luis Cordova <cordoval@gmail.com> */ class UserManipulator { /** * User manager * * @var UserManagerInterface */ private $userManager; public function __construct(UserManagerInterface $userManager) { $this->userManager = $userManager; } /** * Creates a user and returns it. * * @param string $username * @param string $password * @param string $email * @param string $name * @param Boolean $active * @param Boolean $superadmin * * @return \FOS\UserBundle\Model\UserInterface */ public function create($username, $password, $email, $name, $active, $superadmin) { $user = $this->userManager->createUser(); $user->setUsername($username); $user->setEmail($email); $user->setName($name); $user->setPlainPassword($password); $user->setEnabled((Boolean)$active); $user->setSuperAdmin((Boolean)$superadmin); $this->userManager->updateUser($user); return $user; } } 

В этом классе мне нужна только функция create, поэтому остальные команды, такие как promotion, demote .., не знают о новых свойствах вашего пользователя, поэтому мне не нужно создавать CompilerPass для переопределения всей службы.

4. Наконец, определите эту новую службу UserManipulator в каталоге Resources / config и добавьте ее в расширение DependencyInjection:

 services: acme.util.user_manipulator: class: Acme\UserBundle\Util\UserManipulator arguments: [@fos_user.user_manager] 

Готово!!!

Вы можете переопределить команды консоли, если вы создаете (или уже имеете) свой собственный пакет, который является дочерним элементом этого пакета (см. Наследование Bundle ). Затем, поместив класс в ваш комплект с тем же именем / именем, что и исходная команда, вы его эффективно отмените.

Например, чтобы переопределить FOS / UserBundle / Command / CreateUserCommand.php, создайте MyCompany / UserBundle / Command / CreateUserCommand, где MyCompanyUserBundle имеет FOSUserBundle в качестве родителя.

Ваш класс команд может расширить класс команд FOS, чтобы повторно использовать (бит) его. Однако, посмотрев на FOS CreateUserCommand, я думаю, вам нужно будет переопределить все методы, чтобы добавить дополнительные поля ввода, и в этом случае нет никакой пользы для этого. Конечно, это также означает, что вы можете просто создать свою собственную команду в любом комплекте, но, на мой взгляд, лучше сохранить настройку FOSUserBundle в дочернем комплекте.

В Symfony (3.3) вы можете переопределить команды консоли, следуя этим ссылкам. https://symfony.com/doc/current/console/calling_commands.html и параметры на странице https://symfony.com/doc/current/console/input.html.

Код от symfony doc:

 use Symfony\Component\Console\Input\ArrayInput; // ... protected function execute(InputInterface $input, OutputInterface $output) { $command = $this->getApplication()->find('demo:greet'); $arguments = array( 'command' => 'demo:greet', 'name' => 'Fabien', '--yell' => true, ); $greetInput = new ArrayInput($arguments); $returnCode = $command->run($greetInput, $output); // ... }