我有一个实体'Contact'与另一个实体'Invoice'有一个OneToMany关联:
// src/AppBundle/Entity/Contact.php
/**
* @var Collection
*
* @ORMOneToMany(targetEntity="Invoice", mappedBy="contact", cascade={"persist", "remove"}, orphanRemoval=true)
**/
private $invoices;
// src/AppBundle/Entity/Invoice.php
/**
* @var Contacts
*
* @ORMManyToOne(targetEntity="Contact", inversedBy="invoices")
* @ORMJoinColumn(name="id_contact_fk", referencedColumnName="id_contact_pk")
**/
private $contact;
然后我有一个Sonata管理类'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()))来代替连接列。因此,似乎我需要做的是以某种方式覆盖查询,Sonata Admin/Doctrine在ContactAdmin编辑视图被呈现时使用。
我知道createQuery()方法在一个Sonata Admin类可以被覆盖,但是(纠正我,如果我错了在这里)这只是用于生成列表视图的查询调用。
有sonata.admin.event.configure.form事件,我可以采取行动,但我不确定是否有任何方式我可以修改查询从该上下文中?
我该怎么做呢?
经过一番挖掘,我发现sonata_type_collection表单类型接受一个未记录的名为'data'的参数。你可以直接传递给它一个Collection of objects,它会使用这些对象
接受的解决方案确实允许您将选项限制为查询,但它不会在保存实体后用值填充表单字段。
使用query_builder
选项代替:
$formMapper->add('invoices', null, [
'query_builder' => function(DoctrineORMEntityRepository $invoice_repo) {
return $invoice_repo
->createQueryBuilder('invoice')
->where('invoice.date > :date')
->setParameter('date', new DateTime('1 year ago'))
;
}
]);