Pošta

Pošiljanje
E-pošta

Pošiljanje e-poštnih sporočil

Ali boste pošiljali e-poštna sporočila, kot so glasila ali potrditve naročil? Nette Framework zagotavlja potrebna orodja z zelo dobrim vmesnikom API. Prikazali bomo:

  • kako ustvariti e-poštno sporočilo, vključno s priponkami
  • kako ga poslati
  • kako združiti e-poštna sporočila in predloge

Namestitev

Prenesite in namestite paket s programom Composer:

composer require nette/mail

Ustvarjanje e-poštnih sporočil

E-pošta je objekt Nette\Mail\Message:

$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
	->addTo('peter@example.com')
	->addTo('jack@example.com')
	->setSubject('Order Confirmation')
	->setBody("Hello, Your order has been accepted.");

Vsi parametri morajo biti kodirani v UTF-8.

Poleg določitve prejemnikov z metodo addTo() lahko določite tudi prejemnika kopije z metodo addCc() ali prejemnika slepe kopije z metodo addBcc(). Vse te metode, vključno s setFrom(), sprejemajo naslovnika na tri načine:

$mail->setFrom('john.doe@example.com');
$mail->setFrom('john.doe@example.com', 'John Doe');
$mail->setFrom('John Doe <john.doe@example.com>');

Telo elektronskega sporočila, napisanega v jeziku HTML, se posreduje z metodo setHtmlBody():

$mail->setHtmlBody('<p>Hello,</p><p>Your order has been accepted.</p>');

Ni vam treba ustvariti alternativnega besedila, Nette ga bo ustvaril samodejno namesto vas. In če e-poštno sporočilo nima nastavljenega predmeta, bo ta prevzet iz <title> elementa.

Slike lahko tudi izjemno enostavno vstavite v telo HTML elektronskega sporočila. Samo kot drugi parameter podajte pot, kjer se slike fizično nahajajo, in Nette jih bo samodejno vključil v e-poštno sporočilo:

// samodejno doda /path/to/images/background.gif v e-pošto
$mail->setHtmlBody(
	'<b>Hello</b> <img src="background.gif">',
	'/path/to/images',
);

Algoritem za vstavljanje slik podpira naslednje vzorce: <img src=...>, <body background=...>, url(...) znotraj atributa HTML style in posebno sintakso [[...]].

Ali je lahko pošiljanje e-poštnih sporočil še lažje?

Elektronska sporočila so kot razglednice. Nikoli ne pošiljajte gesel ali drugih poverilnic po e-pošti.

Priponke

Elektronskemu sporočilu lahko seveda priložite priponke. Uporabite addAttachment(string $file, string $content = null, string $contentType = null).

// vstavi datoteko /path/to/example.zip v e-pošto pod imenom example.zip
$mail->addAttachment('/path/to/example.zip');

// vstavi datoteko /path/to/example.zip v e-pošto pod imenom info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));

// priloži novo vsebino datoteke example.txt "Hello John!"
$mail->addAttachment('example.txt', 'Hello John!');

Predloge

Če pošiljate e-poštna sporočila HTML, jih je dobro napisati v sistemu predlog Latte. Kako to storite?

$latte = new Latte\Engine;
$params = [
	'orderId' => 123,
];

$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
	->addTo('jack@example.com')
	->setHtmlBody(
		$latte->renderToString('/path/to/email.latte', $params),
		'/path/to/images',
	);

Datoteka email.latte:

<html>
<head>
	<meta charset="utf-8">
	<title>Order Confirmation</title>
	<style>
	body {
		background: url("background.png")
	}
	</style>
</head>
<body>
	<p>Hello,</p>

	<p>Your order number {$orderId} has been accepted.</p>
</body>
</html>

Nette samodejno vstavi vse slike, nastavi predmet glede na <title> elementa in ustvari alternativno besedilo za telo HTML.

Uporaba v aplikaciji Nette

Če uporabljate e-pošto skupaj z aplikacijo Nette Application, tj. predavatelji, boste morda želeli ustvariti povezave v predlogah z uporabo atributa n:href ali oznake {link}. Latte jih v osnovi ne pozna, vendar jih je zelo enostavno dodati. Ustvarjanje povezav lahko opravi objekt Nette\Application\LinkGenerator, ki ga dobite s posredovanjem z uporabo vbrizgavanja odvisnosti.

use Nette;

class MailSender
{
	public function __construct(
		private Nette\Application\LinkGenerator $linkGenerator,
		private Nette\Bridges\ApplicationLatte\TemplateFactory $templateFactory,
	) {
	}

	private function createTemplate(): Nette\Application\UI\Template
	{
		$template = $this->templateFactory->createTemplate();
		$template->getLatte()->addProvider('uiControl', $this->linkGenerator);
		return $template;
	}

	public function createEmail(): Nette\Mail\Message
	{
		$template = $this->createTemplate();
		$html = $template->renderToString('/path/to/email.latte', $params);

		$mail = new Nette\Mail\Message;
		$mail->setHtmlBody($html);
		// ...
		return $mail;
	}
}

V predlogi je povezava ustvarjena tako kot v običajni predlogi. Vse povezave, ustvarjene prek LinkGeneratorja, so absolutne:

