Сортировка столбцов страницы администратора

Мы используем пакет Sonata для нашего административного раздела. Когда пользователь переходит в какой-либо раздел в админке, например продукты, и пытается отсортировать по определенному столбцу, он не запоминает порядок сортировки на следующей странице, а также пользователь может сортировать только в одном направлении. не знаете, как это исправить?

Вот мой код, в котором я расширяю класс администратора Sonata:

namespace Project\AdminBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Doctrine\ORM\EntityManager;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;

abstract class AbstractAdmin extends Admin
{
/** @var int */
protected $maxPerPage = 10;

/** @var int */
protected $maxPageLinks = 30;

/** @var \Doctrine\ORM\Mapping\ClassMetadata */
protected $metadata;

/** @var Doctrine\ORM\EntityManager $entityManager */
protected $entityManager;

/** @var array */
protected $forbiddenFormFields = array(
    'id', 'createdAt', 'updatedAt', 'publishedAt', 'notifiedAt'
);

/** @var array */
protected $optionalFormFields = array(
    'slug'
);

/** @var array */
protected $forbiddenShowFields = array(
    'id'
);

/** @var array */
protected $forbiddenDatagridFields = array(
    'createdAt', 'updatedAt', 'publishedAt', 'notifiedAt'
);

/** @var array */
protected $forbiddenDatagridTypes = array(
    'datetime', 'date', 'float', 'decimal'
);

/** @var array */
protected $forbiddenListFields = array();

/** @var array */
protected $listIdentifierFields = array(
    'id', 'name', 'slug', 'symbol'
);

/** @var array */
public $leftMostFields = array(
    'id', 'name', 'slug'
);

/** @var array */
public $rightMostFields = array(
    'notifiedAt', 'createdAt', 'updatedAt', 'publishedAt',
);

/** @var array */
public $fields;

/**
 * Extended constructor with Entity Manager
 *
 * @param string                     $code
 * @param string                     $class
 * @param string                     $baseControllerName
 * @param Doctrine\ORM\EntityManager $entityManager
 */
public function __construct($code, $class, $baseControllerName,
                            $entityManager)
{
    parent::__construct($code, $class, $baseControllerName);
    $this->entityManager = $entityManager;
    $this->metadata      = $entityManager->getClassMetadata($class);
    $fields = array_merge($this->metadata->getAssociationNames(),
        $this->metadata->getFieldNames());
    $this->fields = $this->sortFields($fields);

    // Set default ordering of lists
    if (!$this->hasRequest()) {
        $this->datagridValues = array(
            '_page'       => 1,
            '_sort_order' => 'DESC',
            '_sort_by'    => 'updatedAt'
        );
    }
}

/**
 * @param FormMapper $mapper
 */
protected function configureFormFields(FormMapper $mapper)
{
    parent::configureFormFields($mapper);
    foreach ($this->fields as $field) {
        $options = array();
        $type = $this->metadata->getTypeOfField($field);

        if (in_array($type, array('bool', 'boolean'))) {
            $options['required'] = false;
        }

        if (in_array($field, $this->forbiddenFormFields)) {
            continue;
        }

        if (in_array($field, $this->optionalFormFields)) {
            $options['required'] = false;
        }

        if ($this->metadata->isAssociationWithSingleJoinColumn($field)) {
            $assoc = $this->metadata->getAssociationMapping($field);
            if (@$assoc['joinColumns']['0']['nullable']) {
                $options['required'] = false;
            }
        }

        $associations = $this->metadata->getAssociationMappings();
        if (isset($associations[$field])) {
            $options['attr'] = array('class' => 'chzn-select');
            if ((isset($associations[$field]['joinTable'])) ||
               (!$associations[$field]['isOwningSide'])) {
                $options['required'] = false;
            }
        }

        $mapper->add($field, null, $options);
    }
}

/**
 * @param ShowMapper $mapper
 */
protected function configureShowFields(ShowMapper $mapper)
{
    parent::configureShowFields($mapper);
    foreach ($this->fields as $field) {
        if (in_array($field, $this->forbiddenShowFields)) {
            continue;
        }
        $mapper->add($field);
    }
}

/**
 * @param DatagridMapper $mapper
 *
 * @return void
 */
protected function configureDatagridFilters(DatagridMapper $mapper)
{
    parent::configureDatagridFilters($mapper);
    foreach ($this->fields as $field) {
        $type = $this->metadata->getTypeOfField($field);
        if (in_array($field, $this->forbiddenDatagridFields)) {
            continue;
        }
        if (in_array($type, $this->forbiddenDatagridTypes)) {
            continue;
        }
        $mapper->add($field);
    }
}

/**
 * @param ListMapper $mapper
 */
protected function configureListFields(ListMapper $mapper)
{
    parent::configureListFields($mapper);

    foreach ($this->fields as $field) {
        if (in_array($field, $this->forbiddenListFields)) {
            continue;
        }

        if (in_array($field, $this->listIdentifierFields)) {
            $mapper->addIdentifier($field, null, array('route' => array('name' => 'show')));
        } else {
            $mapper->add($field);
        }
    }
}

/**
 * @throws \Exception
 */
public function sortFields($fields)
{
    $leftMost = $this->leftMostFields;
    $rightMost = $this->rightMostFields;

    usort($fields, function($a, $b) use ($leftMost, $rightMost) {
        if (count(array_intersect($leftMost, $rightMost)) != 0) {
            throw new \Exception('Leftmost and Rightmost must differ');
        }

        $leftPosA = array_search($a, $leftMost);
        $isALeftMost = is_integer($leftPosA);
        $rightPosA = array_search($a, $rightMost);
        $isARightMost = is_integer($rightPosA);

        $leftPosB = array_search($b, $leftMost);
        $isBLeftMost = is_integer($leftPosB);
        $rightPosB = array_search($b, $rightMost);
        $isBRightMost = is_integer($rightPosB);

        if ($isALeftMost && $isBLeftMost) {
            return $leftPosA - $leftPosB;
        }
        if ($isARightMost && $isBRightMost) {
            return $rightPosA - $rightPosB;
        }
        if ($isALeftMost || $isBRightMost){
            return -1;
        }
        if ($isARightMost || $isBLeftMost) {
            return 1;
        }
        return strnatcasecmp($a, $b);
    });

    return $fields;
}
}

