Mail

Gönderme
E-postalar

E-posta Gönderme

Örneğin bültenler veya sipariş onayları gibi e-postalar göndermek mi istiyorsunuz? Nette Framework, çok hoş bir API ile gerekli araçları sağlar. Göstereceğiz:

  • ekler dahil e-posta nasıl oluşturulur
  • nasıl gönderilir
  • e-postalar ve şablonlar nasıl birleştirilir

Kurulum

Kütüphaneyi Composer aracını kullanarak indirip kurun:

composer require nette/mail

E-posta Oluşturma

E-posta, Nette\Mail\Message sınıfının bir nesnesidir. Örneğin şöyle oluşturalım:

$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
	->addTo('petr@example.com')
	->addTo('jirka@example.com')
	->setSubject('Sipariş Onayı')
	->setBody("Merhaba,\nsiparişiniz alındı.");

Girilen tüm parametreler UTF-8 olmalıdır.

Alıcıyı addTo() metoduyla belirtmenin yanı sıra, kopya alıcısını addCc() veya gizli kopya alıcısını addBcc() ile de belirtebilirsiniz. setFrom() dahil tüm bu metotlarda, alıcıyı üç şekilde yazabiliriz:

$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');

HTML olarak yazılan e-posta gövdesi setHtmlBody() metoduyla iletilir:

$mail->setHtmlBody('<p>Merhaba,</p><p>siparişiniz alındı.</p>');

Metin alternatifini oluşturmanıza gerek yok, Nette sizin için otomatik olarak oluşturacaktır. Ve e-postanın bir konusu yoksa, onu <title> öğesinden almaya çalışacaktır.

HTML gövdesine resim eklemek de son derece kolaydır. İkinci parametre olarak resimlerin fiziksel olarak bulunduğu yolu iletmeniz yeterlidir ve Nette bunları otomatik olarak e-postaya dahil edecektir:

// /path/to/images/background.gif dosyasını otomatik olarak e-postaya ekler
$mail->setHtmlBody(
	'<b>Merhaba</b> <img src="background.gif">',
	'/path/to/images',
);

Resimleri ekleyen algoritma şu kalıpları arar: <img src=...>, <body background=...>, HTML style niteliği içindeki url(...) ve özel sözdizimi [[...]].

E-posta göndermek daha kolay olabilir mi?

E-posta bir kartpostal gibidir. Asla e-posta ile şifre veya diğer erişim bilgilerini göndermeyin.

Ekler

Elbette e-postaya ekler eklenebilir. Bunun için addAttachment(string $file, ?string $content = null, ?string $contentType = null) metodu kullanılır.

// /path/to/example.zip dosyasını example.zip adıyla e-postaya ekler
$mail->addAttachment('/path/to/example.zip');

// /path/to/example.zip dosyasını info.zip olarak adlandırılmış şekilde e-postaya ekler
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));

// "Merhaba John!" içeriğiyle example.txt dosyasını e-postaya ekler
$mail->addAttachment('example.txt', 'Merhaba John!');

Şablonlar

HTML e-postaları gönderiyorsanız, bunları Latte şablonlama sisteminde yazmak doğaldır. Nasıl yapılır?

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

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

email.latte dosyası:

<html>
<head>
	<meta charset="utf-8">
	<title>Sipariş Onayı</title>
	<style>
	body {
		background: url("background.png")
	}
	</style>
</head>
<body>
	<p>Merhaba,</p>

	<p>Sipariş numaranız {$orderId} alındı.</p>
</body>
</html>

Nette tüm resimleri otomatik olarak ekler, konuyu <title> öğesine göre ayarlar ve HTML'ye bir metin alternatifi oluşturur.

Nette Uygulamasında Kullanım

E-postaları Nette Uygulaması ile birlikte, yani presenter'larla kullanıyorsanız, şablonlarda n:href niteliği veya {link} etiketi kullanarak bağlantılar oluşturmak isteyebilirsiniz. Latte bunları varsayılan olarak bilmez, ancak eklemek çok kolaydır. Bağlantıları oluşturabilen nesne Nette\Application\LinkGenerator'dır, buna bağımlılık enjeksiyonu kullanarak iletilmesini isteyerek erişebilirsiniz:

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;
	}
}

Şablonda daha sonra bağlantıları alıştığımız gibi oluştururuz. LinkGenerator aracılığıyla oluşturulan tüm bağlantılar mutlak olacaktır.

<a n:href="Presenter:action">Bağlantı</a>

E-posta Gönderme

