我有2个实体 - 用户和组。 他们有许多一对多的关系,集团用于存储用户的角色。
我试图通过增加集合,使用户编辑表单,我希望能够通过从下拉列表中选择它来添加一个新的角色(仅限于什么是已经在DB)
UserType.php:
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
->add('email')
->add('forename')
->add('surname')
->add('isActive')
->add('joinDate', 'date', array('input' => 'datetime', 'format' => 'dd-MM-yyyy'))
->add('lastActive', 'date', array('input' => 'datetime', 'format' => 'dd-MM-yyyy'))
->add('groups', 'collection', array(
'type' => new GroupType(),
'allow_add' => true,
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Sfox\CoreBundle\Entity\User'
));
}
}
和GroupType.php:
class GroupType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('role');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
"data_class" => 'Sfox\CoreBundle\Entity\Group'
));
}
}
这将显示在基本的文本框的形式的作用,但如果我添加一个条目的形式,将级联坚持新进入论坛,如果我是编辑条目,它会改变底层Group的数据。
我试图使一个GroupSelectType.php:
class GroupSelectType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('role', 'entity', array('class'=>'SfoxCoreBundle:Group', 'property'=>'name'));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
"data_class" => 'Sfox\CoreBundle\Entity\Group'
));
}
}
添加字段作为一个“实体”型,这显示了正确的选择框(但是默认值),我似乎无法绑定到用户类型表格!
所有我想要做的方式是修改用户实体底层“群体”的ArrayCollection。
有谁知道我能做到这一点?
嗯,我研究出了解决办法为别人有类似的问题所困扰?
我不得不创建一个自定义表单类型,并宣布它作为一种服务,所以我可以通过在实体管理器。 然后,我需要做出dataTransformer改变我的组对象转化为形式的整数
自GroupSelectType:
class GroupSelectType extends AbstractType
{
/**
* @var ObjectManager
*/
private $om;
private $choices;
/**
* @param ObjectManager $om
*/
public function __construct(ObjectManager $om)
{
$this->om = $om;
// Build our choices array from the database
$groups = $om->getRepository('SfoxCoreBundle:Group')->findAll();
foreach ($groups as $group)
{
// choices[key] = label
$this->choices[$group->getId()] = $group->getName() . " [". $group->getRole() ."]";
}
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new GroupToNumberTransformer($this->om);
$builder->addModelTransformer($transformer);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
"choices" => $this->choices,
));
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'group_select';
}
}
在构造函数中我得到所有可用组,并把它们放入其传递给选择框作为一个选项“选择”阵列。
你会还请注意,我用一个自定义的数据转换,这是对的groupId(这是在形式的呈现使用)更改为组实体。 我做了一个GroupSelectType服务,并在[@ doctrine.orm.entity_manager]通过
services.yml(束配置):
services:
sfox_core.type.group_select:
class: Sfox\CoreBundle\Form\Type\GroupSelectType
arguments: [@doctrine.orm.entity_manager]
tags:
- { name: form.type, alias: group_select }
GroupToNumberTranformer.php
class GroupToNumberTransformer implements DataTransformerInterface
{
/**
* @var ObjectManager
*/
private $om;
/**
* @param ObjectManager $om
*/
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
/**
* Transforms an object (group) to a string (number).
*
* @param Group|null $group
* @return string
*/
public function transform($group)
{
if (null === $group) {
return "";
}
return $group->getId();
}
/**
* Transforms a string (number) to an object (group).
*
* @param string $number
* @return Group|null
* @throws TransformationFailedException if object (group) is not found.
*/
public function reverseTransform($number)
{
if (!$number) {
return null;
}
$group = $this->om
->getRepository('SfoxCoreBundle:Group')
->findOneBy(array('id' => $number))
;
if (null === $group) {
throw new TransformationFailedException(sprintf(
'Group with ID "%s" does not exist!',
$number
));
}
return $group;
}
}
而我的修改UserType.php - 请注意,我用我的自定义表单类型“GROUP_SELECT”现在,因为它是作为服务运行:
class UserType extends AbstractType
{
private $entityManager;
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new GroupToNumberTransformer($this->entityManager);
$builder
->add('username')
->add('email')
->add('forename')
->add('surname')
->add('isActive')
->add('joinDate', 'date', array('input' => 'datetime', 'format' => 'dd-MM-yyyy'))
->add('lastActive', 'date', array('input' => 'datetime', 'format' => 'dd-MM-yyyy'));
$builder
->add(
$builder->create('groups', 'collection', array(
'type' => 'group_select',
'allow_add' => true,
'options' => array(
'multiple' => false,
'expanded' => false,
)
))
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Sfox\CoreBundle\Entity\User'
));
}
public function getName()
{
return 'sfox_corebundle_usertype';
}
}