messenger.html.twig 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. {% extends '@WebProfiler/Profiler/layout.html.twig' %}
  2. {% import _self as helper %}
  3. {% block toolbar %}
  4. {% if collector.messages|length > 0 %}
  5. {% set status_color = collector.exceptionsCount ? 'red' %}
  6. {% set icon %}
  7. {{ include('@WebProfiler/Icon/messenger.svg') }}
  8. <span class="sf-toolbar-value">{{ collector.messages|length }}</span>
  9. {% endset %}
  10. {% set text %}
  11. {% for bus in collector.buses %}
  12. {% set exceptionsCount = collector.exceptionsCount(bus) %}
  13. <div class="sf-toolbar-info-piece">
  14. <b>{{ bus }}</b>
  15. <span
  16. title="{{ exceptionsCount }} message(s) with exceptions"
  17. class="sf-toolbar-status sf-toolbar-status-{{ exceptionsCount ? 'red' }}"
  18. >
  19. {{ collector.messages(bus)|length }}
  20. </span>
  21. </div>
  22. {% endfor %}
  23. {% endset %}
  24. {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: 'messenger', status: status_color }) }}
  25. {% endif %}
  26. {% endblock %}
  27. {% block menu %}
  28. <span class="label{{ collector.exceptionsCount ? ' label-status-error' }}{{ collector.messages is empty ? ' disabled' }}">
  29. <span class="icon">{{ include('@WebProfiler/Icon/messenger.svg') }}</span>
  30. <strong>Messages</strong>
  31. {% if collector.exceptionsCount > 0 %}
  32. <span class="count">
  33. <span>{{ collector.exceptionsCount }}</span>
  34. </span>
  35. {% endif %}
  36. </span>
  37. {% endblock %}
  38. {% block head %}
  39. {{ parent() }}
  40. <style>
  41. .message-item thead th { position: relative; cursor: pointer; user-select: none; padding-right: 35px; }
  42. .message-item tbody tr td:first-child { width: 170px; }
  43. .message-item .label { float: right; padding: 1px 5px; opacity: .75; margin-left: 5px; }
  44. .message-item .toggle-button { position: absolute; right: 6px; top: 6px; opacity: .5; pointer-events: none }
  45. .message-item .icon svg { height: 24px; width: 24px; }
  46. .message-item .sf-toggle-off .icon-close, .sf-toggle-on .icon-open { display: none; }
  47. .message-item .sf-toggle-off .icon-open, .sf-toggle-on .icon-close { display: block; }
  48. .message-bus .badge.status-some-errors { line-height: 16px; border-bottom: 2px solid #B0413E; }
  49. .message-item tbody.sf-toggle-content.sf-toggle-visible { display: table-row-group; }
  50. td.message-bus-dispatch-caller { background: #f1f2f3; }
  51. .theme-dark td.message-bus-dispatch-caller { background: var(--base-1); }
  52. </style>
  53. {% endblock %}
  54. {% block panel %}
  55. {% import _self as helper %}
  56. <h2>Messages</h2>
  57. {% if collector.messages is empty %}
  58. <div class="empty">
  59. <p>No messages have been collected.</p>
  60. </div>
  61. {% else %}
  62. <div class="sf-tabs message-bus">
  63. <div class="tab">
  64. {% set messages = collector.messages %}
  65. {% set exceptionsCount = collector.exceptionsCount %}
  66. <h3 class="tab-title">All<span class="badge {{ exceptionsCount ? exceptionsCount == messages|length ? 'status-error' : 'status-some-errors' }}">{{ messages|length }}</span></h3>
  67. <div class="tab-content">
  68. <p class="text-muted">Ordered list of dispatched messages across all your buses</p>
  69. {{ helper.render_bus_messages(messages, true) }}
  70. </div>
  71. </div>
  72. {% for bus in collector.buses %}
  73. <div class="tab message-bus">
  74. {% set messages = collector.messages(bus) %}
  75. {% set exceptionsCount = collector.exceptionsCount(bus) %}
  76. <h3 class="tab-title">{{ bus }}<span class="badge {{ exceptionsCount ? exceptionsCount == messages|length ? 'status-error' : 'status-some-errors' }}">{{ messages|length }}</span></h3>
  77. <div class="tab-content">
  78. <p class="text-muted">Ordered list of messages dispatched on the <code>{{ bus }}</code> bus</p>
  79. {{ helper.render_bus_messages(messages) }}
  80. </div>
  81. </div>
  82. {% endfor %}
  83. </div>
  84. {% endif %}
  85. {% endblock %}
  86. {% macro render_bus_messages(messages, showBus = false) %}
  87. {% set discr = random() %}
  88. {% for dispatchCall in messages %}
  89. <table class="message-item">
  90. <thead>
  91. <tr>
  92. <th colspan="2" class="sf-toggle"
  93. data-toggle-selector="#message-item-{{ discr }}-{{ loop.index0 }}-details"
  94. data-toggle-initial="{{ loop.first ? 'display' }}"
  95. >
  96. <span class="dump-inline">{{ profiler_dump(dispatchCall.message.type) }}</span>
  97. {% if showBus %}
  98. <span class="label">{{ dispatchCall.bus }}</span>
  99. {% endif %}
  100. {% if dispatchCall.exception is defined %}
  101. <span class="label status-error">exception</span>
  102. {% endif %}
  103. <a class="toggle-button">
  104. <span class="icon icon-close">{{ include('@WebProfiler/images/icon-minus-square.svg') }}</span>
  105. <span class="icon icon-open">{{ include('@WebProfiler/images/icon-plus-square.svg') }}</span>
  106. </a>
  107. </th>
  108. </tr>
  109. </thead>
  110. <tbody id="message-item-{{ discr }}-{{ loop.index0 }}-details" class="sf-toggle-content">
  111. <tr>
  112. <td colspan="2" class="message-bus-dispatch-caller">
  113. <span class="metadata">In
  114. {% set caller = dispatchCall.caller %}
  115. {% if caller.line %}
  116. {% set link = caller.file|file_link(caller.line) %}
  117. {% if link %}
  118. <a href="{{ link }}" title="{{ caller.file }}">{{ caller.name }}</a>
  119. {% else %}
  120. <abbr title="{{ caller.file }}">{{ caller.name }}</abbr>
  121. {% endif %}
  122. {% else %}
  123. {{ caller.name }}
  124. {% endif %}
  125. line <a class="text-small sf-toggle" data-toggle-selector="#sf-trace-{{ discr }}-{{ loop.index0 }}">{{ caller.line }}</a>
  126. </span>
  127. <div class="hidden" id="sf-trace-{{ discr }}-{{ loop.index0 }}">
  128. <div class="trace">
  129. {{ caller.file|file_excerpt(caller.line)|replace({
  130. '#DD0000': 'var(--highlight-string)',
  131. '#007700': 'var(--highlight-keyword)',
  132. '#0000BB': 'var(--highlight-default)',
  133. '#FF8000': 'var(--highlight-comment)'
  134. })|raw }}
  135. </div>
  136. </div>
  137. </td>
  138. </tr>
  139. {% if showBus %}
  140. <tr>
  141. <td class="text-bold">Bus</td>
  142. <td>{{ dispatchCall.bus }}</td>
  143. </tr>
  144. {% endif %}
  145. <tr>
  146. <td class="text-bold">Message</td>
  147. <td>{{ profiler_dump(dispatchCall.message.value, maxDepth=2) }}</td>
  148. </tr>
  149. <tr>
  150. <td class="text-bold">Envelope stamps <span class="text-muted">when dispatching</span></td>
  151. <td>
  152. {% for item in dispatchCall.stamps %}
  153. {{ profiler_dump(item) }}
  154. {% else %}
  155. <span class="text-muted">No items</span>
  156. {% endfor %}
  157. </td>
  158. </tr>
  159. {% if dispatchCall.stamps_after_dispatch is defined %}
  160. <tr>
  161. <td class="text-bold">Envelope stamps <span class="text-muted">after dispatch</span></td>
  162. <td>
  163. {% for item in dispatchCall.stamps_after_dispatch %}
  164. {{ profiler_dump(item) }}
  165. {% else %}
  166. <span class="text-muted">No items</span>
  167. {% endfor %}
  168. </td>
  169. </tr>
  170. {% endif %}
  171. {% if dispatchCall.exception is defined %}
  172. <tr>
  173. <td class="text-bold">Exception</td>
  174. <td>
  175. {{ profiler_dump(dispatchCall.exception.value, maxDepth=1) }}
  176. </td>
  177. </tr>
  178. {% endif %}
  179. </tbody>
  180. </table>
  181. {% endfor %}
  182. {% endmacro %}