Что такое sonata admin
Установка и настройка Sonata Admin на Symfony 4
Приветствую всех. В данной статье поговорим об Symfony 4 и Sonata Admin.
В процессе установки я столкнулся с массой неточностей в документации и сама документация была раскидана по нескольким местам. Здесь я рассмотрю весь процесс, начиная от создания проекта и заканчивая авторизацией вместе с аутентификацией.
Отдельные части настроек взяты из официальной документации, часть бралась из комментариев на GitHub, где обсуждались проблемы при установке. Также расписаны возможные подводные камни и пути их обхода.
Создаем проект на symfony
Для работы с встроенным веб сервером Symfony нужно установить Symfony Client.
Переходим по ссылке http://127.0.0.1:8000/ и получим стандартное приветствие Symfony. Значит все работает корректно.
Устанавливаем Sonata Admin
Sonata Admin и БД
Для того, чтобы взаимодействовать с базой данных нужно установить одну из трех библиотек:
Так как Symfony Flex делает почти все работу за нас при установке, то остается сделать несколько манипуляций для получения конечного результата.
Теперь переходим по ссылке http://127.0.0.1:8000/admin и видим пустой стандартный административный интерфейс.
Создание сущностей
Создадим две сущности для примера, связанные между собой связью один ко многим.
Синхронизируемся с БД.
Настройка сущностей для Sonata Admin
Нужно для каждой сущности создать отдельный файл с описанием, как Sonata Admin должна работать.
Авторизация и аутентификация
Для начала создадим сущность пользователя.
И заодно создадим сущность группы пользователя.
После настроим Twig как движок шаблонов.
На данный момент есть проблемы с работой Symfony Flex и FOSUserBundle. Более подробно можно узнать по ссылкам #2562, #2708 и #2801.
После чего, можно устанавливать бандл.
Настройка ACL
Настройка Doctrine
Настройка работы с почтой
Так как в рамках этой статьи работа с почтой не рассматриватеся, то укажем заглушку вместо реального сервиса.
Интеграция User Bundle в Sonata Admin
Теперь можно обновить ACL и БД.
Для корректной настройки наших Admin классов вместе с ACL нужно внести изменения в настройки.
После запустить следующее:
Вводим demo/demo и попадаем в административную часть.
Итоги
После всех манипуляций мы получили работающую административную часть Sonata Admin на Symfony 4 вместе с аутентификацией и авторизацией c помощью Sonata User + ACL.
Всем спасибо. Если будут вопросы и замечания, то я выслушаю их в комментариях.
Установка и настройка Sonata Admin на Symfony 4
Приветствую всех. В данной статье поговорим об Symfony 4 и Sonata Admin.
В процессе установки я столкнулся с массой неточностей в документации и сама документация была раскидана по нескольким местам. Здесь я рассмотрю весь процесс, начиная от создания проекта и заканчивая авторизацией вместе с аутентификацией.
Отдельные части настроек взяты из официальной документации, часть бралась из комментариев на GitHub, где обсуждались проблемы при установке. Также расписаны возможные подводные камни и пути их обхода.
Создаем проект на symfony
Для работы с встроенным веб сервером Symfony нужно установить Symfony Client.
Переходим по ссылке http://127.0.0.1:8000/ и получим стандартное приветствие Symfony. Значит все работает корректно.
Устанавливаем Sonata Admin
Sonata Admin и БД
Для того, чтобы взаимодействовать с базой данных нужно установить одну из трех библиотек:
Так как Symfony Flex делает почти все работу за нас при установке, то остается сделать несколько манипуляций для получения конечного результата.
Теперь переходим по ссылке http://127.0.0.1:8000/admin и видим пустой стандартный административный интерфейс.
Создание сущностей
Создадим две сущности для примера, связанные между собой связью один ко многим.
Синхронизируемся с БД.
Настройка сущностей для Sonata Admin
Нужно для каждой сущности создать отдельный файл с описанием, как Sonata Admin должна работать.
Авторизация и аутентификация
Для начала создадим сущность пользователя.
И заодно создадим сущность группы пользователя.
После настроим Twig как движок шаблонов.
На данный момент есть проблемы с работой Symfony Flex и FOSUserBundle. Более подробно можно узнать по ссылкам #2562, #2708 и #2801.
После чего, можно устанавливать бандл.
Настройка ACL
Настройка Doctrine
Настройка работы с почтой
Так как в рамках этой статьи работа с почтой не рассматриватеся, то укажем заглушку вместо реального сервиса.
Интеграция User Bundle в Sonata Admin
Теперь можно обновить ACL и БД.
Для корректной настройки наших Admin классов вместе с ACL нужно внести изменения в настройки.
После запустить следующее:
Вводим demo/demo и попадаем в административную часть.
Итоги
После всех манипуляций мы получили работающую административную часть Sonata Admin на Symfony 4 вместе с аутентификацией и авторизацией c помощью Sonata User + ACL.
Всем спасибо. Если будут вопросы и замечания, то я выслушаю их в комментариях.
Что такое sonata admin
После завершения 11 части наше приложение вполне работоспособно. Им могут пользоваться как соискатели, так работодатели. Настало время обсудить администраторскую составляющую нашего сайта. При помощи Sonata Admin Bundle мы полностью реализуем интерфейс администратора менее чем за час.
Установка Sonata Admin Bundle
Чтобы установить последнюю версию бандла, добавьте в файл composer.json следующие строки:
Затем запустите команду обновления пакетов composer:
Теперь укажем в файле AppKernel.php новые бандлы:
Раскомментируйте директиву translator :
Импортируем маршруты администраторской части в общий файл маршрутизации routing.yml :
Добавим роль ROLE_SONATA_ADMIN в app/config/security.yml :
Установим статические файлы бандла:
Не забудьте очистить кеш:
Администраторская часть сайта теперь доступна по адресу: http://joboard.local/app_dev.php/admin/dashboard
CRUD контроллер
Этот контроллер содержит в себе базовые методы для управления моделями(удаление, правка и создание). Один класс Admin соответствует одной сущности вашего приложения. Все действия контроллера могут быть переписаны в зависимости от требований приложения. Контроллер использует класс Admin для создания различных действий. Внутри контроллера объект типа Admin можно получить через свойства настроек.
Создадим контроллеры для каждой модели. Сначала для Category:
Создание класса Admin
Сначала создадим каталог, а затем класс для категорий:
Теперь для вакансий:
Теперь добавим эти классы в файл настроек служб services.yml :
На этом этапе мы видим группу Joboard, включающую в себя модули Job и Category со сылками Add new (добавить) и List (список).
Настройки классов Admin
Если вы перейдете по этим ссылкам, то ничего полезного там не найдете, потому что мы не задали поля для отображения. Выполним базовую настройку для категорий:
Теперь для вакансий:
Итак, мы создали базовый модуль администрирования сайта. Вот список его функциональных возможностей:
Групповые действия
Добавим новый метод, который будет удалять все вакансии, не активированные за последние 60 дней. Для этого нам не надо выбирать никаких объектов, так как мы их будем искать в теле метода.
Вот что у нас получилось:
На сегодня это все. В следующей части рассмотрим, как защитить администраторскую часть. Заодно обсудим систему безопасности Symfony2.
Редактирование древовидных структур с SonataAdminBundle в Symfony2
Редактирование древовидных структур — довольно частая задача в веб-разработке. Это очень удобно пользователю, поскольку дает ему возможность создавать любые иерархии у себя на сайте. Естественно, что после перехода на Symfony2, одной из первых задач стало создание такого иерархического списка страниц и написание админки к нему. А так как в качестве админки я использую SonataAdminBundle, то задача сводилась к настройке его для редактирования деревьев.
Казалось что задача распространенная, востребованная и я ожидал получить готовое решение «из коробки». Однако этого не произошло. Мало того, разработчики из Sonata похоже вообще никогда не думали о том, что кому-то придет в голову «админить» деревья через их бандл.
Начнем с самого дерева. С самого моего «программистского детства» меня учили никогда не изобретать велосипед. И хоть я иногда «брыкался» и парировал, что заново изобретенный велосипед будет легче и ехать вперед, а не боком: всегда получал по рукам и… приходилось исользовать готовые решения. Для древовидной структуры страниц решено было использовать Nested tree из Doctrine Extensions.
Создание модели дерева с использованием Doctrine Extensions Tree не представляет сложности и описано в мануале. Хочу отметить, что для удобного использования расширений Доктрины внутри Symfony2, необходимо подключить StofDoctrineExtensionsBundle, установка и настройка которого, опять же хорошо описана в мануале. Ну а если вдруг у кого-то возникнут с этим проблемы, я с удовольствием помогу в комментариях.
Итак, у меня получилась модель ShtumiPravBundle:Page, полный код которой я не буду приводить в этой статье за ненадобностью.
Теперь хочу сказать несколько слов о нехороших особенностях Nested Tree, из-за которых мне пару раз приходилось все менять.
Вывод древовидной структуры в админке
Одна из первых проблем, которые необходимо было решить — это вывод страниц в админке в виде дерева, т. е. добавить слева перед названием статьи соответствующее уровню вложенности количество пробелов. Та же проблема была и в выпадающих списках select. Решение было найдено очень простое — добавить в модель методы __toString и getLaveledTitle:
Теперь в настройках списка стало возможным использование генерируемого «на лету» поля laveled_title.
Согласен, что решение не самое лучшее, но другого здесь не дано.
Вспомним п. 2 проблем, о которых я писал выше. Наиболее простой способ обойти эту проблему — создать один корневой элемент и либо не использовать его вообще, либо использовать как текст главной страницы.
Я решил дать ему имя «== Корневой элемент ==» и не использовать вообще нигде. Т. е. запретить в админке его редактирование/удаление. Все остальные статьи должны быть либо непосредственными потомками этого корневого элемента, либо потомками потомков. Корневой элемент был создан в БД руками, а для того, чтобы он не был доступен для редактирования, в класс PageAdmin был добавлен метод createQuery.
Здесь я приведу полный код класса PageAdmin, а ниже опишу какие методы и для чего использовались.
При редактировании дерева пагинация не нужна в большинстве случаев. Поэтому я увеличил количество элементов на одну страницу со стандартных 30-ти до 2500.
Добавление/редактирование элементов
Тут основную проблему составлял вывод иерархического выпадающего списка родителей в форме редактирования статьи. Эта проблема была решена добавлением query_builder с замыканием в entity поле parent. Т. к. у нас в БД имеется корневой элемент «== Корневой элемент ==», то поле parent должно быть обязательным.
Что же касается методов postPersist и postUpdate, то они были добавлены с целью вызвать методы verify и recover репозитория для пущей уверенности, что после этих действий структура дерева не будет повреждена.
Сортировка элементов относительно своих соседей
Также нужно было сделать кнопки, с помощью которых пользователь мог бы перемещать статьи вверх/вниз относительно своих соседей. SonataAdminBundle позволяет использовать свои шаблоны в полях списка записей. Поэтому необходимо создать два шаблона: для кнопок вверх и вниз соответственно:
Подключаются эти шаблоны в методе configureListFields класса PageAdmin.
В файл routing.yml необходимо добавить два пути: для кнопок вверх и вниз соответственно:
Ну и естественно, необходимо создать контроллер PageTreeSortController, который и будет выполнять перемещение статьи:
Доступ к данному контроллеру может иметь только администратор, поэтому необходимо ограничение по роли ROLE_SUPER_ADMIN.
Удаление элементов
Основная тонкость удаления элементов дерева заключается в том, что нужно позаботиться, чтобы не возникло конфликтов из-за foreign key и не произошло сбоев в дереве. Об этом я уже говорил в п. 3 проблем Nested tree.
Я специально не стал удалять метод preRemove из класса PageAdmin, чтобы показать, что перед удалением статьи необходимо позаботиться и удалить все связанные с нею записи из других моделей. В моем случае это были модели AdditionalMenu и Service.
Отдельно хочу отметить, что установка в модели каскадного удаления не работает в данном случае. Дело в том, что Doctrine Extensions Tree для удаления потомков пользуется своими методами, которые не обращают внимания на каскадность. Правда для пущей уверенности я все же установил и каскадное удаление:
Удаление же потомков Nested Tree производит автоматически. Тут ничего настраивать не пришлось.
Заключение
Казалось бы ничего сложного в описанном мною решении нет, однако из-за иногда не совсем прозрачного поведения Nested Tree, осложненного особенностями создания админок в SonataAdminBundle, пришлось некоторое время повозиться над этим решением. Надеюсь, что это поможет сохранить время вам, дорогой читатель, при реализации аналогичной задачи.
Чего не хватает данному решению. Первое, что приходит на ум — это сокрытие поддеревьев. Т. е. «плюсики» возле каждого элемента, позволяющие отобразить его потомков. Такое решение будет актуально для очень больших деревьев. Вторая идея доработок вытекает из первой — хотелось бы, чтобы по нажатию на «плюсик» админка запоминала этот родительский элемент и при создании новой статьи выбирала его в поле «родитель» автоматически.
Решение обеих проблем не сложное. Необходимо создать еще один шаблон для «плюсика» и дальше в контроллере сохранять в сессию, какие элементы нужно отображать, а какие скрывать. Ну а в методе createQuery обрабатывать данные из этой сессии.
Административный интерфейс с SonataAdminBundle
Для чего это нужно?
С помощью SonataAdminBundle можно быстро создать конфигурируемый интерфейс редактирования сущностей ORM-модели (также выделены бандлы для работы с MongoDb и PHPCr, но они пока находятся на раннем этапе развития). При этом любую часть интерфейса можно доработать под себя. В конце октября 2011 оформление было переведено на фреймворк Twitter Boostrap, поэтому внешний вид административного интерфейса получается довольно современным.
Установка и базовая конфигурация
В файл deps нужно добавить код для установки SonataAdminBundle и дополнительных бандлов:
В файл app/autoload.php нужно добавить новые пространства имен, в файл app/AppKernel.php инициализацию установленных бандлов
В файл app/config/routing.yml нужно добавить роутинг для административного интерфейса:
И записать в директорию web css,js и пр. от установленных бандлов
Чтобы добавить пароль на адмистистративный интерфейс можно воспользоваться либо штатной авторизацией Symfony 2, либо поставить дополнительный бандл FOSUserBundle
В файле app/config/config.yml можно задать заголовок и логотип, а также переопределить шаблоны административного интерфейса. Для начала добавим заголовок административного интерфейса:
Для того чтобы включить сервис translator нужно модифицировать app/config/config.yml:
После установки, при обращении по адресу http://localhost/admin/dashboard (предполагаем что Symfony 2 установлена на сайт с именем http://localhost) выводится пустой административный интерфейс, для которого пока не прописаны сервисы администрирования сущностей.
Замечание: Translator и IE
Чтобы компонент translator определял русский accept-language нужно в настройках IE добавить в разделе Свойства обозревателя/ Общие / Языки русский язык с кодом ru-Ru
Пример использования
В качеcтве примера сделаем административный интерфейс для редактирования новостей, сущности которых описаны в статье Создание CRUD приложения на Symfony 2. Исходники используемых сущностей можно посмотреть на Github.
SonataAdminBundle использует архитектуру, в которой описание административного интерфейса производится посредством специального класса Admin, в котором производится конфигурация формы редактирования, списка записей, формы поиска записей, страницы отображения записи. Этот принцип был заимствован из проекта Django.
Классы <Имя сущности>Admin
Для редактирования новостей, ссылок к новостям и категорий новостей нужно создать 3 класса в директории Test/NewsBundle/Admin: NewsAdmin, NewsLinkAdmin и NewsCategoryAdmin:
Административный класс для ссылок новостей содержит только метод configureFormFields, т.к. ссылки новостей редактируются вместе с новостью:
NewsCategoryAdmin создается по аналогии с NewsAdmin. Исходники административных классов можно посмотреть на Github.
Регистрация админстративных сервисов
Административный класс нужно зарегистировать как сервис, для чего его нужно прописать в Test/NewsBundle/Resources/config/services.xml. Для сервисов административного интерфейса указывается тэг «sonata.admin», позволяющий отличать их от других сервисов. Также указывается название группы пунктов меню (атрибут «group») и название пункта меню (атрибут «label») — эти данные используются для построения меню административного интерфейса. В нашем случае пункт меню для редактирования ссылок к новости в главном меню показывать не нужно, т.к. они заносятся на странице редактирования новости. Поэтому для сервиса c ставим атрибут show_in_dashboard=«false».
В приведенном примере сервисы используют стандартный контроллер SonataAdminBundle:CRUD, однако при необходимости можно создавать свои контроллеры.
Что получилось
После перезагрузки административный интерфейс выглядит так:
При нажатии на ссылку «Новости / Список» выводится список новостей с возможностью фильтрации записей:
Страница редактирования новоcти выглядит так:
Изменение позиции привязанных сущностей
Привязанные к новости ссылки добавляются без перезагрузки страницы. В сущность «NewsLink» добавлено поле pos, по которому ведется сортировка при запрашивании ссылок к новости. Указании опции ‘sortable’ => ‘pos’ для типа поля sonata_type_collection добавляет в интерфейс возможность изменения порядка новостей, путем перетаскивания строк таблицы:
Однако чтобы изменения положения ссылки отражались в БД нужно дополнить класс NewsAdmin (не уверен что решение правильное, но по крайней мере работает):
Навигация
В базовой поставке SonataAdminBundle есть русская локализация стандартных названий кнопок, заголовков и и т.п. Чтобы локализация была полной, для созданных разделов административного интерфейса нужно создать переводы заголовков, которые автоматически создаются на основе названий сущностей, например, News List, News Create. Для этого в директории Test/NewsBundle/Resources/translations требуется создать файл messages.ru.xliff (про сервис трансляции можно почитать здесь)
Внимание! В тэгах в примере ниже заменена английская c на русскую с, иначе слетает форматирование кода
Заключение
В итоге получился функциональный, расширяемый интерфейс редактирования записей. Все шаблоны и контроллеры, используемые SonataAdmin можно переопределить в конфигурации приложения. Разработчики на базе SonataAdmin сделали несколько полезных для разработки веб-приложений бандлов, реализующих ряд базовых функций: SonataUserBundle (управление пользователями), SonataNewsBundle (блог), SonataMediaBundle (управление медиа-ресурсами) и SonataPageBundle (прототип CMS). Большой проблемой является плохая документированность, особенно SonataPageBundle, хотя на первый взляд интересный продукт.
Update 2012-07-20: актуальная версия статьи с учетом нововведений Symfony 2.1 находится Здесь