Skip to content

[Notifier][WebProfilerBundle][FrameworkBundle] Add notifier section to profiler #36479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
$container->services()
->set('notifier.data_collector', NotificationDataCollector::class)
->args([service('notifier.logger_notification_listener')])
->tag('data_collector', ['template' => '@WebProfiler/Collector/notifier.html.twig', 'id' => 'notifier'])
;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
{% 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 notifications</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>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • exchange icon

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@javiereguiluz Can you work on an icon for the notifier profiler?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being late, but our designer just sent us the icon for the notifier. It uses the "bell icon" which is universal for notifications:

<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><path fill="#AAA" d="M11.23,4.8c-3,.83-5.07,3.18-5.07,5.9H7.39c0-2.21,1.77-4,4.17-4.72ZM7.49,0A12.22,12.22,0,0,0,0,11.59H2.07A10.14,10.14,0,0,1,8.23,2Zm8.24,2a10.14,10.14,0,0,1,6.16,9.64H24A12.24,12.24,0,0,0,16.47,0ZM4.41,15.64V10.7a7.57,7.57,0,0,1,15.14,0v4.94l3.3,4.4H1.11Zm4.45,5.3A3.06,3.06,0,0,0,11.92,24H12a3.07,3.07,0,0,0,3.07-3.06Z"/></svg>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@javiereguiluz as this PR is already merged, it might be better if you create a new PR with the new icon instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @javiereguiluz I created a new PR: #38545


<strong>Notifications</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>Notifications</h2>

{% if not events.messages|length %}
<div class="empty">
<p>No notifications 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">{{ transport }}</span>
</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">Message #{{ loop.index }} <small>({{ event.isQueued() ? 'queued' : 'sent' }})</small></h3>
<div class="tab-content">
<div class="card">
<div class="card-block">
<span class="label">Subject</span>
<h2 class="m-t-10">{{ message.getSubject() ?? '(empty)' }}</h2>
</div>
{% if message.getNotification is defined %}
<div class="card-block">
<div class="row">
<div class="col">
<span class="label">Content</span>
<pre class="prewrap">{{ message.getNotification().getContent() ?? '(empty)' }}</pre>
<span class="label">Importance</span>
<pre class="prewrap">{{ message.getNotification().getImportance() }}</pre>
</div>
</div>
</div>
{% endif %}
<div class="card-block">
<div class="sf-tabs sf-tabs-sm">
{% if message.getNotification is defined %}
<div class="tab">
<h3 class="tab-title">Notification</h3>
{% set notification = event.message.getNotification() %}
<div class="tab-content">
<pre class="prewrap" style="max-height: 600px">
{{- 'Subject: ' ~ notification.getSubject() }}<br/>
{{- 'Content: ' ~ notification.getContent() }}<br/>
{{- 'Importance: ' ~ notification.getImportance() }}<br/>
{{- 'Emoji: ' ~ (notification.getEmoji() is empty ? '(empty)' : notification.getEmoji()) }}<br/>
{{- 'Exception: ' ~ notification.getException() ?? '(empty)' }}<br/>
{{- 'ExceptionAsString: ' ~ (notification.getExceptionAsString() is empty ? '(empty)' : notification.getExceptionAsString()) }}
</pre>
</div>
</div>
{% endif %}
<div class="tab">
<h3 class="tab-title">Message Options</h3>
<div class="tab-content">
<pre class="prewrap" style="max-height: 600px">
{%- if message.getOptions() is null %}
{{- '(empty)' }}
{%- else %}
{{- message.getOptions()|json_encode(constant('JSON_PRETTY_PRINT')) }}
{%- endif %}
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
{% endblock %}
2 changes: 1 addition & 1 deletion src/Symfony/Component/Notifier/Message/ChatMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function getOptions(): ?MessageOptionsInterface
/**
* @return $this
*/
public function transport(?string $transport): self
public function transport(?string $transport): MessageInterface
{
$this->transport = $transport;

Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Notifier/Message/EmailMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public function getOptions(): ?MessageOptionsInterface
/**
* @return $this
*/
public function transport(string $transport): self
public function transport(string $transport): MessageInterface
{
if (!$this->message instanceof Email) {
throw new LogicException('Cannot set a Transport on a RawMessage instance.');
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/Notifier/Message/MessageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ public function getSubject(): string;
public function getOptions(): ?MessageOptionsInterface;

public function getTransport(): ?string;

public function transport(string $transport): self;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big fan, but I don't have any better idea for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could decorate the message with a DebugMessage that exposes this information?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this idea and gave it a try: #38474 WDYT?

}
2 changes: 1 addition & 1 deletion src/Symfony/Component/Notifier/Message/SmsMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function getSubject(): string
/**
* @return $this
*/
public function transport(string $transport): self
public function transport(string $transport): MessageInterface
{
$this->transport = $transport;

Expand Down
4 changes: 4 additions & 0 deletions src/Symfony/Component/Notifier/Transport/NullTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public function __construct(EventDispatcherInterface $dispatcher = null)

public function send(MessageInterface $message): SentMessage
{
if (null === $message->getTransport()) {
$message->transport((string) $this);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to make sure that every transport has a name to show this name in the profiler panel.

}

if (null !== $this->dispatcher) {
$this->dispatcher->dispatch(new MessageEvent($message));
}
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Component/Notifier/Transport/Transports.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ public function supports(MessageInterface $message): bool
public function send(MessageInterface $message): SentMessage
{
if (!$transport = $message->getTransport()) {
foreach ($this->transports as $transport) {
foreach ($this->transports as $transportName => $transport) {
if ($transport->supports($message)) {
$message->transport($transportName);

return $transport->send($message);
}
}
Expand Down