symfony 修改用于在应用筛选器后获取列表项的查询

eyh26e7m  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(111)

我们在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);
        }
    }

    // ...
}

然而,似乎没有一种方法可以在应用过滤器之后修改用于获取列表视图所有项目的查询**,因此我无法更改参数类型。
有一个方法configureQuery(),但这个方法似乎是在应用过滤器之前被调用来创建基本查询的。还有一个方法configureFilterParameters(),但这个方法根本不适用于Doctrine查询。
在解决Sonata Admin的Ulid支持相关问题之前(https://github.com/sonata-project/SonataAdminBundle/issues/7327):有没有一种方法可以在过滤器被应用后,轻松地修改用于获取列表视图中的项目的查询?或者我必须创建自己的ModelManager之类的东西?

py49o6xq

py49o6xq1#

我发现使用CallbackFilterEntityType表单字段非常容易,所以我创建了一个自定义过滤器,它可能没有内置的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
    ]);
    // ...
}

相关问题