修改应用过滤器后用于获取列表项的查询

问题描述 投票:0回答:1

我们在 Symfony 6 项目中使用 ULID 作为我们所有实体 ID 的数据类型。

symfony/uid
包对此有很大帮助。为了快速构建管理界面,我们使用 Sonata Admin 4。

不幸的是,截至目前,Sonata Admin 与 ULID 完全不兼容。这会影响列表视图的实体/模型过滤器:过滤器字段正确显示您可以过滤的所有可用实体,但过滤器未正确应用,因为作为生成的 Doctrine 查询中的参数类型,默认数据类型

string
被用来代替
Ulid
.

以下代码导致显示一个选择字段,显示所有可用的相关实体,但生成的查询使用所选实体的 ULID 作为字符串而不是二进制值,这导致查询结果为空。

protected function configureDatagridFilters(DatagridMapper $datagrid): void
{
    $datagrid->add('subject.relatedEntity', ModelFilter::class);
    // ...
}

在自定义控制器方法的上下文中,我找到了一种使用以下方法更改查询参数类型的方法:

public function myCustomControllerAction(
    ProxyQueryInterface $query, 
    AdminInterface $admin
): Response {
    // Find all parameters that are referencing an 'id' property
    // and change their type to the UlidType of the symfony/uid package
    foreach ($query->getQueryBuilder()->getParameters() as $parameter) {
        if (stripos($parameter->getName(), '_id_') !== false) {
            $parameter->setValue($parameter->getValue(), UlidType::NAME);
        }
    }

    // ...
}

但是,似乎没有办法修改用于获取列表视图的所有项目的查询after应用了过滤器,因此我无法更改参数类型。

有方法

configureQuery()
,但是这个方法似乎被调用来创建基本查询,before应用过滤器。还有方法
configureFilterParameters()
,但是这个方法根本不适用于Doctrine查询。

直到有关 Sonata Admin 的 Ulid 支持的相应问题得到解决(https://github.com/sonata-project/SonataAdminBundle/issues/7327):是否有一种方法可以轻松更改用于获取的查询列表视图的项目after应用过滤器?还是我必须创建自己的

ModelManager
之类的东西?

symfony doctrine-orm doctrine sonata-admin sonata
1个回答
0
投票

我发现将

CallbackFilter
EntityType
表单域一起使用非常容易,所以我刚刚创建了一个自定义过滤器,它可能没有内置的
ModelFilter
那样灵活,但它做的工作:

protected function configureDatagridFilters(DatagridMapper $datagrid): void
{
    $datagrid->add('subject.relatedEntity', CallbackFilter::class, [
        'callback' => function(ProxyQueryInterface $query, string $alias, string $field, FilterData $data): bool {
            if (!$data->hasValue()) {
                return false;
            }

            $qb = $query->getQueryBuilder();
            $qb->andWhere(
                sprintf(
                    'IDENTITY(%s.%s) = :custom_related_entity_filter_selected_id',
                    $alias,
                    $field
                )
            );

            $qb->setParameter(':custom_related_entity_filter_selected_id', $data->getValue()->getId(), UlidType::NAME);

            return true;
        },
        'field_type' => EntityType::class
    ]);
    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.