Nette Documentation Preview

syntax
Nette Mail
**********

<div class=perex>

Ö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

</div>


Kurulum
=======

Kütüphaneyi [Composer|best-practices:composer] aracını kullanarak indirip kurun:

```shell
composer require nette/mail
```


E-posta Oluşturma
=================

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

```php
$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:

```php
$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:

```php
$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:

```php
// /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?

.[tip]
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.

```php
// /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|latte:] şablonlama sisteminde yazmak doğaldır. Nasıl yapılır?

```php
$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ı:

```latte
<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 |dependency-injection:passing-dependencies] kullanarak iletilmesini isteyerek erişebilirsiniz:

```php
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.

```latte
<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. [api:Nette\Mail\Mailer] arayüzünü uygular ve tanıtacağımız birkaç önceden hazırlanmış mailer mevcuttur.

Framework, [yapılandırmaya |#Yapılandırma] dayalı olarak oluşturulan `Nette\Mail\Mailer` türünde bir hizmeti DI konteynerine otomatik olarak ekler ve buna [bağımlılık enjeksiyonu |dependency-injection:passing-dependencies] kullanarak iletilmesini isteyerek erişebilirsiniz.


SendmailMailer
--------------

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

```php
$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.

```php
$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":https://www.php.net/manual/en/context.ssl.php 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.

```php
$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 |#Yapılandırma] ayarlayabilirsiniz. Bağımlılık enjeksiyonu kullanmıyorsanız, bu şekilde kullanılır:

```php
$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 |bootstrap:] 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:

```neon
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":https://www.php.net/manual/en/openssl.configuration.php.

Güvenilirliği artırmak için e-postaları [DKIM teknolojisi |https://blog.nette.org/tr/sign-emails-with-dkim] kullanarak imzalayabiliriz:

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


DI Hizmetleri
=============

Bu hizmetler DI konteynerine eklenir:

| Ad            | Tip                       | Açıklama
|-----------------------------------------------------
| `mail.mailer`	  | [api:Nette\Mail\Mailer]   | [e-postaları gönderen sınıf |#E-posta Gönderme]
| `mail.signer`	  | [api:Nette\Mail\Signer]   | [DKIM imzalama |#DKIM]


{{leftbar: nette:@menu-topics}}

Nette Mail

Ö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, yapılandırmaya 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 Tip Açıklama
mail.mailer Nette\Mail\Mailer e-postaları gönderen sınıf
mail.signer Nette\Mail\Signer DKIM imzalama