diff --git a/_build/conf.py b/_build/conf.py index ffa92d30604..49cc12581ad 100644 --- a/_build/conf.py +++ b/_build/conf.py @@ -127,7 +127,8 @@ 'rst': 'reStructuredText', 'varnish2': 'Varnish 2', 'varnish3': 'Varnish 3', - 'varnish4': 'Varnish 4' + 'varnish4': 'Varnish 4', + 'env': '.env' } # don't enable Sphinx Domains diff --git a/_build/redirection_map b/_build/redirection_map index 7ca4c8ffead..8b86b9c583f 100644 --- a/_build/redirection_map +++ b/_build/redirection_map @@ -505,3 +505,4 @@ /components/class_loader https://github.com/symfony/class-loader /frontend/encore/versus-assetic /frontend /components/http_client /http_client +/components/mailer /mailer diff --git a/components/mailer.rst b/components/mailer.rst deleted file mode 100644 index 30b8d146ab0..00000000000 --- a/components/mailer.rst +++ /dev/null @@ -1,206 +0,0 @@ -.. index:: - single: Mailer - single: Components; Mailer - -The Mailer Component -==================== - - The Mailer component helps sending emails. - -If you're using the Symfony Framework, read the -:doc:`Symfony Framework Mailer documentation `. - -.. versionadded:: 4.3 - - The Mailer component was introduced in Symfony 4.3. - -Installation ------------- - -.. code-block:: terminal - - $ composer require symfony/mailer - -.. include:: /components/require_autoload.rst.inc - -Usage ------ - -The Mailer component has two main classes: a ``Transport`` and the ``Mailer`` itself:: - - use Symfony\Component\Mailer\Mailer; - use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; - - $transport = new EsmtpTransport('localhost'); - $mailer = new Mailer($transport); - $mailer->send($email); - -The ``$email`` object is created via the :doc:`Mime component `. - -Transport ---------- - -The only transport that comes pre-installed is SMTP. - -Below is the list of other popular providers with built-in support: - -================== ============================================= -Service Install with -================== ============================================= -Amazon SES ``composer require symfony/amazon-mailer`` -Gmail ``composer require symfony/google-mailer`` -MailChimp ``composer require symfony/mailchimp-mailer`` -Mailgun ``composer require symfony/mailgun-mailer`` -Postmark ``composer require symfony/postmark-mailer`` -SendGrid ``composer require symfony/sendgrid-mailer`` -================== ============================================= - -For example, suppose you want to use Google's Gmail SMTP server. First, install -it: - -.. code-block:: terminal - - $ composer require symfony/google-mailer - -Then, use the SMTP Gmail transport:: - - use Symfony\Component\Mailer\Bridge\Google\Transport\GmailSmtpTransport; - use Symfony\Component\Mailer\Mailer; - - $transport = new GmailSmtpTransport('user', 'pass'); - $mailer = new Mailer($transport); - $mailer->send($email); - -Each provider provides up to 3 transports: standard SMTP, HTTP (it uses the -provider's API but the body is created by the mailer component), API (it uses -the full API of the provider with no control over the body creation -- features -might be limited as well). - -.. _mailer_dsn: - -The mailer component provides a convenient way to create a transport from a -DSN:: - - use Symfony\Component\Mailer\Transport; - - $transport = Transport::fromDsn($dsn); - -Where ``$dsn`` depends on the provider you want to use. For plain SMTP, use -``smtp://user:pass@example.com`` or ``sendmail+smtp://default`` to use the -``sendmail`` binary. To disable the transport, use ``null://null``. - -For third-party providers, refer to the following table: - -==================== ========================================== =========================================== ======================================== - Provider SMTP HTTP API -==================== ========================================== =========================================== ======================================== - Amazon SES ses+smtp://ACCESS_KEY:SECRET_KEY@default ses+https://ACCESS_KEY:SECRET_KEY@default ses+api://ACCESS_KEY:SECRET_KEY@default - Google Gmail gmail+smtp://USERNAME:PASSWORD@default n/a n/a - Mailchimp Mandrill mandrill+smtp://USERNAME:PASSWORD@default mandrill+https://KEY@default mandrill+api://KEY@default - Mailgun mailgun+smtp://USERNAME:PASSWORD@default mailgun+https://KEY:DOMAIN@default mailgun+api://KEY:DOMAIN@default - Postmark postmark+smtp://ID:ID@default n/a postmark+api://KEY@default - Sendgrid sendgrid+smtp://apikey:KEY@default n/a sendgrid+api://KEY@default -==================== ========================================== =========================================== ======================================== - -.. caution:: - - If your credentials contain special characters, you must URL-encode them. - For example, the DSN ``ses+smtp://ABC1234:abc+12/345@default`` should be - configured as ``ses+smtp://ABC1234:abc%2B12%2F345@default`` - -Instead of choosing a specific protocol, you can also let Symfony pick the -best one by omitting it from the scheme: for instance, ``mailgun://KEY:DOMAIN@default`` -is equivalent to ``mailgun+https://KEY:DOMAIN@default``. - -If you want to override the default host for a provider (to debug an issue using -a service like ``requestbin.com``), change ``default`` by your host: - -.. code-block:: bash - - mailgun+https://KEY:DOMAIN@example.com - mailgun+https://KEY:DOMAIN@example.com:99 - -Note that the protocol is *always* HTTPs and cannot be changed. - -High Availability ------------------ - -Symfony's mailer supports `high availability`_ via a technique called "failover" -to ensure that emails are sent even if one mailer server fails . - -A failover transport is configured with two or more transports and the -``failover`` keyword:: - - $dsn = 'failover(postmark+api://ID@default sendgrid+smtp://KEY@default)'; - -The mailer will start using the first transport. If the sending fails, the -mailer won't retry it with the other transports, but it will switch to the next -transport automatically for the following deliveries. - -Load Balancing --------------- - -Symfony's mailer supports `load balancing`_ via a technique called "round-robin" -to distribute the mailing workload across multiple transports . - -A round-robin transport is configured with two or more transports and the -``roundrobin`` keyword:: - - $dsn = 'roundrobin(postmark+api://ID@default sendgrid+smtp://KEY@default)' - -The mailer will start using the first transport and if it fails, it will retry -the same delivery with the next transports until one of them succeeds (or until -all of them fail). - -Sending emails asynchronously ------------------------------ - -If you want to send emails asynchronously, install the :doc:`Messenger component -`. - -.. code-block:: terminal - - $ composer require symfony/messenger - -Then, instantiate and pass a ``MessageBus`` as a second argument to ``Mailer``:: - - use Symfony\Component\Mailer\Envelope; - use Symfony\Component\Mailer\Mailer; - use Symfony\Component\Mailer\Messenger\MessageHandler; - use Symfony\Component\Mailer\Messenger\SendEmailMessage; - use Symfony\Component\Mailer\Transport; - use Symfony\Component\Messenger\Handler\HandlersLocator; - use Symfony\Component\Messenger\MessageBus; - use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware; - use Symfony\Component\Mime\Address; - - $dsn = 'change-dsn-accordingly'; - - $transport = Transport::fromDsn($dsn); - $handler = new MessageHandler($transport); - - $bus = new MessageBus([ - new HandleMessageMiddleware(new HandlersLocator([ - SendEmailMessage::class => [$handler], - ])), - ]); - - $mailer = new Mailer($transport, $bus); - $mailer->send($email); - - // you can pass an optional Envelope - $mailer->send($email, new Envelope( - new Address('sender@example.com'), - [ - new Address('recipient@example.com'), - ] - )); - -Learn More ------------ - -To learn more about how to use the mailer component, refer to the -:doc:`Symfony Framework Mailer documentation `. - -.. _`high availability`: https://en.wikipedia.org/wiki/High_availability -.. _`load balancing`: https://en.wikipedia.org/wiki/Load_balancing_(computing) diff --git a/components/messenger.rst b/components/messenger.rst index 0ade59dfe87..b0bcb785aa7 100644 --- a/components/messenger.rst +++ b/components/messenger.rst @@ -218,7 +218,7 @@ Your own Sender Imagine that you already have an ``ImportantAction`` message going through the message bus and being handled by a handler. Now, you also want to send this message as an email (using the :doc:`Mime ` and -:doc:`Mailer ` components). +:doc:`Mailer ` components). Using the :class:`Symfony\\Component\\Messenger\\Transport\\Sender\\SenderInterface`, you can create your own message sender:: diff --git a/components/mime.rst b/components/mime.rst index 0d29ca4458c..ce884a51193 100644 --- a/components/mime.rst +++ b/components/mime.rst @@ -61,11 +61,7 @@ methods to compose the entire email message:: ; This only purpose of this component is to create the email messages. Use the -:doc:`Mailer component ` to actually send them. In Symfony -applications, it's easier to use the :doc:`Mailer integration `. - -Most of the details about how to create Email objects, including Twig integration, -can be found in the :doc:`Mailer documentation `. +:doc:`Mailer component ` to actually send them. Twig Integration ---------------- diff --git a/mailer.rst b/mailer.rst index 97a3dca00d7..229964ce30e 100644 --- a/mailer.rst +++ b/mailer.rst @@ -21,10 +21,10 @@ Transport Setup --------------- Emails are delivered via a "transport". Out of the box, you can deliver emails -over ``SMTP`` by configuring your ``.env`` file (the ``user``, ``pass`` and -``port`` parameters are optional): +over SMTP by configuring the DNS in your ``.env`` file (the ``user``, +``pass`` and ``port`` parameters are optional): -.. code-block:: bash +.. code-block:: env # .env MAILER_DSN=smtp://user:pass@smtp.example.com:port @@ -61,7 +61,7 @@ use SendGrid. First, install it: You'll now have a new line in your ``.env`` file that you can uncomment: -.. code-block:: bash +.. code-block:: env # .env MAILER_DSN=sendgrid://KEY@default @@ -79,22 +79,85 @@ also have options that can be configured with query parameters at the end of the sending via ``http``, ``api`` or ``smtp``. Symfony chooses the best available transport, but you can force to use one: -.. code-block:: bash +.. code-block:: env # .env # force to use SMTP instead of HTTP (which is the default) MAILER_DSN=sendgrid+smtp://$SENDGRID_KEY@default +This table shows the full list of available DNS formats for each third +party provider: + +==================== ========================================== =========================================== ======================================== + Provider SMTP HTTP API +==================== ========================================== =========================================== ======================================== + Amazon SES ses+smtp://ACCESS_KEY:SECRET_KEY@default ses+https://ACCESS_KEY:SECRET_KEY@default ses+api://ACCESS_KEY:SECRET_KEY@default + Google Gmail gmail+smtp://USERNAME:PASSWORD@default n/a n/a + Mailchimp Mandrill mandrill+smtp://USERNAME:PASSWORD@default mandrill+https://KEY@default mandrill+api://KEY@default + Mailgun mailgun+smtp://USERNAME:PASSWORD@default mailgun+https://KEY:DOMAIN@default mailgun+api://KEY:DOMAIN@default + Postmark postmark+smtp://ID:ID@default n/a postmark+api://KEY@default + Sendgrid sendgrid+smtp://apikey:KEY@default n/a sendgrid+api://KEY@default +==================== ========================================== =========================================== ======================================== + +.. caution:: + + If your credentials contain special characters, you must URL-encode them. + For example, the DSN ``ses+smtp://ABC1234:abc+12/345@default`` should be + configured as ``ses+smtp://ABC1234:abc%2B12%2F345@default`` + .. tip:: - Check the :ref:`DSN formats ` for all supported providers. + If you want to override the default host for a provider (to debug an issue using + a service like ``requestbin.com``), change ``default`` by your host: + + .. code-block:: env + + # .env + MAILER_DSN=mailgun+https://KEY:DOMAIN@example.com + MAILER_DSN=mailgun+https://KEY:DOMAIN@example.com:99 + + Note that the protocol is *always* HTTPs and cannot be changed. + +High Availability +~~~~~~~~~~~~~~~~~ + +Symfony's mailer supports `high availability`_ via a technique called "failover" +to ensure that emails are sent even if one mailer server fails. + +A failover transport is configured with two or more transports and the +``failover`` keyword: + +.. code-block:: env + + MAILER_DSN="failover(postmark+api://ID@default sendgrid+smtp://KEY@default)" + +The mailer will start using the first transport. If the sending fails, the +mailer won't retry it with the other transports, but it will switch to the next +transport automatically for the following deliveries. + +Load Balancing +~~~~~~~~~~~~~~ + +Symfony's mailer supports `load balancing`_ via a technique called "round-robin" +to distribute the mailing workload across multiple transports. + +A round-robin transport is configured with two or more transports and the +``roundrobin`` keyword: + +.. code-block:: env + + MAILER_DSN="roundrobin(postmark+api://ID@default sendgrid+smtp://KEY@default)" + +The mailer will start using the first transport and if it fails, it will retry +the same delivery with the next transports until one of them succeeds (or until +all of them fail). Creating & Sending Messages --------------------------- -To send an email, autowire the mailer using -:class:`Symfony\\Component\\Mailer\\MailerInterface` and create an -:class:`Symfony\\Component\\Mime\\Email` object:: +To send an email, get a :class:`Symfony\\Component\\Mailer\\Mailer` +instance by type-hinting :class:`Symfony\\Component\\Mailer\\MailerInterface` +and create an :class:`Symfony\\Component\\Mime\\Email` object:: // src/Controller/MailerController.php namespace App\Controller; @@ -343,6 +406,9 @@ frameworks to create complex HTML email messages. First, make sure Twig is insta $ composer require symfony/twig-bundle + # or if you're using the component in a non-Symfony app: + # composer require symfony/twig-bridge + HTML Content ~~~~~~~~~~~~ @@ -426,15 +492,46 @@ previous sections, when using Twig to render email contents you can refer to image files as usual. First, to simplify things, define a Twig namespace called ``images`` that points to whatever directory your images are stored in: -.. code-block:: yaml +.. configuration-block:: - # config/packages/twig.yaml - twig: - # ... + .. code-block:: yaml + + # config/packages/twig.yaml + twig: + # ... - paths: - # point this wherever your images live - '%kernel.project_dir%/assets/images': images + paths: + # point this wherever your images live + '%kernel.project_dir%/assets/images': images + + .. code-block:: xml + + + + + + + + + %kernel.project_dir%/assets/images + + + + .. code-block:: php + + // config/packages/twig.php + $container->loadFromExtension('twig', [ + // ... + 'paths' => [ + // point this wherever your images live + '%kernel.project_dir%/assets/images' => 'images', + ], + ]); Now, use the special ``email.image()`` Twig helper to embed the images inside the email contents: @@ -503,15 +600,46 @@ called ``css`` that points to the directory where ``email.css`` lives: .. _mailer-css-namespace: -.. code-block:: yaml +.. configuration-block:: + + .. code-block:: yaml - # config/packages/twig.yaml - twig: - # ... + # config/packages/twig.yaml + twig: + # ... + + paths: + # point this wherever your css files live + '%kernel.project_dir%/assets/css': css + + .. code-block:: xml + + + - paths: - # point this wherever your css files live - '%kernel.project_dir%/assets/css': css + + + + + %kernel.project_dir%/assets/css + + + + .. code-block:: php + + // config/packages/twig.php + $container->loadFromExtension('twig', [ + // ... + 'paths' => [ + // point this wherever your css files live + '%kernel.project_dir%/assets/css' => 'css', + ], + ]); .. _mailer-markdown: @@ -675,7 +803,7 @@ corresponding private key can read the original message contents:: $encryptedEmail = $encrypter->encrypt($email); // now use the Mailer component to send this $encryptedEmail instead of the original email -You can pass more than one certificate to the ``SMimeEncrypter()`` constructor +You can pass more than one certificate to the ``SMimeEncrypter`` constructor and it will select the appropriate certificate depending on the ``To`` option:: $firstEmail = (new Email()) @@ -708,14 +836,49 @@ You may want to use more than one mailer transport for delivery of your messages This can be configured by replacing the ``dsn`` configuration entry with a ``transports`` entry, like: -.. code-block:: yaml +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/mailer.yaml + framework: + mailer: + transports: + main: '%env(MAILER_DSN)%' + alternative: '%env(MAILER_DSN_IMPORTANT)%' + + .. code-block:: xml + + + + - # config/packages/mailer.yaml - framework: - mailer: - transports: - main: '%env(MAILER_DSN)%' - alternative: '%env(MAILER_DSN_IMPORTANT)%' + + + + %env(MAILER_DSN)% + %env(MAILER_DSN_IMPORTANT)% + + + + + .. code-block:: php + + // config/packages/mailer.php + $container->loadFromExtension('framework', [ + // ... + 'mailer' => [ + 'transports' => [ + 'main' => '%env(MAILER_DSN)%', + 'alternative' => '%env(MAILER_DSN_IMPORTANT)%', + ], + ], + ]); By default the first transport is used. The other transports can be used by adding a text header ``X-Transport`` to an email:: @@ -798,12 +961,41 @@ While developing (or testing), you may want to disable delivery of messages enti You can do this by forcing Mailer to use the ``NullTransport`` in only the ``dev`` environment: -.. code-block:: yaml +.. configuration-block:: - # config/packages/dev/mailer.yaml - framework: - mailer: - dsn: 'null://null' + .. code-block:: yaml + + # config/packages/dev/mailer.yaml + framework: + mailer: + dsn: 'null://null' + + .. code-block:: xml + + + + + + + + + + + + .. code-block:: php + + // config/packages/mailer.php + $container->loadFromExtension('framework', [ + // ... + 'mailer' => [ + 'dsn' => 'null://null', + ], + ]); .. note:: @@ -816,14 +1008,51 @@ Always Send to the same Address Instead of disabling delivery entirely, you might want to *always* send emails to a specific address, instead of the *real* address: -.. code-block:: yaml +.. configuration-block:: - # config/packages/dev/mailer.yaml - framework: - mailer: - envelope: - recipients: ['youremail@example.com'] + .. code-block:: yaml + + # config/packages/dev/mailer.yaml + framework: + mailer: + envelope: + recipients: ['youremail@example.com'] + + .. code-block:: xml + + + + + + + + + + youremail@example.com + + + + + + .. code-block:: php + + // config/packages/mailer.php + $container->loadFromExtension('framework', [ + // ... + 'mailer' => [ + 'envelope' => [ + 'recipients' => ['youremail@example.com'], + ], + ], + ]); +.. _`high availability`: https://en.wikipedia.org/wiki/High_availability +.. _`load balancing`: https://en.wikipedia.org/wiki/Load_balancing_(computing) .. _`download the foundation-emails.css file`: https://github.com/foundation/foundation-emails/blob/develop/dist/foundation-emails.css .. _`league/html-to-markdown`: https://github.com/thephpleague/html-to-markdown .. _`Markdown syntax`: https://commonmark.org/