2013-03-02 49 views
0

好的,下面是我想要做的事情的快速概览。我有一个与“ClientDomain”实体有关系的“客户”实体。我需要一个表单,向我显示给定客户端的所有ClientDomain列表。在控制器中,我知道我需要过滤哪些客户端,但我不确定如何将这些信息传递给formBuilder。如何让symfony 2表单从动态值返回实体

继承人是我迄今为止:

//src/NameSpace/ClientBundle/Entity/Client.php 
use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity 
*/ 
class Client{ 
/** 
* @ORM\Id 
* @ORM\Column(type="integer") 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
protected $client_id; 

/** 
* @ORM\Column(type="string") 
*/ 
protected $name; 

/** 
* @ORM\OneToMany(targetEntity="ClientDomain", mappedBy="client") 
*/ 
protected $domains; 

... 
} 

而且形式:

//src/LG/ClientBundle/Form/ClientDomainSelectionForm.php 
namespace LG\ProjectBundle\Form\Projects; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 

class ClientDomainSelectionForm extends AbstractType { 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('client_domain', 'entity', array(
      'class' => 'LG\ClientBundle\Entity\ClientDomain', 
      'query_builder'=> function(EntityRepository $er) { 
       return $er->createQueryBuilder('cd') 
       /* NEEDS TO FIND DOMAINS BY CLIENT X */ 
      }, 
      'property' => 'domain', 
      'label' => 'Domain: ' 
     )); 
    } 
} 

然后终于控制器:

//src/LG/ClientBundle/Controller/DomainSelectorController.php 
namespace LG/ClientBundle/Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; 

use LG\ClientBundle\Entity\Client; 
use LG\ClientBundle\Entity\ClientDomain; 
use LG\ClientBundle\Entity\ClientActiveDomain; 
use LG\ClientBundle\Form\ClientDomainSelectionForm; 


/** 
* @Route("") 
*/ 
class DomainSelectorController extends Controller{ 

    /** 
    * @Route("/client/{client_slug}/select-domain", name="lg.client.clientdomainselection.selectclient") 
    * @Template 
    */ 
    public function selectDomainAction(Request $request, Client $client){ 
     $activeDomain = new ClientActiveDomain(); 
     $form = $this->createForm(new ClientDomainSelectionForm(), $activeDomain); 
     if ($request->isMethod('POST')) { 
      $form->bind($request); 
      if ($form->isValid()) { 
       $em = $this->getDoctrine()->getEntityManager(); 
       $em->persist($activeDomain); 
       $em->flush(); 
       return $this->redirect(/*huge long url*/); 
      } 
     } 
     return array(
      'form' => $form->createView(), 
     ); 
    } 

} 

正如你可以看到我有机会获得控制器中的客户端实体只是不知道如何将其提供给表单构建器,以便它仅返回th域当前客户。

回答

0

我已经找到了答案,你只需要一个构造函数从控制器添加到窗体,并通过在客户端,像这样:

//src/LG/ClientBundle/Form/ClientDomainSelectionForm.php 
namespace LG\ProjectBundle\Form\Projects; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 

class ClientDomainSelectionForm extends AbstractType { 

    protected $client; 

    public function __construct(Client $client) { 
     $this->client = $client; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $client = $this->client; 
     $builder->add('client_domain', 'entity', array(
      'class' => 'LG\ClientBundle\Entity\ClientDomain', 
      'query_builder'=> function(\Doctrine\ORM\EntityRepository $er) use ($client) { 
       return $er->createQueryBuilder('cd') 
        ->where('cd.client = :client') 
        ->orderBy('cd.domain', 'ASC') 
        ->setParameter('client',$client->getClientId()); 
      }, 
      'property' => 'domain', 
      'label' => 'Domain: ' 
     )); 
    } 
} 

然后在控制器:

//src/LG/ClientBundle/Controller/DomainSelectorController.php 

... 

public function selectDomainAction(Request $request, Client $client){ 

    ... 

    $form = $this->createForm(new ClientDomainSelectionForm($client), $activeDomain); 

    ... 
} 

... 
+2

实际上,您应该创建一个必需的选项'client'而不是使用构造函数,因为构造函数在创建表单的第一个实例时仅调用一次。所以,如果你有两种不同客户的表格,他们将被绑定到第一种表格的客户端。另一方面,选项不共享。 – 2013-03-02 09:19:36

+0

客户端只需在创建时设置即可。一旦完成,实体的所有编辑都是可能的,因为教义已经知道客户端。但是我可以看到你的用例在另一个应用程序中可能发生的地方。感谢您的意见。 – Chausser 2013-03-04 19:31:51