使用FosUserBundle创建管理员用户

Gia*_*dro 13 cmd admin symfony fosuserbundle

我尝试使用以下命令从命令窗口创建具有FOsUserBundle的管理员用户:

php app/console fos:user:create
Run Code Online (Sandbox Code Playgroud)

在我的项目中,管理员用户以强制性的方式扩展其他用户.所以,当我选择用户名,邮件和密码时,它会告诉我:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'latitude' cannot be null
Run Code Online (Sandbox Code Playgroud)

如何在AdminUser中设置值"latitude"?我也使用PUGXMultiUserBundle.

Don*_*sto 14

唯一可能达到我的方法是

1 - 覆盖FOSUserBundle放入Command/CreateUserCommand.php
2 的cli命令- 覆盖用户创建的FOSUserBundle放入方法Util/UserManipulator.php

// Command/CreateUserCommand.php
protected function execute(InputInterface $input, OutputInterface $output)
{
  $username   = $input->getArgument('username');
  $email      = $input->getArgument('email');
  $password   = $input->getArgument('password');
  $inactive   = $input->getOption('inactive');
  $superadmin = $input->getOption('super-admin');
  $latitude   = $input->getOption('latitude'); //this will be your own logic add

  $manipulator = $this->getContainer()->get('fos_user.util.user_manipulator');
  $manipulator->create($username, $password, $email, $latitude, !$inactive, $superadmin);

  $output->writeln(sprintf('Created user <comment>%s</comment>', $username));
}
Run Code Online (Sandbox Code Playgroud)

// Util/UserManipulator.php
public function create($username, $password, $email, $latitude, $active, $superadmin)
{
  $user = $this->userManager->createUser();
  $user->setUsername($username);
  $user->setEmail($email);
  $user->setPlainPassword($password);
  $user->setEnabled((Boolean) $active);
  $user->setSuperAdmin((Boolean) $superadmin);
  $user->setLatitude($latitude);
  $this->userManager->updateUser($user);

  return $user;
 }
Run Code Online (Sandbox Code Playgroud)

当然,当我说覆盖时,我的意思是......覆盖:P所以你不必修改FOSUserBundle原始文件(你知道,由于很多原因它是危险的)但是通过扩展你的捆绑来制作你自己的文件FOSUserBundle

您是否想知道如何通过FOSUserBundle扩展您的捆绑包?

进入你的软件包"mainfile" - 是你用来注册你的软件包 - 只需添加这一行

public function getParent()
{
  return 'FOSUserBundle';
}
Run Code Online (Sandbox Code Playgroud)

然后你只需重新创建你的ovverride文件存放到原始包中的树结构,进入自定义包的Res​​ources /目录(相同的位置,相同的文件名,相同的注释,如果有的话)和......魔术可以开始:)(这是仅对视图有效,请注意!)

"覆盖"意味着什么?

覆盖意味着你采用一个现有的函数,通过重新定义其他地方来"遮蔽"它(声明一个具有相同名称的函数,无论它接受多少参数,无论参数类型如何,因为php不支持方法重载[除非如果你做了一些"黑客"])然后你可以使用它而不是原来的.这是为函数添加额外功能或更改函数本身的常用技术.
假设我们有两个类,A和B,B是A的子类.也说A有一个叫做的方法myMethod().

在B中我们可以做类似的事情

public function myMethod() {
  parent::myMethod();
  //add extra functionalities here
}
Run Code Online (Sandbox Code Playgroud)

以这种方式,我们在调用父("原始")方法时添加额外的功能,然后执行一些额外的功能

而如果在B中我们做出类似的东西

public function myMethod(){//这里有一些代码,但没有调用父方法}

我们正在重新定义的行为 myMethod()

Symfony2如何让我覆盖方法?

正如我之前在回答中所说的那样,你必须让你的包成为包含你试图覆盖的功能的包的孩子(在这种情况下FOSUserBundle).完成后,使用Resources捆绑包中的目录来完成您的需要.重现原始包的"树文件夹结构"(即:文件夹的相同名称),直到到达包含您需要覆盖的功能的类.

按照你的真实例子:你需要覆盖其中execute()包含的功能Command/CreateUserCommand.php.您必须在您的包文件夹中创建该路径:

PathTo/YourCostumBundle/Command/
Run Code Online (Sandbox Code Playgroud)

并在文件中放置CreateUserCommand.php我上面显示的内容.

如果你不明白我在哪里找到这条路,请看看FOSUserBundle代码,这将是绝对清楚的!

为什么直接修改FOSUserBundle代码很危险?

好吧,我可以告诉你一个批评点的答案很多.选择主要(未按重要性排序):

  • 如果您需要更新FOSUserBundle怎么办?你将使用composer并丢失你对FOSUserBundle代码所做的每一次修改
  • 如果您的项目中有多个捆绑包需要使用FOSUserBundle,该怎么办?也许自定义行为对于一个包有意义,但对另一个没有意义.使本地捆绑级别的行为成本化可帮助您保持FOSUserBundle逻辑不变
  • 如果您正在开发要与其他用户共享的捆绑包,该怎么办?您需要强制他们"获取"您自己经过验证的FOSUserBundle版本并警告他们更新它

最后:我完全知道你的实体没有进入 FOSUserBundle,但我可以打赌他们扩展了FOSUserBundle基础用户,所以我上面说的适用于你的情况.

希望现在不那么模糊:)


文档:http://symfony.com/doc/current/cookbook/bundles/inheritance.html#overriding-controllers