TYPO3 CMS  TYPO3_7-6
ModuleController.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
24 
29 {
33  protected $thisScript;
34 
40  protected $moduleName = 'tools_txdbalM1';
41 
47  protected $moduleTemplate;
48 
54  public function init()
55  {
56  $this->MCONF = [
57  'name' => $this->moduleName,
58  ];
59  $this->getLanguageService()->includeLLFile('EXT:dbal/Resources/Private/Language/locallang.xlf');
60  parent::init();
61  $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
62  }
63 
69  public function menuConfig()
70  {
71  $languageService = $this->getLanguageService();
72  $this->MOD_MENU = [
73  'function' => [
74  0 => $languageService->getLL('Debug_log'),
75  'info' => $languageService->getLL('Cached_info'),
76  'sqlcheck' => $languageService->getLL('SQL_check')
77  ]
78  ];
79  parent::menuConfig();
80  }
81 
87  public function main()
88  {
89  $languageService = $this->getLanguageService();
90  $this->thisScript = BackendUtility::getModuleUrl($this->MCONF['name']);
91  // Clean up settings:
92  $this->MOD_SETTINGS = BackendUtility::getModuleData(
93  $this->MOD_MENU,
94  GeneralUtility::_GP('SET'),
95  $this->MCONF['name']
96  );
97  // Draw the header
98  // DBAL page title:
99  $this->content .= '<h1>' . $languageService->getLL('title') . '</h1>';
100  $this->generateMenu();
101  $shortcutName = $languageService->getLL('Debug_log');
102  // Debug log:
103  switch ($this->MOD_SETTINGS['function']) {
104  case 'info':
105  $this->content .= '<h3>' . $languageService->getLL('Cached_info') . '</h3>';
106  $this->content .= '<div>' . $this->printCachedInfo() . '</div>';
107  $shortcutName = $languageService->getLL('Cached_info');
108  break;
109  case 'sqlcheck':
110  $this->content .= '<h3>' . $languageService->getLL('SQL_check') . '</h3>';
111  $this->content .= '<div>' . $this->printSqlCheck() . '</div>';
112  $shortcutName = $languageService->getLL('SQL_check');
113  break;
114  case 0:
115  $this->content .= '<h3>' . $languageService->getLL('Debug_log') . '</h3>';
116  $this->content .= '<div>' . $this->printLogMgm() . '</div>';
117  break;
118  }
119  // ShortCut
120  $shortcutButton = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar()->makeShortcutButton()
121  ->setModuleName($this->MCONF['name'])
122  ->setDisplayName($shortcutName)
123  ->setSetVariables(['function']);
124  $this->moduleTemplate->getDocHeaderComponent()->getButtonBar()->addButton($shortcutButton);
125  }
126 
135  public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
136  {
137  $GLOBALS['SOBE'] = $this;
138  $this->init();
139  $this->main();
140  $this->moduleTemplate->setContent($this->content);
141  $response->getBody()->write($this->moduleTemplate->renderContent());
142  return $response;
143  }
144 
150  protected function printSqlCheck()
151  {
152  $input = GeneralUtility::_GP('tx_dbal');
153  $out = '
154  <form name="sql_check" action="' . $this->thisScript . '" method="post" enctype="multipart/form-data">
155  <script type="text/javascript">
156 /*<![CDATA[*/
157 function updateQryForm(s) {
158  document.getElementById(\'tx-dbal-result\').style.display = \'none\';
159  switch(s) {
160  case \'SELECT\':
161  document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
162  document.getElementById(\'tx-dbal-qryfields\').style.display = \'table-row\';
163  document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
164  document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
165  document.getElementById(\'tx-dbal-qryfrom\').style.display = \'table-row\';
166  document.getElementById(\'tx-dbal-qryinto\').style.display = \'none\';
167  document.getElementById(\'tx-dbal-qrywhere\').style.display = \'table-row\';
168  document.getElementById(\'tx-dbal-qrygroup\').style.display = \'table-row\';
169  document.getElementById(\'tx-dbal-qryorder\').style.display = \'table-row\';
170  document.getElementById(\'tx-dbal-qrylimit\').style.display = \'table-row\';
171  break;
172  case \'INSERT\':
173  document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
174  document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
175  document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'table-row\';
176  document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
177  document.getElementById(\'tx-dbal-qryfrom\').style.display = \'none\';
178  document.getElementById(\'tx-dbal-qryinto\').style.display = \'table-row\';
179  document.getElementById(\'tx-dbal-qrywhere\').style.display = \'table-row\';
180  document.getElementById(\'tx-dbal-qrygroup\').style.display = \'table-row\';
181  document.getElementById(\'tx-dbal-qryorder\').style.display = \'table-row\';
182  document.getElementById(\'tx-dbal-qrylimit\').style.display = \'table-row\';
183  break;
184  case \'UPDATE\':
185  document.getElementById(\'tx-dbal-qryupdate\').style.display = \'table-row\';
186  document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
187  document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
188  document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'table-row\';
189  document.getElementById(\'tx-dbal-qryfrom\').style.display = \'none\';
190  document.getElementById(\'tx-dbal-qryinto\').style.display = \'none\';
191  document.getElementById(\'tx-dbal-qryupdate\').style.display = \'table-row\';
192  document.getElementById(\'tx-dbal-qrywhere\').style.display = \'table-row\';
193  document.getElementById(\'tx-dbal-qrygroup\').style.display = \'none\';
194  document.getElementById(\'tx-dbal-qryorder\').style.display = \'none\';
195  document.getElementById(\'tx-dbal-qrylimit\').style.display = \'none\';
196  break;
197  case \'DELETE\':
198  document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
199  document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
200  document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
201  document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
202  document.getElementById(\'tx-dbal-qryfrom\').style.display = \'table-row\';
203  document.getElementById(\'tx-dbal-qryinto\').style.display = \'none\';
204  document.getElementById(\'tx-dbal-qrywhere\').style.display = \'table-row\';
205  document.getElementById(\'tx-dbal-qrygroup\').style.display = \'none\';
206  document.getElementById(\'tx-dbal-qryorder\').style.display = \'none\';
207  document.getElementById(\'tx-dbal-qrylimit\').style.display = \'none\';
208  break;
209  }
210 }
211 /*]]>*/
212  </script>
213  <table>
214  <tr class="tableheader bgColor5"><th colspan="2">Easy SQL check</th></tr>
215  <tr><td colspan="2">
216  <select name="tx_dbal[QUERY]"size="1" onchange="updateQryForm(this.options[this.selectedIndex].value)">
217  <option value="SELECT" ' . ($input['QUERY'] === 'SELECT' ? 'selected="selected"' : '') . '>SELECT</option>
218  <option value="INSERT" ' . ($input['QUERY'] === 'INSERT' ? 'selected="selected"' : '') . '>INSERT</option>
219  <option value="UPDATE" ' . ($input['QUERY'] === 'UPDATE' ? 'selected="selected"' : '') . '>UPDATE</option>
220  <option value="DELETE" ' . ($input['QUERY'] === 'DELETE' ? 'selected="selected"' : '') . '>DELETE</option>
221  </select>
222  </td></tr>
223  <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>
224  <tr id="tx-dbal-qryfields"><td></td><td><input name="tx_dbal[FIELDS]" value="' . $input['FIELDS'] . '" type="text" size="30" maxsize="100" /></td></tr>
225  <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>
226  <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>
227  <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>
228  <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>
229  <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>
230  <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>
231  <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>
232  <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>
233  <tr>
234  <td></td>
235  <td style="text-align:right;">
236  <input class="btn btn-default" type="submit" value="CHECK" />
237  </td>
238  </tr>
239  <script type="text/javascript">
240 /*<![CDATA[*/
241 updateQryForm(\'' . $input['QUERY'] . '\');
242 /*]]>*/
243  </script>
244  ';
245  $out .= '<tr id="tx-dbal-result" class="bgColor4"><th>Result:</th><td>';
246  switch ($input['QUERY']) {
247  case 'SELECT':
248  $qry = $this->getDatabaseConnection()->SELECTquery($input['FIELDS'], $input['FROM'], $input['WHERE'], $input['GROUP'], $input['ORDER'], $input['LIMIT']);
249  break;
250  case 'INSERT':
251  $qry = $this->getDatabaseConnection()->INSERTquery($input['INTO'], $this->createFieldsValuesArray($input['INSERTVALUES']));
252  break;
253  case 'UPDATE':
254  $qry = $GLOBALS['TYPO3_DB']->UPDATEquery($input['UPDATE'], $input['WHERE'], $this->createFieldsValuesArray($input['UPDATEVALUES']));
255  break;
256  case 'DELETE':
257  $qry = $GLOBALS['TYPO3_DB']->DELETEquery($input['FROM'], $input['WHERE']);
258  break;
259  }
260  $out .= '<pre>' . htmlspecialchars($qry) . '</pre></td></tr>';
261  $out .= '
262  <tr class="tableheader bgColor5">
263  <th colspan="2">RAW SQL check</th>
264  </tr>
265  <tr>
266  <td colspan="2" style="text-align:right;">
267  <textarea name="tx_dbal[RAWSQL]" cols="60" rows="5">' . $input['RAWSQL'] . '</textarea>
268  <br />
269  <input class="btn btn-default" type="submit" value="CHECK" />
270  </td>
271  </tr>';
272  if (!empty($input['RAWSQL'])) {
273  $out .= '<tr class="bgColor4">';
274  $parseResult = $GLOBALS['TYPO3_DB']->SQLparser->parseSQL($input['RAWSQL']);
275  if (is_array($parseResult)) {
276  $newQuery = $GLOBALS['TYPO3_DB']->SQLparser->compileSQL($parseResult);
277  $testResult = $GLOBALS['TYPO3_DB']->SQLparser->debug_parseSQLpartCompare($input['RAWSQL'], $newQuery);
278  if (!is_array($testResult)) {
279  $out .= '<td colspan="2">' . $newQuery;
280  } else {
281  $out .= '<td colspan="2">' . htmlspecialchars($testResult[0]) . '</td></tr>
282  <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]);
283  }
284  } else {
285  $out .= '<th>Result:</th><td style="border:2px solid #f00;">' . $parseResult;
286  }
287  $out .= '</td></tr>';
288  }
289  $out .= '</table></form>';
290  return $out;
291  }
292 
302  protected function createFieldsValuesArray($in)
303  {
304  $ret = [];
305  $in = explode(LF, $in);
306  foreach ($in as $v) {
307  $fv = explode('=', $v);
308  $ret[$fv[0]] = $fv[1];
309  }
310  return $ret;
311  }
312 
322  protected function printCachedInfo()
323  {
324  // Get cmd:
325  if ((string)GeneralUtility::_GP('cmd') === 'clear') {
326  $this->getDatabaseConnection()->clearCachedFieldInfo();
327  $GLOBALS['TYPO3_DB']->cacheFieldInfo();
328  }
329  $out = '<a name="autoincrement"></a><h2>auto_increment</h2>';
330  $out .= '<table border="1" cellspacing="0"><tbody><tr><th>Table</th><th>Field</th></tr>';
331  ksort($GLOBALS['TYPO3_DB']->cache_autoIncFields);
332  foreach ($GLOBALS['TYPO3_DB']->cache_autoIncFields as $table => $field) {
333  $out .= '<tr>';
334  $out .= '<td>' . $table . '</td>';
335  $out .= '<td>' . $field . '</td>';
336  $out .= '</tr>';
337  }
338  $out .= '</tbody></table>';
339  $out .= '<a name="primarykeys"></a><h2>Primary keys</h2>';
340  $out .= '<table border="1" cellspacing="0"><tbody><tr><th>Table</th><th>Field(s)</th></tr>';
341  ksort($GLOBALS['TYPO3_DB']->cache_primaryKeys);
342  foreach ($GLOBALS['TYPO3_DB']->cache_primaryKeys as $table => $field) {
343  $out .= '<tr>';
344  $out .= '<td>' . $table . '</td>';
345  $out .= '<td>' . $field . '</td>';
346  $out .= '</tr>';
347  }
348  $out .= '</tbody></table>';
349  $out .= '<a name="fieldtypes"></a><h2>Field types</h2>';
350  $out .= '
351  <table border="1" cellspacing="0">
352  <tbody>
353  <tr>
354  <th colspan="5">Table</th>
355  </tr>
356  <tr>
357  <th>Field</th>
358  <th>Type</th><th>
359  <a href="#metatypes">Metatype</a></th>
360  <th>NOT NULL</th>
361  <th>Default</th></th>
362  </tr>';
363  ksort($GLOBALS['TYPO3_DB']->cache_fieldType);
364  foreach ($GLOBALS['TYPO3_DB']->cache_fieldType as $table => $fields) {
365  $out .= '<th colspan="5">' . $table . '</th>';
366  foreach ($fields as $field => $data) {
367  $out .= '<tr>';
368  $out .= '<td>' . $field . '</td>';
369  $out .= '<td>' . $data['type'] . '</td>';
370  $out .= '<td>' . $data['metaType'] . '</td>';
371  $out .= '<td>' . ($data['notnull'] ? 'NOT NULL' : '') . '</td>';
372  $out .= '<td>' . $data['default'] . '</td>';
373  $out .= '</tr>';
374  }
375  }
376  $out .= '</tbody></table>';
377  $out .= '<a name="metatypes"></a><h2>Metatype explanation</h2>';
378  $out .= '<pre>
379  C: Varchar, capped to 255 characters.
380  X: Larger varchar, capped to 4000 characters (to be compatible with Oracle).
381  XL: For Oracle, returns CLOB, otherwise the largest varchar size.
382 
383  C2: Multibyte varchar
384  X2: Multibyte varchar (largest size)
385 
386  B: BLOB (binary large object)
387 
388  D: Date (some databases do not support this, and we return a datetime type)
389  T: Datetime or Timestamp
390  L: Integer field suitable for storing booleans (0 or 1)
391  I: Integer (mapped to I4)
392  I1: 1-byte integer
393  I2: 2-byte integer
394  I4: 4-byte integer
395  I8: 8-byte integer
396  F: Floating point number
397  N: Numeric or decimal number</pre>';
398  $menu = '<a href="' . $this->thisScript . '&amp;cmd=clear">CLEAR DATA</a><hr />';
399  $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 />';
400  return $menu . $out;
401  }
402 
410  protected function printLogMgm()
411  {
412  // Disable debugging in any case...
413  $GLOBALS['TYPO3_DB']->debug = false;
414  // Get cmd:
415  $cmd = (string)GeneralUtility::_GP('cmd');
416  switch ($cmd) {
417  case 'flush':
418  $res = $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('tx_dbal_debuglog');
419  $res = $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('tx_dbal_debuglog_where');
420  $outStr = 'Log FLUSHED!';
421  break;
422  case 'joins':
423  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('table_join,exec_time,query,script', 'tx_dbal_debuglog', 'table_join!=\'\'', 'table_join,script,exec_time,query');
424  // Init vars in which to pick up the query result:
425  $tableIndex = [];
426  $tRows = [];
427  $tRows[] = '
428  <tr>
429  <td>Execution time</td>
430  <td>Table joins</td>
431  <td>Script</td>
432  <td>Query</td>
433  </tr>';
434  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
435  $tableArray = $GLOBALS['TYPO3_DB']->SQLparser->parseFromTables($row['table_join']);
436  // Create table name index:
437  foreach ($tableArray as $a) {
438  foreach ($tableArray as $b) {
439  if ($b['table'] != $a['table']) {
440  $tableIndex[$a['table']][$b['table']] = 1;
441  }
442  }
443  }
444  // Create output row
445  $tRows[] = '
446  <tr>
447  <td>' . htmlspecialchars($row['exec_time']) . '</td>
448  <td>' . htmlspecialchars($row['table_join']) . '</td>
449  <td>' . htmlspecialchars($row['script']) . '</td>
450  <td>' . htmlspecialchars($row['query']) . '</td>
451  </tr>';
452  }
453  // Printing direct joins:
454  $outStr .= '<h4>Direct joins:</h4>' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray($tableIndex);
455  // Printing total dependencies:
456  foreach ($tableIndex as $priTable => $a) {
457  foreach ($tableIndex as $tableN => $v) {
458  foreach ($v as $tableP => $vv) {
459  if ($tableP == $priTable) {
460  $tableIndex[$priTable] = array_merge($v, $a);
461  }
462  }
463  }
464  }
465  $outStr .= '<h4>Total dependencies:</h4>' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray($tableIndex);
466  // Printing data rows:
467  $outStr .= '
468  <table border="1" cellspacing="0">' . implode('', $tRows) . '
469  </table>';
470  break;
471  case 'errors':
472  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('serdata,exec_time,query,script', 'tx_dbal_debuglog', 'errorFlag>0', '', 'tstamp DESC');
473  // Init vars in which to pick up the query result:
474  $tRows = [];
475  $tRows[] = '
476  <tr>
477  <td>Execution time</td>
478  <td>Error data</td>
479  <td>Script</td>
480  <td>Query</td>
481  </tr>';
482  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
483  // Create output row
484  $tRows[] = '
485  <tr>
486  <td>' . htmlspecialchars($row['exec_time']) . '</td>
487  <td>' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray(unserialize($row['serdata'])) . '</td>
488  <td>' . htmlspecialchars($row['script']) . '</td>
489  <td>' . htmlspecialchars($row['query']) . '</td>
490  </tr>';
491  }
492  // Printing data rows:
493  $outStr .= '
494  <table border="1" cellspacing="0">' . implode('', $tRows) . '
495  </table>';
496  break;
497  case 'parsing':
498  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('query,serdata', 'tx_dbal_debuglog', 'errorFlag&2=2');
499  $tRows = [];
500  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
501  // Create output row
502  $tRows[] = '
503  <tr>
504  <td>' . htmlspecialchars($row['query']) . '</td>
505  </tr>';
506  }
507  // Printing data rows:
508  $outStr .= '
509  <table border="1" cellspacing="0">' . implode('', $tRows) . '
510  </table>';
511  break;
512  case 'where':
513  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('tstamp,script,tablename,whereclause', 'tx_dbal_debuglog_where', '', '', 'tstamp DESC');
514  $tRows = [];
515  $tRows[] = '
516  <tr>
517  <td>Time</td>
518  <td>Script</td>
519  <td>Table</td>
520  <td>WHERE clause</td>
521  </tr>';
522  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
523  $tRows[] = '
524  <tr>
525  <td>' . BackendUtility::datetime($row['tstamp']) . '</td>
526  <td>' . htmlspecialchars($row['script']) . '</td>
527  <td>' . htmlspecialchars($row['tablename']) . '</td>
528  <td>' . str_replace(['\'\'', '""', 'IS NULL', 'IS NOT NULL'], ['<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>
529  </tr>';
530  }
531  $outStr = '
532  <table border="1" cellspacing="0">' . implode('', $tRows) . '
533  </table>';
534  break;
535  default:
536  // Look for request to view specific script exec:
537  $specTime = GeneralUtility::_GP('specTime');
538  if ($specTime) {
539  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('exec_time,errorFlag,table_join,serdata,query', 'tx_dbal_debuglog', 'tstamp=' . (int)$specTime);
540  $tRows = [];
541  $tRows[] = '
542  <tr>
543  <td>Execution time</td>
544  <td>Error</td>
545  <td>Table joins</td>
546  <td>Data</td>
547  <td>Query</td>
548  </tr>';
549  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
550  $tRows[] = '
551  <tr>
552  <td>' . htmlspecialchars($row['exec_time']) . '</td>
553  <td>' . ($row['errorFlag'] ? 1 : 0) . '</td>
554  <td>' . htmlspecialchars($row['table_join']) . '</td>
555  <td>' . \TYPO3\CMS\Core\Utility\DebugUtility::viewArray(unserialize($row['serdata'])) . '</td>
556  <td>' . str_replace(['\'\'', '""', 'IS NULL', 'IS NOT NULL'], ['<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>
557  </tr>';
558  }
559  } else {
560  $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');
561  $tRows = [];
562  $tRows[] = '
563  <tr>
564  <td>Time</td>
565  <td># of queries</td>
566  <td>Error</td>
567  <td>Time (ms)</td>
568  <td>Script</td>
569  </tr>';
570  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
571  $tRows[] = '
572  <tr>
573  <td>' . BackendUtility::datetime($row['tstamp']) . '</td>
574  <td>' . htmlspecialchars($row['qrycount']) . '</td>
575  <td>' . ($row['error'] ? '<strong style="color:#f00">ERR</strong>' : '') . '</td>
576  <td>' . htmlspecialchars($row['calc_sum']) . '</td>
577  <td><a href="' . $this->thisScript . '&amp;specTime=' . (int)$row['tstamp'] . '">' . htmlspecialchars($row['script']) . '</a></td>
578  </tr>';
579  }
580  }
581  $outStr = '
582  <table border="1" cellspacing="0">' . implode('', $tRows) . '
583  </table>';
584  }
585  $menu = '
586  <a href="' . $this->thisScript . '&amp;cmd=flush">FLUSH LOG</a> -
587  <a href="' . $this->thisScript . '&amp;cmd=joins">JOINS</a> -
588  <a href="' . $this->thisScript . '&amp;cmd=errors">ERRORS</a> -
589  <a href="' . $this->thisScript . '&amp;cmd=parsing">PARSING</a> -
590  <a href="' . $this->thisScript . '">LOG</a> -
591  <a href="' . $this->thisScript . '&amp;cmd=where">WHERE</a> -
592 
593  <a href="' . htmlspecialchars(GeneralUtility::linkThisScript()) . '" target="tx_debuglog">[New window]</a>
594  <hr />
595  ';
596  return $menu . $outStr;
597  }
598 
602  protected function generateMenu()
603  {
604  $menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
605  $menu->setIdentifier('DBALJumpMenu');
606  foreach ($this->MOD_MENU['function'] as $controller => $title) {
607  $item = $menu
608  ->makeMenuItem()
609  ->setHref(
610  BackendUtility::getModuleUrl(
611  $this->moduleName,
612  [
613  'id' => $this->id,
614  'SET' => [
615  'function' => $controller
616  ]
617  ]
618  )
619  )
620  ->setTitle($title);
621  if ($controller === $this->MOD_SETTINGS['function']) {
622  $item->setActive(true);
623  }
624  $menu->addMenuItem($item);
625  }
626  $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
627  }
628 
634  protected function getLanguageService()
635  {
636  return $GLOBALS['LANG'];
637  }
638 
644  protected function getDatabaseConnection()
645  {
646  return $GLOBALS['TYPO3_DB'];
647  }
648 }
static linkThisScript(array $getParams=[])
static getModuleData($MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='')
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
mainAction(ServerRequestInterface $request, ResponseInterface $response)