Création d'une page statique "contact" avec un formulaire, des validateurs et envoi d'emails - Symfony 2 partie 5

Tutorial Symonfy 2 : Création d'une page statique "contact" avec un formulaire, des validateurs et envoi d'emails.

Publié le 02/10/2013

1 - Création de la route

Edition du fichier de routage du bundle :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/config/routing.yml

Ajout de la route suivante :


BloggerBlogBundle_contact:
    pattern:  /contact
    defaults: { _controller: BloggerBlogBundle:Page:contact }
    requirements:
        _method:  GET

2 - Création de l'action dans le controller

Edition du controller "Page" :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Controller/PageController.php

Ajout de la méthode suivante :


public function contactAction()
{
    return $this->render('BloggerBlogBundle:Page:contact.html.twig');
}

3 - Création de la vue associée

Création du fichier de vue :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig

Ajouter le code suivant :


{# src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig #}
{% extends 'BloggerBlogBundle::layout.html.twig' %}

{% block title %}Contact{% endblock%}

{% block body %}
    <header>
        <h1>Contact symblog</h1>
    </header>

    <p>Want to contact symblog?</p>
{% endblock %}

4 - Création du lien vers la page contact

Edition du template de base Twigg :

sudo nano /var/www/symblog/app/Resources/views/base.html.twig

Modifier la balise de lien de la navigation :


<!-- app/Resources/views/base.html.twig -->
{% block navigation %}
    <nav>
        <ul class="navigation">
            <li><a href="{{ path('BloggerBlogBundle_homepage') }}">Home</a></li>
            <li><a href="{{ path('BloggerBlogBundle_about') }}">About</a></li>
            <li><a href="{{ path('BloggerBlogBundle_contact') }}">Contact</a></li>
        </ul>
    </nav>
{% endblock %}

5 - Création de l'entité contact

Nous allons créer une classe qui représente la requête de contact d'un utilisateur, pour cela nous allons créer une classe :


sudo mkdir /var/www/symblog/src/Blogger/BlogBundle/Entity
sudo nano /var/www/symblog/src/Blogger/BlogBundle/Entity/Enquiry.php

Ajouter le code suivant :


<?php
// src/Blogger/BlogBundle/Entity/Enquiry.php

namespace Blogger\BlogBundle\Entity;

class Enquiry
{
    protected $name;

    protected $email;

    protected $subject;

    protected $body;

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }

    public function getSubject()
    {
        return $this->subject;
    }

    public function setSubject($subject)
    {
        $this->subject = $subject;
    }

    public function getBody()
    {
        return $this->body;
    }

    public function setBody($body)
    {
        $this->body = $body;
    }
}

6 - Création du formulaire

Créer un fichier comme suit :


sudo mkdir /var/www/symblog/src/Blogger/BlogBundle/Form
sudo nano /var/www/symblog/src/Blogger/BlogBundle/Form/EnquiryType.php

Ajouter le code suivant :


<?php
// src/Blogger/BlogBundle/Form/EnquiryType.php

namespace Blogger\BlogBundle\Form;

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

class EnquiryType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name');
        $builder->add('email', 'email');
        $builder->add('subject');
        $builder->add('body', 'textarea');
    }

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

7 - Création du formulaire dans le controller

Editions du controller "Page" :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Controller/PageController.php

Remplacer la methode "contactAction()" par :


