是否可以覆盖symfony2 app / console命令?例如,在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','The email'),new InputArgument('password','The password'),new InputArgument('name','The name'),new InputOption('super-admin',null,InputOption::VALUE_NONE,'Set the user as super admin'),new InputOption('inactive','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); } } }
注意我添加了一个名为name的新的输入参数,在命令中,我使用的是一个acme.util.user_manipulator服务,而不是原来的一个os,我也要处理用户的名字.
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,$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.最后,在Resources / config目录中定义新的UserManipulator服务,并将其添加到DependencyInjection扩展中:
services: acme.util.user_manipulator: class: Acme\UserBundle\Util\UserManipulator arguments: [@fos_user.user_manager]
完成!