TYPO3 CMS  TYPO3_7-6
LinkValidatorReport.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 
28 
33 {
37  public $doc;
38 
44  protected $pageRecord = [];
45 
51  protected $isAccessibleForCurrentUser = false;
52 
58  protected $searchLevel;
59 
65  protected $linkAnalyzer;
66 
72  protected $modTS = [];
73 
79  protected $availableOptions = [];
80 
87  protected $checkOpt = [];
88 
95  protected $checkOptionsHtml;
96 
104 
110  protected $content;
111 
115  protected $hookObjectsArr = [];
116 
120  protected $updateListHtml = '';
121 
125  protected $refreshListHtml = '';
126 
130  protected $templateService;
131 
135  protected $iconFactory;
136 
142  public function main()
143  {
144  $this->getLanguageService()->includeLLFile('EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf');
145  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
146  $this->searchLevel = GeneralUtility::_GP('search_levels');
147  if (isset($this->pObj->id)) {
148  $this->modTS = BackendUtility::getModTSconfig($this->pObj->id, 'mod.linkvalidator');
149  $this->modTS = $this->modTS['properties'];
150  }
151  $update = GeneralUtility::_GP('updateLinkList');
152  $prefix = '';
153  if (!empty($update)) {
154  $prefix = 'check';
155  }
156  $set = GeneralUtility::_GP($prefix . 'SET');
157  $this->pObj->handleExternalFunctionValue();
158  if (isset($this->searchLevel)) {
159  $this->pObj->MOD_SETTINGS['searchlevel'] = $this->searchLevel;
160  } else {
161  $this->searchLevel = $this->pObj->MOD_SETTINGS['searchlevel'];
162  }
163  if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
164  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $linkType => $value) {
165  // Compile list of all available types. Used for checking with button "Check Links".
166  if (strpos($this->modTS['linktypes'], $linkType) !== false) {
167  $this->availableOptions[$linkType] = 1;
168  }
169  // Compile list of types currently selected by the checkboxes
170  if ($this->pObj->MOD_SETTINGS[$linkType] && empty($set) || $set[$linkType]) {
171  $this->checkOpt[$linkType] = 1;
172  $this->pObj->MOD_SETTINGS[$linkType] = 1;
173  } else {
174  $this->pObj->MOD_SETTINGS[$linkType] = 0;
175  unset($this->checkOpt[$linkType]);
176  }
177  }
178  }
179  $this->getBackendUser()->pushModuleData('web_info', $this->pObj->MOD_SETTINGS);
180  $this->initialize();
181 
182  // Localization
183  $this->getPageRenderer()->addInlineLanguageLabelFile(
184  ExtensionManagementUtility::extPath('linkvalidator', 'Resources/Private/Language/Module/locallang.xlf')
185  );
186 
187  if ($this->modTS['showCheckLinkTab'] == 1) {
188  $this->updateListHtml = '<input class="btn btn-default" type="submit" name="updateLinkList" id="updateLinkList" value="' . $this->getLanguageService()->getLL('label_update') . '"/>';
189  }
190  $this->refreshListHtml = '<input class="btn btn-default" type="submit" name="refreshLinkList" id="refreshLinkList" value="' . $this->getLanguageService()->getLL('label_refresh') . '"/>';
191  $this->linkAnalyzer = GeneralUtility::makeInstance(LinkAnalyzer::class);
192  $this->updateBrokenLinks();
193 
194  $brokenLinkOverView = $this->linkAnalyzer->getLinkCounts($this->pObj->id);
195  $this->checkOptionsHtml = $this->getCheckOptions($brokenLinkOverView);
196  $this->checkOptionsHtmlCheck = $this->getCheckOptions($brokenLinkOverView, 'check');
197  $this->render();
198 
199  $pageTile = '';
200  if ($this->pObj->id) {
201  $pageRecord = BackendUtility::getRecord('pages', $this->pObj->id);
202  $pageTile = '<h1>' . htmlspecialchars(BackendUtility::getRecordTitle('pages', $pageRecord)) . '</h1>';
203  }
204 
205  return '<div id="linkvalidator-modfuncreport">' . $pageTile . $this->createTabs() . '</div>';
206  }
207 
213  protected function createTabs()
214  {
215  $menuItems = [
216  0 => [
217  'label' => $this->getLanguageService()->getLL('Report'),
218  'content' => $this->flush(true)
219  ],
220  ];
221 
222  if ((bool)$this->modTS['showCheckLinkTab']) {
223  $menuItems[1] = [
224  'label' => $this->getLanguageService()->getLL('CheckLink'),
225  'content' => $this->flush()
226  ];
227  }
228 
229  // @todo: Use $this-moduleTemplate as soon as this class extends from AbstractModule
231  $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
232  return $moduleTemplate->getDynamicTabMenu($menuItems, 'report-linkvalidator');
233  }
234 
240  protected function initialize()
241  {
242  if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
243  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $linkType => $classRef) {
244  $this->hookObjectsArr[$linkType] = GeneralUtility::getUserObj($classRef);
245  }
246  }
247 
248  $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
249  $this->doc->setModuleTemplate('EXT:linkvalidator/Resources/Private/Templates/mod_template.html');
250 
251  $this->pageRecord = BackendUtility::readPageAccess($this->pObj->id, $this->getBackendUser()->getPagePermsClause(1));
252  if ($this->pObj->id && is_array($this->pageRecord) || !$this->pObj->id && $this->isCurrentUserAdmin()) {
253  $this->isAccessibleForCurrentUser = true;
254  }
255 
256  $this->doc->addStyleSheet('module', ExtensionManagementUtility::extRelPath('linkvalidator') . 'Resources/Public/Css/styles.css');
257  $this->getPageRenderer()->loadJquery();
258  $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Linkvalidator/Linkvalidator');
259 
260  $this->templateService = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
261 
262  // Don't access in workspace
263  if ($this->getBackendUser()->workspace !== 0) {
264  $this->isAccessibleForCurrentUser = false;
265  }
266  }
267 
273  protected function updateBrokenLinks()
274  {
275  $searchFields = [];
276  // Get the searchFields from TypoScript
277  foreach ($this->modTS['searchFields.'] as $table => $fieldList) {
278  $fields = GeneralUtility::trimExplode(',', $fieldList, true);
279  foreach ($fields as $field) {
280  if (!$searchFields || !is_array($searchFields[$table]) || array_search($field, $searchFields[$table]) === false) {
281  $searchFields[$table][] = $field;
282  }
283  }
284  }
285  $rootLineHidden = $this->linkAnalyzer->getRootLineIsHidden($this->pObj->pageinfo);
286  if (!$rootLineHidden || $this->modTS['checkhidden'] == 1) {
287  // Get children pages
288  $pageList = $this->linkAnalyzer->extGetTreeList(
289  $this->pObj->id,
290  $this->searchLevel,
291  0,
292  $this->getBackendUser()->getPagePermsClause(1),
293  $this->modTS['checkhidden']
294  );
295  if ($this->pObj->pageinfo['hidden'] == 0 || $this->modTS['checkhidden']) {
296  $pageList .= $this->pObj->id;
297  }
298 
299  $this->linkAnalyzer->init($searchFields, $pageList, $this->modTS);
300 
301  // Check if button press
302  $update = GeneralUtility::_GP('updateLinkList');
303  if (!empty($update)) {
304  $this->linkAnalyzer->getLinkStatistics($this->checkOpt, $this->modTS['checkhidden']);
305  }
306  }
307  }
308 
314  protected function render()
315  {
316  if ($this->isAccessibleForCurrentUser) {
317  $this->content = $this->renderBrokenLinksTable();
318  } else {
319  // If no access or if ID == zero
321  $message = GeneralUtility::makeInstance(
322  FlashMessage::class,
323  $this->getLanguageService()->getLL('no.access'),
324  $this->getLanguageService()->getLL('no.access.title'),
326  );
328  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
330  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
331  $defaultFlashMessageQueue->enqueue($message);
332  }
333  }
334 
341  protected function flush($form = false)
342  {
343  return $this->doc->moduleBody(
344  $this->pageRecord,
345  $this->getDocHeaderButtons(),
346  $form ? $this->getTemplateMarkers() : $this->getTemplateMarkersCheck()
347  );
348  }
349 
355  protected function getLevelSelector()
356  {
357  // Build level selector
358  $options = [];
360  0 => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_0'),
361  1 => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_1'),
362  2 => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_2'),
363  3 => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_3'),
364  4 => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_4'),
365  999 => $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_infi')
366  ];
367  foreach ($availableOptions as $optionValue => $optionLabel) {
368  $options[] = '<option value="' . $optionValue . '"' . ($optionValue === (int)$this->searchLevel ? ' selected="selected"' : '') . '>' . htmlspecialchars($optionLabel) . '</option>';
369  }
370  return '<select name="search_levels" class="form-control">' . implode('', $options) . '</select>';
371  }
372 
378  protected function renderBrokenLinksTable()
379  {
380  $brokenLinkItems = '';
381  $brokenLinksTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###NOBROKENLINKS_CONTENT###');
382  $keyOpt = [];
383  if (is_array($this->checkOpt)) {
384  $keyOpt = array_keys($this->checkOpt);
385  }
386 
387  // Table header
388  $brokenLinksMarker = $this->startTable();
389 
390  $rootLineHidden = $this->linkAnalyzer->getRootLineIsHidden($this->pObj->pageinfo);
391  if (!$rootLineHidden || (bool)$this->modTS['checkhidden']) {
392  $pageList = $this->linkAnalyzer->extGetTreeList(
393  $this->pObj->id,
394  $this->searchLevel,
395  0,
396  $this->getBackendUser()->getPagePermsClause(1),
397  $this->modTS['checkhidden']
398  );
399  // Always add the current page, because we are just displaying the results
400  $pageList .= $this->pObj->id;
401 
402  $records = $this->getDatabaseConnection()->exec_SELECTgetRows(
403  '*',
404  'tx_linkvalidator_link',
405  'record_pid IN (' . $pageList . ') AND link_type IN (\'' . implode('\',\'', $keyOpt) . '\')',
406  '',
407  'record_uid ASC, uid ASC'
408  );
409  if (!empty($records)) {
410  // Display table with broken links
411  $brokenLinksTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###BROKENLINKS_CONTENT###');
412  $brokenLinksItemTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###BROKENLINKS_ITEM###');
413 
414  // Table rows containing the broken links
415  $items = [];
416  foreach ($records as $record) {
417  $items[] = $this->renderTableRow($record['table_name'], $record, $brokenLinksItemTemplate);
418  }
419  $brokenLinkItems = implode(LF, $items);
420  } else {
421  $brokenLinksMarker = $this->getNoBrokenLinkMessage($brokenLinksMarker);
422  }
423  } else {
424  $brokenLinksMarker = $this->getNoBrokenLinkMessage($brokenLinksMarker);
425  }
426  $brokenLinksTemplate = $this->templateService->substituteMarkerArray(
427  $brokenLinksTemplate,
428  $brokenLinksMarker, '###|###',
429  true
430  );
431  return $this->templateService->substituteSubpart($brokenLinksTemplate, '###BROKENLINKS_ITEM', $brokenLinkItems);
432  }
433 
440  protected function getNoBrokenLinkMessage(array $brokenLinksMarker)
441  {
442  $brokenLinksMarker['LIST_HEADER'] = '<h3>' . $this->getLanguageService()->getLL('list.header', true) . '</h3>';
444  $message = GeneralUtility::makeInstance(
445  FlashMessage::class,
446  $this->getLanguageService()->getLL('list.no.broken.links'),
447  $this->getLanguageService()->getLL('list.no.broken.links.title'),
448  FlashMessage::OK
449  );
451  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
453  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
454  $defaultFlashMessageQueue->enqueue($message);
455  $brokenLinksMarker['NO_BROKEN_LINKS'] = $defaultFlashMessageQueue->renderFlashMessages();
456  return $brokenLinksMarker;
457  }
458 
464  protected function startTable()
465  {
466  // Listing head
467  $makerTableHead = [
468  'tablehead_path' => $this->getLanguageService()->getLL('list.tableHead.path'),
469  'tablehead_element' => $this->getLanguageService()->getLL('list.tableHead.element'),
470  'tablehead_headlink' => $this->getLanguageService()->getLL('list.tableHead.headlink'),
471  'tablehead_linktarget' => $this->getLanguageService()->getLL('list.tableHead.linktarget'),
472  'tablehead_linkmessage' => $this->getLanguageService()->getLL('list.tableHead.linkmessage'),
473  'tablehead_lastcheck' => $this->getLanguageService()->getLL('list.tableHead.lastCheck'),
474  ];
475 
476  // Add CSH to the header of each column
477  foreach ($makerTableHead as $column => $label) {
478  $makerTableHead[$column] = BackendUtility::wrapInHelp('linkvalidator', $column, $label);
479  }
480  // Add section header
481  $makerTableHead['list_header'] = '<h3>' . $this->getLanguageService()->getLL('list.header', true) . '</h3>';
482  return $makerTableHead;
483  }
484 
493  protected function renderTableRow($table, array $row, $brokenLinksItemTemplate)
494  {
495  $markerArray = [];
496  $fieldName = '';
497  // Restore the linktype object
498  $hookObj = $this->hookObjectsArr[$row['link_type']];
499 
500  // Construct link to edit the content element
501  $requestUri = GeneralUtility::getIndpEnv('REQUEST_URI') .
502  '&id=' . $this->pObj->id .
503  '&search_levels=' . $this->searchLevel;
504  $url = BackendUtility::getModuleUrl('record_edit', [
505  'edit' => [
506  $table => [
507  $row['record_uid'] => 'edit'
508  ]
509  ],
510  'returnUrl' => $requestUri
511  ]);
512  $actionLinkOpen = '<a href="' . htmlspecialchars($url);
513  $actionLinkOpen .= '" title="' . htmlspecialchars($this->getLanguageService()->getLL('list.edit')) . '">';
514  $actionLinkClose = '</a>';
515  $elementHeadline = $row['headline'];
516  // Get the language label for the field from TCA
517  if ($GLOBALS['TCA'][$table]['columns'][$row['field']]['label']) {
518  $fieldName = $this->getLanguageService()->sL($GLOBALS['TCA'][$table]['columns'][$row['field']]['label']);
519  // Crop colon from end if present
520  if (substr($fieldName, '-1', '1') === ':') {
521  $fieldName = substr($fieldName, '0', strlen($fieldName) - 1);
522  }
523  }
524  // Fallback, if there is no label
525  $fieldName = !empty($fieldName) ? $fieldName : $row['field'];
526  // column "Element"
527  $element = '<span title="' . htmlspecialchars($table . ':' . $row['record_uid']) . '">' . $this->iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>';
528  if (empty($elementHeadline)) {
529  $element .= '<i>' . htmlspecialchars($this->getLanguageService()->getLL('list.no.headline')) . '</i>';
530  } else {
531  $element .= htmlspecialchars($elementHeadline);
532  }
533  $element .= ' ' . htmlspecialchars(sprintf($this->getLanguageService()->getLL('list.field'), $fieldName));
534  $markerArray['actionlinkOpen'] = $actionLinkOpen;
535  $markerArray['actionlinkClose'] = $actionLinkClose;
536  $markerArray['actionlinkIcon'] = $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render();
537  $markerArray['path'] = BackendUtility::getRecordPath($row['record_pid'], '', 0, 0);
538  $markerArray['element'] = $element;
539  $markerArray['headlink'] = htmlspecialchars($row['link_title']);
540  $markerArray['linktarget'] = htmlspecialchars($hookObj->getBrokenUrl($row));
541  $response = unserialize($row['url_response']);
542  if ($response['valid']) {
543  $linkMessage = '<span class="valid">' . htmlspecialchars($this->getLanguageService()->getLL('list.msg.ok')) . '</span>';
544  } else {
545  $linkMessage = '<span class="error">'
546  . nl2br(
547  // Encode for output
548  htmlspecialchars(
549  $hookObj->getErrorMessage($response['errorParams']),
550  ENT_QUOTES,
551  'UTF-8',
552  false
553  )
554  )
555  . '</span>';
556  }
557  $markerArray['linkmessage'] = $linkMessage;
558 
559  $lastRunDate = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $row['last_check']);
560  $lastRunTime = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'], $row['last_check']);
561  $markerArray['lastcheck'] = htmlspecialchars(sprintf($this->getLanguageService()->getLL('list.msg.lastRun'), $lastRunDate, $lastRunTime));
562 
563  // Return the table html code as string
564  return $this->templateService->substituteMarkerArray($brokenLinksItemTemplate, $markerArray, '###|###', true, true);
565  }
566 
574  protected function getCheckOptions(array $brokenLinkOverView, $prefix = '')
575  {
576  $markerArray = [];
577  if (!empty($prefix)) {
578  $additionalAttr = ' class="' . $prefix . '"';
579  } else {
580  $additionalAttr = ' class="refresh"';
581  }
582  $checkOptionsTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###CHECKOPTIONS_SECTION###');
583  $hookSectionTemplate = $this->templateService->getSubpart($checkOptionsTemplate, '###HOOK_SECTION###');
584  $markerArray['statistics_header'] = '<h3>' . $this->getLanguageService()->getLL('report.statistics.header', true) . '</h3>';
585  $markerArray['total_count_label'] = BackendUtility::wrapInHelp('linkvalidator', 'checkboxes', $this->getLanguageService()->getLL('overviews.nbtotal'));
586  $markerArray['total_count'] = $brokenLinkOverView['brokenlinkCount'] ?: '0';
587 
588  $linktypes = GeneralUtility::trimExplode(',', $this->modTS['linktypes'], true);
589  $hookSectionContent = '';
590  if (is_array($linktypes)) {
591  if (
592  !empty($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])
593  && is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])
594  ) {
595  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $type => $value) {
596  if (in_array($type, $linktypes)) {
597  $hookSectionMarker = [
598  'count' => $brokenLinkOverView[$type] ?: '0',
599  ];
600 
601  $translation = $this->getLanguageService()->getLL('hooks.' . $type) ?: $type;
602  $hookSectionMarker['option'] = '<input type="checkbox"' . $additionalAttr . ' id="' . $prefix . 'SET_' . $type . '" name="' . $prefix
603  . 'SET[' . $type . ']" value="1"' . ($this->pObj->MOD_SETTINGS[$type] ? ' checked="checked"' : '') . '/>' . '<label for="'
604  . $prefix . 'SET_' . $type . '">&nbsp;' . htmlspecialchars($translation) . '</label>';
605 
606  $hookSectionContent .= $this->templateService->substituteMarkerArray(
607  $hookSectionTemplate,
608  $hookSectionMarker, '###|###',
609  true,
610  true
611  );
612  }
613  }
614  }
615  }
616  $checkOptionsTemplate = $this->templateService->substituteSubpart(
617  $checkOptionsTemplate,
618  '###HOOK_SECTION###',
619  $hookSectionContent
620  );
621  return $this->templateService->substituteMarkerArray($checkOptionsTemplate, $markerArray, '###|###', true, true);
622  }
623 
629  protected function getDocHeaderButtons()
630  {
631  return [
632  'csh' => BackendUtility::cshItem('_MOD_web_func', ''),
633  'shortcut' => $this->getShortcutButton(),
634  'save' => ''
635  ];
636  }
637 
643  protected function getShortcutButton()
644  {
645  $result = '';
646  if ($this->getBackendUser()->mayMakeShortcut()) {
647  $result = $this->doc->makeShortcutIcon('', 'function', $this->pObj->MCONF['name']);
648  }
649  return $result;
650  }
651 
657  protected function getTemplateMarkers()
658  {
659  return [
660  'FUNC_TITLE' => $this->getLanguageService()->getLL('report.func.title'),
661  'CHECKOPTIONS_TITLE' => $this->getLanguageService()->getLL('report.statistics.header'),
662  'FUNC_MENU' => $this->getLevelSelector(),
663  'CONTENT' => $this->content,
664  'CHECKOPTIONS' => $this->checkOptionsHtml,
665  'ID' => '<input type="hidden" name="id" value="' . $this->pObj->id . '" />',
666  'REFRESH' => '<input type="submit" class="btn btn-default" name="refreshLinkList" id="refreshLinkList" value="' . $this->getLanguageService()->getLL('label_refresh') . '" />',
667  'UPDATE' => '',
668  ];
669  }
670 
676  protected function getTemplateMarkersCheck()
677  {
678  return [
679  'FUNC_TITLE' => $this->getLanguageService()->getLL('checklinks.func.title'),
680  'CHECKOPTIONS_TITLE' => $this->getLanguageService()->getLL('checklinks.statistics.header'),
681  'FUNC_MENU' => $this->getLevelSelector(),
682  'CONTENT' => '',
683  'CHECKOPTIONS' => $this->checkOptionsHtmlCheck,
684  'ID' => '<input type="hidden" name="id" value="' . $this->pObj->id . '" />',
685  'REFRESH' => '',
686  'UPDATE' => '<input type="submit" class="btn btn-default" name="updateLinkList" id="updateLinkList" value="' . $this->getLanguageService()->getLL('label_update') . '"/>',
687  ];
688  }
689 
695  protected function isCurrentUserAdmin()
696  {
697  return $this->getBackendUser()->isAdmin();
698  }
699 
705  protected function getLanguageService()
706  {
707  return $GLOBALS['LANG'];
708  }
709 
715  protected function getBackendUser()
716  {
717  return $GLOBALS['BE_USER'];
718  }
719 
723  protected function getDatabaseConnection()
724  {
725  return $GLOBALS['TYPO3_DB'];
726  }
727 }
static readPageAccess($id, $perms_clause)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static getRecordTitle($table, $row, $prep=false, $forceResult=true)
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']