Parliamo del progetto
PHP symfony Sonata

Symfony 4 / Sonata : Creare un'interfaccia annidata (nested interface)

Vedremo come si costruisce un'interfaccia di’amministratore, composée di diverse tabelle che hanno relazioni Many2Many.Riprendiamo il nostro esempio di’interfaccia disponibile molti/molti qui Abbiamo un tavolo zona, che è compost...

Symfony 4 / Sonata : Creare un'interfaccia annidata (nested interface)

Vedremo come si costruisce un'interfaccia di’amministratore, composée di diverse tabelle che hanno relazioni Many2Many.

Riprendiamo il nostro esempio di’interfaccia disponibile molti/molti qui
Abbiamo un tavolo zona, che è compostoé di diversi élémenti del tavolo diéappartamenti. Su questi déappartamenti, abbiamo delle agenzie.
Per coronare il tutto, e per dare un senso à questa chaînato da donneésì, aggiungiamo una tabella zx_credential, che riprendeésente dei commerciali.
Ecco la nostra chaînato da donneée: Commerciali->Zone>Déappartamenti->Agenzie.

data model workbench

Per il nostro progetto, abbiamo modélisé l’insieme del database tramite MySQL Workbench, ed esportazioneé le schéma in MySql.

Non ci resta più che’à esportare le entity (con getter e setter), e créper i CRUD Sonata

php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity
php bin/console make:entity --regenerate App
php bin/console make:sonata:admin App/Entity/ZxZone
php bin/console make:sonata:admin App/Entity/ZxCredential
php bin/console make:sonata:admin App/Entity/Agences
php bin/console make:sonata:admin App/Entity/Departement
php bin/console cache:clear

Per la forma, rinominiamo la nostra tabella « zx_credential » in « Accècommerciali ».
Nel file service.yaml basta modificare l’argomento « etichetta ».

    admin.zx_credential:
        class: App\Admin\ZxCredentialAdmin
        arguments: [~, App\Entity\ZxCredential, App\Controller\ZxCredentialAdminController]
        tags:
            - { name: sonata.admin, manager_type: orm, group: admin, label: "Accès commerciaux" }
        public: true
Sélection_131

Fino’qui, niente di più classico. Ma quello che l’si desidera c’è avere un'interfaccia con tutta la chaînato da donneée liée tra di loro, in modo che quando il’acceso édite a un commerciale, abbiamo la possibilitàé d’andare direttamente nella configurazione della sua zona, poi i suoi déappartamenti, poi le sue agenzie.
Per questo, noi andiamo spéidentificare le connessioni tra le tabelle tramite una chiamata à la méthode « aggiungiFiglio » nel servizio del nostro CRUD. E noi andremo spécifié i bambini di ogni tavolo.
Perché il processo possa funzionare dobbiamo spéspecificare il servizio per bambini, così come il campo del genitore utilizzatoé per fare il legame.

Nella nostra connessione ZxCredential->ZxZone, abbiamo il seguente campo nella nostra entità figlio (ZxZone) :

Sélection_133

C’è quindi quello che è utilizzatoé per fare il collegamento, e che useremo nella nostra configurazione.

    admin.zx_credential:
        class: App\Admin\ZxCredentialAdmin
        arguments: [~, App\Entity\ZxCredential, App\Controller\ZxCredentialAdminController]
        calls:
            - [addChild, ["@admin.zx_zone", 'zxCredential']] 
        tags:
            - { name: sonata.admin, manager_type: orm, group: admin, label: "Accès commerciaux" }
        public: true

La configurazione complèci dà questo:

   admin.departement:
        class: App\Admin\DepartementAdmin
        arguments: [~, App\Entity\Departement, ~]
        calls:
            - [addChild, ["@admin.agences","departement"]] 
        tags:
            - { name: sonata.admin, manager_type: orm, group: admin, label: Departement }
        public: true
        
    admin.zx_zone:
        class: App\Admin\ZxZoneAdmin
        arguments: [~, App\Entity\ZxZone, App\Controller\ZxZoneAdminController]
        calls:
            - [addChild, ["@admin.departement", "zxZone"]] 
        tags:
            - { name: sonata.admin, manager_type: orm, group: admin, label: Zones }
        public: true

    admin.zx_credential:
        class: App\Admin\ZxCredentialAdmin
        arguments: [~, App\Entity\ZxCredential, App\Controller\ZxCredentialAdminController]
        calls:
            - [addChild, ["@admin.zx_zone", 'zxCredential']] 
        tags:
            - { name: sonata.admin, manager_type: orm, group: admin, label: "Accès commerciaux" }
        public: true

    admin.agences:
        class: App\Admin\AgencesAdmin
        arguments: [~, App\Entity\Agences, ~]
        tags:
            - { name: sonata.admin, manager_type: orm, group: admin, label: Agences }
        public: true

