Instal dan konfigurasikan Sonata Admin di Symfony 4


Salam untuk semuanya. Artikel ini akan berbicara tentang Symfony 4 dan Sonata Admin.


Selama proses instalasi, saya menemukan banyak ketidakakuratan dalam dokumentasi dan dokumentasi itu sendiri tersebar di beberapa tempat. Di sini saya akan mempertimbangkan seluruh proses, dari pembuatan proyek hingga otorisasi bersama dengan otentikasi.


Beberapa bagian dari pengaturan diambil dari dokumentasi resmi, beberapa diambil dari komentar pada GitHub, di mana masalah instalasi dibahas. Kemungkinan jebakan dan jalan di sekitar mereka juga dicat.


Membuat proyek symfony


$ composer create-project symfony/skeleton sonatademo 

 $ cd sonatademo 

Untuk menggunakan Server Web Tertanam Symfony, Anda harus menginstal Klien Symfony .


Kita mulai.


 $ symfony serve 

Kami mengikuti tautan http://127.0.0.1:8000/ dan kami akan menerima salam standar Symfony. Jadi semuanya bekerja dengan benar.



Instal Sonata Admin


 $ composer require sonata-project/admin-bundle 

Sonata Admin dan DB


Untuk berinteraksi dengan database, Anda perlu menginstal salah satu dari tiga perpustakaan:



Pada artikel ini saya menggunakan SonataDoctrineORMAdminBundle , yang lebih dari cukup untuk bekerja dengan MySQL atau Sqlite .


Instal SonataDoctrineORMAdminBundle .


 $ composer require sonata-project/doctrine-orm-admin-bundle 

Sekarang mari kita mengkonfigurasi pekerjaan dengan Sqlite .


Buka file .env dan di bagian ###> doctrine/doctrine-bundle ### ubah DATABASE_URL .


 DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" 

Karena Symfony Flex melakukan hampir semua pekerjaan untuk kami selama instalasi, ia tetap melakukan beberapa manipulasi untuk mendapatkan hasil akhir.


 # config/packages/framework.yaml framework: translator: { fallbacks: ['en'] } 

Kami melakukan


 $ composer dump-env dev 

Sekarang kita ikuti tautan http://127.0.0.1:8000/admin dan kita melihat antarmuka administratif standar kosong.



Penciptaan Entitas


Mari kita membuat dua entitas misalnya, dihubungkan oleh hubungan satu ke banyak.


 <?php // src/Entity/City.php namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity */ class City { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer", options={"unsigned":true}) */ private $id; /** * @var string * * @ORM\Column(type="string") */ private $title; /** * @var string * * @ORM\Column(type="text") */ private $description; /** * @var bool * * @ORM\Column(type="boolean") */ private $isBig = false; /** * @ORM\OneToMany(targetEntity="Address", mappedBy="city") */ private $addresses; public function __construct() { $this->addresses = new ArrayCollection(); } public function getAddresses() { return $this->addresses; } /** * @return string */ public function getTitle(): ?string { return $this->title; } /** * @param string $title * @return City */ public function setTitle(string $title): City { $this->title = $title; return $this; } /** * @return string */ public function getDescription(): ?string { return $this->description; } /** * @param string $description * @return City */ public function setDescription(string $description): City { $this->description = $description; return $this; } /** * @return bool */ public function isBig(): ?bool { return $this->isBig; } /** * @param bool $isBig * @return City */ public function setIsBig(bool $isBig): City { $this->isBig = $isBig; return $this; } public function __toString() { return $this->title; } } 

 <?php // src/Entity/Address.php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity */ class Address { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer", options={"unsigned":true}) */ private $id; /** * @var string * * @ORM\Column(type="string") */ private $title; /** * @var string * * @ORM\Column(type="text") */ private $description; /** * @ORM\ManyToOne(targetEntity="City", inversedBy="addresses") */ private $city; /** * @return string */ public function getTitle(): ?string { return $this->title; } /** * @param string $title * @return Address */ public function setTitle(string $title): Address { $this->title = $title; return $this; } /** * @return string */ public function getDescription(): ?string { return $this->description; } /** * @param string $description * @return Address */ public function setDescription(string $description): Address { $this->description = $description; return $this; } /** * @return City */ public function getCity(): ?City { return $this->city; } /** * @param City $city * @return Address */ public function setCity(City $city) { $this->city = $city; return $this; } public function __toString() { return $this->title; } } 

Kami menyinkronkan dengan database.


 bin/console doctrine:schema:create 

Konfigurasi Entitas untuk Admin Sonata


