{% extends app.request.isXmlHttpRequest ? '@WebProfiler/Profiler/ajax_layout.html.twig' : '@WebProfiler/Profiler/layout.html.twig' %}
{% block toolbar %}
{% set profiler_markup_version = profiler_markup_version|default(1) %}
{% set icon %}
{% if profiler_markup_version == 1 %}
<img width="20" height="28" alt="Database" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAcCAYAAABh2p9gAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQRJREFUeNpi/P//PwM1ARMDlcGogZQDlpMnT7pxc3NbA9nhQKxOpL5rQLwJiPeBsI6Ozl+YBOOOHTv+AOllQNwtLS39F2owKYZ/gRq8G4i3ggxEToggWzvc3d2Pk+1lNL4fFAs6ODi8JzdS7mMRVyDVoAMHDsANdAPiOCC+jCQvQKqBQB/BDbwBxK5AHA3E/kB8nKJkA8TMQBwLxaBIKQbi70AvTADSBiSadwFXpCikpKQU8PDwkGTaly9fHFigkaKIJid4584dkiMFFI6jkTJII0WVmpHCAixZQEXWYhDeuXMnyLsVlEQKI45qFBQZ8eRECi4DBaAlDqle/8A48ip6gAADANdQY88Uc0oGAAAAAElFTkSuQmCC" />
<span class="sf-toolbar-value sf-toolbar-status {% if collector.querycount > 50 %}sf-toolbar-status-yellow{% endif %}">{{ collector.querycount }}</span>
{% if collector.querycount > 0 %}
<span class="sf-toolbar-info-piece-additional-detail">in {{ '%0.2f'|format(collector.time * 1000) }} ms</span>
{% endif %}
{% if collector.invalidEntityCount > 0 %}
<span class="sf-toolbar-info-piece-additional sf-toolbar-status sf-toolbar-status-red">{{ collector.invalidEntityCount }}</span>
{% endif %}
{% else %}
{% if collector.querycount > 0 or collector.invalidEntityCount > 0 %}
{% set status = collector.invalidEntityCount > 0 ? 'red' : collector.querycount > 50 ? 'yellow' %}
{{ include('@Doctrine/Collector/icon.svg') }}
{% if collector.querycount == 0 and collector.invalidEntityCount > 0 %}
<span class="sf-toolbar-value">{{ collector.invalidEntityCount }}</span>
<span class="sf-toolbar-label">errors</span>
{% else %}
<span class="sf-toolbar-value">{{ collector.querycount }}</span>
<span class="sf-toolbar-info-piece-additional-detail">
<span class="sf-toolbar-label">in</span>
<span class="sf-toolbar-value">{{ '%0.2f'|format(collector.time * 1000) }}</span>
<span class="sf-toolbar-label">ms</span>
</span>
{% endif %}
{% endif %}
{% endif %}
{% endset %}
{% set text %}
<div class="sf-toolbar-info-piece">
<b>Database Queries</b>
<span class="sf-toolbar-status">{{ collector.querycount }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Query time</b>
<span>{{ '%0.2f'|format(collector.time * 1000) }} ms</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Invalid entities</b>
<span class="sf-toolbar-status {{ collector.invalidEntityCount > 0 ? 'sf-toolbar-status-red' : '' }}">{{ collector.invalidEntityCount }}</span>
</div>
{% if collector.cacheEnabled %}
<div class="sf-toolbar-info-piece">
<b>Cache hits</b>
<span class="sf-toolbar-status sf-toolbar-status-green">{{ collector.cacheHitsCount }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Cache misses</b>
<span class="sf-toolbar-status {{ collector.cacheMissesCount > 0 ? 'sf-toolbar-status-yellow' : '' }}">{{ collector.cacheMissesCount }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Cache puts</b>
<span class="sf-toolbar-status {{ collector.cachePutsCount > 0 ? 'sf-toolbar-status-yellow' : '' }}">{{ collector.cachePutsCount }}</span>
</div>
{% else %}
<div class="sf-toolbar-info-piece">
<b>Second Level Cache</b>
<span class="sf-toolbar-status">disabled</span>
</div>
{% endif %}
{% endset %}
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url, status: status|default('') }) }}
{% endblock %}
{% block menu %}
{% set profiler_markup_version = profiler_markup_version|default(1) %}
{% if profiler_markup_version == 1 %}
<span class="label">
<span class="icon"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAcCAYAAAB/E6/TAAABLUlEQVR42u3TP0vDQBiA8UK/gDiLzi0IhU4OEunk5OQUAhGSOBUCzqWfIKSzX8DRySF0URCcMjWLIJjFD9Cpk/D6HITecEPUuzhIAz8CIdyTP/f2iqI4qaqqDx8l5Ic2uIeP/bquezCokOAFF+oCN3t4gPzSEjc4NEPaCldQbzjELTYW0RJzHDchwwem+ons6ZBpLSJ7nueJC22h0V+FzmwWV0ee59vQNV67CGVZJmEYbkNjfpY6X6I0Qo4/3RMmTdDDspuQVsJvgkP3IdMbIkIjLPBoadG2646iKJI0Ta2wxm6OdnP0/Tk6DYJgHcfxpw21RtscDTDDnaVZ26474GkkSRIrrPEv5sgMTfHe+cA2O6wPH6vOBpYQNALneHb96XTEDI6dzpEZ0VzO0Rf3pP5LMLI4tAAAAABJRU5ErkJggg==" alt="" /></span>
<strong>Doctrine</strong>
<span class="count">
<span>{{ collector.querycount }}</span>
<span>{{ '%0.0f'|format(collector.time * 1000) }} ms</span>
</span>
</span>
{% else %}
<span class="label {{ collector.invalidEntityCount > 0 ? 'label-status-error' }} {{ collector.querycount == 0 ? 'disabled' }}">
<span class="icon">{{ include('@Doctrine/Collector/icon.svg') }}</span>
<strong>Doctrine</strong>
{% if collector.invalidEntityCount %}
<span class="count">
<span>{{ collector.invalidEntityCount }}</span>
</span>
{% endif %}
</span>
{% endif %}
{% endblock %}
{% block panel %}
{% set profiler_markup_version = profiler_markup_version|default(1) %}
{% if 'explain' == page %}
{{ render(controller('DoctrineBundle:Profiler:explain', {
token: token,
panel: 'db',
connectionName: app.request.query.get('connection'),
query: app.request.query.get('query')
})) }}
{% else %}
{{ block('queries') }}
{% endif %}
{% endblock %}
{% block queries %}
{% if profiler_markup_version == 1 %}
<style>
.hidden { display: none; }
.queries-table td, .queries-table th { vertical-align: top; }
.queries-table td > div { margin-bottom: 6px; }
.highlight pre { margin: 0; white-space: pre-wrap; }
.highlight .keyword { color: #8959A8; font-weight: bold; }
.highlight .word { color: #222222; }
.highlight .variable { color: #916319; }
.highlight .symbol { color: #222222; }
.highlight .comment { color: #999999; }
.highlight .backtick { color: #718C00; }
.highlight .string { color: #718C00; }
.highlight .number { color: #F5871F; font-weight: bold; }
.highlight .error { color: #C82829; }
</style>
{% endif %}
<h2>Queries</h2>
{% for connection, queries in collector.queries %}
{% if collector.connections|length > 1 %}
<h3>{{ connection }} <small>connection</small></h3>
{% endif %}
{% if queries is empty %}
<div class="empty">
<p>No database queries were performed.</p>
</div>
{% else %}
<table class="alt queries-table">
<thead>
<tr>
<th class="nowrap" onclick="javascript:sortTable(this, 0, 'queries-{{ loop.index }}')" data-sort-direction="-1" style="cursor: pointer;">#<span class="text-muted">▲</span></th>
<th class="nowrap" onclick="javascript:sortTable(this, 1, 'queries-{{ loop.index }}')" style="cursor: pointer;">Time<span></span></th>
<th style="width: 100%;">Info</th>
</tr>
</thead>
<tbody id="queries-{{ loop.index }}">
{% for i, query in queries %}
<tr id="queryNo-{{ i }}-{{ loop.parent.loop.index }}">
<td>{{ loop.index }}</td>
<td class="nowrap">{{ '%0.2f'|format(query.executionMS * 1000) }} ms</td>
<td>
{{ query.sql|doctrine_pretty_query(highlight_only = true) }}
<div>
<strong class="font-normal text-small">Parameters</strong>: {{ query.params|yaml_encode }}
</div>
<div class="text-small font-normal">
<a href="#" {{ profiler_markup_version == 1 ? 'onclick="return toggleRunnableQuery(this);"' }} class="sf-toggle link-inverse" data-toggle-selector="#formatted-query-{{ i }}-{{ loop.parent.loop.index }}" data-toggle-alt-content="Hide formatted query">View formatted query</a>
<a href="#" {{ profiler_markup_version == 1 ? 'onclick="return toggleRunnableQuery(this);"' }} class="sf-toggle link-inverse" data-toggle-selector="#original-query-{{ i }}-{{ loop.parent.loop.index }}" data-toggle-alt-content="Hide runnable query">View runnable query</a>
{% if query.explainable %}
<a class="link-inverse" href="{{ path('_profiler', { panel: 'db', token: token, page: 'explain', connection: connection, query: i }) }}" onclick="return explain(this);" data-target-id="explain-{{ i }}-{{ loop.parent.loop.index }}">Explain query</a>
{% endif %}
</div>
<div id="formatted-query-{{ i }}-{{ loop.parent.loop.index }}" class="sql-runnable hidden">
{{ query.sql|doctrine_pretty_query }}
</div>
<div id="original-query-{{ i }}-{{ loop.parent.loop.index }}" class="sql-runnable hidden">
{{ (query.sql ~ ';')|doctrine_replace_query_parameters(query.params)|doctrine_pretty_query(highlight_only = true) }}
</div>
{% if query.explainable %}
<div id="explain-{{ i }}-{{ loop.parent.loop.index }}"></div>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endfor %}
<h2>Database Connections</h2>
{% if not collector.connections %}
<div class="empty">
<p>There are no configured database connections.</p>
</div>
{% else %}
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.connections, labels: ['Name', 'Service'] }, with_context = false ) }}
{% endif %}
<h2>Entity Managers</h2>
{% if not collector.managers %}
<div class="empty">
<p>There are no configured entity managers.</p>
</div>
{% else %}
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.managers, labels: ['Name', 'Service'] }, with_context = false ) }}
{% endif %}
<h2>Second Level Cache</h2>
{% if not collector.cacheEnabled %}
<div class="empty">
<p>Second Level Cache is not enabled.</p>
</div>
{% else %}
{% if not collector.cacheCounts %}
<div class="empty">
<p>Second level cache information is not available.</p>
</div>
{% else %}
{% if profiler_markup_version == 1 %}
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.cacheCounts }, with_context = false) }}
{% else %}
<div class="metrics">
<div class="metric">
<span class="value">{{ collector.cacheCounts.hits }}</span>
<span class="label">Hits</span>
</div>
<div class="metric">
<span class="value">{{ collector.cacheCounts.misses }}</span>
<span class="label">Misses</span>
</div>
<div class="metric">
<span class="value">{{ collector.cacheCounts.puts }}</span>
<span class="label">Puts</span>
</div>
</div>
{% endif %}
{% if collector.cacheRegions.hits %}
<h3>Number of cache hits</h3>
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.cacheRegions.hits }, with_context = false) }}
{% endif %}
{% if collector.cacheRegions.misses %}
<h3>Number of cache misses</h3>
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.cacheRegions.misses }, with_context = false) }}
{% endif %}
{% if collector.cacheRegions.puts %}
<h3>Number of cache puts</h3>
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.cacheRegions.puts }, with_context = false) }}
{% endif %}
{% endif %}
{% endif %}
<h2>Entities Mapping</h2>
{% for manager, classes in collector.entities %}
{% if collector.managers|length > 1 %}
<h3>{{ manager }} <small>entity manager</small></h3>
{% endif %}
{% if classes is empty %}
<div class="empty">
<p>No loaded entities.</p>
</div>
{% else %}
<table>
<thead>
<tr>
<th scope="col">Class</th>
<th scope="col">Mapping errors</th>
</tr>
</thead>
<tbody>
{% for class in classes %}
{% set contains_errors = collector.mappingErrors[manager] is defined and collector.mappingErrors[manager][class] is defined %}
<tr class="{{ contains_errors ? 'status-error' }}">
<td>{{ class }}</td>
<td class="font-normal">
{% if contains_errors %}
<ul>
{% for error in collector.mappingErrors[manager][class] %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% else %}
No errors.
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endfor %}
<script type="text/javascript">//<![CDATA[
function explain(link) {
"use strict";
var targetId = link.getAttribute('data-target-id');
var targetElement = document.getElementById(targetId);
if (targetElement.style.display != 'block') {
Sfjs.load(targetId, link.href, null, function(xhr, el) {
el.innerHTML = 'An error occurred while loading the query explanation.';
});
targetElement.style.display = 'block';
link.innerHTML = 'Hide query explanation';
} else {
targetElement.style.display = 'none';
link.innerHTML = 'Explain query';
}
return false;
}
function sortTable(header, column, targetId) {
"use strict";
var direction = parseInt(header.getAttribute('data-sort-direction')) || 1,
items = [],
target = document.getElementById(targetId),
rows = target.children,
headers = header.parentElement.children,
i;
for (i = 0; i < rows.length; ++i) {
items.push(rows[i]);
}
for (i = 0; i < headers.length; ++i) {
headers[i].removeAttribute('data-sort-direction');
if (headers[i].children.length > 0) {
headers[i].children[0].innerHTML = '';
}
}
header.setAttribute('data-sort-direction', (-1*direction).toString());
header.children[0].innerHTML = direction > 0 ? '<span class="text-muted">▲</span>' : '<span class="text-muted">▼</span>';
items.sort(function(a, b) {
return direction * (parseFloat(a.children[column].innerHTML) - parseFloat(b.children[column].innerHTML));
});
for (i = 0; i < items.length; ++i) {
Sfjs.removeClass(items[i], i % 2 ? 'even' : 'odd');
Sfjs.addClass(items[i], i % 2 ? 'odd' : 'even');
target.appendChild(items[i]);
}
}
{% if profiler_markup_version == 1 %}
function toggleRunnableQuery(target) {
var targetSelector = target.getAttribute('data-toggle-selector');
var targetElement = document.querySelector(targetSelector);
if (targetElement.style.display != 'block') {
targetElement.style.display = 'block';
target.innerHTML = 'Hide runnable query';
} else {
targetElement.style.display = 'none';
target.innerHTML = 'View runnable query';
}
return false;
}
{% endif %}
//]]></script>
{% endblock %}
|