A questo punto, tutti i nostri tavoli sono collegatiésì, ma sarà necessario configurare il menu per navigare tra di esse.
Per questo, aggiungeremo la méthode configureSideMenu nel nostro admin dei commerciali « ZxCredentialAdmin ».
Attenzione, c’è nel punto di’entraé di l’interfaccia che’bisogna configurare il menu. Quindi tutta la chaîCommerciali>Zone>Déappartamenti->Agenzie andranno a farsi negli Commerciali.

1ª énastro, aggiungiamo gli use in tutte le nostre interfacce d’admin, come ça c’è chiusoé.

<?php

declare(strict_types=1);

namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;

/*gestion de nos interfaces imbriquées*/
use Knp\Menu\ItemInterface as MenuItemInterface;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Route\RouteCollection;

Poi aggiungiamo il nostro primo collegamento alla gestione delle zone, dalla’interfaccia Zx_Credential.

   protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null): void
    {
        if (!$childAdmin && !\in_array($action, ['edit'], true)) {
            return;
        }
         
        $admin = $this->isChild() ? $this->getParent() : $this;
        $id = $admin->getRequest()->get('id');
        $label=$this->hasSubject() && null !== $this->getSubject()->getLabel() ? $this->getSubject()->getLabel():null;
        

    
        $menu->addChild(
            'Configuration de l\'accès commercial : '.$label,
            $admin->generateMenuUrl('edit', ['id' => $id])
             
            );
    
        $child=$menu->addChild( 'Listes des zones',
            [
                'uri' => $admin->generateUrl('admin.zx_zone.list', ['id' => $id])
            ]);
        
        
        
    }
    

In breve, quello che’bisogna ricordare, e che non’non è chiaro nella documentazione, c’è la strada à configurare. Ci serve il nome della rotta, poi l’id.
Per l’id, c’è semplice, per un primo livello, c’è sempre :

$id = $admin->getRequest()->get('id');

E per il viaggio, c’è sempre la mêmi ha scelto, c’è il nome del servizio seguito dal tipo di vista. Quindi qui admin.zx_zone.elenco
Che ci dà :

$child=$menu->addChild( 'Listes des zones',
            [
                'uri' => $admin->generateUrl('admin.zx_zone.list', ['id' => $id])
            ]);
commercial_zone-1

A questo punto, abbiamo il nostro première interfaccia incastratoée. Per le seguenti, noi andremo répéper la configurazione.
Quanto segue non’non spiegatoé nella documentazione, perché c’est d’una logica implacabile. Ma potrete cercare a lungo se non’non avete capito il funzionamento di’incastro delle interfacce.
Ciò che’bisogna ben capire c’è che tutto si fa à partire dalla i primière interfaccia. L’inclusione dei pulsanti del menu e la costruzione delle rotte.
La prima, poi la première+la seconda, poi la prima+la seconda+la terzaèio.

L’l'interfaccia deve costruirsi sempre nel nostro primoère interfaccia, per ogni énastri. Per questo abbiamo bisogno di rétazzaérer l’ID à ogni ébattute, e costruire la strada.
E per rétazzaérer les clés, la cosa c’è di scrutare le strade che sono généréè per symfony, tramite il comando debug:router

