返回

SonataAdmin 上集合和可翻译实体排序指南

php

SonataAdmin 上的集合和可翻译实体排序

在构建管理界面的过程中,SonataAdmin 允许你管理实体,并带有可定制的列表、显示、创建和编辑视图。在本文中,我们将重点关注如何在 SonataAdmin 中对集合和可翻译实体进行排序。

问题阐述

假设我们有一个 Country 实体,它与 CountryTranslation 实体有一对多的关系。CountryTranslation 实体存储特定于语言的翻译。现在,我们希望按 CountryTranslation 实体中的 label 字段对 Country 实体列表进行排序。

解决方法

为了解决此问题,我们需要修改 CountryAdmin 类的 configureListFields 方法。具体来说,我们需要更新 translations.label 字段的 accessor,使其直接从 CountryTranslation 实体中获取 label 值,而不是通过 Country 实体。此外,我们需要添加 sort_field_mappingsort_parent_association_mappings 选项,以指定排序字段和父关联映射。

protected function configureListFields(ListMapper $list): void
{
    $locale = $this->getRequest()->getLocale();
    $list
        ->addIdentifier('code', null, ['label' => 'admin.entity_translatable.label.code'])
        ->add('translations.label', null, [
            'label' => 'admin.entity_translatable.label.label',
            'sortable' => true,
            'sort_field_mapping' => [
                'fieldName' => 'translations.label'
            ],
            'sort_parent_association_mappings' => [
                'translations'
            ],
        ])
        ->add('createdAt', null, ['label' => 'admin.entity_translatable.label.created_at'])
        ->add('createdBy', null, ['label' => 'admin.entity_translatable.label.created_by'])
        ->add('updatedAt', null, ['label' => 'admin.entity_translatable.label.updated_at'])
        ->add('updatedBy', null, ['label' => 'admin.entity_translatable.label.updated_by']);
}

代码示例

现在,我们来看看如何将此解决方案应用到一个实际的 Symfony 控制器中:

// CountryController.php
class CountryController extends AbstractController
{
    /**
     * @Route("/admin/country", name="admin_country_list")
     */
    public function listAction(ListMapper $listMapper): Response
    {
        $listMapper
            ->add('translations.label', null, [
                'label' => 'Label',
                'sortable' => true,
                'sort_field_mapping' => [
                    'fieldName' => 'translations.label'
                ],
                'sort_parent_association_mappings' => [
                    'translations'
                ],
            ]);

        return $this->render('@SonataAdmin/CRUD/list.html.twig', [
            'admin' => $this->admin,
            'action' => 'list',
        ]);
    }
}

常见问题解答

1. 为什么我们需要修改 accessor

修改 accessor 允许我们直接访问 CountryTranslation 实体中的 label 字段,从而使排序能够基于特定语言的翻译。

2. sort_field_mappingsort_parent_association_mappings 的作用是什么?

sort_field_mapping 指定要排序的实体字段,而 sort_parent_association_mappings 指定与要排序的实体关联的父实体。在我们的例子中,CountryTranslation 实体与 Country 实体关联,因此我们需要指定 translations 作为父实体。

3. 如何自定义排序顺序?

可以通过修改 sortable 选项来自定义排序顺序。您可以指定 ascdesc 来分别启用升序或降序排序。

4. 我可以对多个字段进行排序吗?

是的,你可以通过向 ListMapper 添加多个 add 方法来对多个字段进行排序。

5. 这种方法适用于所有可翻译实体吗?

是的,这种方法适用于所有使用 Gedmo\Translatable 扩展的可翻译实体。