Symfony3 FOS UserBundle如何将选择加载为实体

时间:2016-09-06 14:04:01

标签: fosuserbundle symfony

我正在使用带有FOS UsersBundle的Symfony3.1,我希望将一些添加的字段作为特定实体加载。

RegistrationType我有

->add('country', ChoiceType::class, array(
    'label' => 'label.country',
    'required' => false,
    'placeholder' => 'label.select_country',
    'choices'  => array(
        'France' => '7v8tqr',
    ),
    ))

在我的实体User中,我有

/**
 * @ORM\OneToOne(targetEntity="Country")
 * @ORM\JoinColumn(name="country", referencedColumnName="short")
 */
protected $country;

我无法使用EntityType,因为它会加载每个可用的实体,并且对于相当庞大的省份和城市使用相同类型的字段(我使用javascript管理其内容)。

当我加载注册用户时,country字段作为Country Entity提供,但是当我注册新用户或修改现有用户时,我只有字符串“short”,这会导致错误Expected value of type "AppBundle\Entity\Country" for association field "AppBundle\Entity\User#$country", got "string" instead.

有解决方案吗?

1 个答案:

答案 0 :(得分:1)

感谢@mcriecken带领我朝着正确的方向前进,我使用EventListener实现了以下解决方案

services.yml

中的

app_user.registration:
    class: AppBundle\EventListener\UserRegistrationListener
    arguments: ['@doctrine.orm.entity_manager']
    tags:
        - { name: kernel.event_subscriber }

和EventListener UserRegistrationListener.php

<?php

namespace AppBundle\EventListener;

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Doctrine\ORM\EntityManager;

class UserRegistrationListener implements EventSubscriberInterface
{
    protected $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    /**
     * {@inheritDoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
        );
    }

    public function onRegistrationSuccess(FormEvent $event)
    {
        $form = $event->getForm()->getData();

        //Gets the locations
        $form->setCountry($this->getCountry($form->getCountry()));
        $form->setProvince($this->getProvince($form->getProvince()));
        $form->setCity($this->getCity($form->getCity()));
    }

    //Loads the country as an entity
    public function getCountry($short)
    {
        if ($short == null) return null;

        $repository = $this->em->getRepository('AppBundle:Country');
        return $repository->findOneByShort($short);
    }

    //Loads the province as an entity
    public function getProvince($short)
    {
        if ($short == null) return null;

        $repository = $this->em->getRepository('AppBundle:Province');
        return $repository->findOneByShort($short);
    }

    //Loads the city as an entity
    public function getCity($short)
    {
        if ($short == null) return null;

        $repository = $this->em->getRepository('AppBundle:City');
        return $repository->findOneByShort($short);
    }

}

然后最后我的FOS用户对象包含COuntry,省和城市作为对象,它可以保存到DB: - )