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

php app/console fos:user:create

在我的项目中,管理员用户扩展了其他用户的强制性权限。所以,当我选择我的用户名、邮件和密码时,它告诉我:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'latitude' cannot be null

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

最佳答案

对我来说唯一可能的方法是

1 - 覆盖 FOSUserBundle 的 cli 命令放入 Command/CreateUserCommand.php2 - 覆盖 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));
}


// 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;
 }

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

您想知道如何让 FOSUserBundle 扩展您的包吗?

进入你的包“mainfile” - 是你用来注册你的包的那个 - 只需添加这一行
public function getParent()
{
  return 'FOSUserBundle';
}

然后,您只需将 ovverride 文件所在的树结构重新创建到原始包、自定义包的 Resources/目录(相同的位置、相同的文件名、相同的注释(如果有))和 .... 魔法可以开始:)(这是仅对观点有效,请注意!)

“覆盖”是什么意思?

覆盖意味着你采用一个现有的函数,通过在别处重新定义来“隐藏”它(声明一个具有相同名称的函数,无论它接受多少参数,无论参数类型如何,因为 php 不支持方法重载 [除非你做了一些“hack”])然后你可以用它代替原来的。这是向函数添加额外功能或更改函数本身的常用技术。
假设我们有两个类,A 和 B,其中 B 是 A 的子类。还说 A 有一个名为 myMethod() 的方法。

在 B 中,我们可以做类似的事情
public function myMethod() {
  parent::myMethod();
  //add extra functionalities here
}

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

而如果在 B 中我们做了类似的事情

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

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

Symfony2 如何让我覆盖方法?

正如我之前在我的回答中所说,您必须使您的包成为包含您要覆盖的函数的包的子代(在这种情况下为 FOSUserBundle )。完成后,使用包的 Resources 目录来完成您需要的操作。重现原始包的“树文件夹结构”(即:文件夹的相同名称),直到到达包含需要覆盖的函数的类。

按照您的真实示例:您需要覆盖 execute() 中包含的 Command/CreateUserCommand.php 函数。您必须在捆绑文件夹中创建该路径:
PathTo/YourCostumBundle/Command/

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

如果您不明白我在哪里找到该路径,请查看 FOSUserBundle 代码,它将绝对清楚!

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

好吧,我可以向您展示很多回答批评点的问题。选择主要(不按重要性排序):
  • 如果需要更新FOSUserBundle怎么办?您将使用 composer 并丢失您对 FOSUserBundle 代码
  • 所做的所有修改
  • 如果您的项目中有多个需要使用 FOSUserBundle 的包怎么办?也许自定义行为对一个包有意义,但对另一个没有意义。在本地包级别定制行为可帮助您保持 FOSUserBundle 逻辑完整
  • 如果您正在开发要与其他用户共享的包,该怎么办?你需要强制他们“接受”你自己的服装化 FOSUserBundle 版本并警告他们更新它

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

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

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

    关于symfony - 使用 FosUserBundle 创建管理员用户,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21760612/

    10-13 08:02