2016-07-07 43 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以確保您從右表中進行選擇。