问题
I want to override FOSUserBundle so that I can add extra fields(name,avatar,...) to user entity .
I also want to create a command like fos:user:create
for creating user,so I create createUserCommand.php
and override UserManipulator.php
but when runnig command it comes with this error Column 'name' cannot be null
I think I must override UserInteface,UserManager and ...
But in this way I have to override almost whole FOSUserBundle !!
Is there any good tutorial that explain how to do this job ?
Symp/UserBundle/Util/UsertManipulator
<?php
namespace Symp\UserBundle\Util;
use FOS\UserBundle\Model\UserManagerInterface;
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 Boolean $active
* @param Boolean $superadmin
*
* @return \FOS\UserBundle\Model\UserInterface
*/
public function create($username, $password, $email, $active, $superadmin,$name)
{
$user = $this->userManager->createUser();
$user->setName($name);
$user->setUsername($username);
$user->setEmail($email);
$user->setPlainPassword($password);
$user->setEnabled((Boolean) $active);
$user->setSuperAdmin((Boolean) $superadmin);
$this->userManager->updateUser($user);
return $user;
}
/**
* Activates the given user.
*
* @param string $username
*/
public function activate($username)
{
$user = $this->userManager->findUserByUsername($username);
if (!$user) {
throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
}
$user->setEnabled(true);
$this->userManager->updateUser($user);
}
/**
* Deactivates the given user.
*
* @param string $username
*/
public function deactivate($username)
{
$user = $this->userManager->findUserByUsername($username);
if (!$user) {
throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
}
$user->setEnabled(false);
$this->userManager->updateUser($user);
}
/**
* Changes the password for the given user.
*
* @param string $username
* @param string $password
*/
public function changePassword($username, $password)
{
$user = $this->userManager->findUserByUsername($username);
if (!$user) {
throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
}
$user->setPlainPassword($password);
$this->userManager->updateUser($user);
}
/**
* Promotes the given user.
*
* @param string $username
*/
public function promote($username)
{
$user = $this->userManager->findUserByUsername($username);
if (!$user) {
throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
}
$user->setSuperAdmin(true);
$this->userManager->updateUser($user);
}
/**
* Demotes the given user.
*
* @param string $username
*/
public function demote($username)
{
$user = $this->userManager->findUserByUsername($username);
if (!$user) {
throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
}
$user->setSuperAdmin(false);
$this->userManager->updateUser($user);
}
/**
* Adds role to the given user.
*
* @param string $username
* @param string $role
*
* @return Boolean true if role was added, false if user already had the role
*/
public function addRole($username, $role)
{
$user = $this->userManager->findUserByUsername($username);
if (!$user) {
throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
}
if ($user->hasRole($role)) {
return false;
}
$user->addRole($role);
$this->userManager->updateUser($user);
return true;
}
/**
* Removes role from the given user.
*
* @param string $username
* @param string $role
*
* @return Boolean true if role was removed, false if user didn't have the role
*/
public function removeRole($username, $role)
{
$user = $this->userManager->findUserByUsername($username);
if (!$user) {
throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
}
if (!$user->hasRole($role)) {
return false;
}
$user->removeRole($role);
$this->userManager->updateUser($user);
return true;
}
}
Symp/UserBundle/Command/CreateUserCommand
<?php
namespace Symp\UserBundle\Command;
use FOS\UserBundle\Command\CreateUserCommand as BaseCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class CreateUserCommand extends BaseCommand
{
/**
* @see Command
*/
protected function configure()
{
$this
->setName('symp:user:create')
->setDescription('Create a user.')
->setDefinition(array(
new InputArgument('name', InputArgument::REQUIRED, 'The name of user'),
new InputArgument('username', InputArgument::REQUIRED, 'The username'),
new InputArgument('email', InputArgument::REQUIRED, 'The email'),
new InputArgument('password', InputArgument::REQUIRED, 'The password'),
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)
{
$name = $input->getArgument('name');
$username = $input->getArgument('username');
$email = $input->getArgument('email');
$password = $input->getArgument('password');
$inactive = $input->getOption('inactive');
$superadmin = $input->getOption('super-admin');
$manipulator = $this->getContainer()->get('symp_user.util.user_manipulator');
$manipulator->create($username, $password, $email, !$inactive, $superadmin,$name);
$output->writeln(sprintf('Created user <comment>%s</comment>', $username));
}
/**
* @see Command
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
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');
}
}
);
$input->setArgument('name',$name);
}
parent::interact($input,$output);
}
}
回答1:
The error occurs because $name
is never set. In the following $name
is passed to the manipulator with a setter; $name
does not appear in the argument list.
Instead try this:
services.yml
app.user_manipulator:
class: AppBundle\Tools\UserManipulator
arguments: [@fos_user.user_manager]
CreateUserCommand modification
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
/**
* @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('app:user:create')
->setDescription('Create a user.')
->setDefinition(array(
new InputArgument('username', InputArgument::REQUIRED, 'A username'),
new InputArgument('name', InputArgument::REQUIRED, 'A name'),
new InputArgument('email', InputArgument::REQUIRED, 'An email'),
new InputArgument('password', InputArgument::REQUIRED, 'A password'),
new InputOption('inactive', null, InputOption::VALUE_NONE, 'Set the user as inactive'),
new InputOption('superadmin', null, InputOption::VALUE_NONE, 'Set the user as superadmin'),
))
->setHelp(<<<EOT
The <info>app:user:create</info> command creates a user:
<info>php app/console app:user:create bborko</info>
This interactive shell will ask you for ...
EOT
);
}
/**
* @see Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$name = $input->getArgument('name');
$email = $input->getArgument('email');
$password = $input->getArgument('password');
$inactive = $input->getOption('inactive');
$superadmin = $input->getOption('superadmin');
$manipulator = $this->getContainer()->get('app.user_manipulator');
$manipulator->setName($name);
$manipulator->create($username, $password, $email, !$inactive, $superadmin);
$output->writeln(sprintf('Created user <comment>%s</comment>', $username));
}
/**
* @see Command
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$helper = $this->getHelper('question');
if (!$input->getArgument('username')) {
$question = new Question('Please enter a username: ');
$question->setValidator(function ($answer) {
if (empty($answer)) {
throw new \RuntimeException(
'A username is required'
);
}
return $answer;
});
$question->setMaxAttempts(2);
$input->setArgument('username', $helper->ask($input, $output, $question));
}
if (!$input->getArgument('name')) {
$question = new Question('Please enter a name: ');
$question->setValidator(function ($answer) {
if (empty($answer)) {
throw new \RuntimeException(
'A name is required'
);
}
return $answer;
});
$question->setMaxAttempts(2);
$input->setArgument('name', $helper->ask($input, $output, $question));
}
if (!$input->getArgument('email')) {
$question = new Question('Please enter an email: ');
$question->setValidator(function ($answer) {
if (empty($answer)) {
throw new \RuntimeException(
'An e-mail address is required'
);
}
return $answer;
});
$question->setMaxAttempts(2);
$input->setArgument('email', $helper->ask($input, $output, $question));
}
if (!$input->getArgument('password')) {
$question = new Question('Please enter a password: ');
$question->setValidator(function ($answer) {
if (empty($answer)) {
throw new \RuntimeException(
'A password is required'
);
}
return $answer;
});
$question->setMaxAttempts(5);
$input->setArgument('password', $helper->ask($input, $output, $question));
}
}
}
UserManipulator
namespace AppBundle\Tools;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\UserManipulator as Manipulator;
/**
* Executes some manipulations on the users
*
* @author Christophe Coevoet <stof@notk.org>
* @author Luis Cordova <cordoval@gmail.com>
*/
class UserManipulator extends Manipulator
{
/**
* 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 Boolean $active
* @param Boolean $superadmin
*
* @return \FOS\UserBundle\Model\UserInterface
*/
public function create($username, $password, $email, $active, $superadmin)
{
$user = $this->userManager->createUser();
$user->setUsername($username);
$user->setName($this->name);
$user->setEmail($email);
$user->setPlainPassword($password);
$user->setEnabled((Boolean) $active);
$this->userManager->updateUser($user, true);
return $user;
}
public function setName($name)
{
$this->name = $name;
}
}
来源:https://stackoverflow.com/questions/28706656/overriding-fosuserbundle