Noi andiamo a créer una una interfaccia di’amministrazione 1N, con due entitàés. La première One, e la seconda Many, e fare un pannello di’admin per la tabella One, che potrà essere assegnato a diversiéléments della tabella Many. Per rendere la cosa più piccante, ci s’aggiungi alcuni paramètre aggiuntivi, come campi timestamp per una data di sincronizzazione con un SI, e campi primari che non s’non chiamano ID e che non sono auto incrementémenteés.
Nel nostro caso, abbiamo una sincronizzazione con un SI che nonérichiede un campo timestamp.
Basta solo di créper un campo di tipo datetime
Aggiungere l’opzioni di annotazione={« predefinito »: « TIMESTAMP_ATTUALE »}
L’annotazione seguente créera un campo Timepstamps con di default CURRENT_TIMESTAMP.
* @ORM\Column(type="datetime", nullable=false, options={"default": "CURRENT_TIMESTAMP"})
* @ORM\Version
Per nominare correttamente la tabella e créper gli indici, basta aggiungere il’annotazione seguente in entêtè di classe
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Index;
/**
* @ORM\Entity(repositoryClass="App\Repository\WcoconRepository")
* @Table(name="table_name",indexes={@Index(name="PRIMARY", columns={"champs1", "champs2"})})
*/
Per usare un altro campo che « ID »messo daébisogna, bisogna solo aggiungere l’annotazione seguente :
/**
* @ORM\Column(type="integer")
* @ORM\Id()
*/
private $numero_dossier;
Una volta stabilita la relazione, bisogna préciser l’id che sarà usatoénella mappatura. altrimenti avremo un errore del tipo:
Nome della colonnaidil riferimento per la relazione da App\Entity\Many verso App\Entity\One non esiste.
Quindi in l’entitàé ‘molte’, bisogna aggiungere la relazione con l’id de l’entitàé ‘Una’
/**
* @ORM\ManyToOne(targetEntity="App\Entity\One", inversedBy="Ones")
* @ORM\JoinColumn(nullable=false, name="many_id", referencedColumnName="one_id")
*/
private $many_id;
Ultimo punto che ha la sua importanza; Perévite che l’l'oggetto abbia un nome del tipo« App\Entity\One:sdfsdfgsdgmlkpoufsdlkjfsdg »durante il’édizione, è préfépossibile di sovraccaricare la mémetodo __toString(), per visualizzare il nome di l’oggetto.
Nel’entità basta di’includere una méthode :
public function __toString()
{
return "Nom object ".$this->getName();
}
Una volta fatto, basta effettuare la migrazione:
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Se necessario per régénécreare il repositoryàpartire dalle entitàéper disponibili basta eseguire questo comando :
php bin/console make:entity --regenerate
Le entitàénon saranno modificatiés.
Per testare la relazione tra le entitàés, possiamo passare il seguente ordine:
php bin/console doctrine:schema:validate
A questo punto, non ci resta che’da mettere in atto le interfacce di gestione in l’amministratore e potremo cominciareà développer l’autenticazione front-end.
Premièreébatti l’interfaccia d’admin è di créper la classe in src/Admin/TableAdmin.php
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
use Sonata\AdminBundle\Form\Type\ModelType;
use Sonata\AdminBundle\Form\Type\ModelListType;
use Sonata\Form\Type\CollectionType;
class OneAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->tab('General');
$formMapper->with('Parametres', ['class' => 'col-md-4']);
$formMapper->add('name', TextType::class, ['required' => false, 'label'=>'Site internet','attr' => ['placeholder' => '']]);
$formMapper->end()
$formMapper->with('Parametres', ['class' => 'col-md-8']);
$formMapper->add('nomduchampsArrayCollection', EntityType::class, [
'class' => 'App\Entity\Many',
'choice_label' => 'nom_du_champs_autre_table',
'label' => 'champs liste',
'multiple' => true,
//'expanded' => true,
]);
$formMapper->end()
$formMapper->end('General');
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper->add('name');
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper->addIdentifier('name', null, ['label' => 'Nom']);
}
public function prePersist($object)
{
$this->preUpdate($object);
}
public function preUpdate($object)
{
$mapping=$object->getManys()->getMapping();
$currentManys=$this->createQuery()->getQueryBuilder()->getQuery()->getEntityManager()->getRepository($mapping["targetEntity"])
->findBy([$mapping["mappedBy"]=>$this->id($object)]);
$object->setMany($object->getManys(),$currentManys);
}
public function setMany($collections,$currentManys)
{
foreach ($currentCollections as $w)
{
if(!$collections->contains($w)){
$w->setCollectionID(null);
}
}
$this->collections= new ArrayCollection();
foreach ($collections as $collection) {
$this->addCollections($collections);
}
}
}
Nel’entity One.php bisogna aggiungere la nostra nuova méthode pour géripristinare le modifiche
public function setMany($manys,$current)
{
foreach ($current as $w) {
if(!$manys->contains($w)){
$w->setManyField(null);
}
}
$this->manys = new ArrayCollection();
foreach ($manys as $m) {
$this->addMany($m);
}
}
Occorre poi registrare il servizio in config/services.yaml
admin.MaTable:
class: App\Admin\MaTableAdmin
arguments: [~, App\Entity\MaTable, ~]
tags:
- { name: sonata.admin, manager_type: orm, label: "Table MaTable" }
public: true
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.