[英]Symfony 3.4 - FOSUserBundle - Overwritting create command failed
I'm trying to override the FOSUser bundle user creation command. 我正在尝试覆盖FOSUser捆绑用户创建命令。
I followed this tutorial: https://blog.overnetcity.com/2012/10/15/symfony2-fosuserbundle-comment-etendre-la-commande-par-defaut-de-creation-dun-utilisateur/ 我遵循了本教程: https : //blog.overnetcity.com/2012/10/15/symfony2-fosuserbundle-comment-etendre-la-commande-par-defaut-de-creation-dun-utilisateur/
But when I launch my new command, I get this error: 但是,当我启动新命令时,出现以下错误:
Cannot autowire service "Site\\PagesBundle\\Command\\CreateUserCommand": argument " $userManipulator " of method "FOS\\UserBundle\\Command\\CreateUserCommand::__construct()" references class "FOS\\UserBundle\\Util\\UserManipulator" but no such service exists.
无法自动装配服务“ Site \\ PagesBundle \\ Command \\ CreateUserCommand”:方法“ FOS \\ UserBundle \\ Command \\ CreateUserCommand :: __ construct()”的参数“ $ userManipulator ”引用类“ FOS \\ UserBundle \\ Util \\ UserManipulator”,但不存在此类服务。 You should maybe alias this class to the existing "fos_user.util.user_manipulator" service.
您可能应该将此类别名为现有的“ fos_user.util.user_manipulator”服务。
It seems that no one had this problem before me. 似乎没有人在我之前遇到这个问题。 Yet I respected the tutorial, the imports, all that was needed.
但是我尊重所有需要的教程,导入。
I show you my code: 我给你看我的代码:
<?php
namespace Site\PagesBundle\Command;
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;
use FOS\UserBundle\Command\CreateUserCommand as BaseCommand;
class CreateUserCommand extends BaseCommand
{
/**
* @see Command
*/
protected function configure()
{
parent::configure();
$this
->setName('atelech:user:create')
->getDefinition()->addArguments(array(
new InputArgument('nom', InputArgument::REQUIRED, 'Le nom'),
new InputArgument('prenom', InputArgument::REQUIRED, 'Le prenom')
))
;
$this->setHelp(<<<EOT
// L'aide qui va bien
EOT
);
}
/**
* @see Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$email = $input->getArgument('email');
$password = $input->getArgument('password');
$nom = $input->getArgument('nom');
$prenom = $input->getArgument('prenom');
$inactive = $input->getOption('inactive');
$superadmin = $input->getOption('super-admin');
/** @var \FOS\UserBundle\Model\UserManager $user_manager */
$user_manager = $this->getContainer()->get('fos_user.user_manager');
/** @var \Acme\AcmeUserBundle\Entity\User $user */
$user = $user_manager->createUser();
$user->setUsername($username);
$user->setEmail($email);
$user->setPlainPassword($password);
$user->setEnabled((Boolean) !$inactive);
$user->setSuperAdmin((Boolean) $superadmin);
$user->setNom($nom);
$user->setPrenom($prenom);
$user_manager->updateUser($user);
$output->writeln(sprintf('Created user <comment>%s</comment>', $username));
}
/**
* @see Command
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
parent::interact($input, $output);
if (!$input->getArgument('nom')) {
$nom = $this->getHelper('dialog')->askAndValidate(
$output,
'Please choose a nom:',
function($nom) {
if (empty($nom)) {
throw new \Exception('nom can not be empty');
}
return $nom;
}
);
$input->setArgument('nom', $nom);
}
if (!$input->getArgument('prenom')) {
$prenom = $this->getHelper('dialog')->askAndValidate(
$output,
'Please choose a prenom:',
function($prenom) {
if (empty($prenom)) {
throw new \Exception('prenom can not be empty');
}
return $prenom;
}
);
$input->setArgument('prenom', $prenom);
}
}
}
I wanted to add the two attributes "name" and "first name" 我想添加两个属性“名称”和“名字”
Thanks for your help ! 谢谢你的帮助 !
so.. 所以..
checked on Symfony 3.4.24 and friendsofsymfony/user-bundle (2.0) 检查了Symfony 3.4.24和friendsofsymfony / user-bundle(2.0)
and the code is next according to sources of fosuserbundle: 接下来是根据fosuserbundle的来源编写的代码:
<?php
namespace AppBundle\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use FOS\UserBundle\Command\CreateUserCommand as BaseCommand;
use Symfony\Component\Console\Question\Question;
class CreateUserCommand extends BaseCommand
{
/**
* @see Command
*/
protected function configure()
{
parent::configure();
$this
->setName('atelech:user:create')
->getDefinition()->addArguments(
array(
new InputArgument('nom', InputArgument::REQUIRED, 'Le nom'),
new InputArgument('prenom', InputArgument::REQUIRED, 'Le prenom'),
)
);
$this->setHelp(
<<<EOT
// L'aide qui va bien
EOT
);
}
/**
* @see Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$email = $input->getArgument('email');
$password = $input->getArgument('password');
$nom = $input->getArgument('nom');
$prenom = $input->getArgument('prenom');
$inactive = $input->getOption('inactive');
$superadmin = $input->getOption('super-admin');
$userManager = $this->getContainer()->get('fos_user.user_manager');
/** @var \Acme\AcmeUserBundle\Entity\User $user */
$user = $userManager->createUser();
$user->setUsername($username);
$user->setEmail($email);
$user->setPlainPassword($password);
$user->setEnabled((Boolean)!$inactive);
$user->setSuperAdmin((Boolean)$superadmin);
$user->setNom($nom);
$user->setPrenom($prenom);
$userManager->updateUser($user);
$output->writeln(sprintf('Created user <comment>%s</comment>', $username));
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
parent::interact($input, $output);
$questions = array();
foreach (['nom', 'prenom'] as $key) {
if (!$input->getArgument($key)) {
$question = new Question("Please choose a $key:");
$question->setValidator(
function ($username) use ($key) {
if (empty($username)) {
throw new \Exception("$key can not be empty");
}
return $username;
}
);
$questions[$key] = $question;
}
}
foreach ($questions as $name => $question) {
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument($name, $answer);
}
}
}
and nothing in service.yml - everything is autowired correctly 在service.yml中没有任何内容-一切都正确地自动接线
check for your namespace pls :) 检查您的名称空间请:)
I had this error in symfony 4 but this is issue for all symfony from 3.3 and nevest. 我在symfony 4中有此错误,但这对于所有3.3和nevest的symfony来说都是问题。
In DefinitionErrorExceptionPass.php line 54:
Cannot autowire service "App\Command\AppUserCreateCommand": argument "$user
Manipulator" of method "__construct()" references class "FOS\UserBundle\Uti
l\UserManipulator" but no such service exists. You should maybe alias this
class to the existing "fos_user.util.user_manipulator" service.
is because from Symfony 3.3 services are private by default and autowired. 这是因为默认情况下,Symfony 3.3中的服务是私有的,并且自动连接。 To fix you should describe your private argument of constructor of command in
services.yml
. 要解决此问题,应在
services.yml
描述命令构造函数的私有参数。
This code should fix problem: 此代码应解决问题:
App\Command\AppUserCreateCommand:
arguments: ['@fos_user.util.user_manipulator']
Second reason of this error. 此错误的第二个原因。 You not overriding constructor, but if constructor of extending class is not declared php uses constructor of parent class.
您不会覆盖构造函数,但是如果未声明扩展类的构造函数,则php将使用父类的构造函数。 This one:
这个:
public function __construct(UserManipulator $userManipulator)
{
$this->userManipulator = $userManipulator;
}
so even if you not typed it, UserManipulator
is used and this is reason of error. 因此,即使您没有键入它,
UserManipulator
使用UserManipulator
,这是错误的原因。
If you want to know more I recommend tutorial: https://symfonycasts.com/screencast/symfony-3.3/autowiring-aliases 如果您想了解更多信息,我建议您学习以下教程: https : //symfonycasts.com/screencast/symfony-3.3/autowiring-aliases
In my case I resigned from using FOS\\UserBundle\\Util\\UserManipulator
because of his method create
is too constraint. 就我而言,由于他的
create
方法过于FOS\\UserBundle\\Util\\UserManipulator
,我辞职了,不再使用FOS\\UserBundle\\Util\\UserManipulator
。 I create class that extends it: 我创建扩展它的类:
src/Util/AppUserManipulator.php
<?php
namespace App\Util;
use App\Entity\User;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\UserManipulator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Request;
class AppUserManipulator extends UserManipulator
{
/**
* User manager.
*
* @var UserManagerInterface
*/
private $userManager;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
/**
* @var RequestStack
*/
private $requestStack;
/**
* UserManipulator constructor.
*
* @param UserManagerInterface $userManager
* @param EventDispatcherInterface $dispatcher
* @param RequestStack $requestStack
*/
public function __construct(UserManagerInterface $userManager, EventDispatcherInterface $dispatcher, RequestStack $requestStack)
{
parent::__construct($userManager, $dispatcher, $requestStack);
$this->userManager = $userManager;
$this->dispatcher = $dispatcher;
$this->requestStack = $requestStack;
}
/**
* Creates a user and returns it.
*
* @param string $username
* @param string $password
* @param string $email
* @param bool $active
* @param bool $superadmin
* @param string $firstName
* @param string $lastName
* @param string $phoneNumber
*
* @return \FOS\UserBundle\Model\UserInterface
*/
public function createAppUser($username, $password, $email, $active, $superadmin, $firstName, $lastName, $phoneNumber)
{
/**
* @var User
*/
$user = $this->userManager->createUser();
if($user instanceof User) {
$user->setUsername($username);
$user->setEmail($email);
$user->setPlainPassword($password);
$user->setEnabled((bool)$active);
$user->setSuperAdmin((bool)$superadmin);
$user->setFirstName($firstName);
$user->setLastName($lastName);
$user->setPhoneNumber($phoneNumber);
$this->userManager->updateUser($user);
$event = new UserEvent($user, $this->getRequest());
$this->dispatcher->dispatch(FOSUserEvents::USER_CREATED, $event);
}
return $user;
}
/**
* @return Request
*/
private function getRequest()
{
return $this->requestStack->getCurrentRequest();
}
}
Command that I created has code src/Command/AppUserCreateCommand.php
我创建的命令的代码为
src/Command/AppUserCreateCommand.php
<?php
namespace App\Command;
use App\Util\AppUserManipulator;
use FOS\UserBundle\Command\CreateUserCommand;
use FOS\UserBundle\Util\UserManipulator;
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;
use Symfony\Component\Console\Style\SymfonyStyle;
class AppUserCreateCommand extends CreateUserCommand
{
const PROPERTIES = [
'first_name' => 'First Name',
'last_name' => 'Last Name',
'phone_number' => 'Phone Number'
];
protected static $defaultName = 'app:user:create';
private $userManipulator;
public function __construct(AppUserManipulator $userManipulator)
{
parent::__construct($userManipulator);
$this->userManipulator = $userManipulator;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
parent::configure();
$this->setName('app:user:create')
->setHelp(preg_replace('/fos:user:create/', 'app:user:create', $this->getHelp()));
foreach (self::PROPERTIES as $name => $description) {
$this->addArgument($name, InputArgument::REQUIRED, $description);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// code from parent start
$username = $input->getArgument('username');
$email = $input->getArgument('email');
$password = $input->getArgument('password');
$inactive = $input->getOption('inactive');
$superadmin = $input->getOption('super-admin');
// code from parent end
foreach (self::PROPERTIES as $name => $description) {
${$name} = $input->getArgument($name);
}
$this->userManipulator->createAppUser($username, $password, $email, !$inactive, $superadmin, ...array_keys(self::PROPERTIES));
$output->writeln(sprintf('Created user <comment>%s</comment>', $username));
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
parent::interact($input, $output);
$questions = array();
foreach (self::PROPERTIES as $name => $description) {
if (!$input->getArgument($name)) {
$question = new Question("Please choose a $name:");
$question->setValidator(function ($property) use ($name){
if (empty($property)) {
throw new \Exception("$name can not be empty");
}
return $property;
});
$questions[$name] = $question;
}
}
foreach ($questions as $name => $question) {
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument($name, $answer);
}
}
}
to use type 使用类型
./bin/console app:user:create
note : using my solution you should not change services.yaml
because of services defined by me like AppUserManipulator
are autowired by default. 注意 :使用我的解决方案时,您不应更改
services.yaml
因为默认情况下,我定义的服务(例如AppUserManipulator
是自动连接的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.