Очень часто бывает нужно изменять порядок записей из панели администрирования. Конечно, это можно сделать, введя параметр для сортировки, и меняя его, но это не совсем удобно. Сегодня будем делать сортировку записей из админки мышкой.
Перед применением рецепта, изложенного в этой статье, нужно установить и настроить проект на Symfony и Sonata Admin.
В нашем случае, есть админка для работы с каруселью на фронтэнде. Нужно добавить в нее изменение порядка следования баннеров.
Вот то, что мы хотим получить:
Для начала устанавливаем пакеты:
composer require gedmo/doctrine-extensions
composer require pixassociates/sortable-behavior-bundle
composer require stof/doctrine-extensions-bundle
После установки в bundles.php должны появиться две строки:
[
...
Pix\SortableBehaviorBundle\PixSortableBehaviorBundle::class => ['all' => true],
Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
]
Включаем сортировку в конфигах:
# config/packages/stof_doctrine_extensions.yaml
stof_doctrine_extensions
default_locale ru_RU
orm
default
sortabletrue
# config/services.yaml
# Добавлям Gedmo сервис
gedmo.listener.sortable
class Gedmo\Sortable\SortableListener
calls
'@annotation_reader'setAnnotationReader
tags
name doctrine.event_subscriber connection default
# Прописываем контроллер «PixSortableBehaviorBundle:SortableAdmin» в классе администрирования
admin.banner
class App\Admin\BannerAdmin
arguments
~
App\Entity\Banner
PixSortableBehaviorBundle:SortableAdmintags
name sonata.admin manager_type orm label Баннеры group CMS
Прописываем порядок следования в классе администрирования:
# src/Admin/BannerAdmin.php
...
use Sonata\AdminBundle\Route\RouteCollection;
...
final class BannerAdmin extends AbstractAdmin
{
protected $datagridValues = [
'_page' => 1,
'_sort_order' => 'ASC',
'_sort_by' => 'position',
];
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
...
->add('_action', null, [
'label' => false,
'actions' => [
'move' => [
'template' => '@PixSortableBehavior/Default/_sort_drag_drop.html.twig',
'enable_top_bottom_buttons' => false,
],
]
])
;
}
protected function configureRoutes(RouteCollection $collection)
{
$collection->add('move', $this->getRouterIdParameter().'/move/{position}');
}
}
Изменения в сущности Banner:
# src/Entity/Banner.php
...
use Gedmo\Mapping\Annotation as Gedmo;
...
class Banner
{
/**
* @Gedmo\SortablePosition
* @ORM\Column(type="integer")
*/
private $position;
...
public function getPosition(): ?int
{
return $this->position;
}
public function setPosition(int $position): self
{
$this->position = $position;
return $this;
}
}
В шаблон страницы админки нужно добавить js бандла «pixsortablebehavior»:
{# templates/admin/layout.html.twig #}
{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('admin') }}
+ {{ encore_entry_script_tags('jquery-ui') }}
+ {{ encore_entry_script_tags('sortable') }}
{% endblock %}
# webpack.config.js
Encore
+ .addEntry('jquery-ui', './public/bundles/pixsortablebehavior/js/jquery-ui.min.js')
+ .addEntry('sortable', './public/bundles/pixsortablebehavior/js/init.js')
Вот и всё! Теперь у нас есть сортировка. Осталось только на фронтэнде, при получении записей из базы, не забыть отсортировать по полю position.