Symfony. Администраторский раздел Sonata Admin. Команды для работы с ORM в своём расширении (bundles).

Опубликовано admin - ср, 03/16/2022 - 14:04

Установка Symfony 5. Установка своего бандла.Перед тем как рассказывать о создании администраторского раздела на Symfony, хотелось озвучить то, что пригодится для него. Итак в предыдущих статьях вы научились создавать "bundles" на symfony. Однако для удобства нам понадобится Sonata Admin в качестве расширения для работы с нашим бандлом.   

В итоге у на будут следующие знания: 

Во-первых про структуру и организацию своего бандла.

Во-вторых это об основных командах для работы с ORM.

В-третьих о некоторых специфических особенностях при создании "bundles".

Однако, прежде чем начать. Перечислю самые необходимые команды без которых невозможно обойтись при  создании администраторского раздела Sonata Admin.

Для создания файла c SQL транзакциями пригодится команда:

$ symfony console make:migration

Команда symfony, не всегда доступна если не установлен cli symfony, тогда ее можно заменить на php  bin/console .....

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

После этой команды следует команда для вставки (исполнения SQL кода):

$ symfony console doctrine:migrations:migrate

Команда для создания форм, например для комментариев:

symfony console make:form CommentFormType Comment

Где и как размещать свой бандл написано в предыдущей статье - Установка Symfony 5. Часть 1. Установка своего бандла.

Как создать структуру указано в Создание бандла на symfony 5. Часть 2. Основа бандла. Поэтому мы не будем останавливаться на данных вопросах подробно.

Единственное напомню, можно для упрощения разработки при создании своего bundles использовать временный репозиторий, указав его в файле composer.json:

    "repositories": [
        {
            "type" : "path",
            "url" : "./bundles/ProductBundle"
        },
        {
            "type" : "path",
            "url" : "./bundles/FOSMessageBundle"
        },
        {
            "type" : "path",
            "url" : "./bundles/StarRatingBundle"
        }
    ]

К примеру,  "url" : "./bundles/ProductBundle" это ваш бандл, который при выполнении команды composer require "название репозитория" подключит его для использования в приложении.

Чтобы загруженные файлы не находились в Git-репозиторий, добавьте директорию /public/uploads в файл .gitignore:

--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+/public/uploads

Дополнительно Вам понадобятся следующие команды.

Перегенерировать определенный класс:

php bin/console make:entity --regenerate App\\Entity\\Category

так неправильно:

php bin/console make:entity --regenerate App\Entity\Course

так правильно для собственного расширения symfony:

symfony console make:entity \\eap1985\\NewsTopBundle\\Entity\\NewsTop

Для регенерации всех сущностей:

 php bin/console make:entity --regenerate eap1985\\StarRatingBundle\\Entity\\StarRating

Итак, после этого можно перейти к администраторскому разделу на SonataAdmin.

Наш администраторский раздел будет содержать подразделы для редактирования данных  из нашего бандла.

Для установки администраторского раздела укажите:

composer require "sonata-project/doctrine-orm-admin-bundle": "^4.0",
composer require "sonata-project/media-bundle": "^4.1",
composer require "sonata-project/twig-extensions": "^1.10",

 Примерно так выглядит администраторский раздел после установки: 

Symfony Sonata Admin

Как видно на изображении разделы "Категории", "Комментарии", "Заказы" и др - это все сущности "entity".

Чтобы вывести в админ разделе  ранее созданную сущность необходимо создать директорию "app/src/Admin".

В нем создается класс примерного содержания:

<?php
// src/Admin/BlogPostAdmin.php

namespace App\Admin;

use eap1985\ProductBundle\Entity\ProductBody;
use eap1985\ProductBundle\Entity\Product;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\Filter\DateTimeType;
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Component\Form\ChoiceList\ChoiceList;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use App\Entity\Category;
use Sonata\AdminBundle\Form\Type\ModelType;

use Symfony\Component\Validator\Constraints\Date;
use Vich\UploaderBundle\Form\Type\VichFileType;


