【问题标题】:Sonata - How to create filter on dynamic property?Sonata - 如何在动态属性上创建过滤器?
【发布时间】:2016-07-07 07:40:14
【问题描述】:

进入奏鸣曲,我有一个预订管理员。

在此管理员中,我将一些字段存储到数据库中,例如“姓氏”、“名字”或“参考”。我还有一个字段“状态”,它是非数据库存储的,它在我的预订实体中定义如下。

    public function getState(){
        if (/*Complex condition*/)
          return 'canceled_not_refund';
        else if (/*Complex condition*/)
          return 'canceled';
        else if (/*Complex condition*/)
          return "no-payment";
        else if (/*Complex condition*/)
          return "partial_payment";
        else if (/*Complex condition*/)
          return "ok";
        else if(/*Complex condition*/)
          return "ended";
      }

我试图在“状态”字段上定义一个过滤器,但我得到:

[语义错误] line 0, col 87 near 'state = :sta': Error: Class MyBundle\Entity\Booking 没有名为 state 的字段或关联

有没有办法在 Sonata Admin 中定义这种过滤器?

感谢帮助!

【问题讨论】:

  • 我看不到任何方法。 Sonata 必须将所有实体加载到内存中并过滤它们。所有filter methods 都使用QueryBuilder。

标签: php symfony sonata-admin sonata


【解决方案1】:

正如 Lumen 已经评论的那样,所有过滤器都与 QueryBuilder 一起使用,因此无法尝试直接过滤不在数据库中的内容。

假设您所说的complex condition 仅包含数据库中的字段,您可以执行以下操作:

protected function configureDatagridFilters(DatagridMapper 
$datagridMapper)
{
    $datagridMapper
        ->add('status', 'doctrine_orm_callback', array(
            'label' => 'Payment Status',
            'callback' => function($queryBuilder, $alias, $field, $value) {
                if ($value['value'] == 'canceled_not_refund') {

                    $queryBuilder->andWhere($alias . '.columnA = :some_value');
                    $queryBuilder->andWhere($alias . '.columnB = :other_value');
                    $queryBuilder->setParameter('some_value', 'some');
                    $queryBuilder->setParameter('other_value', 'other');

                } elseif ($value['value'] == 'canceled') {

                    $queryBuilder->andWhere($alias . '.columnA = :some_value');
                    $queryBuilder->andWhere($alias . '.columnB = :other_value');
                    $queryBuilder->setParameter('some_value', 'some');
                    $queryBuilder->setParameter('other_value', 'other');

                }

            }
            ), 'choice', array('choices' => array(
                   ''    => '', // Empty option to not filter anything
                   'canceled_not_refund' => 'Canceled without refund', 
                   'canceled'  => 'Canceled'),  
        ));
}

当然,您可以将回调移动到单独的函数中以使代码更简洁。

这样做的一个很大的缺点是你会得到一些代码重复,所以如果你的逻辑改变来确定状态,它需要在两个地方改变。

请注意,在 queryBuilder 中,您需要 $alias 以确保您从正确的表中进行选择。

【讨论】:

    猜你喜欢
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    相关资源
    最近更新 更多