Ustvarjamo kontaktni obrazec
Pogledali si bomo, kako v Nette ustvariti kontaktni obrazec, vključno s pošiljanjem na e-pošto. Pa začnimo!
Najprej moramo ustvariti nov projekt. Kako to storiti, pojasnjuje stran Začenjamo. Nato pa lahko že začnemo z ustvarjanjem obrazca.
Najenostavneje je ustvariti obrazec neposredno v presenterju. Lahko
uporabimo vnaprej pripravljen HomePresenter
. Vanjo dodamo komponento contactForm
, ki predstavlja
obrazec. To storimo tako, da v kodo zapišemo tovarniško metodo createComponentContactForm()
, ki bo komponento
izdelala:
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
class HomePresenter extends Presenter
{
protected function createComponentContactForm(): Form
{
$form = new Form;
$form->addText('name', 'Ime:')
->setRequired('Vnesite ime');
$form->addEmail('email', 'E-pošta:')
->setRequired('Vnesite e-pošto');
$form->addTextarea('message', 'Sporočilo:')
->setRequired('Vnesite sporočilo');
$form->addSubmit('send', 'Pošlji');
$form->onSuccess[] = [$this, 'contactFormSucceeded'];
return $form;
}
public function contactFormSucceeded(Form $form, stdClass $data): void
{
// pošiljanje e-pošte
}
}
Kot vidite, smo ustvarili dve metodi. Prva metoda createComponentContactForm()
ustvari nov obrazec. Ta ima polja
za ime, e-pošto in sporočilo, ki jih dodajamo z metodami addText()
, addEmail()
in
addTextArea()
. Dodali smo tudi gumb za pošiljanje obrazca. Kaj pa, če uporabnik ne izpolni katerega od polj?
V takem primeru bi mu morali sporočiti, da je to obvezno polje. To smo dosegli z metodo setRequired()
. Na koncu
smo dodali tudi dogodek onSuccess
, ki se sproži, če je
obrazec uspešno poslan. V našem primeru pokliče metodo contactFormSucceeded
, ki poskrbi za obdelavo poslanega
obrazca. To bomo v kodo dodali čez trenutek.
Komponento contactForm
bomo pustili izrisati v predlogi Home/default.latte
:
{block content}
<h1>Kontaktni obrazec</h1>
{control contactForm}
Za samo pošiljanje e-pošte bomo ustvarili nov razred, ki ga bomo poimenovali ContactFacade
in ga postavili
v datoteko 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') // vaša e-pošta
->setFrom($email, $name)
->setSubject('Sporočilo iz kontaktnega obrazca')
->setBody($message);
$this->mailer->send($mail);
}
}
Metoda sendMessage()
ustvari in pošlje e-pošto. Za to uporablja t.i. mailer, ki si ga pusti posredovati kot
odvisnost prek konstruktorja. Preberite več o pošiljanju e-pošte.
Zdaj se vrnemo nazaj k presenterju in dokončamo metodo contactFormSucceeded()
. Ta pokliče metodo
sendMessage()
razreda ContactFacade
in ji posreduje podatke iz obrazca. In kako pridobimo objekt
ContactFacade
? Pustimo si ga posredovati s konstruktorjem:
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('Sporočilo je bilo poslano');
$this->redirect('this');
}
}
Ko je e-pošta poslana, uporabniku prikažemo še t.i. flash sporočilo, ki potrjuje, da je bilo sporočilo poslano, nato pa preusmerimo na naslednjo stran, da obrazca ni mogoče ponovno poslati s pomočjo refresh v brskalniku.
Tako, in če vse deluje, bi morali biti sposobni poslati e-pošto iz vašega kontaktnega obrazca. Čestitam!
HTML predloga e-pošte
Zaenkrat se pošilja navadno besedilno e-sporočilo, ki vsebuje samo sporočilo, poslano z obrazcem. V e-pošti pa lahko
uporabimo HTML in naredimo njen videz privlačnejši. Zanjo bomo ustvarili predlogo v Latte, ki jo bomo zapisali v
app/Model/contactEmail.latte
:
<html>
<title>Sporočilo iz kontaktnega obrazca</title>
<body>
<p><strong>Ime:</strong> {$name}</p>
<p><strong>E-pošta:</strong> {$email}</p>
<p><strong>Sporočilo:</strong> {$message}</p>
</body>
</html>
Ostane še prilagoditi ContactFacade
, da bo uporabljal to predlogo. V konstruktorju bomo zahtevali razred
LatteFactory
, ki zna izdelati objekt Latte\Engine
, torej izrisovalnik Latte predlog. S pomočjo metode
renderToString()
bomo predlogo izrisali v datoteko, prvi parameter je pot do predloge, drugi pa so
spremenljivke.
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') // vaša e-pošta
->setFrom($email, $name)
->setHtmlBody($body);
$this->mailer->send($mail);
}
}
Generirano HTML e-pošto nato posredujemo metodi setHtmlBody()
namesto prvotni setBody()
. Prav tako
nam ni treba navajati zadeve e-pošte v setSubject()
, ker si jo bo knjižnica vzela iz elementa
<title>
predloge.
Konfiguracija
V kodi razreda ContactFacade
je še vedno trdo kodiran naš administratorski e-naslov
admin@example.com
. Bolje bi bilo, da ga premaknemo v konfiguracijsko datoteko. Kako to storiti?
Najprej prilagodimo razred ContactFacade
in niz z e-pošto nadomestimo s spremenljivko, posredovano
s konstruktorjem:
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);
// ...
}
}
Drugi korak pa je navedba vrednosti te spremenljivke v konfiguraciji. V datoteko app/config/services.neon
zapišemo:
services:
- App\Model\ContactFacade(adminEmail: admin@example.com)
In to je to. Če bi bilo elementov v odseku services
veliko in bi imeli občutek, da se e-pošta med njimi
izgublja, jo lahko naredimo za spremenljivko. Prilagodimo zapis na:
services:
- App\Model\ContactFacade(adminEmail: %adminEmail%)
In v datoteki app/config/common.neon
definiramo to spremenljivko:
parameters:
adminEmail: admin@example.com
In končano!