Penting bagi setiap entitas untuk membuat file terpisah dengan deskripsi tentang bagaimana Admin Sonata harus bekerja.


 <?php // src/Admin/CityAdmin.php namespace App\Admin; use App\Entity\Address; use App\Entity\City; use Sonata\AdminBundle\Admin\AbstractAdmin; use Sonata\AdminBundle\Datagrid\ListMapper; use Sonata\AdminBundle\Datagrid\DatagridMapper; use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Form\Type\CollectionType; use Sonata\AdminBundle\Form\Type\ModelType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; final class CityAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $formMapper) { $formMapper->add('title', TextType::class); $formMapper->add('description', TextareaType::class); $formMapper->add('isBig', CheckboxType::class); } protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper->add('title'); $datagridMapper->add('isBig'); } protected function configureListFields(ListMapper $listMapper) { $listMapper->addIdentifier('title'); $listMapper->addIdentifier('isBig'); } } 

 <?php // src/Admin/AddressAdmin.php namespace App\Admin; use App\Entity\City; use Sonata\AdminBundle\Admin\AbstractAdmin; use Sonata\AdminBundle\Datagrid\ListMapper; use Sonata\AdminBundle\Datagrid\DatagridMapper; use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Form\Type\ModelType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; final class AddressAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $formMapper) { $formMapper->add('title', TextType::class); $formMapper->add('description', TextareaType::class); $formMapper->add('city', ModelType::class, [ 'class' => City::class, 'property' => 'title', ]); } protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper->add('title'); } protected function configureListFields(ListMapper $listMapper) { $listMapper->addIdentifier('title'); } } 

Kelas-kelas ini perlu dijelaskan dalam service.yaml .


 # config/service.yaml services: ... App\Admin\CityAdmin: arguments: [~, App\Entity\City, ~] tags: - { name: sonata.admin, manager_type: orm, label: City } App\Admin\AddressAdmin: arguments: [~, App\Entity\Address, ~] tags: - { name: sonata.admin, manager_type: orm, label: Address } 

Jika kesalahan terjadi ketika memasuki bagian administratif, misalnya Unable to generate a URL for the named route , maka Anda perlu menghapus cache aplikasi dan coba lagi.


 bin/console cache:clear 

Sekarang, jika Anda mengklik tautan http://127.0.0.1:8000/admin kita akan melihat daftar dua elemen Address dan City , tempat Anda dapat melihat daftar dan membuat entitas baru.



Otorisasi dan Otentikasi


Pertama, buat entitas pengguna.


 <?php // src/Entity/User.php namespace App\Entity; use Sonata\UserBundle\Entity\BaseUser as BaseUser; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\Table(name="fos_user") */ class User extends BaseUser { /** * @ORM\Id * @ORM\Column(type="integer", options={"unsigned":true}) * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @return int */ public function getId() { return $this->id; } } 

Dan pada saat yang sama membuat esensi grup pengguna.


 <?php // src/Entity/Group.php namespace App\Entity; use Sonata\UserBundle\Entity\BaseGroup as BaseGroup; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\Table(name="fos_group") */ class Group extends BaseGroup { /** * @ORM\Id * @ORM\Column(type="integer", options={"unsigned":true}) * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @return int */ public function getId() { return $this->id; } } 

Setelah kita mengkonfigurasi Twig sebagai mesin template.


 framework: ... templating: engines: ['twig'] 

Saat ini ada masalah dengan Symfony Flex dan FOSUserBundle. Untuk detail lebih lanjut, lihat tautan # 2562 , # 2708 dan # 2801 .


Meskipun masalah ini tidak terselesaikan, Anda perlu melakukan beberapa manipulasi tambahan sebelum menginstal Sonata User Bundle .


 # config/service.yaml services: ... mailer: alias: fos_user.mailer.noop public: true 

 # config/packages/fos_user.yaml fos_user: db_driver: orm firewall_name: main user_class: App\Entity\User registration: confirmation: enabled: false from_email: address: '%env(MAILER_USER_ADDRESS)%' sender_name: '%env(MAILER_USER_NAME)%' service: user_manager: sonata.user.orm.user_manager mailer: 'fos_user.mailer.noop' group: group_class: App\Entity\Group group_manager: sonata.user.orm.group_manager 

Setelah itu, Anda dapat menginstal bundel.


 $ composer require sonata-project/user-bundle 

Pengaturan ACL


Dalam Symfony 4, ACL dipindahkan ke symfony/acl-bundle . Karena itu, harus diinstal secara terpisah.


 composer require symfony/acl-bundle 

 # config/packages/sonata_user.yaml sonata_user: security_acl: true manager_type: orm 

 # config/packages/acl.yaml acl: connection: default 

Mengkonfigurasi Doktrin


 # config/packages/doctrine.yaml doctrine: orm: mappings: SonataUserBundle: ~ FOSUserBundle: ~ 

Menyiapkan pekerjaan dengan surat


Karena pekerjaan dengan surat tidak dianggap dalam kerangka artikel ini, kami akan menunjukkan sebuah rintisan alih-alih layanan nyata.


 # config/packages/sonata_user.yaml sonata_user: mailer: fos_user.mailer.noop 

