管理セクションには Sonata バンドルを使用しています。ユーザーが管理画面の任意のセクション (たとえば製品) に移動し、特定の列で並べ替えようとすると、次のページの並べ替え順序が記憶されず、ユーザーは一方向にしか並べ替えることができません。それを修正する方法を知りませんか?
Sonata admin クラスを拡張するコードは次のとおりです。
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;
}
}
twigファイルにsort_byを追加したところ、1ページから11ページ、9ページから10ページと行っても1ページから9ページしか動作せず、次のページのソート順を覚えていません。
小枝ファイル:
<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 %}">«</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 %}">‹</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 %}">›</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 %}">»</a></li>
{% endif %}