Создание пользователя-администратора с помощью FosUserBundle

Я пытаюсь создать Admin User с FOsUserBundle из окон команд с помощью следующей команды:

php app/console fos:user:create

В моем проекте пользователь Admin добавляет другого пользователя с обязательной проверкой. Поэтому, когда я выбираю свое имя пользователя, почту и пароль, он сообщает мне:

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

Как установить значение "широта" в моем AdminUser? Я также использую PUGXMultiUserBundle.

Ответ 1

Единственный способ достичь этого для меня -

1 - переопределить команду cli FOSUserBundle, помещенную в Command/CreateUserCommand.php
2 - переопределите метод создания пользователя 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 находятся в исходном комплекте, в свой собственный каталог Resource/directory (та же позиция, то же имя файла, те же аннотации, если таковые имеются) и... магия может start:) (это действительно только для просмотров, обратите внимание!)

Что означает "переопределение"?

Override означает, что вы берете существующую функцию, "тень" ее, переопределяя в другом месте (объявляйте функцию с тем же именем, независимо от того, сколько параметров она принимает, независимо от типа аргументов, поскольку php не поддерживает перегрузку метода [кроме случаев, когда вы делаете "хак" ]), а затем вы можете использовать его вместо оригинала. Это общий метод добавления дополнительных функций к функции или для изменения самой функции.
Скажем, что у нас есть два класса: A и B с B, который является дочерним классом A. Скажем также, что A имеет метод под названием myMethod().

В B мы можем сделать что-то вроде

public function myMethod() {
  parent::myMethod();
  //add extra functionalities here
}

таким образом мы добавляем дополнительные функции, поскольку мы вызываем родительский ( "оригинальный" ) метод, а затем выполняем некоторые дополнительные функции

Если в B мы делаем что-то вроде

public function myMethod() { // некоторый код здесь, но не вызывающий родительский метод }

мы переопределяем поведение myMethod()

Как Symfony2 позволяет мне переопределять методы?

Как я уже говорил в своем ответе, вы должны сделать свой пакет дочерним элементом пакета, содержащего функции (ы), которые вы пытаетесь переопределить (в этом случае FOSUserBundle). После того, как вы это сделали, используйте каталог Resources вашего пакета, чтобы выполнить то, что вам нужно. воспроизведите "структуру дерева папок" исходного пакета (например: одинаковые имена папок) пока вы не достигнете класса, который содержит функцию, которую вам нужно переопределить.

Следуйте вашему примеру: вам нужно переопределить функцию execute(), содержащуюся в Command/CreateUserCommand.php. Вам необходимо создать в папке пакета этот путь:

PathTo/YourCostumBundle/Command/

и поместите в файл CreateUserCommand.php содержимое, которое я покажу вам выше.

Если вы не понимаете, где я нахожу этот путь, посмотрите код FOSUserBundle, и это будет абсолютно ясно!

Почему опасно изменять код FOSUserBundle напрямую?

Хорошо, есть много ответов на точку критики, которую я могу вам показать. Выбор основного (не упорядоченного по важности):

  • Что делать, если вам нужно обновить FOSUserBundle? Вы будете использовать композитор и потеряете все изменения, внесенные вами в код FOSUserBundle.
  • Что делать, если у вас есть более одного пакета в вашем проекте, который должен использовать FOSUserBundle? Возможно, обычное поведение имеет смысл для пакета, но не для другого. Коумизация поведения на локальном уровне связок помогает сохранить целостность логики FOSUserBundle.
  • Что делать, если вы разрабатываете пакет, который хотите поделиться с другим пользователем? Вам нужно заставить их "взять" свою собственную костюмированную версию FOSUserBundle и предупредить их об обновлении.

Наконец: я прекрасно знаю, что ваша сущность не входит в FOSUserBundle, но я могу поспорить, что они расширяют базовый пользователь FOSUserBundle, поэтому то, что я сказал выше, применимо к вашему делу.

Надеюсь, что теперь он будет менее размытым:)


Документация: http://symfony.com/doc/current/cookbook/bundles/inheritance.html#overriding-controllers