final class CommentAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $form): void
    {

        $subject = $this->getSubject();

        if (null === $subject->getState()) {
            $subject->setState('spam');
        }

        $state = $subject->getState();
        dump($state === 'spam' ? true  : false);
        dump($state === 'published' ? true  : false);
        $form
            ->with('News comments ', ['class' => 'col-md-9'])
            ->add('author', TextType::class)
            ->add('email', TextType::class)
            ->add('text', TextareaType::class)
            ->add('state', ChoiceType::class,[
                'choices'  => [
                    'spam' => 'spam',
                    'published' => 'published',
                    'accept' => 'accept',
                ],
            ])

            ->add('createdAt')
            ->end()
        ;
    }

    protected function configureListFields(ListMapper $list): void
    {
        $list->addIdentifier('createdAt','date',array('label' => 'Playlist','sortable' => true));
        $list->addIdentifier('author');
        $list->addIdentifier('email');
        $list->addIdentifier('state',ChoiceType::class);
    }
    protected function configureDatagridFilters(\Sonata\AdminBundle\Datagrid\DatagridMapper $datagridMapper) : void
    {
        $datagridMapper
            ->add('id')
            ->add('author')
            ->add('createdAt')
            ->add('email')
            ->add('state');
    }


    protected function configureShowFields(ShowMapper $show): void
    {
        $show->add('author');

        $show->add('email');
        $show->add('state',ChoiceType::class);

    }

    public function toString(object $object): string
    {
        return $object instanceof ProductBody
            ? $object->getEntityId()
            : 'Comment Post'; // shown in the breadcrumb on the create view
    }
}
Symfony Sonata Admin

На скриншоте сверху видно, что получится в результате, но для этого необходимо подключить в файле sservice.yaml соответствующий сервис:

    admin.comment:
        class: App\Admin\CommentAdmin
        tags:
            - { name: sonata.admin, model_class: App\Entity\Comment, manager_type: orm, label: Comments }

Как заметно, за основу комментариев взята сущность "App\Entity\Comment":

model_class: App\Entity\Comment

вот ее класс:

<?php

namespace App\Entity;

use App\Repository\CommentRepository;
use Doctrine\ORM\Mapping as ORM;
use eap1985\ProductBundle\Entity\Product;
use Symfony\Component\Validator\Constraints as Assert;
/**
 * @ORM\Entity(repositoryClass=CommentRepository::class)
 */
class Comment
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $author;

    /**
     * @ORM\Column(type="text")
     * @Assert\NotBlank
     */
    private $text;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     * @Assert\Email
     */
    private $email;

    /**
     * @ORM\Column(type="datetime")
     */
    private $createdAt;

    /**
     * @ORM\ManyToOne(targetEntity=Product::class, inversedBy="comments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $Product;

    /**
     * @ORM\Column(type="string", length=255, options={"default": "submitted"})
     * @ORM\Column(type="string", length=255)
     */

    private $state = 'submitted';
    public function getId(): ?int
    {
        return $this->id;
    }

    public function getAuthor(): ?string
    {
        return $this->author;
    }

    public function setAuthor(string $author): self
    {
        $this->author = $author;

        return $this;
    }

    public function getText(): ?string
    {
        return $this->text;
    }

    public function setText(string $text): self
    {
        $this->text = $text;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeInterface
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    public function getProduct(): ?Product
    {
        return $this->Product;
    }

    public function setProduct(?Product $Product): self
    {
        $this->Product = $Product;

        return $this;
    }

    public function getState(): ?string
    {
        return $this->state;
    }

    public function setState(string $state): self
    {
        $this->state = $state;

        return $this;
    }
}

Сейчас,  доступно  настраивать админ раздел, Но это вопрос для отдельно рассмотрения. В следующих статьях мы обязательно вернемся к более сложным примерам админ разделов SonataAdmin. 

Взаимосвязанные материалы

# 1. Как использовать EventDispatcher в Symfony 6 для собственных событий (понедельник, июля 18, 2022 - 16:22 ),

В этой статья я хочу рассказать о создании собственных событий и собственных обработчиков этих событий в Symfony 6 с использованием EventDispatcher. читать...

# 2. Создание собственного шаблона для полей формы с select (четверг, июля 14, 2022 - 20:50 ),
Не могу не рассказать о создании собственного шаблона для полей формы с select, поскольку потратил на это пол дня. читать...
# 3. Symfony. Администраторский раздел Sonata Admin. Команды для работы с ORM в своём расширении (bundles). (среда, марта 16, 2022 - 14:04 ),
Symfony. Администраторский раздел Sonata Admin. А также об основных командах для работы с ORM в своём расширении (bundles). читать...
# 4. Создание бандла на symfony 5. Часть 2. (пятница, мая 29, 2020 - 21:26 ),
Мы напишем бандл под названием NewsTop, который будет выводить новости с обновлением данных через ajax. NewsTop – приложение для вывода новостей на сайте. читать...
# 5. Установка Symfony 5. Часть 1. Установка своего бандла. (пятница, мая 29, 2020 - 19:06 ),

1. Основная установка.

читать...

На разработку сайта! Скидки до 20%!