Sindbad~EG File Manager
{% extends '@WebProfiler/Profiler/layout.html.twig' %}
{% from _self import form_tree_entry, form_tree_details %}
{% block toolbar %}
{% if collector.data.nb_errors > 0 or collector.data.forms|length %}
{% set status_color = collector.data.nb_errors ? 'red' %}
{% set icon %}
{{ include('@WebProfiler/Icon/form.svg') }}
<span class="sf-toolbar-value">
{{ collector.data.nb_errors ?: collector.data.forms|length }}
</span>
{% endset %}
{% set text %}
<div class="sf-toolbar-info-piece">
<b>Number of forms</b>
<span class="sf-toolbar-status">{{ collector.data.forms|length }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Number of errors</b>
<span class="sf-toolbar-status sf-toolbar-status-{{ collector.data.nb_errors > 0 ? 'red' }}">{{ collector.data.nb_errors }}</span>
</div>
{% endset %}
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url, status: status_color }) }}
{% endif %}
{% endblock %}
{% block menu %}
<span class="label label-status-{{ collector.data.nb_errors ? 'error' }} {{ collector.data.forms is empty ? 'disabled' }}">
<span class="icon">{{ include('@WebProfiler/Icon/form.svg') }}</span>
<strong>Forms</strong>
{% if collector.data.nb_errors > 0 %}
<span class="count">
<span>{{ collector.data.nb_errors }}</span>
</span>
{% endif %}
</span>
{% endblock %}
{% block head %}
{{ parent() }}
<style>
#tree-menu {
float: left;
padding-right: 10px;
width: 230px;
}
#tree-menu ul {
list-style: none;
margin: 0;
padding-left: 0;
}
#tree-menu li {
margin: 0;
padding: 0;
width: 100%;
}
#tree-menu .empty {
border: 0;
padding: 0;
}
#tree-details-container {
border-left: 1px solid #DDD;
margin-left: 250px;
padding-left: 20px;
}
.tree-details {
padding-bottom: 40px;
}
.tree-details h3 {
font-size: 18px;
position: relative;
}
.toggle-icon {
display: inline-block;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgBAMAAADpp+X/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QweDgwx4LcKwAAAABVQTFRFAAAA////////////////ZmZm////bvjBwAAAAAV0Uk5TABZwsuCVEUjgAAAAAWJLR0QF+G/pxwAAAE1JREFUGNNjSHMSYGBgUEljSGYAAzMGBwiDhUEBwmBiEIAwGBmwgTQgQGWgA7h2uIFwK+CWwp1BpHvYEqDuATEYkBlY3IOmBq6dCPcAAIT5Eg2IksjQAAAAAElFTkSuQmCC") no-repeat top left #5eb5e0;
}
.closed .toggle-icon, .closed.toggle-icon {
background-position: bottom left;
}
.toggle-icon.empty {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAZgBmAGYHukptAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QweDhIf6CA40AAAAFRJREFUOMvtk7ENACEMA61vfx767MROWfO+AdGBHlNyTZrYUZRYDBII4NWE1pNdpFarfgLUbpDaBEgBYRiEVjsvDLa1l6O4Z3wkFWN+OfLKdpisOH/TlICzukmUJwAAAABJRU5ErkJggg==");
}
.tree .tree-inner {
cursor: pointer;
padding: 5px 7px 5px 22px;
position: relative;
}
.tree .toggle-button {
/* provide a bigger clickable area than just 10x10px */
width: 16px;
height: 16px;
margin-left: -18px;
}
.tree .toggle-icon {
width: 10px;
height: 10px;
/* position the icon in the center of the clickable area */
margin-left: 3px;
margin-top: 3px;
background-size: 10px 20px;
background-color: #AAA;
}
.tree .toggle-icon.empty {
width: 10px;
height: 10px;
position: absolute;
top: 50%;
margin-top: -5px;
margin-left: -15px;
background-size: 10px 10px;
}
.tree ul ul .tree-inner {
padding-left: 37px;
}
.tree ul ul ul .tree-inner {
padding-left: 52px;
}
.tree ul ul ul ul .tree-inner {
padding-left: 67px;
}
.tree ul ul ul ul ul .tree-inner {
padding-left: 82px;
}
.tree .tree-inner:hover {
background: #dfdfdf;
}
.tree .tree-inner:hover span:not(.has-error) {
color: var(--base-0);
}
.tree .tree-inner.active, .tree .tree-inner.active:hover {
background: var(--tree-active-background);
font-weight: bold;
}
.tree .tree-inner.active .toggle-icon, .tree .tree-inner:hover .toggle-icon, .tree .tree-inner.active:hover .toggle-icon {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgBAMAAADpp+X/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QweDhEYXWn+sAAAABhQTFRFAAAA39/f39/f39/f39/fZmZm39/f////gc3YPwAAAAV0Uk5TAAtAc6ZeVyCYAAAAAWJLR0QF+G/pxwAAAE1JREFUGNNjSHMSYGBgUEljSGYAAzMGBwiDhUEBwmBiEIAwGBmwgXIgQGWgA7h2uIFwK+CWwp1BpHvYC6DuATEYkBlY3IOmBq6dCPcAADqLE4MnBi/fAAAAAElFTkSuQmCC");
background-color: #999;
}
.tree .tree-inner.active .toggle-icon.empty, .tree .tree-inner:hover .toggle-icon.empty, .tree .tree-inner.active:hover .toggle-icon.empty {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QweDhoucSey4gAAABVQTFRFAAAA39/f39/f39/f39/fZmZm39/fD5Dx2AAAAAV0Uk5TAAtAc6ZeVyCYAAAAAWJLR0QF+G/pxwAAADJJREFUCNdjSHMSYGBgUEljSGYAAzMGBwiDhUEBwmBiEIAwGBnIA3DtcAPhVsAthTkDAFOfBKW9C1iqAAAAAElFTkSuQmCC");
}
.tree-details .toggle-icon {
width: 16px;
height: 16px;
/* vertically center the button */
position: absolute;
top: 50%;
margin-top: -9px;
margin-left: 6px;
}
.badge-error {
float: right;
background: var(--background-error);
color: #FFF;
padding: 1px 4px;
font-size: 10px;
font-weight: bold;
vertical-align: middle;
}
.has-error {
color: var(--color-error);
}
.errors h3 {
color: var(--color-error);
}
.errors th {
background: var(--background-error);
color: #FFF;
}
.errors .toggle-icon {
background-color: var(--background-error);
}
h3 a, h3 a:hover, h3 a:focus {
color: inherit;
text-decoration: inherit;
}
h2 + h3.form-data-type {
margin-top: 0;
}
h3.form-data-type + h3 {
margin-top: 1em;
}
.theme-dark .toggle-icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgBAMAAADpp+X/AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAVUExURUdwTH+Ag0lNUZiYmGRmbP///zU5P2n9VV4AAAAFdFJOUwCv+yror0g1sQAAAE1JREFUGNNjSFM0YGBgEEpjSGEAAzcGBQiDiUEAwmBkMIAwmBmwgVAgQGWgA7h2uIFwK+CWwp1BpHtYA6DuATEYkBlY3IOmBq6dCPcAAKMtEEs3tfChAAAAAElFTkSuQmCC');
}
.theme-dark .toggle-icon.empty {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAASUExURUdwTDI3OzQ5PS4uLjU3PzU5P4keoyIAAAAFdFJOUwBApgtzrnKGEwAAADJJREFUCNdjCFU0YGBgEAplCGEAA1cGBQiDiUEAwmBkMIAwmBnIA3DtcAPhVsAthTkDACsZBBmrTTSxAAAAAElFTkSuQmCC');
}
.theme-dark .tree .tree-inner.active .toggle-icon, .theme-dark .tree .tree-inner:hover .toggle-icon, .theme-dark .tree .tree-inner.active:hover .toggle-icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgBAMAAADpp+X/AAAAD1BMVEVHcEx/gIOYmJiZmZn///+IJ2wIAAAAA3RSTlMAryoIUq0uAAAAUElEQVQY02NgYFQ2NjYWYGBgMAYDBgZmCMOAQRjCMGRQhjCMoEqAipAYLkCAykBXA9cONxBuBdxShDOIc4+JM9Q9IIYxMgOLe9DUwLUT4R4AznguG0qfEa0AAAAASUVORK5CYII=');
background-color: transparent;
}
.theme-dark .tree .tree-inner.active .toggle-icon.empty, .theme-dark .tree .tree-inner:hover .toggle-icon.empty, .theme-dark .tree .tree-inner.active:hover .toggle-icon.empty {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAACVBMVEVHcEwyNzuqqqrd9nIgAAAAAnRSTlMAQABPjKgAAAArSURBVAjXY2BctcqBgWvVqgUMWqtWrWDIWrVqJcMqICCGACsGawMbADIKANflJYEoGMqtAAAAAElFTkSuQmCC');
background-color: transparent;
}
</style>
{% endblock %}
{% block panel %}
<h2>Forms</h2>
{% if collector.data.forms|length %}
<div id="tree-menu" class="tree">
<ul>
{% for formName, formData in collector.data.forms %}
{{ form_tree_entry(formName, formData, true) }}
{% endfor %}
</ul>
</div>
<div id="tree-details-container">
{% for formName, formData in collector.data.forms %}
{{ form_tree_details(formName, formData, collector.data.forms_by_hash, loop.first) }}
{% endfor %}
</div>
{% else %}
<div class="empty">
<p>No forms were submitted for this request.</p>
</div>
{% endif %}
<script>
function Toggler(storage) {
"use strict";
var STORAGE_KEY = 'sf_toggle_data',
states = {},
isCollapsed = function (button) {
return Sfjs.hasClass(button, 'closed');
},
isExpanded = function (button) {
return !isCollapsed(button);
},
expand = function (button) {
var targetId = button.dataset.toggleTargetId,
target = document.getElementById(targetId);
if (!target) {
throw "Toggle target " + targetId + " does not exist";
}
if (isCollapsed(button)) {
Sfjs.removeClass(button, 'closed');
Sfjs.removeClass(target, 'hidden');
states[targetId] = 1;
storage.setItem(STORAGE_KEY, states);
}
},
collapse = function (button) {
var targetId = button.dataset.toggleTargetId,
target = document.getElementById(targetId);
if (!target) {
throw "Toggle target " + targetId + " does not exist";
}
if (isExpanded(button)) {
Sfjs.addClass(button, 'closed');
Sfjs.addClass(target, 'hidden');
states[targetId] = 0;
storage.setItem(STORAGE_KEY, states);
}
},
toggle = function (button) {
if (Sfjs.hasClass(button, 'closed')) {
expand(button);
} else {
collapse(button);
}
},
initButtons = function (buttons) {
states = storage.getItem(STORAGE_KEY, {});
// must be an object, not an array or anything else
// `typeof` returns "object" also for arrays, so the following
// check must be done
// see http://stackoverflow.com/questions/4775722/check-if-object-is-array
if ('[object Object]' !== Object.prototype.toString.call(states)) {
states = {};
}
for (var i = 0, l = buttons.length; i < l; ++i) {
var targetId = buttons[i].dataset.toggleTargetId,
target = document.getElementById(targetId);
if (!target) {
throw "Toggle target " + targetId + " does not exist";
}
// correct the initial state of the button
if (Sfjs.hasClass(target, 'hidden')) {
Sfjs.addClass(buttons[i], 'closed');
}
// attach listener for expanding/collapsing the target
clickHandler(buttons[i], toggle);
if (states.hasOwnProperty(targetId)) {
// open or collapse based on stored data
if (0 === states[targetId]) {
collapse(buttons[i]);
} else {
expand(buttons[i]);
}
}
}
};
return {
initButtons: initButtons,
toggle: toggle,
isExpanded: isExpanded,
isCollapsed: isCollapsed,
expand: expand,
collapse: collapse
};
}
function JsonStorage(storage) {
var setItem = function (key, data) {
storage.setItem(key, JSON.stringify(data));
},
getItem = function (key, defaultValue) {
var data = storage.getItem(key);
if (null !== data) {
try {
return JSON.parse(data);
} catch(e) {
}
}
return defaultValue;
};
return {
setItem: setItem,
getItem: getItem
};
}
function TabView() {
"use strict";
var activeTab = null,
activeTarget = null,
select = function (tab) {
var targetId = tab.dataset.tabTargetId,
target = document.getElementById(targetId);
if (!target) {
throw "Tab target " + targetId + " does not exist";
}
if (activeTab) {
Sfjs.removeClass(activeTab, 'active');
}
if (activeTarget) {
Sfjs.addClass(activeTarget, 'hidden');
}
Sfjs.addClass(tab, 'active');
Sfjs.removeClass(target, 'hidden');
activeTab = tab;
activeTarget = target;
},
initTabs = function (tabs) {
for (var i = 0, l = tabs.length; i < l; ++i) {
var targetId = tabs[i].dataset.tabTargetId,
target = document.getElementById(targetId);
if (!target) {
throw "Tab target " + targetId + " does not exist";
}
clickHandler(tabs[i], select);
Sfjs.addClass(target, 'hidden');
}
if (tabs.length > 0) {
select(tabs[0]);
}
};
return {
initTabs: initTabs,
select: select
};
}
var tabTarget = new TabView(),
toggler = new Toggler(new JsonStorage(sessionStorage)),
clickHandler = function (element, callback) {
Sfjs.addEventListener(element, 'click', function (e) {
if (!e) {
e = window.event;
}
callback(this);
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
e.stopPropagation();
return false;
});
};
tabTarget.initTabs(document.querySelectorAll('.tree .tree-inner'));
toggler.initButtons(document.querySelectorAll('a.toggle-button'));
</script>
{% endblock %}
{% macro form_tree_entry(name, data, is_root) %}
{% import _self as tree %}
{% set has_error = data.errors is defined and data.errors|length > 0 %}
<li>
<div class="tree-inner" data-tab-target-id="{{ data.id }}-details">
{% if has_error %}
<div class="badge-error">{{ data.errors|length }}</div>
{% endif %}
{% if data.children is not empty %}
<a class="toggle-button" data-toggle-target-id="{{ data.id }}-children" href="#"><span class="toggle-icon"></span></a>
{% else %}
<div class="toggle-icon empty"></div>
{% endif %}
<span {% if has_error or data.has_children_error|default(false) %}class="has-error"{% endif %}>
{{ name|default('(no name)') }}
</span>
</div>
{% if data.children is not empty %}
<ul id="{{ data.id }}-children" {% if not is_root and not data.has_children_error|default(false) %}class="hidden"{% endif %}>
{% for childName, childData in data.children %}
{{ tree.form_tree_entry(childName, childData, false) }}
{% endfor %}
</ul>
{% endif %}
</li>
{% endmacro %}
{% macro form_tree_details(name, data, forms_by_hash, show) %}
{% import _self as tree %}
<div class="tree-details{% if not show|default(false) %} hidden{% endif %}" {% if data.id is defined %}id="{{ data.id }}-details"{% endif %}>
<h2>{{ name|default('(no name)') }}</h2>
{% if data.type_class is defined %}
<h3 class="dump-inline form-data-type">{{ profiler_dump(data.type_class) }}</h3>
{% endif %}
{% if data.errors is defined and data.errors|length > 0 %}
<div class="errors">
<h3>
<a class="toggle-button" data-toggle-target-id="{{ data.id }}-errors" href="#">
Errors <span class="toggle-icon"></span>
</a>
</h3>
<table id="{{ data.id }}-errors">
<thead>
<tr>
<th>Message</th>
<th>Origin</th>
<th>Cause</th>
</tr>
</thead>
<tbody>
{% for error in data.errors %}
<tr>
<td>{{ error.message }}</td>
<td>
{% if error.origin is empty %}
<em>This form.</em>
{% elseif forms_by_hash[error.origin] is not defined %}
<em>Unknown.</em>
{% else %}
{{ forms_by_hash[error.origin].name }}
{% endif %}
</td>
<td>
{% if error.trace %}
<span class="newline">Caused by:</span>
{% for stacked in error.trace %}
{{ profiler_dump(stacked) }}
{% endfor %}
{% else %}
<em>Unknown.</em>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% if data.default_data is defined %}
<h3>
<a class="toggle-button" data-toggle-target-id="{{ data.id }}-default_data" href="#">
Default Data <span class="toggle-icon"></span>
</a>
</h3>
<div id="{{ data.id }}-default_data">
<table>
<thead>
<tr>
<th width="180">Property</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<th class="font-normal" scope="row">Model Format</th>
<td>
{% if data.default_data.model is defined %}
{{ profiler_dump(data.default_data.seek('model')) }}
{% else %}
<em class="font-normal text-muted">same as normalized format</em>
{% endif %}
</td>
</tr>
<tr>
<th class="font-normal" scope="row">Normalized Format</th>
<td>{{ profiler_dump(data.default_data.seek('norm')) }}</td>
</tr>
<tr>
<th class="font-normal" scope="row">View Format</th>
<td>
{% if data.default_data.view is defined %}
{{ profiler_dump(data.default_data.seek('view')) }}
{% else %}
<em class="font-normal text-muted">same as normalized format</em>
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
{% endif %}
{% if data.submitted_data is defined %}
<h3>
<a class="toggle-button" data-toggle-target-id="{{ data.id }}-submitted_data" href="#">
Submitted Data <span class="toggle-icon"></span>
</a>
</h3>
<div id="{{ data.id }}-submitted_data">
{% if data.submitted_data.norm is defined %}
<table>
<thead>
<tr>
<th width="180">Property</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<th class="font-normal" scope="row">View Format</th>
<td>
{% if data.submitted_data.view is defined %}
{{ profiler_dump(data.submitted_data.seek('view')) }}
{% else %}
<em class="font-normal text-muted">same as normalized format</em>
{% endif %}
</td>
</tr>
<tr>
<th class="font-normal" scope="row">Normalized Format</th>
<td>{{ profiler_dump(data.submitted_data.seek('norm')) }}</td>
</tr>
<tr>
<th class="font-normal" scope="row">Model Format</th>
<td>
{% if data.submitted_data.model is defined %}
{{ profiler_dump(data.submitted_data.seek('model')) }}
{% else %}
<em class="font-normal text-muted">same as normalized format</em>
{% endif %}
</td>
</tr>
</tbody>
</table>
{% else %}
<div class="empty">
<p>This form was not submitted.</p>
</div>
{% endif %}
</div>
{% endif %}
{% if data.passed_options is defined %}
<h3>
<a class="toggle-button" data-toggle-target-id="{{ data.id }}-passed_options" href="#">
Passed Options <span class="toggle-icon"></span>
</a>
</h3>
<div id="{{ data.id }}-passed_options">
{% if data.passed_options|length %}
<table>
<thead>
<tr>
<th width="180">Option</th>
<th>Passed Value</th>
<th>Resolved Value</th>
</tr>
</thead>
<tbody>
{% for option, value in data.passed_options %}
<tr>
<th>{{ option }}</th>
<td>{{ profiler_dump(value) }}</td>
<td>
{# values can be stubs #}
{% set option_value = value.value|default(value) %}
{% set resolved_option_value = data.resolved_options[option].value|default(data.resolved_options[option]) %}
{% if resolved_option_value == option_value %}
<em class="font-normal text-muted">same as passed value</em>
{% else %}
{{ profiler_dump(data.resolved_options.seek(option)) }}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="empty">
<p>No options were passed when constructing this form.</p>
</div>
{% endif %}
</div>
{% endif %}
{% if data.resolved_options is defined %}
<h3>
<a class="toggle-button" data-toggle-target-id="{{ data.id }}-resolved_options" href="#">
Resolved Options <span class="toggle-icon"></span>
</a>
</h3>
<div id="{{ data.id }}-resolved_options" class="hidden">
<table>
<thead>
<tr>
<th width="180">Option</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for option, value in data.resolved_options %}
<tr>
<th scope="row">{{ option }}</th>
<td>{{ profiler_dump(value) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% if data.view_vars is defined %}
<h3>
<a class="toggle-button" data-toggle-target-id="{{ data.id }}-view_vars" href="#">
View Variables <span class="toggle-icon"></span>
</a>
</h3>
<div id="{{ data.id }}-view_vars" class="hidden">
<table>
<thead>
<tr>
<th width="180">Variable</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for variable, value in data.view_vars %}
<tr>
<th scope="row">{{ variable }}</th>
<td>{{ profiler_dump(value) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
</div>
{% for childName, childData in data.children %}
{{ tree.form_tree_details(childName, childData, forms_by_hash) }}
{% endfor %}
{% endmacro %}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists