Override symfony2 console commands?

后端 未结 4 1939
囚心锁ツ
囚心锁ツ 2020-12-10 04:56

Is it possible to override symfony2 app/console commands? For example, in the FOS UserBundle I\'d like to add a few more fields it asks when it creates a user with its cons

4条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-10 05:20

    The whole process for adding more fields to the command is:

    1.In your AcmeDemoBundle class you must set FOSUser as parent:

    2.Once you do that you can recreate the CreateUserCommand in your bundle:

    
     * @author Thibault Duplessis 
     * @author Luis Cordova 
     */
    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(<<fos:user:create command creates a user:
    
      php app/console fos:user:create matthieu
    
    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:
    
      php app/console fos:user:create matthieu matthieu@example.com mypassword
    
    You can create a super admin via the super-admin flag:
    
      php app/console fos:user:create admin --super-admin
    
    You can create an inactive user (will not be able to log in):
    
      php app/console fos:user:create thibault --inactive
    
    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 %s', $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);
            }
        }
    }
    

    Note I have added a new input argument called name and inside the command I am using an acme.util.user_manipulator service instead of the original one os there I am going to process also the user's name.

    3.Create your own UserManipulator:

    
     * @author Luis Cordova 
     */
    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;
        }
    }
    

    In this class I only need the create function so the rest of commands like promote, demote.. does not know about your user's new properties so I do not need to create a CompilerPass to override the whole service.

    4.Finally, define this new UserManipulator service in the Resources/config directory and add it to the DependencyInjection Extension:

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

    Done!!!

提交回复
热议问题