Intereting Posts
Если isset для нескольких кнопок отправки Как я могу упростить вложенный php-массив? Каков наилучший способ вывода всех данных из таблицы на страницу без сбоя страницы? Запрос работает в phpmyadmin, но не в скрипте PHP CakePHP – проблема с запросом paginate HABTM Автоматический выход из системы, когда пользователь покидает приложение, не выполняя действия выхода из системы Загрузка двоичных данных с C # на PHP Как получить доступ к объекту, когда имя свойства содержит – (дефис) Facebook Pagetab App – пользователи очень понравились Doctrine2 – множественная вставка одним выстрелом Неизвестный модификатор '(' при использовании preg_match () с выражением REGEX Получение заголовков и метатег с внешнего сайта mkdir (): разрешение отклонено GET переменные с пробелами – они работают, но это правильно или нормально? Переключатель Master / Slave в прикладном уровне Zend Framework

От одного до многих отношений и добавление / изменение формы в SonataAdmin и Symfony2

У меня есть простая программа Symfony2 с двумя объектами: муниципалитет и Poi. Существует отношение «Один-ко-многим» между муниципалитетом и Pois (то есть: ноль или больше pois, размещенных в одном муниципалитете), поэтому файлы Entity выглядят следующим образом:

Poc \ PocBundle \ Entity \ 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; } } 

Poc \ PocBundle \ Entity \ Poi.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; } } 

На данный момент я хочу управлять отношением «один-ко-многим» между муниципалитетом и их поасами из формы добавления / изменения муниципалитета в Sonata Admin.

Я выполнил инструкции, описанные в http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html#advanced-usage-one-to-many , поэтому файл класса MunicipalityAdmin является:

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' )) ; } } 

Форма, которую я пытаюсь получить, – это форма добавления / редактирования, в которой я могу определить название муниципалитета и добавить / удалить связанные pois из объекта Poi, но то, что я действительно получаю, является формой, где я могу определить название муниципалитета , и управлять объектом Poi в виде подформы.

Этот скриншот описывает результат -> http://i.imgur.com/nM1ywwh.png

Я имею в виду, таким образом, я могу добавить новые Pois и отношения с любым муниципалитетом (то есть: Лос-Анджелес), но то, что я пытаюсь получить, – это список al pois, относящихся к этому муниципалитету, и возможность:

  • Добавить новые отношения (т. Е. Связать сироту Пой, например Статую Свободы, с этим муниципалитетом (Нью-Йорк)).
  • Удалите существующие отношения (т. Е. Устраните неверную связь, например «Концертный зал Уолта Диснея» в Нью-Йорке)

Я видел способ справиться с этим в обратном порядке, выбрав муниципалитет, связанный с каждым Poi в форме добавления / изменения Poi (много-к-одному), но мне интересно, есть ли способ управлять этими отношениями в другое лицо.

Могу ли я сделать это в SonataAdmin? Любая подсказка?

ОБНОВЛЕНИЕ: разрешил пользовательский интерфейс и добавил pois, но не удалил

У меня есть способ показать виджет, который я ищу, определив форму следующим образом:

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

Я сделал, чтобы изменить «sonata_type_collection» для нулевого значения. Теперь я получаю форму, похожую на этот снимок экрана -> Правильный графический интерфейс формы

… это как раз поведение, которое я хочу.

Первоначально дополнения в этом виджете (то есть: добавление новых маршрутов в муниципалитет) не сохранялись. Благодаря комментарию Radomir Wojtera, я понял, что в моем классе муниципалитета есть методы, которые не были реализованы (setPois, addPoi и removePoi).

Я добавил эти методы …

 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); } 

… и теперь я могу захватить новые Pois для муниципалитета, но когда я удаляю некоторые Pois, они не отделяются. поэтому я могу добавлять отношения, но не удалять.

Наконец, я могу решить вторую проблему (удаление Poi из муниципалитета не сработало), установив orphanRemoval = true в настройке Entity

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

Первая проблема решается, как указано в обновлении вопроса.