2011-07-16 13 views
35

Estoy usando la lista de opciones de entidades en mi formulario. Quiero usar solo entidades específicas (en ejemplo: solo los grupos a los que pertenece el usuario) Por lo tanto, en el controlador, obtengo estos grupos y trato de pasarlos al formBuider.Symfony 2: cómo pasar datos a formBuilder?

controlador:

/.../ 
$groups = $em->getRepository('VendorMyBundle:Group')->getUserGroups($user); 
$form = $this->createForm(new Message($groups), $message); 
/.../ 

es así, ¿ahora qué? cómo usarlo en formBuilder? cómo cambiar esta línea para usar el conjunto pasado de grupos?

->add('group','entity',array('class' => 'Vendor\MyBundle\Entity\Group', 'label'=>'Group:')) 

o de la otra manera:

class MessageType 
{ 
/.../ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
    $builder 
     ->add('group','entity', 
     array(
      'class' => 'Vendor\MyBundle\Entity\Group', 
      'property' => 'name', 
      'query_builder' => function ($repository) { 
      $qb = $repository->createQueryBuilder('group'); 
      $qb->add('where', 'group.administrator = :user'); 
      $qb->setParameter('user', $user->getId()); 
      return $qb; 
      }, 
      'label' => 'Group' 
     ) 
    ) 
     // Continue adding fields 
    ; 
    } 
/.../ 
} 

así que ¿cómo puedo obtener el objeto $ usuario utilizar en forma constructor? ($ Usuario representan actual usuario registrado)

+2

hice la misma pregunta: - http: // stackoverflow.com/questions/7807388/passing-data-from-controller-to-type-symfony2 ¡la solución de Bacteries es realmente buena! : thumbsup: – xeon

+0

Si necesita ejecutar consultas, hacer llamadas de API, etc. para representar una vista, entonces lo está haciendo mal. Si se trata de una restricción que Symfony coloca en el marco (no hay otra forma de suministrar datos arbitrarios al generador de formularios), avergüéncelos. Este es el trabajo claramente definido del controlador. – eggmatters

Respuesta

2

Si desea utilizar consulta personalizada, usted tiene que fijar query_builder opción como sigue:

use Doctrine\ORM\EntityRepository; 

... 

$message = new Message(); 

$form = $this->createFormBuilder($message) 
      ->add('group', 'entity', array(
        'class' => 'Vendor\MyBundle\Entity\Group', 
        'label'=>'Group:', 
        'query_builder' => function(EntityRepository $er) { 
         return $er->createQueryBuilder('g') 
           ->... // whatever you want to do 
         } 
        )) 
      ->getForm(); 

usted puede encontrar más información sobre generador de consultas en Doctrine manual y sobre las opciones para entity en Symfony2 manual.

+0

Sí, sé cómo usar una consulta personalizada, pero ¿cómo puedo usarla cuando quiero obtener grupos de usuarios registrados actualmente? debo declarar un contenedor en una clase de tipo de formulario? ej: en el controlador estoy usando '$ this-> get ('security.context') -> getToken() -> getUser()' – jacobmaster

+1

Yo recomendaría usar ManyToOne o ManyToMany relación aquí. Haría las cosas mucho más fáciles. –

+0

hago mi pregunta más específica. tal vez ahora me puedas ayudar ... – jacobmaster

28

Puede dar el objeto que desea utilizar en el método __construct().

Ej:

$form = $this 
    ->get('form.factory') 
    ->create(new ApplyStepOneFormType($this->company, $this->ad), $applicant); 

En el tipo de formulario:

function __construct(\Your\Bundle\Entity\Company $company, \DYB\ConnectBundle\Entity\Ad $ad) { 
    $this->company = $company; 
    $this->ad = $ad; 
} 

Y luego, en el tipo de forma en el método buildForm: solución

$company = $this->company;  
$builder->add('ad', 'entity', array(
    'class' => '\Your\Bundle\Entity\Ad', 
    'query_builder' => function(\Your\Bundle\Repository\AdRepository $er) use ($company) { 
     return $er->getActiveAdsQueryBuilder($company); 
    }, 
)); 
2

Bacterias es uno muy bueno . Solo una nota para ahorrar dolor de cabeza a otro tipo como yo :)

En esta parte puedo señalar la parte use ($company). Estaba oculto por el marco y, por supuesto, nada funciona correctamente sin él.

$builder->add('ad', 'entity', array(
    'class' => 
     '\Your\Bundle\Entity\Ad', 
    'query_builder' => 
     function(\Your\Bundle\Repository\AdRepository $er) use ($company) { 
      return $er->getActiveAdsQueryBuilder($company); 
     }, 
    ) 
); 
0

La mejor manera (mi opinión) es dar a su formulario entityManager y seleccione todo lo que necesita en él. Pero no olvide declarar la clave vacía en setDefaults(), de lo contrario los datos no pasarán a su constructor.

Algo como éste

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $options['em']->getRepository(''); // select all you need 
    $builder->add('title', 'text') 
      ->add('content', 'textarea'); 
} 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'Main\BlogBundle\Entity\Post', 
     'validation_groups' => array('post'), 
     'required' => false, 
     'em' => null // this var is for your entityManager 
     )); 
} 

Aplicar EM opción tan simple ... solución

+0

Sin embargo, ¿esto no acaba con el propósito de una aplicación MVC? Pensé que el objetivo de un marco era ocultar la capa de datos de la capa de renderizado. Me gusta, en la medida de lo posible. – eggmatters

+0

Symfony2 rompe todos los patrones que conoces ... Así que no te sorprendas. Mostré la solución que funcionó para mí, sf2 es un mvc malo para desarrollar si quieres trabajar con patrones. Si tiene más elegante, use el suyo ... – user1954544

11
//In controller pass the value which you want to use in builder form in array like 

$object = new Question(); 
$form->create(new QuestionType() , $object , array('sqtname'=>2,'question_type'=>2)); 


//In Form type class 
public function buildForm(FormBuilderInterface $builder , array $options) 
    { 
    //for setting data field dynamically 
    if (array_key_exists('question_type', $options) && $options['question_type'] != '') { 
    $data = $em->getReference("RecrutOnlineStandardBundle:StdQuestionType",$options['question_type']->getId()); 
    } else { 
    $data = ""; 
    } 


    $builder->add('StdQuestionType', 'entity', array(
     'class' => 'TestStandardBundle:StdQuestionType', 
     'property' => 'name', 
     'empty_value' => 'Sélectionner un question type', 
     'required' => true, 
     'data' => $data, 
     'query_builder' => function(EntityRepository $er) use ($options) { 
      if (isset($options['sqtname']) && $options['sqtname'] != '') { 
       return $er->createQueryBuilder('sqt') 
           ->where("sqt.name!= ".$options['sqtname']); 
      } else{ 
       return $er->createQueryBuilder('sqt'); 
      } 
     } 
    )); 
} 

public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
     'data_class' => 'Test\QuestionBundle\Entity\Question', 
     'required' => false, 
     'sqtname' => '', 
     'question_type' =>'' 
     )); 
    } 
3

Bacterias no es una buena idea. Por ejemplo, si declara su tipo como servicio, es imposible pasar un objeto al constructor.

Una solución perfecta son las opciones: simplemente pase los datos como opción al generador de formularios.

+0

Además, su solución va a romperse en 3.0 ya que los tipos están construidos por FQCN – Ryall