Mailer, e-postaların gönderilmesini sağlayan bir sınıftır. Nette\Mail\Mailer arayüzünü uygular ve tanıtacağımız birkaç önceden hazırlanmış mailer mevcuttur.

Framework, #configuration dayalı olarak oluşturulan Nette\Mail\Mailer türünde bir hizmeti DI konteynerine otomatik olarak ekler ve buna bağımlılık enjeksiyonu kullanarak iletilmesini isteyerek erişebilirsiniz.

SendmailMailer

Varsayılan mailer, PHP mail fonksiyonunu kullanan SendmailMailer'dır. Kullanım örneği:

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

returnPath'i ayarlamak istiyorsanız ve sunucunuz onu sürekli olarak üzerine yazıyorsa, $mailer->commandArgs = '-fMuj@email.cz' kullanın.

SmtpMailer

Postayı bir SMTP sunucusu üzerinden göndermek için SmtpMailer kullanılır.

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

Yapıcıya şu ek parametreler iletilebilir:

  • port – ayarlanmazsa, ssl için varsayılan 25 veya 465 kullanılır
  • timeout – SMTP bağlantısı için zaman aşımı
  • persistent – kalıcı bağlantı kullan
  • clientHost – istemci Host başlığını ayarla
  • streamOptions – bağlantı için SSL context options ayarlamanıza olanak tanır

FallbackMailer

E-postaları doğrudan göndermez, ancak bir dizi mailer aracılığıyla göndermeyi aracılık eder. Bir mailer başarısız olursa, bir sonrakiyle denemeyi tekrarlar. Sonuncusu da başarısız olursa, baştan tekrar başlar.

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

Yapıcıda ek parametreler olarak tekrar deneme sayısını ve milisaniye cinsinden bekleme süresini belirtebiliriz.

DKIM

DKIM (DomainKeys Identified Mail), sahte mesajların tespit edilmesine de yardımcı olan e-postaların güvenilirliğini artırmaya yönelik bir teknolojidir. Gönderilen mesaj, gönderenin alan adının özel anahtarıyla imzalanır ve bu imza e-posta başlığında saklanır. Alıcı sunucu, bu imzayı alan adının DNS kayıtlarında saklanan genel anahtarla karşılaştırır. İmzanın eşleşmesiyle, e-postanın gerçekten gönderenin alan adından geldiği ve mesajın iletimi sırasında değiştirilmediği kanıtlanır.

E-postaların imzalanmasını mailer'a doğrudan yapılandırmada ayarlayabilirsiniz. Bağımlılık enjeksiyonu kullanmıyorsanız, bu şekilde kullanılır:

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

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

Yapılandırma

Nette Mail için yapılandırma seçeneklerine genel bakış. Tüm framework'ü değil, yalnızca bu kütüphaneyi kullanıyorsanız, yapılandırmanın nasıl yükleneceğini okuyun.

E-postaları göndermek için varsayılan olarak Nette\Mail\SendmailMailer mailer'ı kullanılır ve bu daha fazla yapılandırılmaz. Ancak, onu Nette\Mail\SmtpMailer olarak değiştirebiliriz:

mail:
	# SmtpMailer kullanır
	smtp: true       # (bool) varsayılan false'dur

	host: ...        # (string)
	port: ...        # (int)
	username: ...    # (string)
	password: ...    # (string)
	timeout: ...     # (int)
	encryption: ...  # (ssl|tls|null) varsayılan null'dur ('secure' takma adı vardır)
	clientHost: ...  # (string) varsayılan $_SERVER['HTTP_HOST']'dur
	persistent: ...  # (bool) varsayılan false'dur

	# SMTP sunucusuna bağlanmak için bağlam, varsayılan stream_context_get_default()'dur
	context:
		ssl:         # seçeneklerin özeti https://www.php.net/manual/en/context.ssl.php adresinde
			allow_self_signed: ...
			...
		http:        # seçeneklerin özeti https://www.php.net/manual/en/context.http.php adresinde
			header: ...
			...

context › ssl › verify_peer: false seçeneği ile SSL sertifika doğrulamasını kapatabilirsiniz. Kesinlikle tavsiye etmiyoruz bunu yapmanızı, çünkü uygulama savunmasız hale gelir. Bunun yerine sertifikaları depoya ekleyin.

Güvenilirliği artırmak için e-postaları DKIM teknolojisi kullanarak imzalayabiliriz:

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

DI Hizmetleri

Bu hizmetler DI konteynerine eklenir:

Ad Tür Açıklama
mail.mailer Nette\Mail\Mailer e-postaları gönderen sınıf
mail.signer Nette\Mail\Signer DKIM imzalama
versiyon: 4.0