Шаг 9: Создание административной панели

5.2 version
Maintained Unmaintained
5.0

Создание административной панели

Именно администраторы проекта будут добавлять предстоящие конференции в базу данных. Административная панель — это защищённый раздел сайта, где администраторы проекта могут изменять данные, модерировать отзывы и многое другое.

Можно быстро сгенерировать панель администрирования на базе модели проекта, используя один из бандлов. EasyAdmin как раз то, что нам нужно.

Настройка бандла EasyAdmin

Для начала добавьте бандл EasyAdmin в зависимости проекта:

1
$ symfony composer req "admin:^3"

EasyAdmin автоматически генерирует админ-панель из определённых контроллеров в приложении. Создайте директорию src/Controller/Admin/ для этих контроллеров:

1
$ mkdir src/Controller/Admin/

Начнём работу с EasyAdmin с создания «административной панели», которая будет служит главной отправной точкой для управления данными сайта:

1
$ symfony console make:admin:dashboard

Для создания контролера используйте ответы по умолчанию:

src/Controller/Admin/DashboardController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
namespace App\Controller\Admin;

use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class DashboardController extends AbstractDashboardController
{
    /**
     * @Route("/admin", name="admin")
     */
    public function index(): Response
    {
        return parent::index();
    }

    public function configureDashboard(): Dashboard
    {
        return Dashboard::new()
            ->setTitle('Guestbook');
    }

    public function configureMenuItems(): iterable
    {
        yield MenuItem::linktoDashboard('Dashboard', 'fa fa-home');
        // yield MenuItem::linkToCrud('The Label', 'icon class', EntityClass::class);
    }
}

По соглашению все контроллеры, относящиеся к админ-панели, определяются в собственном пространстве имён App\Controller\Admin.

Чтобы посмотреть созданную административную панель в браузере перейдите по пути /admin, который был задан в методе index(). Вы можете изменить путь на любой другой:

Вуаля! У нас есть симпатичная административная панель, которую можно настроить как вам угодно.

В следующем шаге создадим контроллеры для управления конференциями и комментариями.

В контроллере админпанели вы, возможно, обратили внимание на метод configureMenuItems(), в котором закомментирован вызов метода, добавляющего ссылку на «CRUD-действие». CRUD — это аббревиатура от «Create, Read, Update и Delete» («Создать, Прочитать, Обновить, Удалить»), четырёх основных операций, которые можно проделать над любой сущностью. Это именно то, что нам нужно от панели администрирования; Однако этим EasyAdmin не ограничивается — с его помощью ещё можно искать и фильтровать данные.

Давайте сгенерируем CRUD-контроллер для конференций:

1
$ symfony console make:admin:crud

Выберите 1, чтобы создать контроллер с CRUD-действиями для конференций и используйте значения по умолчанию для других вопросов. Результатом будет следующий файл:

src/Controller/Admin/ConferenceCrudController.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace App\Controller\Admin;

use App\Entity\Conference;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;

class ConferenceCrudController extends AbstractCrudController
{
    public static function getEntityFqcn(): string
    {
        return Conference::class;
    }

    /*
    public function configureFields(string $pageName): iterable
    {
        return [
            IdField::new('id'),
            TextField::new('title'),
            TextEditorField::new('description'),
        ];
    }
    */
}

Сделайте то же самое для комментариев:

1
$ symfony console make:admin:crud

Остаётся добавить новые CRUD-интерфейсы конференций и комментариев в админпанель:

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
--- a/src/Controller/Admin/DashboardController.php
+++ b/src/Controller/Admin/DashboardController.php
@@ -2,6 +2,8 @@

 namespace App\Controller\Admin;

+use App\Entity\Comment;
+use App\Entity\Conference;
 use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
 use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
 use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
@@ -26,7 +28,8 @@ class DashboardController extends AbstractDashboardController

     public function configureMenuItems(): iterable
     {
-        yield MenuItem::linktoDashboard('Dashboard', 'fa fa-home');
-        // yield MenuItem::linkToCrud('The Label', 'fas fa-list', EntityClass::class);
+        yield MenuItem::linktoRoute('Back to the website', 'fas fa-home', 'homepage');
+        yield MenuItem::linkToCrud('Conferences', 'fas fa-map-marker-alt', Conference::class);
+        yield MenuItem::linkToCrud('Comments', 'fas fa-comments', Comment::class);
     }
 }

Мы переопределили метод configureMenuItems(), в котором добавили пункты меню для конференций и комментариев с соответствующими иконками, а также в самое начало меню поместили ссылку на главную страницу.

С помощью встроенного в EasyAdmin API-метода MenuItem::linkToRoute() легко создавать ссылки на CRUD-сущности.