Integrasi Bundel Pengguna di Sonata Admin


 # config/routes.yaml sonata_user_admin_security: resource: '@SonataUserBundle/Resources/config/routing/admin_security.xml' prefix: /admin sonata_user_admin_resetting: resource: '@SonataUserBundle/Resources/config/routing/admin_resetting.xml' prefix: /admin/resetting 

 # config/packages/security.yaml security: encoders: FOS\UserBundle\Model\UserInterface: sha512 providers: fos_userbundle: id: fos_user.user_provider.username role_hierarchy: ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN] ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false # -> custom firewall for the admin area of the URL admin: pattern: /admin(.*) context: user form_login: provider: fos_userbundle login_path: /admin/login use_forward: false check_path: /admin/login_check failure_path: null logout: path: /admin/logout target: /admin/login anonymous: true # -> end custom configuration # default login area for standard users # This firewall is used to handle the public login area # This part is handled by the FOS User Bundle main: pattern: .* context: user form_login: provider: fos_userbundle login_path: /login use_forward: false check_path: /login_check failure_path: null logout: true anonymous: true access_control: # Admin login page needs to be accessed without credential - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/admin/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY } # Secured part of the site # This config requires being logged for the whole site and having the admin role for the admin part. # Change these rules to adapt them to your needs - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] } - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY } 

 # config/packages/sonata_user.yaml sonata_user: ... class: user: App\Entity\User group: App\Entity\Group 

Sekarang Anda dapat memperbarui ACL dan basis data.


 $ bin/console acl:init 

 $ php bin/console doctrine:schema:update --force 

Buat pengguna super. Tentukan demo nama dan demo kata sandi.


 $ bin/console fos:user:create --super-admin Please choose a username:demo Please choose an email:demo@demo.com Please choose a password: Created user demo 

Untuk mengkonfigurasi dengan benar kelas Admin kami, bersama dengan ACL, Anda perlu melakukan perubahan pada pengaturan.


 sonata_admin: ... security: handler: sonata.admin.security.handler.acl 

Setelah menjalankan yang berikut:


 $ bin/console sonata:admin:setup-acl Starting ACL AdminBundle configuration > install ACL for App\Admin\AddressAdmin - add role: ROLE_APP\ADMIN\ADDRESSADMIN_GUEST, permissions: ["LIST"] - add role: ROLE_APP\ADMIN\ADDRESSADMIN_STAFF, permissions: ["LIST","CREATE"] - add role: ROLE_APP\ADMIN\ADDRESSADMIN_EDITOR, permissions: ["OPERATOR","EXPORT"] - add role: ROLE_APP\ADMIN\ADDRESSADMIN_ADMIN, permissions: ["MASTER"] > install ACL for App\Admin\CityAdmin - add role: ROLE_APP\ADMIN\CITYADMIN_GUEST, permissions: ["LIST"] - add role: ROLE_APP\ADMIN\CITYADMIN_STAFF, permissions: ["LIST","CREATE"] - add role: ROLE_APP\ADMIN\CITYADMIN_EDITOR, permissions: ["OPERATOR","EXPORT"] - add role: ROLE_APP\ADMIN\CITYADMIN_ADMIN, permissions: ["MASTER"] > install ACL for sonata.user.admin.user - add role: ROLE_SONATA_USER_ADMIN_USER_GUEST, permissions: ["LIST"] - add role: ROLE_SONATA_USER_ADMIN_USER_STAFF, permissions: ["LIST","CREATE"] - add role: ROLE_SONATA_USER_ADMIN_USER_EDITOR, permissions: ["OPERATOR","EXPORT"] - add role: ROLE_SONATA_USER_ADMIN_USER_ADMIN, permissions: ["MASTER"] > install ACL for sonata.user.admin.group - add role: ROLE_SONATA_USER_ADMIN_GROUP_GUEST, permissions: ["LIST"] - add role: ROLE_SONATA_USER_ADMIN_GROUP_STAFF, permissions: ["LIST","CREATE"] - add role: ROLE_SONATA_USER_ADMIN_GROUP_EDITOR, permissions: ["OPERATOR","EXPORT"] - add role: ROLE_SONATA_USER_ADMIN_GROUP_ADMIN, permissions: ["MASTER"] 

Sekarang, ketika Anda mencoba masuk ke alamat http://127.0.0.1:8000/admin, kami akan dialihkan ke http://127.0.0.1:8000/admin/login .



Masukkan demo / demo dan masuk ke bagian administrasi.



Ringkasan


Setelah semua manipulasi, kami mendapat bagian administratif yang berfungsi dari Sonata Admin di Symfony 4 bersama dengan otentikasi dan otorisasi menggunakan Sonata User + ACL.


Terima kasih semuanya. Jika Anda memiliki pertanyaan dan komentar, saya akan mendengarkan mereka di komentar.

Source: https://habr.com/ru/post/id460345/


All Articles