1 - Création d'un Bundle CMS
On va créer un bundle CMS pour gérer l'affichage des pages de notre site. Pour simplifier cette partie on va générer des pages avec un contenu statique. Le route vont passer le controller Template et on pourra se passer de la création de controller pour l'affichage des pages front de notre site.
php app/console generate:bundle --namespace= BlogTest/CmsBundle
2 - Création du template "base" pour le CMSBundle
Création du template base incluant la navigation et le block de connexion à l'espace "mon compte" :
nano /app/Resources/views/base.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Title page{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block header %}
<ul>
<li><a href="{{ path('homepage') }}">Home</a></li>
<li><a href="{{ path('imprint') }}">Mentions légales</a></li>
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
<li><a href="{{ path('fos_user_security_logout') }}">Déconnexion</a></li>
<li>Bonjour, {{ app.user }}</li>
{% else %}
<li><a href="{{ path('fos_user_registration_register') }}">Inscription</a></li>
<li><a href="{{ path('fos_user_security_login') }}">Connexion</a></li>
{% endif %}
</ul>
{% endblock %}
{% block flash %}
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="flash-notice">
{{ flashMessage }}
</div>
{% endfor %}
{% for flashMessage in app.session.flashbag.get('error') %}
<div class="flash-error">
{{ flashMessage }}
</div>
{% endfor %}
{% endblock %}
{% block rubric %}{% endblock %}
{% block body %}{% endblock %}
{% block footer %}{% endblock footer %}
{% block javascripts %}{% endblock %}
</body>
</html>
3 - Création des routes et vues pour le CMSBundle
On va créer un layout pour le bundle et une vue pour les pages index et imprint.
Création du layout :
nano src/BlogTest/CmsBundle/Resources/views/layout.html.twig
{% extends '::base.html.twig' %}
Création de la vue index :
nano src/BlogTest/CmsBundle/Resources/views/Cms/index.html.twig
{% extends '@BlogTestCms/layout.html.twig' %}
{% block body %}Home{% endblock %}
{% block rubric %}
<p>Here some content...</p>
{% endblock %}
Création de la vue imprint :
{% extends '@BlogTestCms/layout.html.twig' %}
{% block body %}
<p>Imprint</p>
{% endblock %}
Ajout des routes :
nano src/BlogTest/CmsBundle/Resources/config/routing.yml
homepage:
path: /
defaults: { _controller: FrameworkBundle:Template:template, template: BlogTestCmsBundle:Cms:index.html.twig }
requirements:
_method: GET
imprint:
path: /imprint
defaults: { _controller: FrameworkBundle:Template:template, template: BlogTestCmsBundle:Cms:imprint.html.twig }
requirements:
_method: GET
On dispose maintenant d'un front opérationnel. On va pouvoir "brancher" l'action login de FOSUserBundke et surcharger les vues show qui affichera l'espace "mon compte" correspondant à la route sonata_user_profile_edit.
4 - Modification du fichier config.yml
On modifie le fichier de configuration config.yml pour permettre la surcharge de FOSUserBundle et SonataUserBundle, ainsi que l'envoie des email au format html.
nano app/config/config.yml
# FOS User Bundle
fos_user:
db_driver: orm
firewall_name: main
user_class: BlogTest\UserBundle\Entity\User
service:
mailer: fos_user.mailer.twig_swift
registration:
form:
type: blogtest_sonata_user_register
validation_groups: [Register, Default, Registration]
confirmation:
enabled: true
template: BlogTestUserBundle:Registration:email.html.twig
profile:
form:
type: blogtest_sonata_user_profile
#validation_groups: [Profile, Default]
resetting:
email:
template: BlogTestUserBundle:Resetting:email.html.twig
group:
group_class: BlogTest\UserBundle\Entity\Group
from_email:
address: pa@foulquier.info
sender_name: paf
5 - Héritage de SonataUserBundle pour notre UserBundle
On appel le parent du bundle SonataUserBundle pour notre UserBundle.
nano src/BlogTest/UserBundle/BlogTestUserBundle.php
<?php
namespace BlogTest\UserBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class BlogTestUserBundle extends Bundle
{
/**
* {@inheritdoc}
*/
public function getParent()
{
return 'SonataUserBundle';
}
}
6 - Surcharge des routes de FOSUserBundle dans le UserBundle
On surcharge les routes du FOSUserBundle de façon a personnaliser nos url propres en ajoutant les routes suivantes :
nano src/BlogTest/UserBundle/Resources/config/routing.yml
# SECURITY
fos_user_security_login:
pattern: /connexion
defaults: { _controller: FOSUserBundle:Security:login }
requirements:
_method: GET
fos_user_security_check:
pattern: /connexion/verification
defaults: { _controller: FOSUserBundle:Security:check }
requirements:
_method: POST
fos_user_security_logout:
pattern: /deconnexion
defaults: { _controller: FOSUserBundle:Security:logout }
requirements:
_method: GET
# REGISTRATION
fos_user_registration_register:
pattern: /inscription
defaults: { _controller: FOSUserBundle:Registration:register }
requirements:
_method: GET|POST
fos_user_registration_check_email:
pattern: /inscription/e-mail
defaults: { _controller: FOSUserBundle:Registration:checkEmail }
requirements:
_method: GET
fos_user_registration_confirm:
pattern: /inscription/confirmation/{token}
defaults: { _controller: FOSUserBundle:Registration:confirm }
requirements:
_method: GET
fos_user_registration_confirmed:
pattern: /inscription/confirmation
defaults: { _controller: FOSUserBundle:Registration:confirmed }
requirements:
_method: GET
# RESETTING PASSWORD
fos_user_resetting_request:
pattern: /mot-de-passe-oublie/reinitialisation
defaults: { _controller: FOSUserBundle:Resetting:request }
requirements:
_method: GET
fos_user_resetting_send_email:
pattern: /mot-de-passe-oublie/e-mail
defaults: { _controller: FOSUserBundle:Resetting:sendEmail }
requirements:
_method: GET|POST
fos_user_resetting_check_email:
pattern: /mot-de-passe-oublie/verification
defaults: { _controller: FOSUserBundle:Resetting:checkEmail }
requirements:
_method: GET
fos_user_resetting_reset:
pattern: /mot-de-passe-oublie/{token}
defaults: { _controller: FOSUserBundle:Resetting:reset }
requirements:
_method: GET|POST
# PROFILE
fos_user_profile_show:
pattern: /profile
defaults: { _controller: FOSUserBundle:Profile:show }
requirements:
_method: GET
fos_user_profile_edit:
pattern: /profile/editer
defaults: { _controller: FOSUserBundle:Profile:edit }
requirements:
_method: GET|POST
7 - Surcharge des vues controller Profile (espace privé utilisateur) du bundle SonataUserBundle (qui surcharge le bundle FOSUserBundle) :
On va créer dans notre bundle UserBundle les vues show.html.twig et edit.html.twig afficheront les pages : "mon compte" et le formulaires d'édition de données "mon compte".
On a commence par la création d'un layout :
nano scr/TestBlog/UserBundle/Resources/views/layout.html.twig
{% extends '::base.html.twig' %}
Création de la vue show :
nano scr/TestBlog/UserBundle/Resources/views/Profile/show.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
Nom d'utilisateur : {{ app.user.username }}<br />
Adresse e-mail : {{ app.user.email }}<br />
<a href="{{ path('fos_user_profile_edit') }}">Editer</a>
{% endblock %}
Création de la vue edit :
nano scr/TestBlog/UserBundle/Resources/views/Profile/edit.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
<form action="{{ path('fos_user_profile_edit') }}" {{ form_enctype(form) }} method="post">
{{ form_widget(form) }}
<input type="submit" value="Mettre à jour" />
</form>
{% endblock %}
8 - Création des FormType d'inscription et de modifications des informations utilisateurs :
On va créer un FormType pour l'inscription de nos utilisateurs depuis la partie publique de notre site web.
Création du FormType ProfileType :
nano src/BlogTest/UserBundle/Form/Type/ProfileType.php
<?php
/**
* Created by PhpStorm.
* User: gerard
* Date: 09/09/2014
* Time: 10:16
*/
namespace BlogTest\UserBundle\Form\Type;
use FOS\UserBundle\Form\Type\ProfileFormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ProfileType extends ProfileFormType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('gender', 'choice', array(
'label' => 'profile.fields.gender',
'translation_domain' => 'forms',
'choices' => array(
'm' => 'M.',
'f' => 'Mme'
)
))
->add('firstname', 'text', array(
'label' => 'profile.fields.firstname',
'translation_domain' => 'forms'
))
->add('address', 'textarea', array(
'label' => 'profile.fields.address',
'translation_domain' => 'forms'
))
->add('zipCode', 'text', array(
'label' => 'profile.fields.zip_code',
'translation_domain' => 'forms'
))
->add('lastname', 'text', array(
'label' => 'profile.fields.lastname',
'translation_domain' => 'forms'
))
->add('phone', 'text', array(
'label' => 'profile.fields.phone',
'translation_domain' => 'forms'
))
->add('email', 'email', array(
'label' => 'profile.fields.email',
'translation_domain' => 'forms'
))
->add('plainPassword', 'repeated', array(
'first_options' => array(
'label' => 'profile.fields.password_first'
),
'second_options' => array(
'label' => 'profile.fields.password_second'
),
'required' => false,
'translation_domain' => 'forms'
))
;
}
public function setDefaultOption(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => array('Default', 'Account')
));
}
public function getName()
{
return 'blogtest_sonata_user_profile';
}
}
Création du FormType RegisterType :
nano src/BlogTest/UserBundle/Form/Type/RegisterType.php
<?php
/**
* Created by PhpStorm.
* User: gerard
* Date: 15/09/2014
* Time: 15:03
*/
namespace BlogTest\UserBundle\Form\Type;
use FOS\UserBundle\Form\Type\RegistrationFormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RegisterType extends RegistrationFormType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('firstname', 'text', array(
'label' => 'profile.fields.firstname',
'translation_domain' => 'forms'
))
;
}
public function setDefaultOption(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => array('Default', 'Register')
));
}
public function getName()
{
return 'blogtest_sonata_user_register';
}
}
9 - Ajout des formulaires en tant que services
services:
user.form.profile.type:
class: BlogTest\UserBundle\Form\Type\ProfileType
parent: fos_user.profile.form.type
tags:
- { name: form.type, alias: blogtest_sonata_user_profile }
user.form.register.type:
class: BlogTest\UserBundle\Form\Type\RegisterType
parent: fos_user.registration.form.type
tags:
- { name: form.type, alias: blogtest_sonata_user_register }
10 - Création des Handler pour les formulaires ProfileType
Création du handler pour le formulaire ProfilType :
nano src/BlogTest/UserBundle/Form/Handler/ProfileFormHandler
<?php
/**
* Created by PhpStorm.
* User: gerard
* Date: 09/09/2014
* Time: 10:31
*/
namespace BlogTest\UserBundle\Form\Handler;
use Sonata\UserBundle\Form\Handler\ProfileFormHandler as BaseHandler;
class ProfileFormHandler extends BaseHandler
{
protected $form;
protected $request;
protected $templating;
public function __construct($request, $form, $templating)
{
$this->request = $request;
$this->form = $form;
$this->templating = $templating;
}
}
11 - Ajout des traductions
Traduction des formulaires :
nano src/BlogTest/UserBundle/Resources/translations/forms.fr.yml
profile:
fields:
gender: Civilité
firstname: Prénom
lastname: Nom
address: Adresse
zip_code: Code postal
phone: Téléphone
email: E-mail
password_first: Mot de passe
password_second: Mot de passe (validation)
register:
fields:
firstname: Nom
Traduction du contenu des email de FOSUserBundle :
nano src/BlogTest/UserBundle/Resources/translations/FOSUserBundle.fr.yml
# Resetting account
resetting:
email:
subject: |
[Vet-Tune] Réinitialisation de votre mot de passe
message: |
<p>Bonjour %username%,</p>
<p>Pour réinitialiser votre mot de passe, merci de cliquer sur le lien suivant :</p>
<p style="text-align:center"><a href="%confirmationUrl%">%confirmationUrl%</a></p>
<p>Cordialement,<br />Vet-Tune.</p>
# Registration
registration:
email:
subject: |
[Vet-Tune] Bienvenue %username% !
message: |
<p>Bonjour %username%,</p>
<p>Pour valider votre compte utilisateur, merci de vous rendre sur :</p>
<p style="text-align:center"><a href="%confirmationUrl%">%confirmationUrl%</a></p>
<p>Cordialement,<br />Vet-Tune.</p>
Traduction des messages d'erreurs des des validateurs :
nano src/BlogTest/UserBundle/Resources/translations/validators.fr.yml
valid_phone_number: Cette valeur n'est pas un numéro de téléphone valide.
"'{{ value }}' is not a valid email.": "'{{ value }}' n'est pas une adresse e-mail valide."
not_empty_field: Le champs ne peut être vide.
12 - Surcharge des vues du controller Registration (inscription utilisateur) du bundle SonataUserBundle
On va créer dans notre UserBundle les vues qui vont permettre le process d'inscription d'un nouvel utilisateur depuis la partie publique du site :
scr/BlogTest/UserBundle/Resources/views/ Registration/ inc/ email.html.twig checkEmail.html.twig confirmed.html.twig email.html.twig register.html.twig
Création du template de corps du email de validation :
nano src/BlogTest/UserBundle/Resources/views/Registration/inc/email.html.twig
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Template mailing</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
/* Fonts and Content */
body, td { font-family: 'Helvetica Neue', Arial, Helvetica, Geneva, sans-serif; font-size:14px; }
body { background-color: #2A374E; margin: 0; padding: 0; -webkit-text-size-adjust:none; -ms-text-size-adjust:none; }
h2{ padding-top:12px; /* ne fonctionnera pas sous Outlook 2007+ */color:#0E7693; font-size:22px; }
</style>
</head>
<body style="margin:0px; padding:0px; -webkit-text-size-adjust:none;">
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:rgb(42, 55, 78)" >
<tbody>
<tr>
<td align="center" bgcolor="#2A374E">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="w640" width="640" height="10"></td>
</tr>
<tr>
<td class="w640" width="640" height="10"></td>
</tr>
<!-- entete -->
<tr class="pagetoplogo">
<td class="w640" width="640">
<table class="w640" width="640" cellpadding="0" cellspacing="0" border="0" bgcolor="#F2F0F0">
<tbody>
<tr>
<td class="w30" width="30"></td>
<td class="w580" width="580" valign="middle" align="left">
<div class="pagetoplogo-content">
<img class="w580" style="text-decoration: none; display: block; color:#476688; font-size:30px;" src="logo.png" alt="Logo" width="482" height="108"/>
</div>
</td>
<td class="w30" width="30"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<!-- separateur horizontal -->
<tr>
<td class="w640" width="640" height="1" bgcolor="#d7d6d6"></td>
</tr>
<!-- contenu -->
<tr class="content">
<td class="w640" class="w640" width="640" bgcolor="#ffffff">
<table class="w640" width="640" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="w30" width="30"></td>
<td class="w580" width="580">
<!-- une zone de contenu -->
<table class="w580" width="580" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="w580" width="580">
<h2 style="color:#0E7693; font-size:22px; padding-top:12px;">Confirmation d'inscription</h2>
<div align="left" class="article-content">
{{ 'registration.email.message'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}, 'FOSUserBundle')|raw }}
</div>
</td>
</tr>
<tr>
<td class="w580" width="580" height="1" bgcolor="#c7c5c5"></td>
</tr>
</tbody>
</table>
</td>
<td class="w30" class="w30" width="30"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<!-- separateur horizontal de 15px de haut-->
<tr>
<td class="w640" width="640" height="15" bgcolor="#ffffff"></td>
</tr>
<!-- pied de page -->
<tr class="pagebottom">
<td class="w640" width="640">
<table class="w640" width="640" cellpadding="0" cellspacing="0" border="0" bgcolor="#c7c7c7">
<tbody>
<tr>
<td colspan="5" height="10"></td>
</tr>
<tr>
<td class="w30" width="30"></td>
<td class="w580" width="580" valign="top">
<p align="right" class="pagebottom-content-left">
<a style="color: #255D5C;" href="{{ url('homepage') }}"><span style="color: #255D5C;">Link</span></a>
</p>
</td>
<td class="w30" width="30"></td>
</tr>
<tr>
<td colspan="5" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="w640" width="640" height="60"></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Création de la vue checkEmail :
nano src/BlogTest/UserBundle/Resources/views/Registration/checkEmail.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
<p>{{ 'registration.check_email'|trans({'%email%': user.email}, 'FOSUserBundle') }}</p>
{% endblock %}
Création de la vue confirmed :
nano src/BlogTest/UserBundle/Resources/views/Registration/confirmed.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
<p>{{ 'registration.confirmed'|trans({'%username%': user.username}, 'FOSUserBundle') }}</p>
{% if app.session is not empty %}
{% set targetUrl = app.session.get('_security.' ~ app.security.token.providerKey ~ '.target_path') %}
{% if targetUrl is not empty %}<p><a href="{{ targetUrl }}">{{ 'registration.back'|trans({}, 'FOSUserBundle') }}</a></p>{% endif %}
{% endif %}
{% endblock %}
Création de la vue email de validation :
nano src/BlogTest/UserBundle/Resources/views/Registration/email.html.twig
{% block subject %}
{% autoescape false %}
{{ 'registration.email.subject'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}, 'FOSUserBundle') }}
{% endautoescape %}
{% endblock %}
{% block body_text %}
{% autoescape false %}
{{ 'registration.email.message'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}, 'FOSUserBundle') }}
{% endautoescape %}
{% endblock %}
{% block body_html %}
{% include 'BlogTestUserBundle:Registration:inc/email.html.twig' %}
{% endblock %}
Création de la vue register :
nano src/BlogTest/UserBundle/Resources/views/Registration/register.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
<p>Inscription :</p>
<form action="{{ path('fos_user_registration_register') }}" {{ form_enctype(form) }} method="POST" class="fos_user_registration_register">
{{ form_widget(form) }}
<div>
<input type="submit" value="{{ 'registration.submit'|trans({}, 'FOSUserBundle') }}" />
</div>
</form>
{% endblock %}
13 - Surcharge des vues du controller Resetting (reset mot de passe utilisateur) du bundle SonataUserBundle
On passe maintenant à la surcharge des vues du controller Resetting pour la réinitialisation du mot de passe utilisateur : scr/BlogTest/UserBundle/Resources/views/ Resetting/ inc/ email.html.twig checkEmail.html.twig passwordAlreadyRequested.html.twig request.html.twig request_content.html.twig reset.html.twig reset_content.html.twig
Création du template du corps de l'email de réinitialisation de mot de passe:
nano src/BlogTest/UserBundle/Resources/views/Resetting/inc/email.html.twig
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Template mailing</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
/* Fonts and Content */
body, td { font-family: 'Helvetica Neue', Arial, Helvetica, Geneva, sans-serif; font-size:14px; }
body { background-color: #2A374E; margin: 0; padding: 0; -webkit-text-size-adjust:none; -ms-text-size-adjust:none; }
h2{ padding-top:12px; /* ne fonctionnera pas sous Outlook 2007+ */color:#0E7693; font-size:22px; }
</style>
</head>
<body style="margin:0px; padding:0px; -webkit-text-size-adjust:none;">
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:rgb(42, 55, 78)" >
<tbody>
<tr>
<td align="center" bgcolor="#2A374E">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="w640" width="640" height="10"></td>
</tr>
<tr>
<td class="w640" width="640" height="10"></td>
</tr>
<!-- entete -->
<tr class="pagetoplogo">
<td class="w640" width="640">
<table class="w640" width="640" cellpadding="0" cellspacing="0" border="0" bgcolor="#F2F0F0">
<tbody>
<tr>
<td class="w30" width="30"></td>
<td class="w580" width="580" valign="middle" align="left">
<div class="pagetoplogo-content">
<img class="w580" style="text-decoration: none; display: block; color:#476688; font-size:30px;" src="logo.png" alt="Logo" width="482" height="108"/>
</div>
</td>
<td class="w30" width="30"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<!-- separateur horizontal -->
<tr>
<td class="w640" width="640" height="1" bgcolor="#d7d6d6"></td>
</tr>
<!-- contenu -->
<tr class="content">
<td class="w640" class="w640" width="640" bgcolor="#ffffff">
<table class="w640" width="640" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="w30" width="30"></td>
<td class="w580" width="580">
<!-- une zone de contenu -->
<table class="w580" width="580" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="w580" width="580">
<h2 style="color:#0E7693; font-size:22px; padding-top:12px;">Reinitialisation du mot de passe</h2>
<div align="left" class="article-content">
<p>{{ 'resetting.email.message'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}, 'FOSUserBundle')|raw }}</p>
</div>
</td>
</tr>
<tr>
<td class="w580" width="580" height="1" bgcolor="#c7c5c5"></td>
</tr>
</tbody>
</table>
</td>
<td class="w30" class="w30" width="30"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<!-- separateur horizontal de 15px de haut-->
<tr>
<td class="w640" width="640" height="15" bgcolor="#ffffff"></td>
</tr>
<!-- pied de page -->
<tr class="pagebottom">
<td class="w640" width="640">
<table class="w640" width="640" cellpadding="0" cellspacing="0" border="0" bgcolor="#c7c7c7">
<tbody>
<tr>
<td colspan="5" height="10"></td>
</tr>
<tr>
<td class="w30" width="30"></td>
<td class="w580" width="580" valign="top">
<p align="right" class="pagebottom-content-left">
<a style="color:#255D5C;" href="{{ url('homepage') }}"><span style="color:#255D5C;">Link</span></a>
</p>
</td>
<td class="w30" width="30"></td>
</tr>
<tr>
<td colspan="5" height="10"></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="w640" width="640" height="60"></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Création de la vue checkEmail :
nano src/BlogTest/UserBundle/Resources/views/Resetting/inc/checkEmail.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
<p>
{{ 'resetting.check_email'|trans({'%email%': email}, 'FOSUserBundle') }}
</p>
{% endblock %}
Création de la vue email :
nano src/BlogTest/UserBundle/Resources/views/Resetting/email.html.twig
{% block subject %}
{% autoescape false %}
{{ 'resetting.email.subject'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}, 'FOSUserBundle') }}
{% endautoescape %}
{% endblock %}
{% block body_text %}
{% autoescape false %}
{{ 'resetting.email.message'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}, 'FOSUserBundle') }}
{% endautoescape %}
{% endblock %}
{% block body_html %}
{% include 'BlogTestUserBundle:Resetting:inc/email.html.twig' %}
{% endblock %}
Création de la vue passwordAlreadyRequested :
nano src/BlogTest/UserBundle/Resources/views/Resetting/passwordAlreadyRequested.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
<p>{{ 'resetting.password_already_requested'|trans({}, 'FOSUserBundle') }}</p>
{% endblock %}
Création de la vue request :
nano src/BlogTest/UserBundle/Resources/views/Resetting/request.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
{% include "FOSUserBundle:Resetting:request_content.html.twig" %}
{% endblock %}
Création de la vue request_content :
nano src/BlogTest/UserBundle/Resources/views/Resetting/request_content.html.twig
<form action="{{ path('fos_user_resetting_send_email') }}" method="POST" class="fos_user_resetting_request">
<div>
{% if invalid_username is defined %}
<p>{{ 'resetting.request.invalid_username'|trans({'%username%': invalid_username}, 'FOSUserBundle') }}</p>
{% endif %}
<label for="username">{{ 'resetting.request.username'|trans({}, 'FOSUserBundle') }}</label>
<input type="text" id="username" name="username" required="required" />
</div>
<div>
<input type="submit" value="{{ 'resetting.request.submit'|trans({}, 'FOSUserBundle') }}" />
</div>
</form>
Création de la vue reset :
nano src/BlogTest/UserBundle/Resources/views/Resetting/reset.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
{% include "FOSUserBundle:Resetting:reset_content.html.twig" %}
{% endblock %}
Création de la vue reset_content :
nano src/BlogTest/UserBundle/Resources/views/Resetting/reset_content.html.twig
<form action="{{ path('fos_user_resetting_reset', {'token': token}) }}" {{ form_enctype(form) }} method="POST" class="fos_user_resetting_reset">
{{ form_widget(form) }}
<div>
<input type="submit" value="{{ 'resetting.reset.submit'|trans({}, 'FOSUserBundle') }}" />
</div>
</form>
14 - Surcharge des vues du controller Security (login utilisateur) du bundle SonataUserBundle
On va créer dans notre UserBundle les vues qui vont permettre le process d'inscription d'un nouvel utilisateur depuis la partie publique du site :
scr/BlogTest/UserBundle/Resources/views/ Security/ login.html.twig
Création de la vue login :
nano src/BlogTest/UserBundle/Resources/views/Security/login.html.twig
{% extends 'BlogTestUserBundle::layout.html.twig' %}
{% block body %}
<div class="row">
<div class="col-md-6">
<div class="panel panel-info">
<div class="panel-heading">
<h2 class="panel-title">{{ 'title_user_authentication'|trans({}, 'SonataUserBundle') }}</h2>
</div>
<div class="panel-body">
{% if error %}
<div class="alert alert-danger alert-error">{{ error|trans({}, 'FOSUserBundle') }}</div>
{% endif %}
<form action="{{ path("fos_user_security_check") }}" method="post" role="form"
class="form-horizontal">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
<div class="form-group">
<label for="username"
class="col-lg-3 col-sm-3 control-label">{{ 'security.login.username'|trans({}, 'FOSUserBundle') }}</label>
<div class="col-lg-9 col-sm-9"><input type="text" class="form-control" id="username"
name="_username" value="{{ last_username }}"
required="required"/></div>
</div>
<div class="form-group control-group">
<label for="password"
class="col-lg-3 col-sm-3 control-label">{{ 'security.login.password'|trans({}, 'FOSUserBundle') }}</label>
<div class="col-lg-9 col-sm-9"><input type="password" class="form-control" id="password"
name="_password" required="required"/></div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<div class="checkbox control-group">
<label for="remember_me">
<input type="checkbox" id="remember_me" name="_remember_me" value="on"/>
{{ 'security.login.remember_me'|trans({}, 'FOSUserBundle') }}
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<input type="submit" id="_submit" name="_submit" class="btn btn-primary"
value="{{ 'security.login.submit'|trans({}, 'FOSUserBundle') }}"/>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<a href="{{ path('fos_user_resetting_request') }}">
<strong>Reset password</strong>
</a>
{% endblock %}
15 - Test des fonctionnalités mon compte
On va pouvoir tester nos fonctionnalités.
Grace à l'application mailcatcher il va nous être possible d'intercepter les mails sans passer par un smtp externe.
Dans le fichier app/config/parameters.yml, modifier le mailer_host comme suit :
mailer_host: 'localhost:1025'