[TASK] Remove deprecated code
[Packages/TYPO3.CMS.git] / typo3 / sysext / dbal / Classes / Controller / ModuleController.php
1 <?php
2 namespace TYPO3\CMS\Dbal\Controller;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2004-2013 Kasper Skårhøj (kasperYYYY@typo3.com)
8 * (c) 2004-2013 Karsten Dambekalns (karsten@typo3.org)
9 * All rights reserved
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * Script class; Backend module for DBAL extension
30 *
31 * @author Kasper Skårhøj <kasper@typo3.com>
32 * @author Karsten Dambekalns <karsten@typo3.org>
33 */
34 class ModuleController extends \TYPO3\CMS\Backend\Module\BaseScriptClass {
35
36 /**
37 * @var string
38 */
39 protected $thisScript;
40
41 /**
42 * Adds items to the ->MOD_MENU array. Used for the function menu selector.
43 *
44 * @return void
45 */
46 public function menuConfig() {
47 $this->MOD_MENU = array(
48 'function' => array(
49 0 => $GLOBALS['LANG']->getLL('Debug_log'),
50 'info' => $GLOBALS['LANG']->getLL('Cached_info'),
51 'sqlcheck' => $GLOBALS['LANG']->getLL('SQL_check')
52 )
53 );
54 parent::menuConfig();
55 }
56
57 /**
58 * Main function of the module. Write the content to $this->content
59 *
60 * @return void
61 */
62 public function main() {
63 $this->thisScript = 'mod.php?M=' . $this->MCONF['name'];
64 // Clean up settings:
65 $this->MOD_SETTINGS = \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData($this->MOD_MENU, \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('SET'), $this->MCONF['name']);
66 // Draw the header
67 $this->doc = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
68 $this->doc->backPath = $GLOBALS['BACK_PATH'];
69 $this->doc->form = '<form action="" method="post">';
70 // JavaScript
71 $this->doc->JScode = $this->doc->wrapScriptTags('
72 script_ended = 0;
73 function jumpToUrl(URL) { //
74 window.location.href = URL;
75 }
76 ');
77 // DBAL page title:
78 $this->content .= $this->doc->startPage($GLOBALS['LANG']->getLL('title'));
79 $this->content .= $this->doc->header($GLOBALS['LANG']->getLL('title'));
80 $this->content .= $this->doc->spacer(5);
81 $this->content .= $this->doc->section('', $this->doc->funcMenu('', \TYPO3\CMS\Backend\Utility\BackendUtility::getFuncMenu(0, 'SET[function]', $this->MOD_SETTINGS['function'], $this->MOD_MENU['function'])));
82 // Debug log:
83 switch ($this->MOD_SETTINGS['function']) {
84 case 'info':
85 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('Cached_info'), $this->printCachedInfo());
86 break;
87 case 'sqlcheck':
88 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('SQL_check'), $this->printSqlCheck());
89 break;
90 case 0:
91 $this->content .= $this->doc->section($GLOBALS['LANG']->getLL('Debug_log'), $this->printLogMgm());
92 break;
93 }
94 // ShortCut
95 if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
96 $this->content .= $this->doc->spacer(20) . $this->doc->section('', $this->doc->makeShortcutIcon('id', implode(',', array_keys($this->MOD_MENU)), $this->MCONF['name']));
97 }
98 $this->content .= $this->doc->spacer(10);
99 }
100
101 /**
102 * Prints out the module HTML
103 *
104 * @return string HTML output
105 */
106 public function printContent() {
107 $this->content .= $this->doc->endPage();
108 echo $this->content;
109 }
110
111 /**
112 * Displays a form to check DBAL SQL methods and parse raw SQL.
113 *
114 * @return string HTML output
115 */
116 protected function printSqlCheck() {
117 $input = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_dbal');
118 $out = '
119 <form name="sql_check" action="' . $this->thisScript . '" method="post" enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '">
120 <script type="text/javascript">
121 /*<![CDATA[*/
122 function updateQryForm(s) {
123 document.getElementById(\'tx-dbal-result\').style.display = \'none\';
124 switch(s) {
125 case \'SELECT\':
126 document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
127 document.getElementById(\'tx-dbal-qryfields\').style.display = \'table-row\';
128 document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
129 document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
130 document.getElementById(\'tx-dbal-qryfrom\').style.display = \'table-row\';
131 document.getElementById(\'tx-dbal-qryinto\').style.display = \'none\';
132 document.getElementById(\'tx-dbal-qrywhere\').style.display = \'table-row\';
133 document.getElementById(\'tx-dbal-qrygroup\').style.display = \'table-row\';
134 document.getElementById(\'tx-dbal-qryorder\').style.display = \'table-row\';
135 document.getElementById(\'tx-dbal-qrylimit\').style.display = \'table-row\';
136 break;
137 case \'INSERT\':
138 document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
139 document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
140 document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'table-row\';
141 document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
142 document.getElementById(\'tx-dbal-qryfrom\').style.display = \'none\';
143 document.getElementById(\'tx-dbal-qryinto\').style.display = \'table-row\';
144 document.getElementById(\'tx-dbal-qrywhere\').style.display = \'table-row\';
145 document.getElementById(\'tx-dbal-qrygroup\').style.display = \'table-row\';
146 document.getElementById(\'tx-dbal-qryorder\').style.display = \'table-row\';
147 document.getElementById(\'tx-dbal-qrylimit\').style.display = \'table-row\';
148 break;
149 case \'UPDATE\':
150 document.getElementById(\'tx-dbal-qryupdate\').style.display = \'table-row\';
151 document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
152 document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
153 document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'table-row\';
154 document.getElementById(\'tx-dbal-qryfrom\').style.display = \'none\';
155 document.getElementById(\'tx-dbal-qryinto\').style.display = \'none\';
156 document.getElementById(\'tx-dbal-qryupdate\').style.display = \'table-row\';
157 document.getElementById(\'tx-dbal-qrywhere\').style.display = \'table-row\';
158 document.getElementById(\'tx-dbal-qrygroup\').style.display = \'none\';
159 document.getElementById(\'tx-dbal-qryorder\').style.display = \'none\';
160 document.getElementById(\'tx-dbal-qrylimit\').style.display = \'none\';
161 break;
162 case \'DELETE\':
163 document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
164 document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
165 document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
166 document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
167 document.getElementById(\'tx-dbal-qryfrom\').style.display = \'table-row\';
168 document.getElementById(\'tx-dbal-qryinto\').style.display = \'none\';
169 document.getElementById(\'tx-dbal-qrywhere\').style.display = \'table-row\';
170 document.getElementById(\'tx-dbal-qrygroup\').style.display = \'none\';
171 document.getElementById(\'tx-dbal-qryorder\').style.display = \'none\';
172 document.getElementById(\'tx-dbal-qrylimit\').style.display = \'none\';
173 break;
174 }
175 }
176 /*]]>*/
177 </script>
178 <table>
179 <tr class="tableheader bgColor5"><th colspan="2">Easy SQL check</th></tr>
180 <tr><td colspan="2">
181 <select name="tx_dbal[QUERY]"size="1" onchange="updateQryForm(this.options[this.selectedIndex].value)">
182 <option value="SELECT" ' . ($input['QUERY'] === 'SELECT' ? 'selected="selected"' : '') . '>SELECT</option>
183 <option value="INSERT" ' . ($input['QUERY'] === 'INSERT' ? 'selected="selected"' : '') . '>INSERT</option>
184 <option value="UPDATE" ' . ($input['QUERY'] === 'UPDATE' ? 'selected="selected"' : '') . '>UPDATE</option>
185 <option value="DELETE" ' . ($input['QUERY'] === 'DELETE' ? 'selected="selected"' : '') . '>DELETE</option>
186 </select>
187 </td></tr>
188 <tr id="tx-dbal-qryupdate" style="display:none;"><td></td><td><input name="tx_dbal[UPDATE]" value="' . $input['UPDATE'] . '" type="text" size="30" maxsize="100" /></td></tr>
189 <tr id="tx-dbal-qryfields"><td></td><td><input name="tx_dbal[FIELDS]" value="' . $input['FIELDS'] . '" type="text" size="30" maxsize="100" /></td></tr>
190 <tr id="tx-dbal-qryinsertvalues" style="display:none;"><td></td><td><textarea name="tx_dbal[INSERTVALUES]" cols="30" rows="4">' . $input['INSERTVALUES'] . '</textarea></td></tr>
191 <tr id="tx-dbal-qryupdatevalues" style="display:none;"><th>SET</th><td><textarea name="tx_dbal[UPDATEVALUES]" cols="30" rows="4">' . $input['UPDATEVALUES'] . '</textarea></td></tr>
192 <tr id="tx-dbal-qryfrom"><th>FROM</th><td><input name="tx_dbal[FROM]" value="' . $input['FROM'] . '" type="text" size="30" maxsize="100" /></td></tr>
193 <tr id="tx-dbal-qryinto" style="display:none;"><th>INTO</th><td><input name="tx_dbal[INTO]" value="' . $input['INTO'] . '" type="text" size="30" maxsize="100" /></td></tr>
194 <tr id="tx-dbal-qrywhere"><th>WHERE</th><td><input name="tx_dbal[WHERE]" value="' . $input['WHERE'] . '" type="text" size="30" maxsize="100" /></td></tr>
195 <tr id="tx-dbal-qrygroup"><th>GROUP BY</th><td><input name="tx_dbal[GROUP]" value="' . $input['GROUP'] . '" type="text" size="30" maxsize="100" /></td></tr>
196 <tr id="tx-dbal-qryorder"><th>ORDER BY</th><td><input name="tx_dbal[ORDER]" value="' . $input['ORDER'] . '" type="text" size="30" maxsize="100" /></td></tr>
197 <tr id="tx-dbal-qrylimit"><th>LIMIT</th><td><input name="tx_dbal[LIMIT]" value="' . $input['LIMIT'] . '" type="text" size="30" maxsize="100" /></td></tr>
198 <tr><td></td><td style="text-align:right;"><input type="submit" value="CHECK" /></td></tr>
199 <script type="text/javascript">
200 /*<![CDATA[*/
201 updateQryForm(\'' . $input['QUERY'] . '\');
202 /*]]>*/
203 </script>
204 ';
205 $out .= '<tr id="tx-dbal-result" class="bgColor4"><th>Result:</th><td>';
206 switch ($input['QUERY']) {
207 case 'SELECT':
208 $qry = $GLOBALS['TYPO3_DB']->SELECTquery($input['FIELDS'], $input['FROM'], $input['WHERE'], $input['GROUP'], $input['ORDER'], $input['LIMIT']);
209 break;
210 case 'INSERT':
211 $qry = $GLOBALS['TYPO3_DB']->INSERTquery($input['INTO'], $this->createFieldsValuesArray($input['INSERTVALUES']));
212 break;
213 case 'UPDATE':
214 $qry = $GLOBALS['TYPO3_DB']->UPDATEquery($input['UPDATE'], $input['WHERE'], $this->createFieldsValuesArray($input['UPDATEVALUES']));
215 break;
216 case 'DELETE':
217 $qry = $GLOBALS['TYPO3_DB']->DELETEquery($input['FROM'], $input['WHERE']);
218 break;
219 }
220 $out .= '<pre>' . htmlspecialchars($qry) . '</pre></td></tr>';
221 $out .= '
222 <tr class="tableheader bgColor5"><th colspan="2">RAW SQL check</th></tr>
223 <tr><td colspan="2" style="text-align:right;"><textarea name="tx_dbal[RAWSQL]" cols="60" rows="5">' . $input['RAWSQL'] . '</textarea><br /><input type="submit" value="CHECK" /></td></tr>';
224 if (!empty($input['RAWSQL'])) {
225 $out .= '<tr class="bgColor4">';
226 $parseResult = $GLOBALS['TYPO3_DB']->SQLparser->parseSQL($input['RAWSQL']);
227 if (is_array($parseResult)) {
228 $newQuery = $GLOBALS['TYPO3_DB']->SQLparser->compileSQL($parseResult);
229 $testResult = $GLOBALS['TYPO3_DB']->SQLparser->debug_parseSQLpartCompare($input['RAWSQL'], $newQuery);
230 if (!is_array($testResult)) {
231 $out .= '<td colspan="2">' . $newQuery;
232 } else {
233 $out .= '<td colspan="2">' . htmlspecialchars($testResult[0]) . '</td></tr>
234 <tr><th>Error:</th><td style="border:2px solid #f00;">Input query did not match the parsed and recompiled query exactly (not observing whitespace):<br />' . htmlspecialchars($testResult[1]);
235 }
236 } else {
237 $out .= '<th>Result:</th><td style="border:2px solid #f00;">' . $parseResult;
238 }
239 $out .= '</td></tr>';
240 }
241 $out .= '</table></form>';
242 return $out;
243 }
244
245 /**
246 * Parses a very simple text format into an array.
247 *
248 * Each line is seen as a key/value pair that is exploded at =. This is used
249 * in the simple SQL check to input values for INSERT and UPDATE statements.
250 *
251 * @param string $in String to parse into key/value array.
252 * @return array Array created from the input string.
253 */
254 protected function createFieldsValuesArray($in) {
255 $ret = array();
256 $in = explode(chr(10), $in);
257 foreach ($in as $v) {
258 $fv = explode('=', $v);
259 $ret[$fv[0]] = $fv[1];
260 }
261 return $ret;
262 }
263
264 /**
265 * Prints out the cached information about the database.
266 *
267 * The DBAL caches a lot of information, e.g. about auto increment fields,
268 * field types and primary keys. This method formats all this into a HTML
269 * table to display in the BE.
270 *
271 * @return string HTML output
272 */
273 protected function printCachedInfo() {
274 // Get cmd:
275 if ((string) \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('cmd') === 'clear') {
276 $GLOBALS['TYPO3_DB']->clearCachedFieldInfo();
277 $GLOBALS['TYPO3_DB']->cacheFieldInfo();
278 }
279 $out = '<a name="autoincrement"></a><h2>auto_increment</h2>';
280 $out .= '<table border="1" cellspacing="0"><tbody><tr><th>Table</th><th>Field</th></tr>';
281 ksort($GLOBALS['TYPO3_DB']->cache_autoIncFields);
282 foreach ($GLOBALS['TYPO3_DB']->cache_autoIncFields as $table => $field) {
283 $out .= '<tr>';
284 $out .= '<td>' . $table . '</td>';
285 $out .= '<td>' . $field . '</td>';
286 $out .= '</tr>';
287 }
288 $out .= '</tbody></table>';
289 $out .= $this->doc->spacer(5);
290 $out .= '<a name="primarykeys"></a><h2>Primary keys</h2>';
291 $out .= '<table border="1" cellspacing="0"><tbody><tr><th>Table</th><th>Field(s)</th></tr>';
292 ksort($GLOBALS['TYPO3_DB']->cache_primaryKeys);
293 foreach ($GLOBALS['TYPO3_DB']->cache_primaryKeys as $table => $field) {
294 $out .= '<tr>';
295 $out .= '<td>' . $table . '</td>';
296 $out .= '<td>' . $field . '</td>';
297 $out .= '</tr>';
298 }
299 $out .= '</tbody></table>';
300 $out .= $this->doc->spacer(5);
301 $out .= '<a name="fieldtypes"></a><h2>Field types</h2>';
302 $out .= '<table border="1" cellspacing="0"><tbody><tr><th colspan="5">Table</th></tr><tr><th>Field</th><th>Type</th><th><a href="#metatypes">Metatype</a></th><th>NOT NULL</th><th>Default</th></th></tr>';
303 ksort($GLOBALS['TYPO3_DB']->cache_fieldType);
304 foreach ($GLOBALS['TYPO3_DB']->cache_fieldType as $table => $fields) {
305 $out .= '<th colspan="5">' . $table . '</th>';
306 foreach ($fields as $field => $data) {
307 $out .= '<tr>';
308 $out .= '<td>' . $field . '</td>';
309 $out .= '<td>' . $data['type'] . '</td>';
310 $out .= '<td>' . $data['metaType'] . '</td>';
311 $out .= '<td>' . ($data['notnull'] ? 'NOT NULL' : '') . '</td>';
312 $out .= '<td>' . $data['default'] . '</td>';
313 $out .= '</tr>';
314 }
315 }
316 $out .= '</tbody></table>';
317 $out .= $this->doc->spacer(5);
318 $out .= '<a name="metatypes"></a><h2>Metatype explanation</h2>';
319 $out .= '<pre>
320 C: Varchar, capped to 255 characters.
321 X: Larger varchar, capped to 4000 characters (to be compatible with Oracle).
322 XL: For Oracle, returns CLOB, otherwise the largest varchar size.
323
324 C2: Multibyte varchar
325 X2: Multibyte varchar (largest size)
326
327 B: BLOB (binary large object)
328
329 D: Date (some databases do not support this, and we return a datetime type)
330 T: Datetime or Timestamp
331 L: Integer field suitable for storing booleans (0 or 1)
332 I: Integer (mapped to I4)
333 I1: 1-byte integer
334 I2: 2-byte integer
335 I4: 4-byte integer
336 I8: 8-byte integer
337 F: Floating point number
338 N: Numeric or decimal number</pre>';
339 $menu = '<a href="' . $this->thisScript . '&amp;cmd=clear">CLEAR DATA</a><hr />';
340 $menu .= '<a href="#autoincrement">auto_increment</a> | <a href="#primarykeys">Primary keys</a> | <a href="#fieldtypes">Field types</a> | <a href="#metatypes">Metatype explanation</a><hr />';
341 return $menu . $out;
342 }
343
344 /**
345 * Printing the debug-log from the DBAL extension
346 *
347 * To enabled debugging, you will have to enabled it in the configuration!
348 *
349 * @return string HTML content
350 */
351 protected function printLogMgm() {
352 // Disable debugging in any case...
353 $GLOBALS['TYPO3_DB']->debug = FALSE;
354 // Get cmd:
355 $cmd = (string) \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('cmd');
356 switch ($cmd) {
357 case 'flush':
358 $res = $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('tx_dbal_debuglog');
359 $res = $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('tx_dbal_debuglog_where');
360 $outStr = 'Log FLUSHED!';
361 break;
362 case 'joins':
363 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('table_join,exec_time,query,script', 'tx_dbal_debuglog', 'table_join!=\'\'', 'table_join,script,exec_time,query');
364 // Init vars in which to pick up the query result:
365 $tableIndex = array();
366 $tRows = array();
367 $tRows[] = '
368 <tr>
369 <td>Execution time</td>
370 <td>Table joins</td>
371 <td>Script</td>
372 <td>Query</td>
373 </tr>';
374 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
375 $tableArray = $GLOBALS['TYPO3_DB']->SQLparser->parseFromTables($row['table_join']);
376 // Create table name index:
377 foreach ($tableArray as $a) {
378 foreach ($tableArray as $b) {
379 if ($b['table'] != $a['table']) {
380 $tableIndex[$a['table']][$b['table']] = 1;
381 }
382 }
383 }
384 // Create output row
385 $tRows[] = '
386 <tr>
387 <td>' . htmlspecialchars($row['exec_time']) . '</td>
388 <td>' . htmlspecialchars($row['table_join']) . '</td>
389 <td>' . htmlspecialchars($row['script']) . '</td>
390 <td>' . htmlspecialchars($row['query']) . '</td>
391 </tr>';
392 }
393 // Printing direct joins:
394 $outStr .= '<h4>Direct joins:</h4>' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray($tableIndex);
395 // Printing total dependencies:
396 foreach ($tableIndex as $priTable => $a) {
397 foreach ($tableIndex as $tableN => $v) {
398 foreach ($v as $tableP => $vv) {
399 if ($tableP == $priTable) {
400 $tableIndex[$priTable] = array_merge($v, $a);
401 }
402 }
403 }
404 }
405 $outStr .= '<h4>Total dependencies:</h4>' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray($tableIndex);
406 // Printing data rows:
407 $outStr .= '
408 <table border="1" cellspacing="0">' . implode('', $tRows) . '
409 </table>';
410 break;
411 case 'errors':
412 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('serdata,exec_time,query,script', 'tx_dbal_debuglog', 'errorFlag>0', '', 'tstamp DESC');
413 // Init vars in which to pick up the query result:
414 $tRows = array();
415 $tRows[] = '
416 <tr>
417 <td>Execution time</td>
418 <td>Error data</td>
419 <td>Script</td>
420 <td>Query</td>
421 </tr>';
422 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
423 // Create output row
424 $tRows[] = '
425 <tr>
426 <td>' . htmlspecialchars($row['exec_time']) . '</td>
427 <td>' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray(unserialize($row['serdata'])) . '</td>
428 <td>' . htmlspecialchars($row['script']) . '</td>
429 <td>' . htmlspecialchars($row['query']) . '</td>
430 </tr>';
431 }
432 // Printing data rows:
433 $outStr .= '
434 <table border="1" cellspacing="0">' . implode('', $tRows) . '
435 </table>';
436 break;
437 case 'parsing':
438 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('query,serdata', 'tx_dbal_debuglog', 'errorFlag&2=2');
439 $tRows = array();
440 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
441 // Create output row
442 $tRows[] = '
443 <tr>
444 <td>' . htmlspecialchars($row['query']) . '</td>
445 </tr>';
446 }
447 // Printing data rows:
448 $outStr .= '
449 <table border="1" cellspacing="0">' . implode('', $tRows) . '
450 </table>';
451 break;
452 case 'where':
453 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('tstamp,script,tablename,whereclause', 'tx_dbal_debuglog_where', '', '', 'tstamp DESC');
454 $tRows = array();
455 $tRows[] = '
456 <tr>
457 <td>Time</td>
458 <td>Script</td>
459 <td>Table</td>
460 <td>WHERE clause</td>
461 </tr>';
462 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
463 $tRows[] = '
464 <tr>
465 <td>' . \TYPO3\CMS\Backend\Utility\BackendUtility::datetime($row['tstamp']) . '</td>
466 <td>' . htmlspecialchars($row['script']) . '</td>
467 <td>' . htmlspecialchars($row['tablename']) . '</td>
468 <td>' . str_replace(array('\'\'', '""', 'IS NULL', 'IS NOT NULL'), array('<span style="background-color:#ff0000;color:#ffffff;padding:2px;font-weight:bold;">\'\'</span>', '<span style="background-color:#ff0000;color:#ffffff;padding:2px;font-weight:bold;">""</span>', '<span style="background-color:#00ff00;color:#ffffff;padding:2px;font-weight:bold;">IS NULL</span>', '<span style="background-color:#00ff00;color:#ffffff;padding:2px;font-weight:bold;">IS NOT NULL</span>'), htmlspecialchars($row['whereclause'])) . '</td>
469 </tr>';
470 }
471 $outStr = '
472 <table border="1" cellspacing="0">' . implode('', $tRows) . '
473 </table>';
474 break;
475 default:
476 // Look for request to view specific script exec:
477 $specTime = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('specTime');
478 if ($specTime) {
479 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('exec_time,errorFlag,table_join,serdata,query', 'tx_dbal_debuglog', 'tstamp=' . (int) $specTime);
480 $tRows = array();
481 $tRows[] = '
482 <tr>
483 <td>Execution time</td>
484 <td>Error</td>
485 <td>Table joins</td>
486 <td>Data</td>
487 <td>Query</td>
488 </tr>';
489 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
490 $tRows[] = '
491 <tr>
492 <td>' . htmlspecialchars($row['exec_time']) . '</td>
493 <td>' . ($row['errorFlag'] ? 1 : 0) . '</td>
494 <td>' . htmlspecialchars($row['table_join']) . '</td>
495 <td>' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray(unserialize($row['serdata'])) . '</td>
496 <td>' . str_replace(array('\'\'', '""', 'IS NULL', 'IS NOT NULL'), array('<span style="background-color:#ff0000;color:#ffffff;padding:2px;font-weight:bold;">\'\'</span>', '<span style="background-color:#ff0000;color:#ffffff;padding:2px;font-weight:bold;">""</span>', '<span style="background-color:#00ff00;color:#ffffff;padding:2px;font-weight:bold;">IS NULL</span>', '<span style="background-color:#00ff00;color:#ffffff;padding:2px;font-weight:bold;">IS NOT NULL</span>'), htmlspecialchars($row['query'])) . '</td>
497 </tr>';
498 }
499 } else {
500 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('tstamp,script, SUM(exec_time) as calc_sum, count(*) AS qrycount, MAX(errorFlag) as error', 'tx_dbal_debuglog', '', 'tstamp,script', 'tstamp DESC');
501 $tRows = array();
502 $tRows[] = '
503 <tr>
504 <td>Time</td>
505 <td># of queries</td>
506 <td>Error</td>
507 <td>Time (ms)</td>
508 <td>Script</td>
509 </tr>';
510 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
511 $tRows[] = '
512 <tr>
513 <td>' . \TYPO3\CMS\Backend\Utility\BackendUtility::datetime($row['tstamp']) . '</td>
514 <td>' . htmlspecialchars($row['qrycount']) . '</td>
515 <td>' . ($row['error'] ? '<strong style="color:#f00">ERR</strong>' : '') . '</td>
516 <td>' . htmlspecialchars($row['calc_sum']) . '</td>
517 <td><a href="' . $this->thisScript . '&amp;specTime=' . intval($row['tstamp']) . '">' . htmlspecialchars($row['script']) . '</a></td>
518 </tr>';
519 }
520 }
521 $outStr = '
522 <table border="1" cellspacing="0">' . implode('', $tRows) . '
523 </table>';
524 break;
525 }
526 $menu = '
527 <a href="' . $this->thisScript . '&amp;cmd=flush">FLUSH LOG</a> -
528 <a href="' . $this->thisScript . '&amp;cmd=joins">JOINS</a> -
529 <a href="' . $this->thisScript . '&amp;cmd=errors">ERRORS</a> -
530 <a href="' . $this->thisScript . '&amp;cmd=parsing">PARSING</a> -
531 <a href="' . $this->thisScript . '">LOG</a> -
532 <a href="' . $this->thisScript . '&amp;cmd=where">WHERE</a> -
533
534 <a href="' . htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::linkThisScript()) . '" target="tx_debuglog">[New window]</a>
535 <hr />
536 ';
537 return $menu . $outStr;
538 }
539
540 }
541
542
543 ?>