Question

J'ai une simple application Symfony2 avec deux entités: municipalité et POI. Il existe une relation "une à plusieurs" entre municipalité et pois (c'est-à-dire: zéro ou plus de POI placé dans une municipalité), de sorte que les fichiers entités sont comme ceci:

pooc \ pocbundle \ entité \ municipality.php

<?php

// Poc\PocBundle\Entity\Municipality.php

namespace Poc\PocBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Municipality
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\MunicipalityRepository")
 */
class Municipality
{
    /**
     * @ORM\OneToMany(targetEntity="Poi", mappedBy="municipality")
     */
    protected $pois;

    public function __construct()
    {
        $this->pois = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Municipality
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add pois
     *
     * @param \Poc\PocBundle\Entity\Poi $pois
     * @return Municipality
     */
    public function addPois(\Poc\PocBundle\Entity\Poi $pois)
    {
        $this->pois[] = $pois;

        return $this;
    }

    /**
     * Remove pois
     *
     * @param \Poc\PocBundle\Entity\Poi $pois
     */
    public function removePois(\Poc\PocBundle\Entity\Poi $pois)
    {
        $this->pois->removeElement($pois);
    }

    /**
     * Get pois
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPois()
    {
        return $this->pois;
    }

    public function __toString()
    {
        return $this->name;
    }
}

pooc \ pocbundle \ entité \ poii.php

<?php

// Poc\PocBundle\Entity\Poi.php

namespace Poc\PocBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Poi
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\PoiRepository")
 */
class Poi
{
    /**
     * @ORM\ManyToOne(targetEntity="Municipality", inversedBy="pois")
     * @ORM\JoinColumn(name="municipality_id", referencedColumnName="id")
     */
    protected $municipality;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Poi
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set municipality
     *
     * @param \Poc\PocBundle\Entity\Municipality $municipality
     * @return Poi
     */
    public function setMunicipality(\Poc\PocBundle\Entity\Municipality $municipality = null)
    {
        $this->municipality = $municipality;

        return $this;
    }

    /**
     * Get municipality
     *
     * @return \Poc\PocBundle\Entity\Municipality 
     */
    public function getMunicipality()
    {
        return $this->municipality;
    }

    public function __toString()
    {
        return $this->name;
    }
}

À ce stade, je souhaite gérer la relation unique entre la municipalité et leur POI de la municipalité Ajout / Modifier le formulaire de Sonata Admin.

J'ai suivi les instructions expliquées dans http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reeference/form_field_definition.html#advanced-Unage-one-a-many , le fichier de classe municipalityAdmin est donc:

poc / pocbundle / admin / municipalityAdmin.php

<?php
namespace Poc\PocBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class MunicipalityAdmin extends Admin
{
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('name')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'show' => array(),
                    'edit' => array(),
                )
            ))
        ;
    }
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name')
            ->add('pois', 'sonata_type_collection', array(), array(
                'edit' => 'inline',
                'inline' => 'table',
                'sortable'  => 'position'
            ))
    ;
    }
}

Le formulaire que j'essaie d'obtenir est un formulaire Ajouter / Modifier où je peux définir le nom de nom de la municipalité et ajouter / supprimer des POI associés de l'entité du POI, mais ce que j'obtiens réellement est une forme où je peux définir le nom de la municipalité et gérer l'entité du POI dans une sorte de sous-forme.

Cette capture d'écran décrit le résultat -> http://i.imgur.com/nm1ywww.png

Je veux dire, de cette manière, je peux ajouter de nouveaux POI et relations avec n'importe quelle municipalité (c'est-à-dire: Los Angeles), mais ce que j'essaie d'obtenir est une liste d'Al Pois qui sont liés à cette municipalité et à la posibilité à:

  • Ajouter de nouvelles relations (c'est-à-dire: associer un POI orphelin comme la statue de la liberté à cette municipalité (New York)).
  • Supprimer les relations existantes (c'est-à-dire: supprimer une relation incorrecte comme "Walt Disney Concert Hall" à New York)

J'ai vu le moyen de gérer cela à l'inverse, sélectionnez la municipalité liée à chaque POI dans le formulaire d'ajout / modification du POI (nombre-à-un), mais je me demande si y a-t-il un moyen de gérer cela relations dans l'autre entité.

Puis-je faire cela à Sonataadmin? Tout indice?

mise à jour: a résolu l'interface utilisateur et ajout de POI, mais ne pas supprimer

J'ai le moyen de montrer le widget que je cherche, en définissant le formulaire de cette manière:

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->add('name')
        ->add('pois', null, array(), array(
            'edit' => 'inline',
            'inline' => 'table',
            'sortable'  => 'position'
        ))
;
}

Qu'est-ce que j'ai fait, c'est changer 'Sonata_Type_Collection' pour la valeur null. Maintenant, je reçois un formulaire comme cette capture d'écran -> GUI de formulaire correct

... que comme le comportement que je veux.

Initialement, les ajouts de ce widget (c'est-à-dire ajouter de nouveaux POI à une municipalité), n'a pas persisté. Grâce au commentaire de Radomir Wojtera, j'ai réalisé qu'il y avait des méthodes non implémentées dans ma catégorie d'entité municipalité (Setpois, AddPoi et RemovePoi).

J'ai ajouté cette méthode ...

public function setPois($pois)
{
    if (count($pois) > 0) {
        foreach ($pois as $i) {
            $this->addPoi($i);
        }
    }

    return $this;
}

public function addPoi(\Poc\PocBundle\Entity\Poi $poi)
{
    $poi->setMunicipality($this);
    $this->pois->add($poi);
}

public function removePoi(\Poc\PocBundle\Entity\Poi $poi)
{
    $this->pois->removeElement($poi);
}

... et maintenant je suis capable de prendre de nouveaux pois pour une municipalité, mais quand je suppose de Pois, ils ne sont pas dissociés. Donc, je peux ajouter des relations, mais pas enlever.

Était-ce utile?

La solution

Enfin, je peux résoudre le deuxième problème (supprimer POI d'une municipalité n'a pas fonctionné) en définissant Orphanremoval= True dans la configuration de l'entité

class Municipality
{
    /**
     * @ORM\OneToMany(targetEntity="Poi", mappedBy="municipality", cascade={"persist"}, orphanRemoval=true))
     */
    protected $pois;
...

Le premier problème est résolu comme commenté dans la mise à jour de la question.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top