Parliamo del progetto
PHP symfony Sonata

Symfony 4 / Sonata : Creare un'amministrazione OneToMany (1N)

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...

Symfony 4 / Sonata : Creare un'amministrazione OneToMany (1N)

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.

Sélection_086

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.

Sélection_092


Per testare la relazione tra le entitàés, possiamo passare il seguente ordine:

php bin/console doctrine:schema:validate
Sélection_091


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.

Condividi questo articolo