Главная страница панели пока пуста. В ней вы можете отобразить различную статистику или любую соответствующую информацию. Поскольку у нас нет ничего подобного, то добавим редирект на страницу со списком конференций:

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
--- a/src/Controller/Admin/DashboardController.php
+++ b/src/Controller/Admin/DashboardController.php
@@ -7,6 +7,7 @@ use App\Entity\Conference;
 use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
 use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
 use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
+use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Annotation\Route;

@@ -17,7 +18,10 @@ class DashboardController extends AbstractDashboardController
      */
     public function index(): Response
     {
-        return parent::index();
+        $routeBuilder = $this->get(AdminUrlGenerator::class);
+        $url = $routeBuilder->setController(ConferenceCrudController::class)->generateUrl();
+
+        return $this->redirect($url);
     }

     public function configureDashboard(): Dashboard

При отображении связанных сущностей (в нашем случае, конференции, прикреплённой к комментарию) EasyAdmin попытается преобразовать объект конференции в строку. Если в объекте не будет реализован «магический» метод __toString(), то по умолчанию EasyAdmin выведет имя объекта вместе с первичным ключом (например, Conference #1). Чтобы сделать название связанной сущности более понятнее, определим этот метод в классе Conference:

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
--- a/src/Entity/Conference.php
+++ b/src/Entity/Conference.php
@@ -44,6 +44,11 @@ class Conference
         $this->comments = new ArrayCollection();
     }

+    public function __toString(): string
+    {
+        return $this->city.' '.$this->year;
+    }
+
     public function getId(): ?int
     {
         return $this->id;

То же самое сделайте в классе Comment:

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
--- a/src/Entity/Comment.php
+++ b/src/Entity/Comment.php
@@ -48,6 +48,11 @@ class Comment
      */
     private $photoFilename;

+    public function __toString(): string
+    {
+        return (string) $this->getEmail();
+    }
+
     public function getId(): ?int
     {
         return $this->id;

Теперь вы можете добавлять, изменять и удалять конференции непосредственно из административной панели. Изучите его интерфейс и добавьте хотя бы одну конференцию.

Добавьте несколько комментариев без фотографий. Пока установите дату вручную, затем в следующих шагах мы сделаем автозаполнение столбца createdAt.

Настройка EasyAdmin

Административная панель по умолчанию работает хорошо, хотя она может по-разному настраиваться, чтобы улучшить удобство её использования. Внесем несколько простых изменений в сущность Comment для демонстрации некоторых возможностей:

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
--- a/src/Controller/Admin/CommentCrudController.php
+++ b/src/Controller/Admin/CommentCrudController.php
@@ -3,7 +3,15 @@
 namespace App\Controller\Admin;

 use App\Entity\Comment;
+use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
+use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
 use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
+use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
+use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
+use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
+use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
+use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
+use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter;

 class CommentCrudController extends AbstractCrudController
 {
@@ -12,14 +20,44 @@ class CommentCrudController extends AbstractCrudController
         return Comment::class;
     }

-    /*
+    public function configureCrud(Crud $crud): Crud
+    {
+        return $crud
+            ->setEntityLabelInSingular('Conference Comment')
+            ->setEntityLabelInPlural('Conference Comments')
+            ->setSearchFields(['author', 'text', 'email'])
+            ->setDefaultSort(['createdAt' => 'DESC']);
+        ;
+    }
+
+    public function configureFilters(Filters $filters): Filters
+    {
+        return $filters
+            ->add(EntityFilter::new('conference'))
+        ;
+    }
+
     public function configureFields(string $pageName): iterable
     {
-        return [
-            IdField::new('id'),
-            TextField::new('title'),
-            TextEditorField::new('description'),
-        ];
+        yield AssociationField::new('conference');
+        yield TextField::new('author');
+        yield EmailField::new('email');
+        yield TextareaField::new('text')
+            ->hideOnIndex()
+        ;
+        yield TextField::new('photoFilename')
+            ->onlyOnIndex()
+        ;
+
+        $createdAt = DateTimeField::new('createdAt')->setFormTypeOptions([
+            'html5' => true,
+            'years' => range(date('Y'), date('Y') + 5),
+            'widget' => 'single_text',
+        ]);
+        if (Crud::PAGE_EDIT === $pageName) {
+            yield $createdAt->setFormTypeOption('disabled', true);
+        } else {
+            yield $createdAt;
+        }
     }
-    */
 }

Чтобы настроить раздел Comment, задайте и упорядочите поля в методе configureFields(). Некоторые поля настраиваются дополнительно, например, скрытие текстового поля на главной странице.

Методы configureFilters() определяют, какие фильтры будут доступны рядом с полем поиска.

Это всего лишь небольшая часть возможных настроек в EasyAdmin.

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

1
$ symfony run psql -c "TRUNCATE conference RESTART IDENTITY CASCADE"

  • « Previous Шаг 8: Описание структуры данных
  • Next » Шаг 10: Создание пользовательского интерфейса

This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.