枚举和 Symfony 表单的教义集合
Posted
技术标签:
【中文标题】枚举和 Symfony 表单的教义集合【英文标题】:Doctrine collection of enums and Symfony Form 【发布时间】:2021-12-06 08:51:48 【问题描述】:用户可以选择他想要接收的电子邮件通知。
通知类型由枚举(MyCLabs 库)定义:
use MyCLabs\Enum\Enum;
final class NotificationType extends Enum
public const DEADLOCKED = 1;
public const REJECTED = 2;
public const SENT = 3;
public const ACCEPTED = 4;
public const REFUSED = 5;
public function translationPath(): string
return 'user.notifications.'.$this->getKey();
用户有更多的通知类型:
/**
* @ORM\Entity()
*/
class Notification
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="notifications")
*/
protected User $user;
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected int $notificationType;
public function __construct(User $user)
$this->user = $user;
public function getNotificationType(): NotificationType
return new NotificationType($this->notificationType);
public function setNotificationType(NotificationType $notificationType): self
$this->notificationType = $notificationType->getValue();
return $this;
用户实体:
/**
* @ORM\Entity()
*/
class User implements UserInterface, EquatableInterface
/**
* @var Collection|Notification[]
* @ORM\OneToMany(targetEntity=Notification::class, mappedBy="user", cascade="persist", "remove", orphanRemoval=true)
*/
protected Collection $notifications;
//...
这是正确的解决方案吗?现在我在为复选框列表制作 Symfony 表单时遇到问题。
类似这样的事情(我知道,这是错误的):
$builder->add('notifications', ChoiceType::class, [
'choices' => NotificationType::values(),
'expanded' => true,
'multiple' => true,
'choice_value' => 'value',
'choice_label' => static function (NotificationType $type): string
return $type->translationPath();
,
]);
我可以在我的情况下使用内置的 Symfony 表单吗?或者你对关系“实体多对多枚举”有更好的解决方案。
【问题讨论】:
你到底有什么问题/错误? 问题:表单字段“通知”预期的 NotificationType 实例数组(选择选项)。但是给定通知实体的集合。 【参考方案1】:我用数据转换器编写了我的 EnumChoiceType,它将 NotificationType
的数组转换为 Notification
实体的集合,反之亦然。
不要忘记在实体集合中设置orphanRemoval=true
。
用法:
$builder->add('notifications', EnumChoiceType::class, [
'enum' => NotificationType::class,
'class' => Notification::class,
'property' => 'notificationType',
'object' => $options['data'],
'expanded' => true,
'multiple' => true,
]);
枚举选择类型:
class EnumChoiceType extends AbstractType implements DataTransformerInterface
/**
* @var mixed
*/
private $object;
private string $property;
private string $class;
public function buildForm(FormBuilderInterface $builder, array $options): void
$this->object = $options['object'];
$this->property = $options['property'];
$this->class = $options['class'];
if ($options['multiple'])
$builder->addModelTransformer($this);
public function configureOptions(OptionsResolver $resolver): void
$resolver->setRequired([
'enum',
]);
$resolver->setDefaults([
'choices' => static function (Options $options)
return call_user_func([$options['enum'], 'values']);
,
'choice_value' => 'value',
'choice_label' => static function (Enum $enum): string
return $enum->translationPath();
,
'property' => 'enum',
'object' => null,
'class' => null,
]);
/**
* @param mixed $value
* @return Enum[]
*/
public function transform($value): array
$array = [];
foreach ($value as $item)
$array[] = PropertyAccess::createPropertyAccessor()->getValue($item, $this->property);
return $array;
/**
* @param Enum[] $value
*/
public function reverseTransform($value): ArrayCollection
$collection = new ArrayCollection();
foreach ($value as $type)
$notification = new $this->class($this->object);
PropertyAccess::createPropertyAccessor()->setValue($notification, $this->property, $type);
$collection->add($notification);
return $collection;
public function getParent(): string
return ChoiceType::class;
【讨论】:
以上是关于枚举和 Symfony 表单的教义集合的主要内容,如果未能解决你的问题,请参考以下文章
使用 Symfony 路由从 .htaccess 重写 URL
Symfony 2.3 Bad Credentials 自定义提供程序