Créons un formulaire de contact
Voyons comment créer un formulaire de contact dans Nette, y compris l'envoi vers un e-mail. C'est parti !
Tout d'abord, nous devons créer un nouveau projet. Comme l'explique la page " Getting Started". Ensuite, nous pouvons commencer à créer le formulaire.
La manière la plus simple est de créer le formulaire directement dans
Presenter. Nous pouvons utiliser le formulaire préétabli HomePresenter
. Nous ajouterons le composant
contactForm
représentant le formulaire. Pour ce faire, nous écrivons la méthode d'usine
createComponentContactForm()
dans le code qui produira le composant :
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
class HomePresenter extends Presenter
{
protected function createComponentContactForm(): Form
{
$form = new Form;
$form->addText('name', 'Name:')
->setRequired('Enter your name');
$form->addEmail('email', 'E-mail:')
->setRequired('Enter your e-mail');
$form->addTextarea('message', 'Message:')
->setRequired('Enter message');
$form->addSubmit('send', 'Send');
$form->onSuccess[] = [$this, 'contactFormSucceeded'];
return $form;
}
public function contactFormSucceeded(Form $form, $data): void
{
// sending an email
}
}
Comme vous pouvez le voir, nous avons créé deux méthodes. La première méthode createComponentContactForm()
crée un nouveau formulaire. Celui-ci comporte des champs pour le nom, l'adresse électronique et le message, que nous ajoutons à
l'aide des méthodes addText()
, addEmail()
et addTextArea()
. Nous avons également ajouté
un bouton pour soumettre le formulaire. Mais que se passe-t-il si l'utilisateur ne remplit pas certains champs ? Dans ce cas, nous
devons l'informer qu'il s'agit d'un champ obligatoire. C'est ce que nous avons fait avec la méthode setRequired()
.
Enfin, nous avons également ajouté un événement
onSuccess
, qui est déclenché si le formulaire est soumis avec succès. Dans notre cas, il appelle la méthode
contactFormSucceeded
, qui se charge de traiter le formulaire soumis. Nous l'ajouterons au code dans un instant.
Laissez le composant contantForm
être rendu dans le modèle Home/default.latte
:
{block content}
<h1>Contant Form</h1>
{control contactForm}
Pour envoyer le courrier électronique lui-même, nous créons une nouvelle classe appelée ContactFacade
et la
plaçons dans le fichier app/Model/ContactFacade.php
:
<?php
declare(strict_types=1);
namespace App\Model;
use Nette\Mail\Mailer;
use Nette\Mail\Message;
class ContactFacade
{
public function __construct(
private Mailer $mailer,
) {
}
public function sendMessage(string $email, string $name, string $message): void
{
$mail = new Message;
$mail->addTo('admin@example.com') // your email
->setFrom($email, $name)
->setSubject('Message from the contact form')
->setBody($message);
$this->mailer->send($mail);
}
}
La méthode sendMessage()
créera et enverra le courrier électronique. Pour ce faire, elle utilise ce que l'on
appelle un „mailer“, qu'elle transmet en tant que dépendance via le constructeur. En savoir plus sur l'envoi de courriels.
Nous allons maintenant retourner au présentateur et compléter la méthode contactFormSucceeded()
. Elle appelle
la méthode sendMessage()
de la classe ContactFacade
et lui transmet les données du formulaire. Et
comment obtenir l'objet ContactFacade
? Il nous sera transmis par le constructeur :
use App\Model\ContactFacade;
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
class HomePresenter extends Presenter
{
public function __construct(
private ContactFacade $facade,
) {
}
protected function createComponentContactForm(): Form
{
// ...
}
public function contactFormSucceeded(stdClass $data): void
{
$this->facade->sendMessage($data->email, $data->name, $data->message);
$this->flashMessage('The message has been sent');
$this->redirect('this');
}
}
Après l'envoi du courrier électronique, nous montrons à l'utilisateur le " message flash", qui confirme que le message a été envoyé, puis nous le redirigeons vers la page suivante, de sorte que le formulaire ne puisse pas être soumis à nouveau en utilisant la fonction refresh du navigateur.
Si tout fonctionne, vous devriez être en mesure d'envoyer un courriel à partir de votre formulaire de contact. Nous vous félicitons !
Modèle d'e-mail HTML
Pour l'instant, un courriel en texte brut contenant uniquement le message envoyé par le formulaire est envoyé. Mais nous
pouvons utiliser le HTML dans l'e-mail et le rendre plus attrayant. Nous allons créer un modèle dans Latte, que nous
enregistrerons dans app/Model/contactEmail.latte
:
<html>
<title>Message from the contact form</title>
<body>
<p><strong>Name:</strong> {$name}</p>
<p><strong>E-mail:</strong> {$email}</p>
<p><strong>Message:</strong> {$message}</p>
</body>
</html>
Il reste à modifier ContactFacade
pour utiliser ce modèle. Dans le constructeur, nous demandons la classe
LatteFactory
, qui peut produire l'objet Latte\Engine
, un moteur de rendu de modèle Latte. Nous utilisons la
méthode renderToString()
pour rendre le modèle dans un fichier, le premier paramètre étant le chemin vers le
modèle et le second les variables.
namespace App\Model;
use Nette\Bridges\ApplicationLatte\LatteFactory;
use Nette\Mail\Mailer;
use Nette\Mail\Message;
class ContactFacade
{
public function __construct(
private Mailer $mailer,
private LatteFactory $latteFactory,
) {
}
public function sendMessage(string $email, string $name, string $message): void
{
$latte = $this->latteFactory->create();
$body = $latte->renderToString(__DIR__ . '/contactEmail.latte', [
'email' => $email,
'name' => $name,
'message' => $message,
]);
$mail = new Message;
$mail->addTo('admin@example.com') // your email
->setFrom($email, $name)
->setHtmlBody($body);
$this->mailer->send($mail);
}
}
Nous passons ensuite l'e-mail HTML généré à la méthode setHtmlBody()
au lieu de l'original
setBody()
. Nous n'avons pas non plus besoin de spécifier le sujet de l'e-mail dans setSubject()
, car la
bibliothèque l'extrait de l'élément <title>
dans le modèle.
Configuration de
Dans le code de la classe ContactFacade
, notre email d'administration admin@example.com
est encore
codé en dur. Il serait préférable de la déplacer dans le fichier de configuration. Comment faire ?
Tout d'abord, nous modifions la classe ContactFacade
et remplaçons la chaîne de l'email par une variable passée
par le constructeur :
class ContactFacade
{
public function __construct(
private Mailer $mailer,
private LatteFactory $latteFactory,
private string $adminEmail,
) {
}
public function sendMessage(string $email, string $name, string $message): void
{
// ...
$mail = new Message;
$mail->addTo($this->adminEmail)
->setFrom($email, $name)
->setHtmlBody($body);
// ...
}
}
Et la deuxième étape consiste à mettre la valeur de cette variable dans la configuration. Dans le fichier
app/config/services.neon
nous ajoutons :
services:
- App\Model\ContactFacade(adminEmail: admin@example.com)
Et c'est tout. S'il y a beaucoup d'éléments dans la section services
et que vous avez l'impression que le
courriel se perd parmi eux, nous pouvons en faire une variable. Nous modifierons l'entrée en :
services:
- App\Model\ContactFacade(adminEmail: %adminEmail%)
et définir cette variable dans le fichier app/config/common.neon
:
parameters:
adminEmail: admin@example.com
Et c'est fait !