Когда мы добавили «sort_by» в файл ветки. Это работает только на страницах с 1 по 9, когда мы переходим с 1 на 11 или с 9 на 10, тогда он не запоминает порядок сортировки на следующей странице.

Файл ветки:

<div class="pagination">
<ul>
                                    {% if admin.datagrid.pager.page != 1  %}
                                        <li><a href="{{ admin.generateUrl('list', admin.modelmanager.paginationparameters(admin.datagrid, 1)) }}" title="{% trans from 'SonataAdminBundle' %}link_first_pager{% endtrans %}">&laquo;</a></li>
                                    {% endif %}

                                    {% if admin.datagrid.pager.page != admin.datagrid.pager.previouspage %}
                                        <li><a href="{{ admin.generateUrl('list', admin.modelmanager.paginationparameters(admin.datagrid, admin.datagrid.pager.previouspage)) }}" title="{% trans from 'SonataAdminBundle' %}link_previous_pager{% endtrans %}">&lsaquo;</a></li>
                                    {% endif %}

                                    {# Set the number of pages to display in the pager #}
                                    {% for page in admin.datagrid.pager.getLinks() %}
                                        {% if page == admin.datagrid.pager.page %}
                                            <li class="active"><a href="{{ admin.generateUrl('list', admin.modelmanager.paginationparameters(admin.datagrid, page)) }}{{sortBy}}">{{ page }}</a></li>
                                        {% else %}
                                            <li><a href="{{ admin.generateUrl('list', admin.modelmanager.paginationparameters(admin.datagrid, page)) }}{{sortBy}}">{{ page }}</a></li>
                                        {% endif %}
                                    {% endfor %}

                                    {% if admin.datagrid.pager.page != admin.datagrid.pager.nextpage %}
                                        <li><a href="{{ admin.generateUrl('list', admin.modelmanager.paginationparameters(admin.datagrid, admin.datagrid.pager.nextpage)) }}" title="{% trans from 'SonataAdminBundle' %}link_next_pager{% endtrans %}">&rsaquo;</a></li>
                                    {% endif %}

                                    {% if admin.datagrid.pager.page != admin.datagrid.pager.lastpage  %}
                                        <li><a href="{{ admin.generateUrl('list', admin.modelmanager.paginationparameters(admin.datagrid, admin.datagrid.pager.lastpage)) }}" title="{% trans from 'SonataAdminBundle' %}link_last_pager{% endtrans %}">&raquo;</a></li>
                                    {% endif %}


person Sid    schedule 08.12.2012    source источник
comment
Может быть, эта ссылка будет полезна для вас соната-admin-bundle-order   -  person    schedule 09.12.2012
comment
@SS спасибо, но я уже видел этот ответ.   -  person Sid    schedule 09.12.2012
comment
Какие версии Symfony2 и SonataAdmin вы используете? Я думаю, что у меня была эта проблема некоторое время назад, но она была исправлена ​​​​обновлением.   -  person RobMasters    schedule 10.12.2012
comment
@RobMasters Моя версия Symfony2 — 2.0.14, а SonataAdmin — 2.0.   -  person Sid    schedule 10.12.2012


Ответы (1)


Это ваша проблема с пагинацией. вы переходите к своему файлу ветки, где вы выполняете разбиение на страницы, и добавляете «sort_by», где вы передаете параметр.

person Community    schedule 12.12.2012
comment
Это ошибка сонаты. Когда я обновлю пакет администратора Sonata, исправьте ее. - person Sid; 07.04.2014