TYPO3 CMS  TYPO3_8-7
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 
30 
35 {
39  public $doc;
40 
46  protected $pageRecord = [];
47 
53  protected $isAccessibleForCurrentUser = false;
54 
60  protected $linkAnalyzer;
61 
67  protected $modTS = [];
68 
74  protected $availableOptions = [];
75 
82  protected $searchLevel = ['report' => 0, 'check' => 0];
83 
91  protected $checkOpt = ['report' => [], 'check' => []];
92 
100  protected $checkOptionsHtml = ['report' => [], 'check' => []];
101 
107  protected $content;
108 
112  protected $hookObjectsArr = [];
113 
117  protected $updateListHtml = '';
118 
122  protected $refreshListHtml = '';
123 
127  protected $templateService;
128 
132  protected $iconFactory;
133 
139  public function main()
140  {
141  $this->getLanguageService()->includeLLFile('EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf');
142  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
143  $update = GeneralUtility::_GP('updateLinkList');
144  $prefix = 'check';
145  $other = 'report';
146 
147  if (empty($update)) {
148  $prefix = 'report';
149  $other = 'check';
150  }
151 
152  // get searchLevel (number of levels of pages to check / show results)
153  $this->searchLevel[$prefix] = GeneralUtility::_GP($prefix . '_search_levels');
154  if (isset($this->pObj->id)) {
155  $this->modTS = BackendUtility::getModTSconfig($this->pObj->id, 'mod.linkvalidator');
156  $this->modTS = $this->modTS['properties'];
157  }
158  if (isset($this->searchLevel[$prefix])) {
159  $this->pObj->MOD_SETTINGS[$prefix . '_searchlevel'] = $this->searchLevel[$prefix];
160  } else {
161  $this->searchLevel[$prefix] = $this->pObj->MOD_SETTINGS[$prefix . '_searchlevel'];
162  }
163  if (isset($this->pObj->MOD_SETTINGS[$other . '_searchlevel'])) {
164  $this->searchLevel[$other] = $this->pObj->MOD_SETTINGS[$other . '_searchlevel'];
165  }
166 
167  // which linkTypes to check (internal, file, external, ...)
168  $set = GeneralUtility::_GP($prefix . '_SET');
169  $this->pObj->handleExternalFunctionValue();
170 
171  if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
172  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $linkType => $value) {
173  // Compile list of all available types. Used for checking with button "Check Links".
174  if (strpos($this->modTS['linktypes'], $linkType) !== false) {
175  $this->availableOptions[$linkType] = 1;
176  }
177 
178  // 1) if "$prefix_values" = "1" : use POST variables
179  // 2) if not set, use stored configuration in $this->>pObj->MOD_SETTINGS
180  // 3) if not set, use default
181  unset($this->checkOpt[$prefix][$linkType]);
182  if (!empty(GeneralUtility::_GP($prefix . '_values'))) {
183  if (isset($set[$linkType])) {
184  $this->checkOpt[$prefix][$linkType] = $set[$linkType];
185  } else {
186  $this->checkOpt[$prefix][$linkType] = '0';
187  }
188  $this->pObj->MOD_SETTINGS[$prefix . '_' . $linkType] = $this->checkOpt[$prefix][$linkType];
189  } elseif (isset($this->pObj->MOD_SETTINGS[$prefix . '_' . $linkType])) {
190  $this->checkOpt[$prefix][$linkType] = $this->pObj->MOD_SETTINGS[$prefix . '_' . $linkType];
191  } else {
192  // use default
193  $this->checkOpt[$prefix][$linkType] = '0';
194  $this->pObj->MOD_SETTINGS[$prefix . '_' . $linkType] = $this->checkOpt[$prefix][$linkType];
195  }
196  if (isset($this->pObj->MOD_SETTINGS[$other . '_' . $linkType])) {
197  $this->checkOpt[$other][$linkType] = $this->pObj->MOD_SETTINGS[$other . '_' . $linkType];
198  }
199  }
200  }
201 
202  // save settings
203  $this->getBackendUser()->pushModuleData('web_info', $this->pObj->MOD_SETTINGS);
204  $this->initialize();
205 
206  // Localization
207  $this->getPageRenderer()->addInlineLanguageLabelFile('EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf');
208 
209  if ($this->modTS['showCheckLinkTab'] == 1) {
210  $this->updateListHtml = '<input class="btn btn-default t3js-update-button" type="submit" name="updateLinkList" id="updateLinkList" value="' . htmlspecialchars($this->getLanguageService()->getLL('label_update')) . '" data-notification-message="' . htmlspecialchars($this->getLanguageService()->getLL('label_update-link-list')) . '"/>';
211  }
212  $this->refreshListHtml = '<input class="btn btn-default t3js-update-button" type="submit" name="refreshLinkList" id="refreshLinkList" value="' . htmlspecialchars($this->getLanguageService()->getLL('label_refresh')) . '" data-notification-message="' . htmlspecialchars($this->getLanguageService()->getLL('label_refresh-link-list')) . '"/>';
213  $this->linkAnalyzer = GeneralUtility::makeInstance(LinkAnalyzer::class);
214  $this->updateBrokenLinks();
215 
216  $brokenLinkOverView = $this->linkAnalyzer->getLinkCounts($this->pObj->id);
217  $this->checkOptionsHtml['report'] = $this->getCheckOptions($brokenLinkOverView, 'report');
218  $this->checkOptionsHtml['check'] = $this->getCheckOptions($brokenLinkOverView, 'check');
219  $this->render();
220 
221  $pageTile = '';
222  if ($this->pObj->id) {
223  $pageRecord = BackendUtility::getRecord('pages', $this->pObj->id);
224  $pageTile = '<h1>' . htmlspecialchars(BackendUtility::getRecordTitle('pages', $pageRecord)) . '</h1>';
225  }
226 
227  return '<div id="linkvalidator-modfuncreport">' . $pageTile . $this->createTabs() . '</div>';
228  }
229 
235  protected function createTabs()
236  {
237  $menuItems = [
238  0 => [
239  'label' => $this->getLanguageService()->getLL('Report'),
240  'content' => $this->flush(true)
241  ],
242  ];
243 
244  if ((bool)$this->modTS['showCheckLinkTab']) {
245  $menuItems[1] = [
246  'label' => $this->getLanguageService()->getLL('CheckLink'),
247  'content' => $this->flush()
248  ];
249  }
250 
251  // @todo: Use $this-moduleTemplate as soon as this class extends from AbstractModule
253  $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
254  return $moduleTemplate->getDynamicTabMenu($menuItems, 'report-linkvalidator');
255  }
256 
260  protected function initialize()
261  {
262  if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
263  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $linkType => $classRef) {
264  $this->hookObjectsArr[$linkType] = GeneralUtility::getUserObj($classRef);
265  }
266  }
267 
268  $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
269  $this->doc->setModuleTemplate('EXT:linkvalidator/Resources/Private/Templates/mod_template.html');
270 
271  $this->pageRecord = BackendUtility::readPageAccess($this->pObj->id, $this->getBackendUser()->getPagePermsClause(1));
272  if ($this->pObj->id && is_array($this->pageRecord) || !$this->pObj->id && $this->isCurrentUserAdmin()) {
273  $this->isAccessibleForCurrentUser = true;
274  }
275 
276  $this->getPageRenderer()->addCssFile('EXT:linkvalidator/Resources/Public/Css/linkvalidator.css', 'stylesheet', 'screen');
277  $this->getPageRenderer()->loadJquery();
278  $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Linkvalidator/Linkvalidator');
279 
280  $this->templateService = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
281 
282  // Don't access in workspace
283  if ($this->getBackendUser()->workspace !== 0) {
284  $this->isAccessibleForCurrentUser = false;
285  }
286  }
287 
291  protected function updateBrokenLinks()
292  {
293  $searchFields = [];
294  // Get the searchFields from TypoScript
295  foreach ($this->modTS['searchFields.'] as $table => $fieldList) {
296  $fields = GeneralUtility::trimExplode(',', $fieldList, true);
297  foreach ($fields as $field) {
298  if (!$searchFields || !is_array($searchFields[$table]) || array_search($field, $searchFields[$table]) === false) {
299  $searchFields[$table][] = $field;
300  }
301  }
302  }
303  $rootLineHidden = $this->linkAnalyzer->getRootLineIsHidden($this->pObj->pageinfo);
304  if (!$rootLineHidden || $this->modTS['checkhidden'] == 1) {
305  // Get children pages
306  $pageList = $this->linkAnalyzer->extGetTreeList(
307  $this->pObj->id,
308  $this->searchLevel['check'],
309  0,
310  $this->getBackendUser()->getPagePermsClause(1),
311  $this->modTS['checkhidden']
312  );
313  if ($this->pObj->pageinfo['hidden'] == 0 || $this->modTS['checkhidden']) {
314  $pageList .= $this->pObj->id;
315  }
316 
317  $this->linkAnalyzer->init($searchFields, $pageList, $this->modTS);
318 
319  // Check if button press
320  $update = GeneralUtility::_GP('updateLinkList');
321  if (!empty($update)) {
322  $this->linkAnalyzer->getLinkStatistics($this->checkOpt['check'], $this->modTS['checkhidden']);
323  }
324  }
325  }
326 
330  protected function render()
331  {
332  if ($this->isAccessibleForCurrentUser) {
333  $this->content = $this->renderBrokenLinksTable();
334  } else {
335  // If no access or if ID == zero
337  $message = GeneralUtility::makeInstance(
338  FlashMessage::class,
339  $this->getLanguageService()->getLL('no.access'),
340  $this->getLanguageService()->getLL('no.access.title'),
342  );
344  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
346  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
347  $defaultFlashMessageQueue->enqueue($message);
348  }
349  }
350 
357  protected function flush($form = false)
358  {
359  return $this->doc->moduleBody(
360  $this->pageRecord,
361  $this->getDocHeaderButtons(),
362  $form ? $this->getTemplateMarkers() : $this->getTemplateMarkersCheck()
363  );
364  }
365 
373  protected function getLevelSelector($prefix = 'report')
374  {
375  // Build level selector
376  $options = [];
378  0 => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
379  1 => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
380  2 => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
381  3 => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
382  4 => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
383  999 => $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
384  ];
385  foreach ($availableOptions as $optionValue => $optionLabel) {
386  $options[] = '<option value="' . $optionValue . '"' . ($optionValue === (int)$this->searchLevel[$prefix] ? ' selected="selected"' : '') . '>' . htmlspecialchars($optionLabel) . '</option>';
387  }
388  return '<select name="' . $prefix . '_search_levels" class="form-control">' . implode('', $options) . '</select>';
389  }
390 
396  protected function renderBrokenLinksTable()
397  {
398  $brokenLinkItems = '';
399  $brokenLinksTemplate = $this->templateService->getSubpart(
400  $this->doc->moduleTemplate,
401  '###NOBROKENLINKS_CONTENT###'
402  );
403 
404  $linkTypes = [];
405  if (is_array($this->checkOpt['report'])) {
406  $linkTypes = array_keys($this->checkOpt['report'], '1');
407  }
408 
409  // Table header
410  $brokenLinksMarker = $this->startTable();
411 
412  $rootLineHidden = $this->linkAnalyzer->getRootLineIsHidden($this->pObj->pageinfo);
413  if (!$rootLineHidden || (bool)$this->modTS['checkhidden']) {
414  $pageList = $this->getPageList($this->pObj->id);
415  $result = false;
416  if (!empty($linkTypes)) {
417  $result = $this->getLinkValidatorBrokenLinks($pageList, $linkTypes);
418  }
419 
420  if ($result && $result->rowCount()) {
421  // Display table with broken links
422  $brokenLinksTemplate = $this->templateService->getSubpart(
423  $this->doc->moduleTemplate,
424  '###BROKENLINKS_CONTENT###'
425  );
426  $brokenLinksItemTemplate = $this->templateService->getSubpart(
427  $this->doc->moduleTemplate,
428  '###BROKENLINKS_ITEM###'
429  );
430 
431  // Table rows containing the broken links
432  $items = [];
433  while ($row = $result->fetch()) {
434  $items[] = $this->renderTableRow($row['table_name'], $row, $brokenLinksItemTemplate);
435  }
436  $brokenLinkItems = implode(LF, $items);
437  } else {
438  $brokenLinksMarker = $this->getNoBrokenLinkMessage($brokenLinksMarker);
439  }
440  } else {
441  $brokenLinksMarker = $this->getNoBrokenLinkMessage($brokenLinksMarker);
442  }
443 
444  $brokenLinksTemplate = $this->templateService->substituteMarkerArray(
445  $brokenLinksTemplate,
446  $brokenLinksMarker,
447  '###|###',
448  true
449  );
450 
451  return $this->templateService->substituteSubpart($brokenLinksTemplate, '###BROKENLINKS_ITEM', $brokenLinkItems);
452  }
453 
461  protected function getPageList(int $currentPageUid): array
462  {
463  $pageList = $this->linkAnalyzer->extGetTreeList(
464  $currentPageUid,
465  $this->searchLevel['report'],
466  0,
467  $this->getBackendUser()->getPagePermsClause(1),
468  $this->modTS['checkhidden']
469  );
470  // Always add the current page, because we are just displaying the results
471  $pageList .= $currentPageUid;
472 
473  return GeneralUtility::intExplode(',', $pageList, true);
474  }
475 
483  protected function getLinkValidatorBrokenLinks(array $pageList, array $linkTypes): Statement
484  {
485  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
486  ->getQueryBuilderForTable('tx_linkvalidator_link');
487  $queryBuilder
488  ->select('*')
489  ->from('tx_linkvalidator_link')
490  ->where(
491  $queryBuilder->expr()->in(
492  'record_pid',
493  $queryBuilder->createNamedParameter($pageList, Connection::PARAM_INT_ARRAY)
494  )
495  )
496  ->orderBy('record_uid')
497  ->addOrderBy('uid');
498 
499  if (!empty($linkTypes)) {
500  $queryBuilder->andWhere(
501  $queryBuilder->expr()->in(
502  'link_type',
503  $queryBuilder->createNamedParameter($linkTypes, Connection::PARAM_STR_ARRAY)
504  )
505  );
506  }
507 
508  return $queryBuilder->execute();
509  }
510 
517  protected function getNoBrokenLinkMessage(array $brokenLinksMarker)
518  {
519  $brokenLinksMarker['LIST_HEADER'] = '<h3>' . htmlspecialchars($this->getLanguageService()->getLL('list.header')) . '</h3>';
521  $message = GeneralUtility::makeInstance(
522  FlashMessage::class,
523  $this->getLanguageService()->getLL('list.no.broken.links'),
524  $this->getLanguageService()->getLL('list.no.broken.links.title'),
526  );
528  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
530  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
531  $defaultFlashMessageQueue->enqueue($message);
532  $brokenLinksMarker['NO_BROKEN_LINKS'] = $defaultFlashMessageQueue->renderFlashMessages();
533  return $brokenLinksMarker;
534  }
535 
541  protected function startTable()
542  {
543  // Listing head
544  $makerTableHead = [
545  'tablehead_path' => $this->getLanguageService()->getLL('list.tableHead.path'),
546  'tablehead_element' => $this->getLanguageService()->getLL('list.tableHead.element'),
547  'tablehead_headlink' => $this->getLanguageService()->getLL('list.tableHead.headlink'),
548  'tablehead_linktarget' => $this->getLanguageService()->getLL('list.tableHead.linktarget'),
549  'tablehead_linkmessage' => $this->getLanguageService()->getLL('list.tableHead.linkmessage'),
550  'tablehead_lastcheck' => $this->getLanguageService()->getLL('list.tableHead.lastCheck'),
551  ];
552 
553  // Add CSH to the header of each column
554  foreach ($makerTableHead as $column => $label) {
555  $makerTableHead[$column] = BackendUtility::wrapInHelp('linkvalidator', $column, $label);
556  }
557  // Add section header
558  $makerTableHead['list_header'] = '<h3>' . htmlspecialchars($this->getLanguageService()->getLL('list.header')) . '</h3>';
559  return $makerTableHead;
560  }
561 
570  protected function renderTableRow($table, array $row, $brokenLinksItemTemplate)
571  {
572  $markerArray = [];
573  $fieldName = '';
574  // Restore the linktype object
575  $hookObj = $this->hookObjectsArr[$row['link_type']];
576 
577  // Construct link to edit the content element
578  $requestUri = GeneralUtility::getIndpEnv('REQUEST_URI') .
579  '&id=' . $this->pObj->id .
580  '&search_levels=' . $this->searchLevel['report'];
582  $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
583  $url = (string)$uriBuilder->buildUriFromRoute('record_edit', [
584  'edit' => [
585  $table => [
586  $row['record_uid'] => 'edit'
587  ]
588  ],
589  'returnUrl' => $requestUri
590  ]);
591  $actionLinkOpen = '<a href="' . htmlspecialchars($url);
592  $actionLinkOpen .= '" title="' . htmlspecialchars($this->getLanguageService()->getLL('list.edit')) . '">';
593  $actionLinkClose = '</a>';
594  $elementHeadline = $row['headline'];
595  // Get the language label for the field from TCA
596  if ($GLOBALS['TCA'][$table]['columns'][$row['field']]['label']) {
597  $fieldName = $this->getLanguageService()->sL($GLOBALS['TCA'][$table]['columns'][$row['field']]['label']);
598  // Crop colon from end if present
599  if (substr($fieldName, '-1', '1') === ':') {
600  $fieldName = substr($fieldName, '0', strlen($fieldName) - 1);
601  }
602  }
603  // Fallback, if there is no label
604  $fieldName = !empty($fieldName) ? $fieldName : $row['field'];
605  // column "Element"
606  $element = '<span title="' . htmlspecialchars($table . ':' . $row['record_uid']) . '">' . $this->iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>';
607  if (empty($elementHeadline)) {
608  $element .= '<i>' . htmlspecialchars($this->getLanguageService()->getLL('list.no.headline')) . '</i>';
609  } else {
610  $element .= htmlspecialchars($elementHeadline);
611  }
612  $element .= ' ' . htmlspecialchars(sprintf($this->getLanguageService()->getLL('list.field'), $fieldName));
613  $markerArray['actionlinkOpen'] = $actionLinkOpen;
614  $markerArray['actionlinkClose'] = $actionLinkClose;
615  $markerArray['actionlinkIcon'] = $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render();
616  $markerArray['path'] = BackendUtility::getRecordPath($row['record_pid'], '', 0, 0);
617  $markerArray['element'] = $element;
618  $markerArray['headlink'] = htmlspecialchars($row['link_title']);
619  $markerArray['linktarget'] = htmlspecialchars($hookObj->getBrokenUrl($row));
620  $response = unserialize($row['url_response']);
621  if ($response['valid']) {
622  $linkMessage = '<span class="valid">' . htmlspecialchars($this->getLanguageService()->getLL('list.msg.ok')) . '</span>';
623  } else {
624  $linkMessage = '<span class="error">'
625  . nl2br(
626  // Encode for output
627  htmlspecialchars(
628  $hookObj->getErrorMessage($response['errorParams']),
629  ENT_QUOTES,
630  'UTF-8',
631  false
632  )
633  )
634  . '</span>';
635  }
636  $markerArray['linkmessage'] = $linkMessage;
637 
638  $lastRunDate = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $row['last_check']);
639  $lastRunTime = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'], $row['last_check']);
640  $markerArray['lastcheck'] = htmlspecialchars(sprintf($this->getLanguageService()->getLL('list.msg.lastRun'), $lastRunDate, $lastRunTime));
641 
642  // Return the table html code as string
643  return $this->templateService->substituteMarkerArray($brokenLinksItemTemplate, $markerArray, '###|###', true, true);
644  }
645 
653  protected function getCheckOptions(array $brokenLinkOverView, $prefix = 'report')
654  {
655  $markerArray = [];
656  if (!empty($prefix)) {
657  $additionalAttr = ' class="' . $prefix . '"';
658  } else {
659  $additionalAttr = ' class="refresh"';
660  }
661  $checkOptionsTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###CHECKOPTIONS_SECTION###');
662  $hookSectionTemplate = $this->templateService->getSubpart($checkOptionsTemplate, '###HOOK_SECTION###');
663  $markerArray['statistics_header'] = '<h3>' . htmlspecialchars($this->getLanguageService()->getLL('report.statistics.header')) . '</h3>';
664  $markerArray['total_count_label'] = BackendUtility::wrapInHelp('linkvalidator', 'checkboxes', $this->getLanguageService()->getLL('overviews.nbtotal'));
665  $markerArray['total_count'] = $brokenLinkOverView['brokenlinkCount'] ?: '0';
666 
667  $linktypes = GeneralUtility::trimExplode(',', $this->modTS['linktypes'], true);
668  $hookSectionContent = '';
669  if (is_array($linktypes)) {
670  if (
671  !empty($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])
672  && is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])
673  ) {
674  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $type => $value) {
675  if (in_array($type, $linktypes)) {
676  $hookSectionMarker = [
677  'count' => $brokenLinkOverView[$type] ?: '0',
678  ];
679 
680  $translation = $this->getLanguageService()->getLL('hooks.' . $type) ?: $type;
681 
682  $checked = ($this->checkOpt[$prefix][$type]) ? 'checked="checked"' : '';
683 
684  $hookSectionMarker['option'] = '<input type="checkbox"' . $additionalAttr
685  . ' id="' . $prefix . '_SET_' . $type
686  . '" name="' . $prefix . '_SET[' . $type . ']" value="1"'
687  . ' ' . $checked . '/>' . '<label for="'
688  . $prefix . '_SET_' . $type . '">&nbsp;' . htmlspecialchars($translation) . '</label>';
689 
690  $hookSectionContent .= $this->templateService->substituteMarkerArray(
691  $hookSectionTemplate,
692  $hookSectionMarker,
693  '###|###',
694  true,
695  true
696  );
697  }
698  }
699  }
700  }
701  $checkOptionsTemplate = $this->templateService->substituteSubpart(
702  $checkOptionsTemplate,
703  '###HOOK_SECTION###',
704  $hookSectionContent
705  );
706 
707  // set this to signal that $prefix_SET variables should be used
708  $checkOptionsTemplate .= '<input type="hidden" name="' . $prefix . '_values" value="1">';
709 
710  return $this->templateService->substituteMarkerArray($checkOptionsTemplate, $markerArray, '###|###', true, true);
711  }
712 
718  protected function getDocHeaderButtons()
719  {
720  return [
721  'csh' => BackendUtility::cshItem('_MOD_web_func', ''),
722  'shortcut' => $this->getShortcutButton(),
723  'save' => ''
724  ];
725  }
726 
732  protected function getShortcutButton()
733  {
734  $result = '';
735  if ($this->getBackendUser()->mayMakeShortcut()) {
736  $result = $this->doc->makeShortcutIcon('', 'function', $this->pObj->MCONF['name']);
737  }
738  return $result;
739  }
740 
747  protected function getTemplateMarkers()
748  {
749  return [
750  'FUNC_TITLE' => $this->getLanguageService()->getLL('report.func.title'),
751  'CHECKOPTIONS_TITLE' => $this->getLanguageService()->getLL('report.statistics.header'),
752  'FUNC_MENU' => $this->getLevelSelector('report'),
753  'CONTENT' => $this->content,
754  'CHECKOPTIONS' => $this->checkOptionsHtml['report'],
755  'ID' => '<input type="hidden" name="id" value="' . $this->pObj->id . '" />',
756  'REFRESH' => '<input type="submit" class="btn btn-default t3js-update-button" name="refreshLinkList" id="refreshLinkList" value="' . htmlspecialchars($this->getLanguageService()->getLL('label_refresh')) . '" data-notification-message="' . htmlspecialchars($this->getLanguageService()->getLL('label_refresh-link-list')) . '" />',
757  'UPDATE' => '',
758  ];
759  }
760 
767  protected function getTemplateMarkersCheck()
768  {
769  return [
770  'FUNC_TITLE' => $this->getLanguageService()->getLL('checklinks.func.title'),
771  'CHECKOPTIONS_TITLE' => $this->getLanguageService()->getLL('checklinks.statistics.header'),
772  'FUNC_MENU' => $this->getLevelSelector('check'),
773  'CONTENT' => '',
774  'CHECKOPTIONS' => $this->checkOptionsHtml['check'],
775  'ID' => '<input type="hidden" name="id" value="' . $this->pObj->id . '" />',
776  'REFRESH' => '',
777  'UPDATE' => '<input type="submit" class="btn btn-default t3js-update-button" name="updateLinkList" id="updateLinkList" value="' . htmlspecialchars($this->getLanguageService()->getLL('label_update')) . '" data-notification-message="' . htmlspecialchars($this->getLanguageService()->getLL('label_update-link-list')) . '"/>',
778  ];
779  }
780 
786  protected function isCurrentUserAdmin()
787  {
788  return $this->getBackendUser()->isAdmin();
789  }
790 
796  protected function getLanguageService()
797  {
798  return $GLOBALS['LANG'];
799  }
800 
806  protected function getBackendUser()
807  {
808  return $GLOBALS['BE_USER'];
809  }
810 }
static intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
static readPageAccess($id, $perms_clause)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static makeInstance($className,... $constructorArguments)
$fields
Definition: pages.php:4
static cshItem($table, $field, $_='', $wrap='')
static getRecordTitle($table, $row, $prep=false, $forceResult=true)
static getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
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']