2016-07-07 78 views
1

进入索纳塔,我有一个预订管理员。索纳塔 - 如何在动态属性上创建过滤器?

在这个管理员我有一些字段存储到数据库像“姓氏”,“名字”或“ref”。我还有一个非DB数据库存储的字段“状态”,它在我的预订实体中定义为这样。

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"; 
     } 

我试图定义的“状态”栏中的过滤器,但我得到:

[Semantical Error] line 0, col 87 near 'state = :sta': Error: Class MyBundle\Entity\Booking has no field or association named state

有没有一种方法来定义这种过滤器的进索纳塔管理员?

请帮忙!

+0

我没有看到任何方法。索纳塔将不得不将所有实体加载到内存中并对其进行过滤。所有[过滤方法](https://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/filter_field_definition.html#filter-field-definition)都可以使用QueryBuilder。 – Lumen

回答

2

正如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'), 
     )); 
} 

当然你也可以回调移动到一个单独的功能,使代码更清洁一点。

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

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