Hozzunk létre egy kapcsolatfelvételi űrlapot
Nézzük meg, hogyan hozhatunk létre egy kapcsolatfelvételi űrlapot a Nette-ben, beleértve annak e-mailben történő elküldését is. Akkor csináljuk!
Először is létre kell hoznunk egy új projektet. Ahogy a Kezdő lépések oldal elmagyarázza. Ezután pedig elkezdhetjük létrehozni az űrlapot.
A legegyszerűbb, ha közvetlenül a Presenterben hozzuk létre az
űrlapot. Használhatjuk az előre elkészített
HomePresenter
. Hozzáadjuk az űrlapot reprezentáló contactForm
komponenst. Ezt úgy tesszük, hogy a
createComponentContactForm()
gyári metódust írjuk be a komponens előállítását végző kódba:
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
}
}
Mint látható, két metódust hoztunk létre. Az első metódus createComponentContactForm()
létrehoz egy új
űrlapot. Ez rendelkezik a név, az e-mail és az üzenet mezőivel, amelyeket a addText()
, addEmail()
és addTextArea()
metódusokkal adunk hozzá. Hozzáadtunk egy gombot is az űrlap elküldéséhez. De mi van akkor,
ha a felhasználó nem tölt ki néhány mezőt? Ebben az esetben tudatnunk kell vele, hogy az adott mező kötelezően
kitöltendő. Ezt a setRequired()
metódussal tettük meg. Végül hozzáadtunk egy onSuccess
eseményt is, amely akkor lép működésbe, ha az űrlapot sikeresen
elküldtük. A mi esetünkben meghívja a contactFormSucceeded
metódust , amely a beküldött űrlap
feldolgozásáról gondoskodik. Ezt is hozzáadjuk a kódhoz egy pillanat múlva.
Legyen a contantForm
komponens megjelenítve a Home/default.latte
sablonban:
{block content}
<h1>Contant Form</h1>
{control contactForm}
Magához az e-mail elküldéséhez hozzunk létre egy új osztályt ContactFacade
néven, és helyezzük el a
app/Model/ContactFacade.php
fájlban:
<?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);
}
}
A sendMessage()
metódus fogja létrehozni és elküldeni az e-mailt. Ehhez egy úgynevezett mailert használ,
amelyet függőségként ad át a konstruktoron keresztül. Olvasson többet az e-mailek
küldéséről.
Most visszamegyünk a prezenterhez, és befejezzük a contactFormSucceeded()
metódust. Meghívja a
ContactFacade
osztály sendMessage()
metódusát, és átadja neki az űrlap adatait. És hogyan kapjuk
meg a ContactFacade
objektumot ? A konstruktor fogja átadni nekünk:
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');
}
}
Az e-mail elküldése után megjelenítjük a felhasználónak az úgynevezett flash üzenetet, amely megerősíti, hogy az üzenet elküldésre került, majd átirányítjuk a következő oldalra, hogy az űrlapot ne lehessen újra elküldeni a böngésző frissítésével.
Nos, ha minden működik, akkor a kapcsolatfelvételi űrlapról már tudsz e-mailt küldeni. Gratulálunk!
HTML e-mail sablon
Egyelőre egy egyszerű szöveges e-mailt küldünk, amely csak az űrlap által küldött üzenetet tartalmazza. De
használhatunk HTML-t az e-mailben, és vonzóbbá tehetjük azt. Létrehozunk hozzá egy sablont a Latte-ban, amelyet a
app/Model/contactEmail.latte
címre mentünk el:
<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>
Már csak a ContactFacade
-t kell módosítani, hogy ezt a sablont használhassuk. A konstruktorban kérjük a
LatteFactory
osztályt, amely képes előállítani a Latte\Engine
objektumot, egy Latte sablon renderelőt. A
renderToString()
metódust használjuk a sablon renderelésére egy fájlba, az első paraméter a sablon elérési
útvonala, a második pedig a változók.
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);
}
}
Ezután a generált HTML e-mailt átadjuk a setHtmlBody()
metódusnak az eredeti setBody()
helyett.
Az e-mail tárgyát sem kell megadnunk a setSubject()
metódusban, mert a könyvtár azt az elemből veszi át.
<title>
sablonból veszi át.
A konfigurálása
A ContactFacade
osztály kódjában az admin e-mail címünk, a admin@example.com
még mindig
keményen kódolva van. Jobb lenne, ha áthelyeznénk a konfigurációs fájlba. Hogyan kell ezt megtenni?
Először is módosítjuk a ContactFacade
osztályt, és az email karakterláncot a konstruktor által átadott
változóval helyettesítjük:
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);
// ...
}
}
A második lépés pedig az, hogy ennek a változónak az értékét a konfigurációba helyezzük. A
app/config/services.neon
fájlban hozzáadjuk:
services:
- App\Model\ContactFacade(adminEmail: admin@example.com)
És ennyi. Ha sok elem van a services
részben, és úgy érezzük, hogy az e-mail elveszik közöttük, akkor
változtathatóvá tehetjük. Módosítjuk a bejegyzést:
services:
- App\Model\ContactFacade(adminEmail: %adminEmail%)
És definiáljuk ezt a változót a app/config/common.neon
fájlban:
parameters:
adminEmail: admin@example.com
És kész!