[Mailer] added support for the profiler
This commit is contained in:
parent
aa93f0b611
commit
f152314e28
@ -8,5 +8,10 @@
|
||||
<service id="mailer.logger_message_listener" class="Symfony\Component\Mailer\EventListener\MessageLoggerListener">
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
|
||||
<service id="mailer.data_collector" class="Symfony\Component\Mailer\DataCollector\MessageDataCollector">
|
||||
<argument type="service" id="mailer.logger_message_listener" />
|
||||
<tag name="data_collector" template="@WebProfiler/Collector/mailer.html.twig" id="mailer" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
@ -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
|
||||
|
@ -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') %}
|
||||
<span class="sf-toolbar-value">{{ events.messages|length }}</span>
|
||||
{% endset %}
|
||||
|
||||
{% set text %}
|
||||
<div class="sf-toolbar-info-piece">
|
||||
<b>Sent messages</b>
|
||||
<span class="sf-toolbar-status">{{ events.messages|length }}</span>
|
||||
</div>
|
||||
|
||||
{% for transport in events.transports %}
|
||||
<div class="sf-toolbar-info-piece">
|
||||
<b>{{ transport }}</b>
|
||||
<span class="sf-toolbar-status">{{ events.messages(transport)|length }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endset %}
|
||||
|
||||
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': profiler_url }) }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ parent() }}
|
||||
<style type="text/css">
|
||||
/* utility classes */
|
||||
.m-t-0 { margin-top: 0 !important; }
|
||||
.m-t-10 { margin-top: 10px !important; }
|
||||
|
||||
/* basic grid */
|
||||
.row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -15px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
.col {
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
max-width: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: 1px;
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
.col-4 {
|
||||
flex: 0 0 33.333333%;
|
||||
max-width: 33.333333%;
|
||||
}
|
||||
|
||||
/* small tabs */
|
||||
.sf-tabs-sm .tab-navigation li {
|
||||
font-size: 14px;
|
||||
padding: .3em .5em;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block menu %}
|
||||
{% set events = collector.events %}
|
||||
|
||||
<span class="label {{ events.messages|length ? '' : 'disabled' }}">
|
||||
<span class="icon">{{ include('@WebProfiler/Icon/mailer.svg') }}</span>
|
||||
|
||||
<strong>E-mails</strong>
|
||||
{% if events.messages|length > 0 %}
|
||||
<span class="count">
|
||||
<span>{{ events.messages|length }}</span>
|
||||
</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
{% set events = collector.events %}
|
||||
|
||||
<h2>Emails</h2>
|
||||
|
||||
{% if not events.messages|length %}
|
||||
<div class="empty">
|
||||
<p>No emails were sent.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="metrics">
|
||||
{% for transport in events.transports %}
|
||||
<div class="metric">
|
||||
<span class="value">{{ events.messages(transport)|length }}</span>
|
||||
<span class="label">{{ events.messages(transport)|length == 1 ? 'message' : 'messages' }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% for transport in events.transports %}
|
||||
<h3>{{ transport }}</h3>
|
||||
|
||||
<div class="card-block">
|
||||
<div class="sf-tabs sf-tabs-sm">
|
||||
{% for event in events.events(transport) %}
|
||||
{% set message = event.message %}
|
||||
<div class="tab">
|
||||
<h3 class="tab-title">Email #{{ loop.index }} <small>({{ event.isQueued() ? 'queued' : 'sent' }})</small></h3>
|
||||
<div class="tab-content">
|
||||
<div class="card">
|
||||
{% if message.headers is not defined %}
|
||||
{# RawMessage instance #}
|
||||
<div class="card-block">
|
||||
<pre class="prewrap" style="max-height: 600px">{{ message.toString() }}</pre>
|
||||
</div>
|
||||
{% else %}
|
||||
{# Message instance #}
|
||||
<div class="card-block">
|
||||
<span class="label">Subject</span>
|
||||
<h2 class="m-t-10">{{ message.headers.get('subject').bodyAsString() ?? '(empty)' }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="card-block">
|
||||
<div class="row">
|
||||
<div class="col col-4">
|
||||
<span class="label">From</span>
|
||||
<pre class="prewrap">{{ (message.headers.get('from').bodyAsString() ?? '(empty)')|replace({'From:': ''}) }}</pre>
|
||||
|
||||
<span class="label">To</span>
|
||||
<pre class="prewrap">{{ (message.headers.get('to').bodyAsString() ?? '(empty)')|replace({'To:': ''}) }}</pre>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Headers</span>
|
||||
<pre class="prewrap">{% for header in message.headers.all|filter(header => (header.name ?? '') not in ['Subject', 'From', 'To']) %}
|
||||
{{- header.toString }}
|
||||
{%~ endfor %}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-block">
|
||||
{% if message.htmlBody is defined %}
|
||||
{# Email instance #}
|
||||
<div class="sf-tabs sf-tabs-sm">
|
||||
<div class="tab">
|
||||
<h3 class="tab-title">HTML Content</h3>
|
||||
<div class="tab-content">
|
||||
<pre class="prewrap" style="max-height: 600px">
|
||||
{%- if message.htmlCharset() %}
|
||||
{{- message.htmlBody()|convert_encoding('UTF-8', message.htmlCharset()) }}
|
||||
{%- else %}
|
||||
{{- message.htmlBody() }}
|
||||
{%- endif -%}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<h3 class="tab-title">Text Content</h3>
|
||||
<div class="tab-content">
|
||||
<pre class="prewrap" style="max-height: 600px">
|
||||
{%- if message.textCharset() %}
|
||||
{{- message.textBody()|convert_encoding('UTF-8', message.textCharset()) }}
|
||||
{%- else %}
|
||||
{{- message.textBody() }}
|
||||
{%- endif -%}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
{% for attachment in message.attachments %}
|
||||
<div class="tab">
|
||||
<h3 class="tab-title">Attachment #{{ loop.index }}</h3>
|
||||
<div class="tab-content">
|
||||
<pre class="prewrap" style="max-height: 600px">{{ attachment.toString() }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="tab">
|
||||
<h3 class="tab-title">Parts Hierarchy</h3>
|
||||
<div class="tab-content">
|
||||
<pre class="prewrap" style="max-height: 600px">{{ message.body().asDebugString() }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<h3 class="tab-title">Raw</h3>
|
||||
<div class="tab-content">
|
||||
<pre class="prewrap" style="max-height: 600px">{{ message.toString() }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#AAAAAA" d="M22,4.9C22,3.9,21.1,3,20.1,3H3.9C2.9,3,2,3.9,2,4.9v13.1C2,19.1,2.9,20,3.9,20h16.1c1.1,0,1.9-0.9,1.9-1.9V4.9z M8.3,14.1l-3.1,3.1c-0.2,0.2-0.5,0.3-0.7,0.3S4,17.4,3.8,17.2c-0.4-0.4-0.4-1,0-1.4l3.1-3.1c0.4-0.4,1-0.4,1.4,0S8.7,13.7,8.3,14.1z M20.4,17.2c-0.2,0.2-0.5,0.3-0.7,0.3s-0.5-0.1-0.7-0.3l-3.1-3.1c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l3.1,3.1C20.8,16.2,20.8,16.8,20.4,17.2z M20.4,7.2l-7.6,7.6c-0.2,0.2-0.5,0.3-0.7,0.3s-0.5-0.1-0.7-0.3L3.8,7.2c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6.9,6.9L19,5.8c0.4-0.4,1-0.4,1.4,0S20.8,6.8,20.4,7.2z"/></svg>
|
After Width: | Height: | Size: 643 B |
@ -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.
|
||||
|
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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 <fabien@symfony.com>
|
||||
*/
|
||||
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';
|
||||
}
|
||||
}
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\Mailer\Event;
|
||||
|
||||
use Symfony\Component\Mime\RawMessage;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user