Patrick
Patrick

Reputation: 129

Symfony2 form processing

I'm having trouble processing my contact form, a simple one though. I have spent much time trying to figure out what is wrong with my code but I've not been able to find a way out. My object is not receiving data. I'm having the following exception:

An exception occurred while executing 'INSERT INTO contact (email, name, message, date) VALUES (?, ?, ?, ?)' with params [null, null, null, "2016-09-19 00:08:48"]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'email' cannot be null

Below is my code:

 <form action="{{ path('ap_platform_contact') }}" method="POST" class="marginBottom25px" id="contact">
    <div class="row">
        <div class="col-md-6">
            <div class="form-group">
                <label for="exampleInputEmail1">Email</label>
                <input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Votre email">
                {{ form_errors(form.email) }}
            </div>
        </div>
        <div class="col-md-6">
            <div class="form-group">
                <label for="exampleInputPassword1">Nom </label>
                <input type="text" name="name" class="form-control" id="exampleInputPassword1" placeholder="Votre nom ou celui de votre société">
                {{ form_errors(form.name) }}
            </div>
        </div>
    </div>
    <div class="form-group">
        <label for="exampleInputEmail1">Message</label>
        <textarea id="exampleInputEmail1" class="form-control" name="message" rows="3"></textarea>
        {{ form_errors(form.message) }}
    </div>
    <!--
    <div class="form-group">
        <div class="g-recaptcha" data-sitekey="6LdICQcUAAAAAMKjB3Cet82jKHwb_4S-ms8Wz-iE"></div>
    </div>
    -->
    <div class="form-group">
        <button type="submit" class="btn tf-btn btn-success">{{ 'Envoyer'|trans }}</button>
    </div>
</form>

The controller:

public function contactAction(Request $request)
{
    // Retrieving POST data
    //$postData = $request->request->get('email');

    $contact = new Contact();

    $form = $this->createForm(new ContactType(), $contact);

    if ($form->handleRequest($request)) {

        /*if ($this->get('ap_platform.antispam')->isSpam($contact->getMessage())) {
            throw new \Exception('The field email is either empty or its content is too short');
        }*/

        $em = $this->getDoctrine()->getManager();
        $em->persist($contact);
        $em->flush();

        //var_dump($contact->getEmail());exit;

        $request->getSession()->getFlashBag()->add('notice', 'Votre message a été envoyé !');

        $mailer = $this->get('mailer');

        $message =  \Swift_Message::newInstance()
            ->setSubject('Message venant du formulaire de contact de chyqat.com')
            ->setFrom('[email protected]')
            ->setTo('[email protected]')
            ->setBody("Nouveau message provenant de ".$contact->getName()."<br>  Adresse Email : <strong>".$contact->getEmail()."</strong> <br>Son message:<br> <i>".$contact->getMessage()."</i>")
        ;

        $mailer->send($message);
    }

    return $this->render("APPlatformBundle:Public:contact.html.twig", array(
        'form' => $form->createView()
    ));
}

ContactType.php file:

class ContactType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email',       'email')
            ->add('message',     'textarea')
            ->add('name',        'text')
        ;
    }

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Advertproject\PlatformBundle\Entity\Contact'
    ));
}

/**
 * @return string
 */
public function getName()
{
    return 'advertproject_platformbundle_contact';
}
}

Contact object:

<?php
/**
 * Created by PhpStorm.
 * User: Patrick
 * Date: 11/30/15
 * Time: 11:58 AM
 */

namespace Advertproject\PlatformBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\Tests\Validator\Constraints as PasswordValidation;



/**
 *
 * Class Contact
 * @ORM\Table(name="contact")
 * @package Advertproject\PlatformBundle\Entity
 * @ORM\Entity()
 */
class Contact
{
    /**
     * @var integer
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     * @ORM\Column(name="email", type="string", length=100)
     *@Assert\NotBlank(message="Veuillez fournir une adresse email")
     * @Assert\Length(max=100)
     */
    protected $email;

    /**
     * @var string
     * @Assert\NotBlank()
     * @ORM\Column(name="name", type="string", length=100)
     */
    protected $name;

    /**
     * @var string
     * @Assert\NotBlank()
     * @Assert\Length(max=1000)
     * @ORM\Column(name="message", type="string")
     */
    protected $message;

    /**
     * @var \DateTime
     * @ORM\Column(name="date", type="datetime")
     */
    protected $date;

    public function __construct()
    {
        $this->date = new \Datetime();
    }

    /**
     * Set email
     * @Assert\NotBlank()
     * @param string $email
     * @return Contact
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email
     *
     * @return string 
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Contact
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set message
     *
     * @param string $message
     * @return Contact
     */
    public function setMessage($message)
    {
        $this->message = $message;

        return $this;
    }

    /**
     * Get message
     *
     * @return string 
     */
    public function getMessage()
    {
        return $this->message;
    }

    /**
     * Set date
     *
     * @param \DateTime $date
     * @return Contact
     */
    public function setDate($date)
    {
        $this->date = $date;

        return $this;
    }

    /**
     * Get date
     *
     * @return \DateTime 
     */
    public function getDate()
    {
        return $this->date;
    }

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

Can anyone help me finding out what is wrong with my code?

Below is what I got after running var_dump($form->getData()) before calling flush() method

object(Advertproject\PlatformBundle\Entity\Contact)#1955 (5) { ["id":protected]=> NULL ["email":protected]=> NULL ["name":protected]=> NULL ["message":protected]=> NULL ["date":protected]=> object(DateTime)#1956 (3) { ["date"]=> string(26) "2016-09-18 20:49:32.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" } }

Upvotes: 1

Views: 133

Answers (2)

martin
martin

Reputation: 96891

Actually, the answer by Togesh Patil is incomplete.

I see two problems with the code:

  1. Template

    When using form you need to provide correct input names so Symfony Form can automatically fetch submitted data from $request. If you don't want to use the default form_widget() Twig helpers you can just grab names for each input and render them as you wish:

    <input type="email" name="{{ form.name.vars.full_name }}" class="...">
    

    Then don't forget to include the CSRF token (if you haven't disabled CSRF protection manually):

    <input type="hidden" name="{{ form._token.vars.full_name }}" value="{{ form._token.vars.value }}">
    

    Btw, helper form_end(form) prints CSRF token automatically for you. See http://symfony.com/doc/current/form/csrf_protection.html and http://symfony.com/doc/current/forms.html#rendering-the-form

  2. Controller

    This is not how you should validate a Form in a controller, see http://symfony.com/doc/current/forms.html#handling-form-submissions:

    $form = $this->createForm(ContactType::class, $contact);
    $form->handleRequest($request);
    
    if ($form->isSubmitted() && $form->isValid()) {
        $contact = $form->getData();
        // persist and so on ...
    }
    

    Notice using ContactType::class instead of new ContactType().

    Also note, that expression if ($form->handleRequest($request)) { is always true because handleRequest() returns $this. See https://github.com/symfony/form/blob/master/Form.php#L486.

Upvotes: 2

Yogesh Patil
Yogesh Patil

Reputation: 81

you should use following code in your html.twig page

     <div class="panel-body">
         {{ form_start(form) }}
         {{ form_errors(form) }}
         {{ form_widget(form) }}
         {{ form_end(form) }}
     </div> 

check following Symfony Documentation for more ways to render forms.

Upvotes: 3

Related Questions