使用FosUserBundle创建管理员用户

时间:2014-02-13 16:59:29

标签: symfony cmd admin fosuserbundle

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

php app/console fos:user:create

在我的项目中,管理员用户通过强制适当性扩展其他用户。因此,当我选择用户名,邮件和密码时,它会告诉我:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'latitude' cannot be null

如何在AdminUser中设置值“latitude”?我也使用PUGXMultiUserBundle。

1 个答案:

答案 0 :(得分:14)

只有可能的方式来达到我的目的是

1 - 覆盖放入FOSUserBundle的{​​{1}}的cli命令 2 - 覆盖放置在Command/CreateUserCommand.php

中的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));
}

当然,当我说覆盖时,我的意思是......覆盖:P所以你不必修改// 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; } 原始文件(你知道,由于很多原因它是危险的)但是通过制作你的捆绑来制作你自己的文件延长FOSUserBundle

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

进入你的软件包“mainfile” - 你用来注册你的软件包 - 只需添加这行

FOSUserBundle

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

“覆盖”是什么意思?

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

在B中我们可以做类似

的事情
myMethod()

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

然而,如果在B中我们做了类似

的事情

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

我们正在重新定义public function myMethod() { parent::myMethod(); //add extra functionalities here }

的行为

Symfony2如何让我覆盖方法?

正如我之前在答案中所说,你必须让你的捆绑包成为包含你试图覆盖的功能的捆绑的孩子(在这种情况下是myMethod())。完成后,使用捆绑包的FOSUserBundle目录来完成您需要的工作。重现原始捆绑包的“tree-folder-structure”(即:相同的名称)文件夹),直到你到达包含你需要覆盖的功能的类。

按照您的真实示例:您需要覆盖Resources中包含的execute()功能。您必须在您的包文件夹中创建该路径:

Command/CreateUserCommand.php

并将文件PathTo/YourCostumBundle/Command/ 放在我上面显示的内容中。

如果您不明白我在哪里找到该路径,请查看CreateUserCommand.php代码,这将是绝对清楚的!

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

嗯,我可以告诉你的批评点有很多答案。选择主要(未按重要性排序):

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

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

希望现在不那么模糊了:)


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