// src/Blogger/BlogBundle/Controller/PageController.php
public function contactAction()
{
    $enquiry = new Enquiry();
    $form = $this->createForm(new EnquiryType(), $enquiry);

    $request = $this->getRequest();
    if ($request->getMethod() == 'POST') {
        $form->bind($request);

        if ($form->isValid()) {
            // Perform some action, such as sending an email

            // Redirect - This is important to prevent users re-posting
            // the form if they refresh the page
            return $this->redirect($this->generateUrl('BloggerBlogBundle_contact'));
        }
    }

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

Nous avons utilisée 2 nouvelles classes dans le controller "Page" et nous allons donc les importer dans ce dernier via leur espaces de nom.

Editions du controller "Page" :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Controller/PageController.php

Ajout des lignes suivantes avant le début de la classe :


<?php
// src/Blogger/BlogBundle/Controller/PageController.php

namespace Blogger\BlogBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Import new namespaces
use Blogger\BlogBundle\Entity\Enquiry;
use Blogger\BlogBundle\Form\EnquiryType;

class PageController extends Controller
// ..

8 - Affichage du formulaire dans la vue Twigg

Edition de la vue :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig

Remplacer le code par le suivant :


{# src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig #}
{% extends 'BloggerBlogBundle::layout.html.twig' %}

{% block title %}Contact{% endblock%}

{% block body %}
    <header>
        <h1>Contact symblog</h1>
    </header>

    <p>Want to contact symblog?</p>

    <form action="{{ path('BloggerBlogBundle_contact') }}" method="post" {{ form_enctype(form) }} class="blogger">
        {{ form_errors(form) }}

        {{ form_row(form.name) }}
        {{ form_row(form.email) }}
        {{ form_row(form.subject) }}
        {{ form_row(form.body) }}

        {{ form_rest(form) }}

        <input type="submit" value="Submit" />
    </form>
{% endblock %}

9 - Ajouter des styles au formulaire

Créer le fichier css suivant :


sudo mkdir /var/www/symblog/src/Blogger/BlogBundle/Resources/public
sudo mkdir /var/www/symblog/src/Blogger/BlogBundle/Resources/public/css
sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/public/css/blog.css

Ajouter le code suivant :


.blogger-notice { text-align: center; padding: 10px; background: #DFF2BF; border: 1px solid; color: #4F8A10; margin-bottom: 10px; }
form.blogger { font-size: 16px; }
form.blogger div { clear: left; margin-bottom: 10px; }
form.blogger label { float: left; margin-right: 10px; text-align: right; width: 100px; font-weight: bold; vertical-align: top; padding-top: 10px; }
form.blogger input[type="text"],
form.blogger input[type="email"]
    { width: 500px; line-height: 26px; font-size: 20px; min-height: 26px; }
form.blogger textarea { width: 500px; height: 150px; line-height: 26px; font-size: 20px; }
form.blogger input[type="submit"] { margin-left: 110px; width: 508px; line-height: 26px; font-size: 20px; min-height: 26px; }
form.blogger ul li { color: #ff0000; margin-bottom: 5px; }

Ajout du lien de la feuille de style dans le formulaire :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/views/layout.html.twig

Remplacer le contenu par le code suivant :


{# src/Blogger/BlogBundle/Resources/views/layout.html.twig #}
{% extends '::base.html.twig' %}

{% block stylesheets %}
    {{ parent() }}
    <link href="{{ asset('bundles/bloggerblog/css/blog.css') }}" type="text/css" rel="stylesheet" />
{% endblock %}

{% block sidebar %}
    Sidebar content
{% endblock %}

10 - Ajout des ressources nécessaires dans le repertoire web de notre application

Nous allons installer les ressources via un lien symbolique dans le repertoire public "web" de notre app :


cd /var/www/symblog
sudo php app/console assets:install web --symlink

11 - Configuration du routage pour accepter le post

Edition du fichier de routage :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/config/routing.yml

Ajouter l'option "POST" à "_method" de la route pour la page contact, comme suit :


# src/Blogger/BlogBundle/Resources/config/routing.yml
BloggerBlogBundle_contact:
    pattern:  /contact
    defaults: { _controller: BloggerBlogBundle:Page:contact }
    requirements:
        _method:  GET|POST

12 - Mise en place des validateurs pour notre formulaire

Editer le fichier Enquiry.php :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Entity/Enquiry.php

Et remplacer avec le contenu suivant :


<?php
// src/Blogger/BlogBundle/Entity/Enquiry.php

namespace Blogger\BlogBundle\Entity;

use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;

class Enquiry
{
    protected $name;

    protected $email;

    protected $subject;

    protected $body;

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }

    public function getSubject()
    {
        return $this->subject;
    }

    public function setSubject($subject)
    {
        $this->subject = $subject;
    }

    public function getBody()
    {
        return $this->body;
    }

    public function setBody($body)
    {
        $this->body = $body;
    }

    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('name', new NotBlank());

        $metadata->addPropertyConstraint('email', new Email());

        $metadata->addPropertyConstraint('subject', new NotBlank());

        $metadata->addPropertyConstraint( 'subject', new Length( array( 'min' => 5) ) );

        $metadata->addPropertyConstraint( 'subject', new Length( array( 'max' => 10) ) );

    }

}

13 - Mise en place de Swift Mailer pour l'envoi du mail

On va d'abord passer en revue les paramètres d'envoi d'email sur notre serveur.

sudo nano /var/www/symblog/app/config/parameters.ini Laisser les valeurs tel qu'elles sont, on les a déjà renseigné lors de l'installation de Symfony.

On va ensuite mettre à jour le controller "Page" :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Controller/PageController.php

En y en mettant à jour avec le contenu suivant :


// src/Blogger/BlogBundle/Controller/PageController.php

public function contactAction()
{
    // ..
    if ($form->isValid()) {

        $message = \Swift_Message::newInstance()
            ->setSubject('Contact enquiry from symblog')
            ->setFrom('enquiries@symblog.co.uk')
            ->setTo('email@email.com')
            ->setBody($this->renderView('BloggerBlogBundle:Page:contactEmail.txt.twig', array('enquiry' => $enquiry)));
        $this->get('mailer')->send($message);

        $this->get('session')->getFlashBag()->Add('notice', 'Your contact enquiry was successfully sent. Thank you!');

        // Redirect - This is important to prevent users re-posting
        // the form if they refresh the page
        return $this->redirect($this->generateUrl('BloggerBlogBundle_contact'));
    }
    // ..
}

Nous allons ensuite ajouter les message flash à la vue Twigg :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig

Mettez à jour avec le contenu suivant :


{# src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig #}

{# rest of template ... #}
<header>
    <h1>Contact symblog</h1>
</header>

{% for flashMessage in app.session.flashbag.get('notice') %}
        <div class="flash-notice">
            {{ flashMessage }}
        </div>
{% endfor %}

<p>Want to contact symblog?</p>

{# rest of template ... #}

Enregistrement du mail du webmaster :

On va créer un nouveau fichier de config du bundle de la façon suivante :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/config/config.yml

Ajouter le code suivant :


# src/Blogger/BlogBundle/Resources/config/config.yml
parameters:
    # Blogger contact email address
    blogger_blog.emails.contact_email: contact@email.com

Enregistrement du nouveau fichier config.yml :

sudo nano /var/www/symblog/app/config/config.yml

Mettre à jour la section "imports" comme suit :


# app/config/config.yml
imports:
    # .. existing import here
    - { resource: @BloggerBlogBundle/Resources/config/config.yml }

On va effectuer une dernière modification dans l'action contact du controller page :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Controller/PageController.php

Mettre à jour avec le code suivant :


// src/Blogger/BlogBundle/Controller/PageController.php

public function contactAction()
{
    // ..
    if ($form->isValid()) {

        $message = \Swift_Message::newInstance()
            ->setSubject('Contact enquiry from symblog')
            ->setFrom('enquiries@symblog.co.uk')
            ->setTo($this->container->getParameter('blogger_blog.emails.contact_email'))
            ->setBody($this->renderView('BloggerBlogBundle:Page:contactEmail.txt.twig', array('enquiry' => $enquiry)));
        $this->get('mailer')->send($message);

        // ..
    }
    // ..
}

Création du template du mail :

sudo nano /var/www/symblog/src/Blogger/BlogBundle/Resources/views/Page/contactEmail.txt.twig

Ajout le contenu suivant :


{# src/Blogger/BlogBundle/Resources/view/Page/contactEmail.txt.twig #}
A contact enquiry was made by {{ enquiry.name }} at {{ "now" | date("Y-m-d H:i") }}.

Reply-To: {{ enquiry.email }}
Subject: {{ enquiry.subject }}
Body:
{{ enquiry.body }}