我有一个实体“联系人”,它与另一个实体“发票”具有一个一对多关联:
// src/AppBundle/Entity/Contact.php
/**
* @var Collection
*
* @ORM\OneToMany(targetEntity="Invoice", mappedBy="contact", cascade={"persist", "remove"}, orphanRemoval=true)
**/
private $invoices;
// src/AppBundle/Entity/Invoice.php
/**
* @var Contacts
*
* @ORM\ManyToOne(targetEntity="Contact", inversedBy="invoices")
* @ORM\JoinColumn(name="id_contact_fk", referencedColumnName="id_contact_pk")
**/
private $contact;
然后我有了Sonata Admin类'ContactAdmin',该类在编辑视图中显示此关联:
// src/AppBundle/Admin/ContactAdmin.php
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->tab('Invoices')
->with('Invoices')
->add('invoices', 'sonata_type_collection', array(
'btn_add' => false,
'required' => false
), array(
'edit' => 'inline',
'inline' => 'table'
))
->end()
->end();
}
效果很好,除了某些联系人有数以百计的发票可以追溯到多年。我只需要显示当年的发票。
看起来似乎没有任何方法可以在Doctrine中映射关联时使用动态值(类似于mysql中的YEAR(CURDATE())代替连接列。所以,我似乎需要做的是覆盖在呈现ContactAdmin编辑视图时Sonata Admin / Doctrine使用的查询。
我知道可以重写Sonata Admin类中的createQuery()方法,但是(如果我错了,请改正我的方法,这仅用于生成列表视图的查询。
有一个我可以处理的sonata.admin.event.configure.form事件,但是我不确定是否有什么方法可以从该上下文修改查询?
我该怎么办?
经过一番挖掘,我发现sonata_type_collection表单类型接受一个名为'data'的未记录参数。您可以直接将其传递给对象集合,并使用这些对象。
接受的解决方案确实允许您将选项限制为查询,但是保存实体后,它不会使用值填充表单字段。
改为使用query_builder
选项:
$formMapper->add('invoices', null, [
'query_builder' => function(\Doctrine\ORM\EntityRepository $invoice_repo) {
return $invoice_repo
->createQueryBuilder('invoice')
->where('invoice.date > :date')
->setParameter('date', new DateTime('1 year ago'))
;
}
]);