我有三个实体:User
,Work
和Journal
。 User
和Work
之间存在多对多关系,定义如下:
在Work
实体中:
/**
* @ORM\ManyToMany(targetEntity="User", inversedBy="peerReviewedWorks")
* @ORM\JoinTable(name="test_work_user_peer")
*/
private $peerReviewers
在User
实体中:
/**
* @ORM\ManyToMany(targetEntity="Work", mappedBy="peerReviewers")
*/
private $peerReviewedWorks;
我的第三个实体Journal
和User
之间没有任何关系,但Journal
和Work
之间存在一对多的关系:
Journal
实体:
/**
* @ORM\OneToMany(targetEntity="Work", mappedBy="journal")
*/
private $works;
Work
实体:
/**
* @ORM\ManyToOne(targetEntity="Journal", inversedBy="works")
* @ORM\JoinColumn(name="journal_id", referencedColumnName="id")
*/
private $journal;
从Work
控制器创建一个表单,让编辑器从列表中选择同行评审者并将其分配给作品:
<?php
public function manageAction(Request $request, Work $work)
{
// ...
$form = $this->createForm(ManageWorkType::class, $work);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// ...
}
}
ManageWorkType
类如下所示:
<?php
class ManageWorkType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// add some stuff
->add('submit', SubmitType::class)
;
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$work = $event->getData();
$form = $event->getForm();
// form field only added when journal is peer-reviewed
if($work->getJournal()->getIsPeerReviewed() == 1) {
// get a list of all active peer-reviewers
$form->add('peerReviewers', EntityType::class, array(
'class' => 'PlatformBundle:User',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.peerReviewStatus = :status')
->setParameter('status', 'active')
;
},
'multiple' => true,
));
}
});
// ...
}
由于并非每个期刊都需要相同数量的同行评审,因此我在number_of_peer_reviewers
实体中有一个字段Journal
,其中包含所需的同行评审人数:
Journal
实体:
/**
* @var string
*
* @ORM\Column(name="numberOfPeerReviewers", type="string", length=1, nullable=true)
*/
private $numberOfPeerReviewers;
在将User
实体的同行评审者分配给Work
实体之前,我必须检查提交表单的编辑是否从列表中选择了所需数量的同行评审者。如果不是这种情况,表格不应该有效。
为了达到这个目的,我尝试在Work
实体中使用回调验证器,但失败了:
/**
* @ORM\ManyToMany(targetEntity="User", inversedBy="peer_reviewed_works")
* @ORM\JoinTable(name="test_work_user_peer")
* @Assert\Valid
*/
private $peerReviewers;
// ...
/**
* @Assert\Callback
*/
public function validate(ExecutionContextInterface $context, $payload)
{
if(count($this->getPeerReviewers()) < $this->getPeerReviewers()->getNumberOfPeerReviewers()) {
$context->buildViolation('Error message')
->atPath('peerReviewers')
->addViolation();
}
}
如您所见,我不知道如何从number_of_peer_reviewers
表格访问Journal
字段。
非常感谢任何指导。