如何在 Sonata Admin 编辑视图中自定义实体关联的 SQL 查询

Posted

技术标签:

【中文标题】如何在 Sonata Admin 编辑视图中自定义实体关联的 SQL 查询【英文标题】:How to customize SQL query for entity associations in Sonata Admin edit view 【发布时间】:2015-10-25 00:20:02 【问题描述】:

我有一个实体“联系人”,它与另一个实体“发票”有 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 类“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-project.org/bundles/admin/master/doc/reference/… 我应该采用 EntityRepository 参数并返回一个查询生成器。 感谢@JasonHendry 的回复,但“查询”只是“sonata_type_model”表单类型的一个选项。而且我相当肯定它只用于设置表单元素的选项,没有办法使用它来覆盖关联查询。 【参考方案1】:

经过一番挖掘,我发现 sonata_type_collection 表单类型接受一个名为“数据”的未记录参数。您可以直接将对象集合传递给它,它会使用这些对象。

【讨论】:

这行得通,但是一旦您保存实体,保存的值就不会再次显示在该字段中。【参考方案2】:

公认的解决方案允许您将选项限制为查询,但它不会在保存实体后使用值填充表单字段。

改用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'))
        ;
    
]);

【讨论】:

以上是关于如何在 Sonata Admin 编辑视图中自定义实体关联的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

Sonata Admin Bundle:在列表视图中显示收藏总数

Sonata Admin 中没有自定义视图的面包屑?

Sonata Admin Bundle - 添加多步骤批处理操作

在 Symfony 2 项目的 Sonata Admin 中使用自定义视图页面进行图像预览

根据值在 Admin 中自定义 Django 表单字段

Sonata Admin:添加自定义触发器/动作到列表/编辑动作