Issue 1:
The problem

In my opinion, the current solution to send emails with Symfony is too "low level". (Related article: Send mails in Symfony in a way that does not suck!)

In my experience, most Symfony applications want to render a Twig template when sending an email. That's why FOSUserBundle includes the TwigSwiftMailer and that's why looking for Swift_Message::newInstance in GitHub gives you thousands of results with lots of shortcut methods to render a template.

The solution

I propose to create a new renderAndSend() method for the mailer service. It would work as follows:

Simplest case (fixed 'to' and 'from' email addresses):

$this->get('mailer')->renderAndSend('email/notification.html.twig', array(
'event' => $event,
));

{# app/Resources/views/email/notification.html.twig #}
{% block to 'user@example.com' %}
{% block from 'alerts@example.com' %}
{% block subject %}[{{ 'now'|date(d/m/Y H:i:s) }}] {{ event.title[:128] }}{% endblock %}

{% block body %}
...
<div>{{ event.content }}</div>
...
{% endblock %}

{% block body %} is a shortcut to set the HTML content. If you need different contents for HTML and TXT, use these blocks instead:

{% block body_html %} ... {% endblock %}
{% block body_text %} ... {% endblock %}

When the $to or $from email addresses are dynamic, you can pass them in the parameters array:

$this->get('mailer')->renderAndSend('email/notification.html.twig', array(
'event' => $event,
'to' => 'user@example.com',
'from' => 'alerts@example.com',
));

Then you don't need to define the to and from blocks:

{# app/Resources/views/email/notification.html.twig #}
{% block subject %}[{{ 'now'|date(d/m/Y H:i:s) }}] {{ event.title[:128] }}{% endblock %}

{% block body %}
...
{% endblock %}

These are the special Twig blocks:

{% block to %} ... {% endblock %}
{% block from %} ... {% endblock %}
{% block subject %} ... {% endblock %}

{% block body %} ... {% endblock %}

{% block body_html %} ... {% endblock %}
{% block body_text %} ... {% endblock %}

If both the Twig block and the parameter are given, the block is used. This allows to use the following:

$this->get('mailer')->renderAndSend('email/notification.html.twig', array(
'event' => $event,
'to' => 'user@example.com',
'user' => $user,
));

{# app/Resources/views/email/notification.html.twig #}
{% block to %}{{ user.name }} <{{ to }}>{% endblock %}
...

The sendAndRender() method would define a third optional parameter to set the file attachments:

$this->get('mailer')->renderAndSend(
'email/notification.html.twig',
array('event' => $event),
array(
$this->container->getParameter('log_dir').'/traces/'.$event->getId(),
$this->container->getParameter('log_dir').'/console_output/'.$event->getId(),
)
);

If the attachments array is associative, the keys are used as the file names:

$this->get('mailer')->renderAndSend(
'email/notification.html.twig',
array('event' => $event),
array(
'trace.txt' => $this->container->getParameter('log_dir').'/traces/'.$event->getId(),
'output.txt' => $this->container->getParameter('log_dir').'/console_output/'.$event->getId(),
)
);

Issue 2:
I see on all Symfony projects a "Mailer" class with this kind of function:

public function sendMessage($object, $fromEmail, $toEmail, $template, array $parameters = [])
{
try {
$message = \Swift_Message::newInstance()
->setSubject($object)
->setFrom($fromEmail)
->setTo($toEmail)
->setBody($this->engine->render($template, $parameters), 'text/html')
;
$this->mailer->send($message, $failedRecipients);
if (!empty($failedRecipients)) {
$this->logger->error('Mail was send but some recipients failed', [
'failed_recipients' => implode(' - ', $failedRecipients)
]);
}
} catch (\Swift_SwiftException $e) {
$this->logger->error('Unable to send email', ['exception' => $e]);
}
}

This is weird to implement his own mailer when we already have a mailer service in Symfony framework.

I propose to create a mailer service (we need to discuss on the name: should we replace the actual mailer ? create a sf_mailer service ?) with templating engine or only Twig (Symfony 3) and logger as dependency and - at least:

a function to send HTML email from twig template

a function to send txt emails

I'm in favor of a class which extends the Swiftmailer instance and add some functions and with a soft dependency on logger. This way:

we can keep mailer as service id

if we add logger as a dependency, we have more informations (new implementation)

the legacy implementations work (no BC)

What do you think ?