php bin/console debug:router
---------------------------------------------------------- ---------- -------- ------ ------------------------------------------------------------------------------------------------------------- 
  Name                                                       Method     Scheme   Host   Path                                                                                                         
 ---------------------------------------------------------- ---------- -------- ------ ------------------------------------------------------------------------------------------------------------- 
  _preview_error                                             ANY        ANY      ANY    /_error/{code}.{_format}                                                                                     
  _wdt                                                       ANY        ANY      ANY    /_wdt/{token}                                                                                                
  _profiler_home                                             ANY        ANY      ANY    /_profiler/                                                                                                  
  _profiler_search                                           ANY        ANY      ANY    /_profiler/search                                                                                            
  _profiler_search_bar                                       ANY        ANY      ANY    /_profiler/search_bar                                                                                        
  _profiler_phpinfo                                          ANY        ANY      ANY    /_profiler/phpinfo                                                                                           
  _profiler_search_results                                   ANY        ANY      ANY    /_profiler/{token}/search/results                                                                            
  _profiler_open_file                                        ANY        ANY      ANY    /_profiler/open                                                                                              
  _profiler                                                  ANY        ANY      ANY    /_profiler/{token}                                                                                           
  _profiler_router                                           ANY        ANY      ANY    /_profiler/{token}/router                                                                                    
  _profiler_exception                                        ANY        ANY      ANY    /_profiler/{token}/exception                                                                                 
  _profiler_exception_css                                    ANY        ANY      ANY    /_profiler/{token}/exception.css   
  admin_app_departement_list                                 ANY        ANY      ANY    /admin/app/departement/list                                                                                  
  admin_app_departement_create                               ANY        ANY      ANY    /admin/app/departement/create                                                                                
  admin_app_departement_batch                                ANY        ANY      ANY    /admin/app/departement/batch                                                                                 
  admin_app_departement_edit                                 ANY        ANY      ANY    /admin/app/departement/{id}/edit                                                                             
  admin_app_departement_delete                               ANY        ANY      ANY    /admin/app/departement/{id}/delete                                                                           
  admin_app_departement_show                                 ANY        ANY      ANY    /admin/app/departement/{id}/show                                                                             
  admin_app_departement_export                               ANY        ANY      ANY    /admin/app/departement/export                                                                                
  admin_app_departement_agences_list                         ANY        ANY      ANY    /admin/app/departement/{id}/agences/list                                                                     
  admin_app_departement_agences_create                       ANY        ANY      ANY    /admin/app/departement/{id}/agences/create                                                                   
  admin_app_departement_agences_batch                        ANY        ANY      ANY    /admin/app/departement/{id}/agences/batch                                                                    
  admin_app_departement_agences_edit                         ANY        ANY      ANY    /admin/app/departement/{id}/agences/{childId}/edit                                                           
  admin_app_departement_agences_delete                       ANY        ANY      ANY    /admin/app/departement/{id}/agences/{childId}/delete                                                         
  admin_app_departement_agences_show                         ANY        ANY      ANY    /admin/app/departement/{id}/agences/{childId}/show                                                           
  admin_app_departement_agences_export                       ANY        ANY      ANY    /admin/app/departement/{id}/agences/export                                                                   
  admin_app_zxcredential_list                                ANY        ANY      ANY    /admin/app/zxcredential/list                                                                                 
  admin_app_zxcredential_create                              ANY        ANY      ANY    /admin/app/zxcredential/create                                                                               
  admin_app_zxcredential_batch                               ANY        ANY      ANY    /admin/app/zxcredential/batch                                                                                
  admin_app_zxcredential_edit                                ANY        ANY      ANY    /admin/app/zxcredential/{id}/edit                                                                            
  admin_app_zxcredential_delete                              ANY        ANY      ANY    /admin/app/zxcredential/{id}/delete                                                                          
  admin_app_zxcredential_show                                ANY        ANY      ANY    /admin/app/zxcredential/{id}/show                                                                            
  admin_app_zxcredential_export                              ANY        ANY      ANY    /admin/app/zxcredential/export                                                                               
  admin_app_zxcredential_zxzone_list                         ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/list                                                                     
  admin_app_zxcredential_zxzone_create                       ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/create                                                                   
  admin_app_zxcredential_zxzone_batch                        ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/batch                                                                    
  admin_app_zxcredential_zxzone_edit                         ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/edit                                                           
  admin_app_zxcredential_zxzone_delete                       ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/delete                                                         
  admin_app_zxcredential_zxzone_show                         ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/show                                                           
  admin_app_zxcredential_zxzone_export                       ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/export                                                                   
  admin_app_zxcredential_zxzone_departement_list             ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/list                                               
  admin_app_zxcredential_zxzone_departement_create           ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/create                                             
  admin_app_zxcredential_zxzone_departement_batch            ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/batch                                              
  admin_app_zxcredential_zxzone_departement_edit             ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/edit                                
  admin_app_zxcredential_zxzone_departement_delete           ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/delete                              
  admin_app_zxcredential_zxzone_departement_show             ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/show                                
  admin_app_zxcredential_zxzone_departement_export           ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/export                                             
  admin_app_zxcredential_zxzone_departement_agences_list     ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/agences/list                        
  admin_app_zxcredential_zxzone_departement_agences_create   ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/agences/create                      
  admin_app_zxcredential_zxzone_departement_agences_batch    ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/agences/batch                       
  admin_app_zxcredential_zxzone_departement_agences_edit     ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/agences/{childChildChildId}/edit    
  admin_app_zxcredential_zxzone_departement_agences_delete   ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/agences/{childChildChildId}/delete  
  admin_app_zxcredential_zxzone_departement_agences_show     ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/agences/{childChildChildId}/show    
  admin_app_zxcredential_zxzone_departement_agences_export   ANY        ANY      ANY    /admin/app/zxcredential/{id}/zxzone/{childId}/departement/{childChildId}/agences/export                      
  admin_app_agences_list                                     ANY        ANY      ANY    /admin/app/agences/list                                                                                      
  admin_app_agences_create                                   ANY        ANY      ANY    /admin/app/agences/create                                                                                    
  admin_app_agences_batch                                    ANY        ANY      ANY    /admin/app/agences/batch                                                                                     
  admin_app_agences_edit                                     ANY        ANY      ANY    /admin/app/agences/{id}/edit                                                                                 
  admin_app_agences_delete                                   ANY        ANY      ANY    /admin/app/agences/{id}/delete                                                                               
  admin_app_agences_show                                     ANY        ANY      ANY    /admin/app/agences/{id}/show    

