覆盖 symfony2 控制台命令? [英] Override symfony2 console commands?
问题描述
是否可以覆盖 symfony2 应用程序/控制台命令?例如,在 FOS UserBundle 中,我想添加更多字段,它在使用其控制台创建用户命令创建用户时询问.这是可能的,还是我需要在自己的包中创建自己的控制台命令?
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 console create user command. Is this possible, or do I need to create my own console command in my own bundle?
推荐答案
向命令中添加更多字段的整个过程是:
The whole process for adding more fields to the command is:
1.在您的 AcmeDemoBundle 类中,您必须将 FOSUser 设置为父级:
1.In your AcmeDemoBundle class you must set FOSUser as parent:
<?php
namespace AcmeUserBundle;
use SymfonyComponentHttpKernelBundleBundle;
use SymfonyComponentDependencyInjectionContainerBuilder;
class AcmeUserBundle extends Bundle
{
public function getParent()
{
return 'FOSUserBundle';
}
}
2.完成后,您可以在包中重新创建 CreateUserCommand:
2.Once you do that you can recreate the CreateUserCommand in your bundle:
<?php
namespace AcmeUserBundleCommand;
use SymfonyBundleFrameworkBundleCommandContainerAwareCommand;
use SymfonyComponentConsoleInputInputArgument;
use SymfonyComponentConsoleInputInputOption;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;
use FOSUserBundleModelUser;
/**
* @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);
}
}
}
请注意,我添加了一个名为 name 的新输入参数,在命令中我使用的是 acme.util.user_manipulator 服务而不是原来的操作系统,我还将处理用户名.
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.创建自己的UserManipulator:
3.Create your own UserManipulator:
<?php
namespace AcmeUserBundleUtil;
use FOSUserBundleModelUserManagerInterface;
/**
* 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 FOSUserBundleModelUserInterface
*/
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 函数,所以其余的命令(如提升、降级...)不知道您用户的新属性,因此我不需要创建 CompilerPass 来覆盖整个服务.
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.最后,在Resources/config目录下定义这个新的UserManipulator服务并添加到DependencyInjection Extension:
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: AcmeUserBundleUtilUserManipulator
arguments: [@fos_user.user_manager]
完成!!!
这篇关于覆盖 symfony2 控制台命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!