问题描述
我需要一些帮助覆盖FormFactory. 我的目标是更改个人资料.因此,由于我也使用Facebook登录,因此我不希望他们更改电子邮件,用户名和密码. 因此,我在捆绑包中使用ProfileController将当前用户移交给ProfileFormType类.
我要做的是实现自己的formFactory,因此我可以设置用户并将其放入呼叫中的选项数组
中return $this->formFactory->createNamed($this->name, $this->type, null, array('validation_groups' => $this->validationGroups, 'user' => $this->user));
要实现这一目标,我需要在sevices.yml中定义我的formFactory.
这是FosuserBundle的原始一个:
<service id="fos_user.profile.form.factory" class="FOS\UserBundle\Form\Factory\FormFactory"> <argument type="service" id="form.factory" /> <argument>%fos_user.profile.form.name%</argument> <argument>%fos_user.profile.form.type%</argument> <argument>%fos_user.profile.form.validation_groups%</argument> </service>
我很难将其转化为YML,因为我不完全理解别名的用法.
您能帮我正确定义它吗?像
skt_user.profile.form.factory: class: SKT\UserBundle\Form\Factory\FormFactory arguments: ???
推荐答案
有趣的是,在发布后,我找到了解决方案.这是我的FormFactory的正确配置:
skt_user.profile.form.factory: class: SKT\UserBundle\Form\Factory\FormFactory arguments: ["@form.factory", "%fos_user.profile.form.name%", "%fos_user.profile.form.type%", "%fos_user.profile.form.validation_groups%"]
在我的控制器中,我只是使用了这两行:
$formFactory = $this->container->get('skt_user.profile.form.factory'); $formFactory->setUser($user);
在工厂中,我实现了此功能
namespace SKT\UserBundle\Form\Factory; use Symfony\Component\Form\FormFactoryInterface; use FOS\UserBundle\Form\Factory\FactoryInterface; class FormFactory implements FactoryInterface { private $formFactory; private $name; private $type; private $validationGroups; private $user; public function __construct(FormFactoryInterface $formFactory, $name, $type, array $validationGroups = null) { $this->formFactory = $formFactory; $this->name = $name; $this->type = $type; $this->validationGroups = $validationGroups; } public function createForm() { return $this->formFactory->createNamed($this->name, $this->type, null, array('validation_groups' => $this->validationGroups, 'user' => $this->user)); } public function setUser($user) { $this->user = $user; } }
这就是我的formType看起来
<?php namespace SKT\UserBundle\Form\Type; use SKT\CaromBundle\Repository\PlayerRepository; use Symfony\Component\Form\FormBuilderInterface; use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class ProfileFormType extends \FOS\UserBundle\Form\Type\ProfileFormType { private $class; /** * @param string $class The User class name */ public function __construct($class) { $this->class= $class; } public function buildForm(FormBuilderInterface $builder, array $options) { // Do not show email and username if login uses facebook if (!$options['user']->getFacebookId()) { $builder ->add('email', 'email', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle')) ->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle')); } $builder ->add('firstname', null, array('label' => 'Vorname')) ->add('lastname', null, array('label' => 'Nachname')) ->add('player', 'entity', array( 'label' => 'Spieler', 'class' => 'SKTCaromBundle:Player', 'property' => 'name', 'query_builder' => function (PlayerRepository $er) { return $er->createQueryBuilder('p') ->orderBy('p.name', 'ASC'); }, 'empty_value' => 'Verbinde Dich mit einem Spieler', 'required' => false, )); } public function getName() { return 'skt_user_profile'; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => $this->class, 'intention' => 'profile', 'user' => null )); } }
工作完美!
问题描述
i need some help overriding the FormFactory. My Goal is to change the Profile. So, as i also use Facebook Login, i do not want them to change email, username and password. So i use the ProfileController in my bundle to hand over the current user to the ProfileFormType class.
What i'm trying to do is to implement my own FormFactory, so i can set the user and put it into the options array inside the call
return $this->formFactory->createNamed($this->name, $this->type, null, array('validation_groups' => $this->validationGroups, 'user' => $this->user));
To achieve this, i need to define my FormFactory in sevices.yml.
Here is the original one from FOSUserBundle:
<service id="fos_user.profile.form.factory" class="FOS\UserBundle\Form\Factory\FormFactory"> <argument type="service" id="form.factory" /> <argument>%fos_user.profile.form.name%</argument> <argument>%fos_user.profile.form.type%</argument> <argument>%fos_user.profile.form.validation_groups%</argument> </service>
I have difficulties to translate this into yml, as i do not understand the usages of aliases completely.
Could you help me to define it correct? Something like
skt_user.profile.form.factory: class: SKT\UserBundle\Form\Factory\FormFactory arguments: ???
推荐答案
Funny, after posting it, I found the solution. This is the correct configuration for my FormFactory:
skt_user.profile.form.factory: class: SKT\UserBundle\Form\Factory\FormFactory arguments: ["@form.factory", "%fos_user.profile.form.name%", "%fos_user.profile.form.type%", "%fos_user.profile.form.validation_groups%"]
In my controller, I simply used these 2 lines:
$formFactory = $this->container->get('skt_user.profile.form.factory'); $formFactory->setUser($user);
In the factory, I implemented this function
namespace SKT\UserBundle\Form\Factory; use Symfony\Component\Form\FormFactoryInterface; use FOS\UserBundle\Form\Factory\FactoryInterface; class FormFactory implements FactoryInterface { private $formFactory; private $name; private $type; private $validationGroups; private $user; public function __construct(FormFactoryInterface $formFactory, $name, $type, array $validationGroups = null) { $this->formFactory = $formFactory; $this->name = $name; $this->type = $type; $this->validationGroups = $validationGroups; } public function createForm() { return $this->formFactory->createNamed($this->name, $this->type, null, array('validation_groups' => $this->validationGroups, 'user' => $this->user)); } public function setUser($user) { $this->user = $user; } }
and this is how my Formtype looks
<?php namespace SKT\UserBundle\Form\Type; use SKT\CaromBundle\Repository\PlayerRepository; use Symfony\Component\Form\FormBuilderInterface; use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class ProfileFormType extends \FOS\UserBundle\Form\Type\ProfileFormType { private $class; /** * @param string $class The User class name */ public function __construct($class) { $this->class= $class; } public function buildForm(FormBuilderInterface $builder, array $options) { // Do not show email and username if login uses facebook if (!$options['user']->getFacebookId()) { $builder ->add('email', 'email', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle')) ->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle')); } $builder ->add('firstname', null, array('label' => 'Vorname')) ->add('lastname', null, array('label' => 'Nachname')) ->add('player', 'entity', array( 'label' => 'Spieler', 'class' => 'SKTCaromBundle:Player', 'property' => 'name', 'query_builder' => function (PlayerRepository $er) { return $er->createQueryBuilder('p') ->orderBy('p.name', 'ASC'); }, 'empty_value' => 'Verbinde Dich mit einem Spieler', 'required' => false, )); } public function getName() { return 'skt_user_profile'; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => $this->class, 'intention' => 'profile', 'user' => null )); } }
works perfect!