diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_debug.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_debug.xml index 17ed496661..7447445949 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_debug.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_debug.xml @@ -8,5 +8,10 @@ + + + + + diff --git a/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md b/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md index d785a0fcd7..ebf52ea3e2 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 4.4.0 ----- + * added support for the Mailer component * added button to clear the ajax request tab * deprecated the `ExceptionController::templateExists()` method * deprecated the `TemplateManager::templateExists()` method diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/mailer.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/mailer.html.twig new file mode 100644 index 0000000000..819711eff7 --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/mailer.html.twig @@ -0,0 +1,202 @@ +{% extends '@WebProfiler/Profiler/layout.html.twig' %} + +{% block toolbar %} + {% set events = collector.events %} + + {% if events.messages|length %} + {% set icon %} + {% include('@WebProfiler/Icon/mailer.svg') %} + {{ events.messages|length }} + {% endset %} + + {% set text %} +
+ Sent messages + {{ events.messages|length }} +
+ + {% for transport in events.transports %} +
+ {{ transport }} + {{ events.messages(transport)|length }} +
+ {% endfor %} + {% endset %} + + {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': profiler_url }) }} + {% endif %} +{% endblock %} + +{% block head %} + {{ parent() }} + +{% endblock %} + +{% block menu %} + {% set events = collector.events %} + + + {{ include('@WebProfiler/Icon/mailer.svg') }} + + E-mails + {% if events.messages|length > 0 %} + + {{ events.messages|length }} + + {% endif %} + +{% endblock %} + +{% block panel %} + {% set events = collector.events %} + +

Emails

+ + {% if not events.messages|length %} +
+

No emails were sent.

+
+ {% endif %} + +
+ {% for transport in events.transports %} +
+ {{ events.messages(transport)|length }} + {{ events.messages(transport)|length == 1 ? 'message' : 'messages' }} +
+ {% endfor %} +
+ + {% for transport in events.transports %} +

{{ transport }}

+ +
+
+ {% for event in events.events(transport) %} + {% set message = event.message %} +
+

Email #{{ loop.index }} ({{ event.isQueued() ? 'queued' : 'sent' }})

+
+
+ {% if message.headers is not defined %} + {# RawMessage instance #} +
+
{{ message.toString() }}
+
+ {% else %} + {# Message instance #} +
+ Subject +

{{ message.headers.get('subject').bodyAsString() ?? '(empty)' }}

+
+ +
+
+
+ From +
{{ (message.headers.get('from').bodyAsString() ?? '(empty)')|replace({'From:': ''}) }}
+ + To +
{{ (message.headers.get('to').bodyAsString() ?? '(empty)')|replace({'To:': ''}) }}
+
+
+ Headers +
{% for header in message.headers.all|filter(header => (header.name ?? '') not in ['Subject', 'From', 'To']) %}
+                                                    {{- header.toString }}
+                                                {%~ endfor %}
+
+
+
+ +
+ {% if message.htmlBody is defined %} + {# Email instance #} +
+
+

HTML Content

+
+
+                                                            {%- if message.htmlCharset() %}
+                                                                {{- message.htmlBody()|convert_encoding('UTF-8', message.htmlCharset()) }}
+                                                            {%- else %}
+                                                                {{- message.htmlBody() }}
+                                                            {%- endif -%}
+                                                        
+
+
+
+

Text Content

+
+
+                                                            {%- if message.textCharset() %}
+                                                                {{- message.textBody()|convert_encoding('UTF-8', message.textCharset()) }}
+                                                            {%- else %}
+                                                                {{- message.textBody() }}
+                                                            {%- endif -%}
+                                                        
+
+
+ {% for attachment in message.attachments %} +
+

Attachment #{{ loop.index }}

+
+
{{ attachment.toString() }}
+
+
+ {% endfor %} + {% endif %} +
+

Parts Hierarchy

+
+
{{ message.body().asDebugString() }}
+
+
+
+

Raw

+
+
{{ message.toString() }}
+
+
+
+
+ {% endif %} +
+
+
+ {% endfor %} +
+
+ {% endfor %} +{% endblock %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/mailer.svg b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/mailer.svg new file mode 100644 index 0000000000..ed649d0681 --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/mailer.svg @@ -0,0 +1 @@ + diff --git a/src/Symfony/Component/Mailer/CHANGELOG.md b/src/Symfony/Component/Mailer/CHANGELOG.md index 76b895a680..ac90ccc499 100644 --- a/src/Symfony/Component/Mailer/CHANGELOG.md +++ b/src/Symfony/Component/Mailer/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 4.4.0 ----- + * Added `MessageDataCollector` * Added `MessageEvents` and `MessageLoggerListener` to allow collecting sent emails * [BC BREAK] `TransportInterface` has a new `getName()` method * [BC BREAK] Classes `AbstractApiTransport` and `AbstractHttpTransport` moved under `Transport` sub-namespace. diff --git a/src/Symfony/Component/Mailer/DataCollector/MessageDataCollector.php b/src/Symfony/Component/Mailer/DataCollector/MessageDataCollector.php new file mode 100644 index 0000000000..3877b25bd3 --- /dev/null +++ b/src/Symfony/Component/Mailer/DataCollector/MessageDataCollector.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\DataCollector; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\Mailer\Event\MessageEvents; +use Symfony\Component\Mailer\EventListener\MessageLoggerListener; + +/** + * @author Fabien Potencier + */ +class MessageDataCollector extends DataCollector +{ + private $events; + + public function __construct(MessageLoggerListener $logger) + { + $this->events = $logger->getEvents(); + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + $this->data['events'] = $this->events; + } + + public function getEvents(): MessageEvents + { + return $this->data['events']; + } + + /** + * {@inheritdoc} + */ + public function reset() + { + $this->data = []; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'mailer'; + } +} diff --git a/src/Symfony/Component/Mailer/Event/MessageEvents.php b/src/Symfony/Component/Mailer/Event/MessageEvents.php index a921022ced..259fe8ffdf 100644 --- a/src/Symfony/Component/Mailer/Event/MessageEvents.php +++ b/src/Symfony/Component/Mailer/Event/MessageEvents.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Mailer\Event; +use Symfony\Component\Mime\RawMessage; + /** * @author Fabien Potencier */ @@ -48,4 +50,18 @@ class MessageEvents return $events; } + + /** + * @return RawMessage[] + */ + public function getMessages(string $name = null): array + { + $events = $this->getEvents($name); + $messages = []; + foreach ($events as $event) { + $messages[] = $event->getMessage(); + } + + return $messages; + } }