FOS UserBundle为注册添加所需的功能

时间:2017-03-17 03:32:03

标签: php symfony model-view-controller fosuserbundle registration

我觉得我已经非常疲惫地使用了Google和Fos UserBundle的文档来搜索初始化注册新用户时所需的基本实体的方法。我已经覆盖了RegistrationController:register方法,并尝试初始化并向用户添加一个名为“Humidor”的实体。这就是目前的情况。

    <?php

namespace UserBundle\Controller;

use Symfony\Component\HttpFoundation\RedirectResponse;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
use AppBundle\Entity\Humidor;
use Symfony\Component\HttpFoundation\Request;

use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class RegistrationController extends BaseController
{
    public function registerAction(Request $request)
    {


        /** @var $formFactory FactoryInterface */
        $formFactory = $this->get('fos_user.registration.form.factory');
        /** @var $userManager UserManagerInterface */
        $userManager = $this->get('fos_user.user_manager');
        /** @var $dispatcher EventDispatcherInterface */
        $dispatcher = $this->get('event_dispatcher');

        $user = $userManager->createUser();
        $user->setEnabled(true);

        $event = new GetResponseUserEvent($user, $request);
        $dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);

        if (null !== $event->getResponse()) {
            return $event->getResponse();
        }

        $form = $formFactory->createForm();
        $form->setData($user);

        $form->handleRequest($request);

        if ($form->isSubmitted()) {
            if ($form->isValid()) {
                $event = new FormEvent($form, $request);
                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
                $humidor = new Humidor();
                $user->addHumidor($humidor);

                $userManager->updateUser($user);

                if (null === $response = $event->getResponse()) {
                    $url = $this->getParameter('fos_user.registration.confirmation.enabled')
                        ? $this->generateUrl('fos_user_registration_confirmed')
                        : $this->generateUrl('fos_user_profile_show');

                    $response = new RedirectResponse($url);
                }

                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

                return $response;
            }

            $event = new FormEvent($form, $request);
            $dispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);

            if (null !== $response = $event->getResponse()) {
                return $response;
            }
        }

        return $this->render('FOSUserBundle:Registration:register.html.twig', array(
            'form' => $form->createView(),
        ));
    }
}

当尝试添加调用addHumidors()这是我的自定义用户实体扩展BaseUser的方法时,我注意到php storm建议所有默认的User方法,但没有来自我的自定义用户,所以显然是错误的。关于如何从我的自定义注册操作挂钩到我的自定义User类的任何建议,甚至是关于更好地实现此功能的意见都是一流的。谢谢

1 个答案:

答案 0 :(得分:2)

首先要做的事情:因为你所做的只是{1}}在一个单一化的用户身上。你也可以把它作为构造函数的一部分。这类似于Doctrine建议使用集合的方式:

new Humidor()

这样,即使是未初始化的用户,也始终可以使用此对象。无论您有什么需求,都可以随心所欲地玩弄它。您可以传递数组而不是单个“默认”雪茄盒,或者您也可以调整class User extends BaseUser { public function __construct(Humidor $humidor = null) { // Doctrine recommends this for ToMany-associations: $this->humidors = new ArrayCollection(); if (null === $humidor) { $humidor = new Humidor(); } $this->addHumidor($humidor); } // [...the rest of your code...] } 以检查它是否为空,然后创建默认值。在任何情况下,在用户内部处理这一点可以让您轻松更改一个类中的默认行为(而不是您调用getHumidors()的所有控制器。它将确保您始终拥有(默认) ?)空的雪茄盒。

第二,关于:

  

我注意到php storm建议了所有默认的User方法,但没有来自我的自定义用户,因此显然是错误的

PhpStorm只是猜测方法的输出,因此它是什么样的对象。在您的情况下,您正在使用EntityManager,它在其界面中引用UserInterface,它也在doc块中使用。

如果您选中FosUserBundle\Model\UserManagerInterface::createUser(),您会发现文件块包含addHumidor()。这是PhpStorm获取UserManager返回的对象的地方,因为您的User-class有比@return UserInterface之类的接口更多的方法,PhpStorm不会知道它们。如果你想告诉PhpStorm有一个具有更多方法的具体对象(即你的用户类),你可以在调用createUser时执行以下操作:

addHumidor

这应该覆盖PhpStorms先前对这种类型的假设,然后在下面的if条件中找到你的方法。如果您接受我的第一个建议,则不必这样做,因为无论如何您都不必调用/** @var $user AppBundle\Entity\User */ $user = $userManager->createUser(); 方法。

至于为什么这是必要的可能有点长的基本要点是,php是动态类型的,PhpStorm永远不会100%知道一个方法在运行时会实际返回什么,因为PHP没有强制一个方法来总是返回同一件事情。这就是为什么PhpStorm必须猜测并且通常采用docblock(或使用php 7:指定的返回类型)作为最权威的来源,因为这显然是开发人员打算返回的内容以及应该预期的内容。