<a n:href="Presenter:action">Link</a>

Pošiljanje e-pošte

Pošiljatelj je razred, odgovoren za pošiljanje e-pošte. Implementira vmesnik Nette\Mail\Mailer in na voljo je več pripravljenih poštnih pošiljateljev, ki jih bomo predstavili.

Ogrodje samodejno doda storitev Nette\Mail\Mailer na podlagi konfiguracije v vsebnik DI, ki ga dobite s posredovanjem z uporabo vbrizgavanja odvisnosti.

SendmailMailer

Privzeta poštna pošta je SendmailMailer, ki uporablja funkcijo PHP mail. Primer uporabe:

$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);

Če želite nastaviti returnPath in ga strežnik še vedno prepiše, uporabite $mailer->commandArgs = '-fmy@email.com'.

SmtpMailer

Za pošiljanje pošte prek strežnika SMTP uporabite SmtpMailer.

$mailer = new Nette\Mail\SmtpMailer(
	host: 'smtp.gmail.com',
	username: 'franta@gmail.com',
	password: '*****',
	encryption: 'ssl',
);
$mailer->send($mail);

Konstruktorju lahko posredujete naslednje dodatne parametre:

port * Če ni nastavljen, se uporabi privzeta vrednost 25 ali 465 za ssl.

  • timeout – časovna omejitev za povezavo SMTP
  • persistent – uporaba trajne povezave
  • clientHost – oznaka odjemalca
  • streamOptions – omogoča nastavitev možnosti konteksta SSL za povezavo

FallbackMailer

Ne pošilja e-poštnih sporočil, temveč jih pošilja prek niza poštnih pošiljateljev. Če en poštni nabiralnik ne uspe, ponovi poskus pri naslednjem. Če je neuspešen tudi zadnji, začne znova s prvim.

$mailer = new Nette\Mail\FallbackMailer([
	$smtpMailer,
	$backupSmtpMailer,
	$sendmailMailer,
]);
$mailer->send($mail);

Drugi parametri v konstruktorju vključujejo število ponovitev in čakalni čas v milisekundah.

DKIM

DKIM (DomainKeys Identified Mail) je zanesljiva tehnologija elektronske pošte, ki pomaga tudi pri odkrivanju lažnih sporočil. Poslano sporočilo je podpisano z zasebnim ključem pošiljateljeve domene, ta podpis pa je shranjen v glavi e-pošte. Prejemnikov strežnik primerja ta podpis z javnim ključem, shranjenim v zapisih DNS domene. Z ujemanjem podpisa se dokaže, da elektronsko sporočilo dejansko izvira iz pošiljateljeve domene in da med prenosom sporočila ni bilo spremenjeno.

Pošiljatelja lahko za podpisovanje e-pošte nastavite v konfiguraciji. Če ne uporabljate vbrizgavanja odvisnosti, se uporablja na naslednji način:

$signer = new Nette\Mail\DkimSigner(
	domain: 'nette.org',
	selector: 'dkim',
	privateKey: file_get_contents('../dkim/dkim.key'),
	passPhrase: '****',
);

$mailer = new Nette\Mail\SendmailMailer; // ali SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);

Konfiguracija

Pregled možnosti konfiguracije za Nette Mail. Če ne uporabljate celotnega ogrodja, temveč samo to knjižnico, preberite, kako naložiti konfiguracijo.

Privzeto se za pošiljanje e-pošte uporablja poštni program Nette\Mail\SendmailMailer, ki ni dodatno konfiguriran. Vendar ga lahko preklopimo na Nette\Mail\SmtpMailer:

mail:
	# uporaba SmtpMailer
	smtp: true       # (bool) privzeto false

	host: ...        # (niz)
	port: ...        # (int)
	username: ...    # (string)
	password: ...    # (string)
	timeout: ...     # (int)
	encryption: ...  # (ssl|tls|null) privzeta vrednost je nič (ima vzdevek 'secure')
	clientHost: ...  # (string) privzeto je $_SERVER['HTTP_HOST']
	persistent: ...  # (bool) privzeto je false

	# kontekst za povezovanje s strežnikom SMTP, privzeto je stream_context_get_default()
	context:
		ssl:         # vse možnosti na https://www.php.net/manual/en/context.ssl.php
			allow_self_signed: ...
			...
		http:        # vse možnosti na https://www.php.net/manual/en/context.http.php
			header: ...
			...

Preverjanje pristnosti potrdila SSL lahko onemogočite z uporabo možnosti context › ssl › verify_peer: false. To je strogo priporočljivo, da tega ne storite, saj bo aplikacija zaradi tega ranljiva. Namesto tega dodajte potrdila v shrambo zaupanja.

Za povečanje zaupanja lahko elektronska sporočila podpišemo s tehnologijo DKIM:

mail:
	dkim:
		domain: myweb.com
		selector: lovenette
		privateKey: %appDir%/cert/dkim.priv
		passPhrase: ...

Storitve DI

Te storitve so dodane vsebniku DI:

Ime Vrsta Opis
mail.mailer Nette\Mail\Mailer razred za pošiljanje e-pošte
mail.signer Nette\Mail\Signer Podpisovanje DKIM
različica: 4.0