E la nostra attenzione particolare si concentrerà sul nostro percorso admin_app_zxcredential_zxzone_departement_agences_list che comprende tutta la nostra catena di datiée.
Lei è composée delle nostre tabelle con il nome degli id che noi andremo a rétazzaéré per costruire le strade delle nostre interfacce.
/admin/app/zxcredential/{id}/zxzone/{childId}/dipartimento/{childChildId}/agenzie/elenco
zxcredential : id
zxzone : idBambino
dipartimento : childChildId

Quindi testando la présenso di queste variabili nei nostri URL in ingresso, potremoéfinire la profondità della nostra interfaccia e costruire i menu in conséuenze.

Per le strade c’è semplice, per ciascuno étappetini, si aggiunge la strada corrente séparé con una pipa | :
zxcredential : admin.zx_zone.list
zxzone : admin.zx_zone|admin.dipartimento.elenco
dipartimento: admin.zx_zone|admin.dipartimento|admin.agenzie.elenco

Ciò che ci dai :

   protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null): void
    {
        if (!$childAdmin && !\in_array($action, ['edit'], true)) {
            return;
        }
         
        $admin = $this->isChild() ? $this->getParent() : $this;
        $id = $admin->getRequest()->get('id');
        $label=$this->hasSubject() && null !== $this->getSubject()->getLabel() ? $this->getSubject()->getLabel():null;
        

    
        $menu->addChild(
            'Configuration de l\'accès commercial : '.$label,
            $admin->generateMenuUrl('edit', ['id' => $id])
             
            );
    
        $child=$menu->addChild( 'Listes des zones',
            [
                'uri' => $admin->generateUrl('admin.zx_zone.list', [
                    'id' => $id
                    
                ])
            ]);
        
        if(!empty($admin->getRequest()->get('childId'))){
            $child=$menu->addChild( 'Listes des departements',
                [
                    'uri' => $admin->generateUrl('admin.zx_zone|admin.departement.list', [
                        'id' => $id, 
                        'childId' => $admin->getRequest()->get('childId')
                        
                    ])
                ]);
        }
        if(!empty($admin->getRequest()->get('childChildId'))){
            $child=$menu->addChild( 'Listes des agences',
                [
                    'uri' => $admin->generateUrl('admin.zx_zone|admin.departement|admin.agences.list', [
                        'id' => $id, 
                        'childId' => $admin->getRequest()->get('childId'),
                        'childChildId' => $admin->getRequest()->get('childChildId')
                    ])
                ]);
        }

    }

La nostra interfaccia è ora completaètu :

commercial_to_agence

Adattare l’esempio alla versione installata

Gli esempi Symfony e Sonata rimangono legati alle versioni indicate nell’articolo. Symfony 4.x e Symfony 6.2 non sono più supportati: per un progetto attuale, utilizzate un ramo mantenuto e la documentazione corrispondente esattamente alle vostre dipendenze.

php bin/console about
composer show symfony/framework-bundle sonata-project/admin-bundle

Prima di riprendere il codice, controllate le firme, i servizi, le rotte e i template interessati. Aggiungete poi un test funzionale che copra le autorizzazioni, il codice HTTP e il risultato visibile.

Riferimento : versioni di Symfony supportate.

Condividi questo articolo