简体   繁体   中英

Symfony2 - Form classes: data_class doesn't seem to work

I am using a Form class to help generate a form. It is a password reset form.

This form needs to be tied to my User entity, once the form is submitted the password will be updated.

Everything is working with the code I have currently, yet in an attempt to strip out some code that I believe shouldn't be required (due to using the data_class option) my validation breaks (as the form seems to become "detached" form the entity)

Ok, so some code:

public function passwordResetAction(Request $request, $key = NULL)
{
    $user = $this->getDoctrine()
            ->getRepository('DemoUserBundle:User\User')
            ->findOneBy(array('resetToken' => $key));

    if (!$user) {
        throw $this->createNotFoundException('No user found for reset token '.$key.'!');
    }

    $form = $this->createForm(new PasswordResetType(), $user);

    if ($request->getMethod() == 'POST') {
        $form->bindRequest($request);

        if ($form->isValid()) {
            $postData = $request->request->get('resetpass');

            $newPassword = $postData['password'];

            $encoder = new MessageDigestPasswordEncoder('sha1', false, 1);
            $password = $encoder->encodePassword($newPassword, $user->getSalt());
            $user->setPassword($password);

            $newToken = base64_encode($user->getUsername().'|'.date('Y-m-d'));
            $user->setResetToken($newToken);

            $em = $this->getDoctrine()->getEntityManager();
            $em->persist($user);
            $em->flush();

            return $this->redirect($this->generateUrl('password_reset_success'));
        }

    }

    return $this->render('DemoUserBundle:User\Reset:password-reset.html.twig', array('key' => $key, 'form' => $form->createView()));
}

The piece of code that I'm interested in is "$form = $this->createForm(new PasswordResetType(), $user);" As you can see, I'm using the Form Type to construct the form and passing it the $user variable that attaches the form to the User entity. Now, as far as I can understand, I should not need this parameter set as I have the entity set in the Form Type (see below for the code)

namespace Demo\UserBundle\Form\Type\User;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\CallbackValidator;

class PasswordResetType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder->add('password', 'password', array('label' => 'New Password'));
        $builder->add('confirmPassword', 'password', array('label' => 'Confirm Password', 'property_path' => false));
        $builder->addValidator(new CallbackValidator(function($form)
            {
                if($form['confirmPassword']->getData() != $form['password']->getData()) {
                    $form['confirmPassword']->addError(new FormError('Passwords must match.'));
            }
        }));
}

public function getDefaultOptions(array $options)
{
    return array(
        'data_class' => 'Demo\UserBundle\Entity\User\User',
    );
}

public function getName()
{
    return 'resetpass';
}

}

So this form should be default attach to the User Entity (without the need for the $user variable) yet it doesn't work. Without that variable being passed, the validation simply doesn't work (an indicator that it isn't being attached to the user entity)

What gives? Any ideas folks?

This data_class option is used to set the appropriate data mapper to be used by the form. If you don't supply it, it guesses it based on the object you pass to it.

It doesn't free you from passing an object to the form. How do you think it would know which object you want to work with?

in the new symfony versions use another method signature (option resolver instead of $options variable):

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
         'data_class' => 'Demo\UserBundle\Entity\User\User',
    ));
}

Note for Symfony 2.7: the form API has slightly changed , so you should use this instead:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
         'data_class' => 'Demo\UserBundle\Entity\User\User',
    ));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM