【问题标题】:Sonata admin - Sorting by translated propertySonata admin - 按翻译属性排序
【发布时间】:2018-07-08 18:36:36
【问题描述】:

我有一个代码:

protected function configureListFields(ListMapper $listMapper)
{
    $listMapper
        ->addIdentifier('name')
   [..]

这是来自翻译的属性(KNP 可翻译)。我试过用:

  • translations.name - 标签可排序,但缺少值
  • name 或 translate.name - 标签不可排序,但值正常

我不知道该怎么做。也许这里有人可以帮助我?

【问题讨论】:

    标签: sonata-admin sonata symfony4


    【解决方案1】:

    你试过$listMapper->add('name',null, array('sortable'=>true))吗?

    【讨论】:

    • 是的,但我收到“错误:传递给 Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery::entityJoin() 的参数 1 必须是数组类型,给定 null”
    【解决方案2】:

    好的,我成功了。

    1) 创建抽象管理类:

    use Sonata\AdminBundle\Admin\AbstractAdmin as BaseAbstractAdmin;
    
    abstract class AbstractAdmin extends BaseAbstractAdmin { .. }
    

    2) 在你的管理类中使用这个类:

    class UserAdmin extends AbstractAdmin { .. }
    

    3) 将此添加到您的列定义中:

    ->add(
         'fieldName',
          null,
          [
              'sortable'                         => true,
              'sort_field_mapping'               => ['fieldName' => 'id'],
              'sort_parent_association_mappings' => [],
          ]
    )
    

    4) 将此方法添加到您的抽象管理类中:

    protected function prepareQueryForTranslatableColumns($query)
    {
        $currentAlias     = $query->getRootAliases()[0];
        $locale           = $this->request->getLocale();
        $parameters       = $this->getFilterParameters();
        $sortBy           = $parameters['_sort_by'];
        $fieldDescription = $this->getListFieldDescription($sortBy);
        $mapping          = $fieldDescription->getAssociationMapping();
        $entityClass      = $mapping['targetEntity'] ?: $this->getClass();
    
        if ($mapping) {
            $mappings   = $fieldDescription->getParentAssociationMappings();
            $mappings[] = $mapping;
    
            foreach ($mappings as $parentMapping) {
                $fieldName = $parentMapping['fieldName'];
                $query->leftJoin($currentAlias . '.' . $fieldName, $fieldName);
    
                $currentAlias = $fieldName;
            }
        }
    
        $query
            ->leftJoin(
                $currentAlias . '.translations',
                'tr',
                'with',
                'tr.locale = :lang OR
                    (NOT EXISTS(SELECT t.id FROM ' . $entityClass . 'Translation t WHERE t.translatable = tr.translatable AND t.locale = :lang)
                    AND tr.locale = :lang_default)'
            )
            ->addOrderBy('tr.name', $parameters['_sort_order'])
            ->setParameter(':lang', $locale)
            ->setParameter(':lang_default', 'en');
    
        return $query;
    }
    

    我使用 JOIN 来获取当前所选语言环境的翻译,如果当前语言环境尚不存在翻译,我添加默认语言环境的翻译(这是使用 NOT EXIST 的原因)。

    5) 将此方法添加到您的管理类中:

    public function createQuery($context = 'list')
    {
        $query = parent::createQuery($context);
    
        if ('list' === $context) {
            $parameters = $this->getFilterParameters();
            $sortBy     = $parameters['_sort_by'];
    
            if (in_array($sortBy, ['fieldName', 'fieldName.fieldName2', 'fieldName3', ..])) {
                $query = parent::prepareQueryForTranslatableColumns($query);
            }
        }
    
        return $query;
    }
    

    【讨论】:

    • 我添加了一个新的更好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2015-11-06
    • 2017-02-20
    • 2019-04-12
    • 2018-01-20
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 2020-04-10
    相关资源
    最近更新 更多