Администратор пользователя Sonata - Зависимость пользовательских полей

Я расширил класс SonataAdmin для FOSUser и добавил 2 настраиваемых поля (тип выбора из внешнего источника данных):Company и я'Sector

хотел бы сделатьSector зависит отCompanyТаким образом, если пользователь выбирает Компанию, он фильтрует доступные Секторы.

Я хотя и об использовании FormEvents для фильтрации при загрузке страницы, но я недаже не знаю, как получитьCompany значение текущей формы.

Вот часть моего обычаяSectorType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->addEventListener(FormEvents::PRE_SET_DATA
    , function(FormEvent $event) {
        $data = $event->getData();
        $form = $event->getForm();
        // Need to get the company value here if set
    });
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'choices' => $this->getSectors(),
    ));
}

public function getSectors()
{
    $sects = array();
    // Need to pass the selected company value to my getList
    // (which gets the list of sector as you can imagine)
    if (($tmp_sects = $this->ssrs->getList('Sector'))) {
        foreach ($tmp_sects as $sect) {
            $label = $sect['id'] ? $sect['label'] : '';
            $sects[$sect['id']] = $label;
        }
    }
    return $sects;
}

Итак, вопрос:

Как получить выбранныйCompany из моего обычая?SectorType

После этого я'Вам нужно будет обновить сектор с помощью Ajax, но это будет другой вопрос

 miragedesign25 июл. 2013 г., 11:41
Посмотрите на этот вопрос, чтобы найти ответ:stackoverflow.com/questions/10118868/…!

Ответы на вопрос(1)

У меня была похожая проблема. Мне нужно было создать объект продажи, который нужно было бы связать во многих отношениях с сущностью предприятия и во многих отношениях со службами. Вот объект продажи:

Дело в том, что сервисы доступны в зависимости от выбранных компаний. Например, услуги a и b могут предоставляться только компании x. А услуги b и c могут предоставляться только компании y. Так что в моем админе в зависимости от выбранной компании мне приходилось отображать доступные сервисы. Для этого мне нужно было сделать 2 вещи:

Сначала создайте динамическую форму с моим администратором продаж, чтобы на стороне сервера я мог получить нужные услуги, доступные для компании, указанной в моем отчете о продажах. И во-вторых, мне пришлось создать собственный тип формы для элемента формы моей компании, чтобы при изменении пользователем на стороне клиента он отправлял ajax-запрос, чтобы получить нужные услуги для выбранной компании.

Что касается моей первой проблемы, я сделал нечто похожее на то, что вы пытались достичь, но вместо того, чтобы создать специальный пользовательский тип для моего элемента services, я добавил слушателя событий непосредственно в администраторе.

Вот сущность Продажа:

/**
 *
 * @ORM\Table(name="sales")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 */
class Sale
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
     public $id;
    /**
     * @ORM\ManyToOne(targetEntity="Branch")
     * @ORM\JoinColumn(name="branch_id", referencedColumnName="id", nullable = false)
     * @Assert\NotBlank(message = "Debe especificar una empresa a la cual asignar el precio de este exámen!")
     */
    private $branch;

    /** Unidirectional many to many
     * @ORM\ManyToMany(targetEntity="Service")
     * @ORM\JoinTable(name="sales_services",
     *      joinColumns={@ORM\JoinColumn(name="sale_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="service_id", referencedColumnName="id")}
     *      )
     * @Assert\Count(min = "1", minMessage = "Debe especificar al menos un servicio a realizar!")
     */
    private $services;


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

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

    /**
     * Set branch
     *
     * @param Astricom\NeurocienciasBundle\Entity\Branch $branch
     */
     //default value always have to be null, because when validation constraint is set to notblank, 
     //if default is not null, before calling the validation constraint an error will pop up explaining
     //that no instance of Branch was passed to the $branch argument.
    public function setBranch(\Astricom\NeurocienciasBundle\Entity\Branch $branch = null)
    {
        $this->branch = $branch;
    }

    /**
     * Get branch
     *
     * @return Astricom\NeurocienciasBundle\Entity\Branch 
     */
    public function getBranch()
    {
        return $this->branch;
    }

     /**
     * Add service
     *
     * @param \Astricom\NeurocienciasBundle\Entity\Service|null $service
     */
    public function addServices(\Astricom\NeurocienciasBundle\Entity\Service $service = null)
    {
        $this->services[] = $service;
    }

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


    /**
     * Sets the creation date
     *
     * @param \DateTime|null $createdAt
     */
    public function setCreatedAt(\DateTime $createdAt = null)
    {
        $this->createdAt = $createdAt;
    }

    /**
     * Returns the creation date
     *
     * @return \DateTime|null
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Sets the last update date
     *
     * @param \DateTime|null $updatedAt
     */
    public function setUpdatedAt(\DateTime $updatedAt = null)
    {    
        $this->updatedAt = $updatedAt;
    }

Итак, в конструкторе формы администратора:

protected function configureFormFields(FormMapper $formMapper)  {
    $em = $this->container->get('doctrine')->getEntityManager();
    $branchQuery = $em->createQueryBuilder();

    $branchQuery->add('select', 'b')
       ->add('from', 'Astricom\NeurocienciasBundle\Entity\Branch b')
       ->add('orderBy', 'b.name ASC');

    $formMapper
      ->with('Empresa/Sucursal')
         ->add('branch','shtumi_ajax_entity_type',array('required' => true, 'label'=>'Empresa/Sucursal','error_bubbling' => true, 'empty_value' => 'Seleccione una empresa/sucursal', 'empty_data'  => null, 'entity_alias'=>'sale_branch', 'attr'=>array('add_new'=>false), 'model_manager' => $this->getModelManager(), 'class'=>'Astricom\NeurocienciasBundle\Entity\Branch', 'query' => $branchQuery)) 
      ->end()
    ;

    $builder = $formMapper->getFormBuilder();
    $factory = $builder->getFormFactory(); 
    $sale = $this->getSubject();
    $builder->addEventListener(FormEvents::PRE_SET_DATA, 
        function(DataEvent $event) use ($sale,$factory, $em) {

            $form = $event->getForm();
            $servicesQuery = $em->createQueryBuilder();
            $servicesQuery->add('select','s')
                ->add('from','Astricom\NeurocienciasBundle\Entity\Service s');

            if (!$sale || !$sale->getId()) {
                $servicesQuery
                    ->where($servicesQuery->expr()->eq('s.id', ':id'))
                    ->setParameter('id', 0);
            }
            else {
                $servicesQuery
                    ->join('s.branch', 'b')
                    ->where($servicesQuery->expr()->eq('b.id', ':id'))
                    ->setParameter('id', $sale->getBranch()->getId());
            }

            $form->add($factory->createNamed('services','entity',null,array('required' => true, 'label'=>'Servicios','error_bubbling' => true, 'attr'=>array('show_value_label'=>true),'class'=>'Astricom\NeurocienciasBundle\Entity\Service','multiple'=>true,'expanded'=>true,'query_builder'=>$servicesQuery)));
        }
    );
}

Хитрость была в том, чтобы передать данные форм. Это неработать, чтобы использовать evet->getData () в слушателе событийс функцией. Вместо этого я прошел через администратора->метод getSubject (). Затем вместо добавления типа формы sonataadmin внутри слушателя событийЯ должен был использовать простой тип формы Symfony.

Часть Ajax, как вы упомянули, это другой вопрос. В этом отношении все странные вещи в методе добавления веток в конструкторе форм связаны с настраиваемым типом поля. Дон»не беспокойся об этом.

Ваш ответ на вопрос