Sonata - 如何在动态 属性 上创建过滤器?
Sonata - How to create filter on dynamic property?
进入索纳塔,我有一个预订管理员。
在这个管理员中,我将一些字段存储到数据库中,例如 "lastname"、"firstname" 或 "ref"。我还有一个非数据库存储的字段 "status",它在我的预订实体中是这样定义的。
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";
}
我试图在 "state" 字段上定义过滤器,但我得到:
[Semantical Error] line 0, col 87 near 'state = :sta': Error: Class MyBundle\Entity\Booking has no field or association named state
有没有办法在 Sonata Admin 中定义这种过滤器?
感谢帮助!
正如 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
来确保您 select 从右边 table.
进入索纳塔,我有一个预订管理员。
在这个管理员中,我将一些字段存储到数据库中,例如 "lastname"、"firstname" 或 "ref"。我还有一个非数据库存储的字段 "status",它在我的预订实体中是这样定义的。
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";
}
我试图在 "state" 字段上定义过滤器,但我得到:
[Semantical Error] line 0, col 87 near 'state = :sta': Error: Class MyBundle\Entity\Booking has no field or association named state
有没有办法在 Sonata Admin 中定义这种过滤器?
感谢帮助!
正如 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
来确保您 select 从右边 table.