如何在 Sonata Admin 编辑视图中自定义 SQL 查询实体关联
How to customize SQL query for entity associations in Sonata Admin edit view
我有一个实体 'Contact',它与另一个实体 'Invoice':
有 OneToMany 关联
// 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 class '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 编辑视图时使用的查询。
我知道 Sonata Admin class 中的 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'))
;
}
]);
我有一个实体 'Contact',它与另一个实体 'Invoice':
有 OneToMany 关联// 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 class '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 编辑视图时使用的查询。
我知道 Sonata Admin class 中的 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'))
;
}
]);