We're using the Sonata bundle for our admin section. When a user goes to any section in admin, products for instance, and tries to sort by a particular column, it doesn't remember the sort order in the next page and also, the user can only sort in one direction.I don't know how to fixed it?
Here my code where I extend Sonata admin class:
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;
}
}
When we added "sort_by" in twig file.It is work only 1 to 9 pages when we go 1 to 11 or 9 to 10 then it doesn't remember the sort order in the next page.
Twig file :
<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 %}