You are browsing the unmaintained documentation for old Nette 2.3. See documentation for current Nette.

Sending E-mails

Almost every web application needs to send e-mails, whether it's newsletter or order confirmation. That's why Nette Framework provides necessary tools. This tutorial will show you how to:

  • create e-mail
  • send it
  • add attachments
  • use templates in e-mails
  • create links

Never send passwords or any other login credentials by e-mail.

Example of creating an e-mail using Nette\Mail\Message class:

use Nette\Mail\Message;

$mail = new 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.");

All parameters must be encoded in UTF-8.

And sending:

use Nette\Mail\SendmailMailer;

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

In presenters and services we don't create mailer manually, but we will require the service of type Nette\Mail\IMailer using DI.

In addition to specifying recipient with addTo(), it's possible to specify recipient of copy with addCc() and recipient of blind copy: addBcc(). In all these methods, including setFrom(), we can specify addressee in three ways:

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

HTML content can be defined using setHtmlBody() method:

$mail->setHTMLBody('<b>Sample HTML</b> <img src="background.gif">');

Embedded images can be inserted using $mail->addEmbeddedFile('background.gif'), but it is not necessary. Why? Because Nette Framework finds and inserts all files referenced in the HTML code automatically. This behavior can be supressed by adding FALSE as a second parameter of the setHtmlBody() method.

If a HTML e-mail has no plain-text alternative, it will be automatically generated. And if it has no subject set, it will be taken from the <title> element.

Attachments

Adding attachments to the e-mail is simple. In order to attach a file, we use addAttachment method:

// attaches example.zip to the e-mail
$mail->addAttachment('path/to/example.zip');

// attaches new example.txt file with "Hello John!" in it
$mail->addAttachment('example.txt', 'Hello John!');

// attaches example.zip renamed to info.zip
$mail->addAttachment('info.zip', file_get_contents('path/to/example.zip'));

Templates

The real power comes in combination with Latte templating system:

$latte = new Latte\Engine;
$params = array(
    'orderId' => 123,
);

$mail = new Message;
$mail->setFrom('John <john@example.com>')
    ->addTo('jack@example.com')
    ->setHtmlBody($latte->renderToString('email.latte', $params));

File email.latte:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; 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>

The Latte Engine itself doesn't provide {link} macro. If we want to use it though, we can use a presenter or a component to create the template for us by calling $template = $this->createTemplate()->setFile('email.latte') and adding it in setHtmlBody(). This way, we are able to create links in the template.

use Nette;

class MyPresenter
{
    public function actionFoo()
    {
        $template = $this->createTemplate()->setFile('email.latte');
        $mail = new Message();
        $mail->setHtmlBody($template);
    }
}

Another option is to register the macro ourselves. Because a presenter is needed for generating links, we pass it as a parameter to the template:

use Nette;
use Nette\Bridges\ApplicationLatte\UIMacros;

function createMessage(Nette\Application\Application $application)

    /** @var Nette\Application\IPresenter */
    $presenter = $application->getPresenter();

    $latte = new Latte\Engine;
    $params = array(
        'orderId' => 123,
        '_presenter' => $presenter, // because of {plink}
        '_control' => $presenter    // because of {link}
    );

    UIMacros::install($latte->getCompiler()); // This registers macros link, plink and others

    // ...
}

In the template, link is created like in a normal template. We use absolute address, so the link always points to the correct domain:

<a href="{link //Presenter:action}">Odkaz</a>

Custom mailer

Default mailer uses PHP function mail. If you need to send mail through a SMTP server, you can use SmtpMailer.

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

You can also create your own mailer – it's a class implementing Nette\Mail\IMailer interface.