奏鸣曲管理员 - 按翻译的属性排序

时间:2018-01-29 23:52:10

标签: sonata-admin sonata symfony4

我有一个代码:

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

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

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

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

好的,我做到了。

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;
}