‪TYPO3CMS  9.5
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 
17 use Doctrine\DBAL\Driver\Statement;
39 
45 {
48 
53  'pObj' => 'Using LinkValidatorReport::$pObj is deprecated and will not be possible anymore in TYPO3 v10.0.',
54  'doc' => 'Using LinkValidatorReport::$doc is deprecated and will not be possible anymore in TYPO3 v10.0.',
55  'function_key' => 'Using LinkValidatorReport::$function_key is deprecated, property will be removed in TYPO3 v10.0.',
56  'extClassConf' => 'Using LinkValidatorReport::$extClassConf is deprecated, property will be removed in TYPO3 v10.0.',
57  'localLangFile' => 'Using LinkValidatorReport::$localLangFile is deprecated, property will be removed in TYPO3 v10.0.',
58  'extObj' => 'Using LinkValidatorReport::$extObj is deprecated, property will be removed in TYPO3 v10.0.',
59  ];
60 
64  private ‪$deprecatedPublicMethods = [
65  'extObjContent' => 'Using LinkValidatorReport::extObjContent() is deprecated, method will be removed in TYPO3 v10.0.',
66  ];
67 
71  protected ‪$doc;
72 
78  protected ‪$pageRecord = [];
79 
85  protected ‪$isAccessibleForCurrentUser = false;
86 
92  protected ‪$linkAnalyzer;
93 
99  protected ‪$modTS = [];
100 
106  protected ‪$availableOptions = [];
107 
114  protected ‪$searchLevel = ['report' => 0, 'check' => 0];
115 
123  protected ‪$checkOpt = ['report' => [], 'check' => []];
124 
132  protected ‪$checkOptionsHtml = ['report' => [], 'check' => []];
133 
139  protected ‪$content;
140 
144  protected ‪$hookObjectsArr = [];
145 
149  protected ‪$updateListHtml = '';
150 
154  protected ‪$refreshListHtml = '';
155 
160 
164  protected ‪$iconFactory;
165 
169  protected ‪$id;
170 
174  protected ‪$pObj;
175 
179  protected ‪$extObj;
180 
188  protected ‪$localLangFile = '';
189 
197  protected ‪$extClassConf;
198 
202  protected ‪$function_key = '';
203 
209  public function ‪init(‪$pObj)
210  {
211  $languageService = $this->‪getLanguageService();
212  $this->pObj = ‪$pObj;
213  // Local lang:
214  if (!empty($this->localLangFile)) {
215  // @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
216  $languageService->includeLLFile($this->localLangFile);
217  }
218  $this->id = (int)GeneralUtility::_GP('id');
219  }
220 
226  public function ‪main()
227  {
228  $this->‪getLanguageService()->‪includeLLFile('EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf');
229  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
230  $update = GeneralUtility::_GP('updateLinkList');
231  $prefix = 'check';
232  $other = 'report';
233 
234  if (empty($update)) {
235  $prefix = 'report';
236  $other = 'check';
237  }
238 
239  // get searchLevel (number of levels of pages to check / show results)
240  $this->searchLevel[$prefix] = GeneralUtility::_GP($prefix . '_search_levels');
241  if (isset($this->id)) {
242  $this->modTS = ‪BackendUtility::getPagesTSconfig($this->id)['mod.']['linkvalidator.'] ?? [];
243  }
244  if (isset($this->searchLevel[$prefix])) {
245  $this->pObj->MOD_SETTINGS[$prefix . '_searchlevel'] = $this->searchLevel[$prefix];
246  } else {
247  $this->searchLevel[$prefix] = $this->pObj->MOD_SETTINGS[$prefix . '_searchlevel'];
248  }
249  if (isset($this->pObj->MOD_SETTINGS[$other . '_searchlevel'])) {
250  $this->searchLevel[$other] = $this->pObj->MOD_SETTINGS[$other . '_searchlevel'];
251  }
252 
253  // which linkTypes to check (internal, file, external, ...)
254  $set = GeneralUtility::_GP($prefix . '_SET');
255 
256  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] ?? [] as $linkType => $value) {
257  // Compile list of all available types. Used for checking with button "Check Links".
258  if (strpos($this->modTS['linktypes'], $linkType) !== false) {
259  $this->availableOptions[$linkType] = 1;
260  }
261 
262  // 1) if "$prefix_values" = "1" : use POST variables
263  // 2) if not set, use stored configuration in $this->>pObj->MOD_SETTINGS
264  // 3) if not set, use default
265  unset($this->checkOpt[$prefix][$linkType]);
266  if (!empty(GeneralUtility::_GP($prefix . '_values'))) {
267  if (isset($set[$linkType])) {
268  $this->checkOpt[$prefix][$linkType] = $set[$linkType];
269  } else {
270  $this->checkOpt[$prefix][$linkType] = '0';
271  }
272  $this->pObj->MOD_SETTINGS[$prefix . '_' . $linkType] = $this->checkOpt[$prefix][$linkType];
273  } elseif (isset($this->pObj->MOD_SETTINGS[$prefix . '_' . $linkType])) {
274  $this->checkOpt[$prefix][$linkType] = $this->pObj->MOD_SETTINGS[$prefix . '_' . $linkType];
275  } else {
276  // use default
277  $this->checkOpt[$prefix][$linkType] = '0';
278  $this->pObj->MOD_SETTINGS[$prefix . '_' . $linkType] = $this->checkOpt[$prefix][$linkType];
279  }
280  if (isset($this->pObj->MOD_SETTINGS[$other . '_' . $linkType])) {
281  $this->checkOpt[$other][$linkType] = $this->pObj->MOD_SETTINGS[$other . '_' . $linkType];
282  }
283  }
284 
285  // save settings
286  $this->‪getBackendUser()->‪pushModuleData('web_info', $this->pObj->MOD_SETTINGS);
287  $this->‪initialize();
288 
289  // Localization
290  $this->‪getPageRenderer()->‪addInlineLanguageLabelFile('EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf');
291 
292  if ($this->modTS['showCheckLinkTab'] == 1) {
293  $this->updateListHtml = '<input class="btn btn-default t3js-update-button" type="submit" name="updateLinkList" id="updateLinkList" value="'
294  . htmlspecialchars($this->‪getLanguageService()->getLL('label_update'))
295  . '" data-notification-message="'
296  . htmlspecialchars($this->‪getLanguageService()->getLL('label_update-link-list'))
297  . '"/>';
298  }
299  $this->refreshListHtml = '<input class="btn btn-default t3js-update-button" type="submit" name="refreshLinkList" id="refreshLinkList" value="'
300  . htmlspecialchars($this->‪getLanguageService()->getLL('label_refresh'))
301  . '" data-notification-message="'
302  . htmlspecialchars($this->‪getLanguageService()->getLL('label_refresh-link-list'))
303  . '"/>';
304  $this->linkAnalyzer = GeneralUtility::makeInstance(LinkAnalyzer::class);
305  $this->‪updateBrokenLinks();
306 
307  $brokenLinkOverView = $this->linkAnalyzer->getLinkCounts($this->id);
308  $this->checkOptionsHtml['report'] = $this->‪getCheckOptions($brokenLinkOverView, 'report');
309  $this->checkOptionsHtml['check'] = $this->‪getCheckOptions($brokenLinkOverView, 'check');
310  $this->‪render();
311 
312  $pageTile = '';
313  if ($this->id) {
314  ‪$pageRecord = ‪BackendUtility::getRecord('pages', $this->id);
315  $pageTile = '<h1>' . htmlspecialchars(‪BackendUtility::getRecordTitle('pages', ‪$pageRecord)) . '</h1>';
316  }
317 
318  return '<div id="linkvalidator-modfuncreport">' . $pageTile . $this->‪createTabs() . '</div>';
319  }
320 
326  protected function ‪createTabs()
327  {
328  $languageService = $this->‪getLanguageService();
329  $menuItems = [
330  0 => [
331  'label' => $languageService->getLL('Report'),
332  'content' => $this->‪flush(true)
333  ],
334  ];
335 
336  if ((bool)$this->modTS['showCheckLinkTab']) {
337  $menuItems[1] = [
338  'label' => $languageService->getLL('CheckLink'),
339  'content' => $this->‪flush()
340  ];
341  }
342 
343  $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
344  return $moduleTemplate->getDynamicTabMenu($menuItems, 'report-linkvalidator');
345  }
346 
350  protected function ‪initialize()
351  {
352  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] ?? [] as $linkType => $className) {
353  $this->hookObjectsArr[$linkType] = GeneralUtility::makeInstance($className);
354  }
355 
356  $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
357  $this->doc->setModuleTemplate('EXT:linkvalidator/Resources/Private/Templates/mod_template.html');
358 
359  $this->pageRecord = ‪BackendUtility::readPageAccess($this->id, $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW));
360  if ($this->id && is_array($this->pageRecord) || !$this->id && $this->‪isCurrentUserAdmin()) {
361  $this->isAccessibleForCurrentUser = true;
362  }
363 
364  $pageRenderer = $this->‪getPageRenderer();
365  $pageRenderer->addCssFile('EXT:linkvalidator/Resources/Public/Css/linkvalidator.css', 'stylesheet', 'screen');
366  $pageRenderer->loadRequireJsModule('TYPO3/CMS/Linkvalidator/Linkvalidator');
367 
368  $this->templateService = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
369 
370  // Don't access in workspace
371  if ($this->‪getBackendUser()->workspace !== 0) {
372  $this->isAccessibleForCurrentUser = false;
373  }
374  }
375 
379  protected function ‪updateBrokenLinks()
380  {
381  $searchFields = [];
382  // Get the searchFields from TypoScript
383  foreach ($this->modTS['searchFields.'] as $table => $fieldList) {
384  ‪$fields = GeneralUtility::trimExplode(',', $fieldList, true);
385  foreach (‪$fields as $field) {
386  if (!$searchFields || !is_array($searchFields[$table]) || !in_array($field, $searchFields[$table], true)) {
387  $searchFields[$table][] = $field;
388  }
389  }
390  }
391  $rootLineHidden = $this->linkAnalyzer->getRootLineIsHidden($this->pObj->pageinfo);
392  if (!$rootLineHidden || $this->modTS['checkhidden'] == 1) {
394  // Get children pages
395  $pageList = $this->linkAnalyzer->extGetTreeList(
396  $this->id,
397  $this->searchLevel['check'],
398  0,
399  $permsClause,
400  $this->modTS['checkhidden']
401  );
402  if ($this->pObj->pageinfo['hidden'] == 0 || $this->modTS['checkhidden']) {
403  $pageList .= ‪$this->id;
404  $pageList = $this->‪addPageTranslationsToPageList($pageList, $permsClause);
405  }
406 
407  $this->linkAnalyzer->init($searchFields, $pageList, $this->modTS);
408 
409  // Check if button press
410  $update = GeneralUtility::_GP('updateLinkList');
411  if (!empty($update)) {
412  $this->linkAnalyzer->getLinkStatistics($this->checkOpt['check'], $this->modTS['checkhidden']);
413  }
414  }
415  }
416 
420  protected function ‪render()
421  {
422  if ($this->isAccessibleForCurrentUser) {
423  $this->content = $this->‪renderBrokenLinksTable();
424  } else {
425  $languageService = $this->‪getLanguageService();
426  // If no access or if ID == zero
427  $message = GeneralUtility::makeInstance(
428  FlashMessage::class,
429  $languageService->getLL('no.access'),
430  $languageService->getLL('no.access.title'),
432  );
434  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
436  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
437  $defaultFlashMessageQueue->enqueue($message);
438  }
439  }
440 
447  protected function ‪flush($form = false)
448  {
449  return $this->doc->moduleBody(
450  $this->pageRecord,
451  $this->‪getDocHeaderButtons(),
452  $form ? $this->‪getTemplateMarkers() : $this->‪getTemplateMarkersCheck()
453  );
454  }
455 
463  protected function ‪getLevelSelector($prefix = 'report')
464  {
465  $languageService = $this->‪getLanguageService();
466  // Build level selector
467  $options = [];
469  0 => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
470  1 => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
471  2 => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
472  3 => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
473  4 => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
474  999 => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi')
475  ];
476  foreach (‪$availableOptions as $optionValue => $optionLabel) {
477  $options[] = '<option value="' . $optionValue . '"' . ($optionValue === (int)$this->searchLevel[$prefix] ? ' selected="selected"' : '') . '>' . htmlspecialchars($optionLabel) . '</option>';
478  }
479  return '<select name="' . $prefix . '_search_levels" class="form-control">' . implode('', $options) . '</select>';
480  }
481 
487  protected function ‪renderBrokenLinksTable()
488  {
489  $brokenLinkItems = '';
490  $brokenLinksTemplate = $this->templateService->getSubpart(
491  $this->doc->moduleTemplate,
492  '###NOBROKENLINKS_CONTENT###'
493  );
494 
495  $linkTypes = [];
496  if (is_array($this->checkOpt['report'])) {
497  $linkTypes = array_keys($this->checkOpt['report'], '1');
498  }
499 
500  // Table header
501  $brokenLinksMarker = $this->‪startTable();
502 
503  $rootLineHidden = $this->linkAnalyzer->getRootLineIsHidden($this->pObj->pageinfo);
504  if (!$rootLineHidden || (bool)$this->modTS['checkhidden']) {
505  $pageList = $this->‪getPageList();
506  $result = false;
507  if (!empty($linkTypes)) {
508  $result = $this->‪getLinkValidatorBrokenLinks($pageList, $linkTypes);
509  }
510 
511  if ($result && $result->rowCount()) {
512  // Display table with broken links
513  $brokenLinksTemplate = $this->templateService->getSubpart(
514  $this->doc->moduleTemplate,
515  '###BROKENLINKS_CONTENT###'
516  );
517  $brokenLinksItemTemplate = $this->templateService->getSubpart(
518  $this->doc->moduleTemplate,
519  '###BROKENLINKS_ITEM###'
520  );
521 
522  // Table rows containing the broken links
523  $items = [];
524  while ($row = $result->fetch()) {
525  $items[] = $this->‪renderTableRow($row['table_name'], $row, $brokenLinksItemTemplate);
526  }
527  $brokenLinkItems = implode(LF, $items);
528  } else {
529  $brokenLinksMarker = $this->‪getNoBrokenLinkMessage($brokenLinksMarker);
530  }
531  } else {
532  $brokenLinksMarker = $this->‪getNoBrokenLinkMessage($brokenLinksMarker);
533  }
534 
535  $brokenLinksTemplate = $this->templateService->substituteMarkerArray(
536  $brokenLinksTemplate,
537  $brokenLinksMarker,
538  '###|###',
539  true
540  );
541 
542  return $this->templateService->substituteSubpart($brokenLinksTemplate, '###BROKENLINKS_ITEM', $brokenLinkItems);
543  }
544 
551  protected function ‪getPageList(): array
552  {
554  $pageList = $this->linkAnalyzer->extGetTreeList(
555  $this->id,
556  $this->searchLevel['report'],
557  0,
558  $permsClause,
559  $this->modTS['checkhidden']
560  );
561  // Always add the current page, because we are just displaying the results
562  $pageList .= ‪$this->id;
563  $pageList = $this->‪addPageTranslationsToPageList($pageList, $permsClause);
564 
565  return GeneralUtility::intExplode(',', $pageList, true);
566  }
567 
575  protected function ‪getLinkValidatorBrokenLinks(array $pageList, array $linkTypes): Statement
576  {
577  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
578  ->getQueryBuilderForTable('tx_linkvalidator_link');
579  $queryBuilder
580  ->select('*')
581  ->from('tx_linkvalidator_link')
582  ->where(
583  $queryBuilder->expr()->orX(
584  $queryBuilder->expr()->andX(
585  $queryBuilder->expr()->in(
586  'record_uid',
587  $queryBuilder->createNamedParameter($pageList, Connection::PARAM_INT_ARRAY)
588  ),
589  $queryBuilder->expr()->eq('table_name', $queryBuilder->createNamedParameter('pages'))
590  ),
591  $queryBuilder->expr()->andX(
592  $queryBuilder->expr()->in(
593  'record_pid',
594  $queryBuilder->createNamedParameter($pageList, Connection::PARAM_INT_ARRAY)
595  ),
596  $queryBuilder->expr()->neq('table_name', $queryBuilder->createNamedParameter('pages'))
597  )
598  )
599  )
600  ->orderBy('record_uid')
601  ->addOrderBy('uid');
602 
603  if (!empty($linkTypes)) {
604  $queryBuilder->andWhere(
605  $queryBuilder->expr()->in(
606  'link_type',
607  $queryBuilder->createNamedParameter($linkTypes, Connection::PARAM_STR_ARRAY)
608  )
609  );
610  }
611 
612  return $queryBuilder->execute();
613  }
614 
621  protected function ‪getNoBrokenLinkMessage(array $brokenLinksMarker)
622  {
623  $languageService = $this->‪getLanguageService();
624  $brokenLinksMarker['LIST_HEADER'] = '<h3>' . htmlspecialchars($languageService->getLL('list.header')) . '</h3>';
626  $message = GeneralUtility::makeInstance(
627  FlashMessage::class,
628  $languageService->getLL('list.no.broken.links'),
629  $languageService->getLL('list.no.broken.links.title'),
631  );
632  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
634  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
635  $defaultFlashMessageQueue->enqueue($message);
636  $brokenLinksMarker['NO_BROKEN_LINKS'] = $defaultFlashMessageQueue->renderFlashMessages();
637  return $brokenLinksMarker;
638  }
639 
645  protected function ‪startTable()
646  {
647  $languageService = $this->‪getLanguageService();
648  // Listing head
649  $makerTableHead = [
650  'tablehead_path' => $languageService->getLL('list.tableHead.path'),
651  'tablehead_element' => $languageService->getLL('list.tableHead.element'),
652  'tablehead_headlink' => $languageService->getLL('list.tableHead.headlink'),
653  'tablehead_linktarget' => $languageService->getLL('list.tableHead.linktarget'),
654  'tablehead_linkmessage' => $languageService->getLL('list.tableHead.linkmessage'),
655  'tablehead_lastcheck' => $languageService->getLL('list.tableHead.lastCheck'),
656  ];
657 
658  // Add CSH to the header of each column
659  foreach ($makerTableHead as $column => $label) {
660  $makerTableHead[$column] = ‪BackendUtility::wrapInHelp('linkvalidator', $column, $label);
661  }
662  // Add section header
663  $makerTableHead['list_header'] = '<h3>' . htmlspecialchars($languageService->getLL('list.header')) . '</h3>';
664  return $makerTableHead;
665  }
666 
675  protected function ‪renderTableRow($table, array $row, $brokenLinksItemTemplate)
676  {
677  $languageService = $this->‪getLanguageService();
678  $markerArray = [];
679  $fieldName = '';
680  // Restore the linktype object
681  $hookObj = $this->hookObjectsArr[$row['link_type']];
682 
683  // Construct link to edit the content element
684  $requestUri = GeneralUtility::getIndpEnv('REQUEST_URI') .
685  '&id=' . $this->id .
686  '&search_levels=' . $this->searchLevel['report'];
688  $uriBuilder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Backend\Routing\UriBuilder::class);
689  $url = (string)$uriBuilder->buildUriFromRoute('record_edit', [
690  'edit' => [
691  $table => [
692  $row['record_uid'] => 'edit'
693  ]
694  ],
695  'columnsOnly' => $row['field'],
696  'returnUrl' => $requestUri
697  ]);
698  $actionLinkOpen = '<a href="' . htmlspecialchars($url);
699  $actionLinkOpen .= '" title="' . htmlspecialchars($languageService->getLL('list.edit')) . '">';
700  $actionLinkClose = '</a>';
701  $elementHeadline = $row['headline'];
702  // Get the language label for the field from TCA
703  if (‪$GLOBALS['TCA'][$table]['columns'][$row['field']]['label']) {
704  $fieldName = $languageService->sL(‪$GLOBALS['TCA'][$table]['columns'][$row['field']]['label']);
705  // Crop colon from end if present
706  if (substr($fieldName, '-1', '1') === ':') {
707  $fieldName = substr($fieldName, '0', strlen($fieldName) - 1);
708  }
709  }
710  // Fallback, if there is no label
711  $fieldName = !empty($fieldName) ? $fieldName : $row['field'];
712  // column "Element"
713  $element = '<span title="' . htmlspecialchars($table . ':' . $row['record_uid']) . '">' . $this->iconFactory->getIconForRecord($table, $row, ‪Icon::SIZE_SMALL)->render() . '</span>';
714  if (empty($elementHeadline)) {
715  $element .= '<i>' . htmlspecialchars($languageService->getLL('list.no.headline')) . '</i>';
716  } else {
717  $element .= htmlspecialchars($elementHeadline);
718  }
719  $element .= ' ' . htmlspecialchars(sprintf($languageService->getLL('list.field'), $fieldName));
720  $markerArray['actionlinkOpen'] = $actionLinkOpen;
721  $markerArray['actionlinkClose'] = $actionLinkClose;
722  $markerArray['actionlinkIcon'] = $this->iconFactory->getIcon('actions-open', ‪Icon::SIZE_SMALL)->render();
723  $markerArray['path'] = ‪BackendUtility::getRecordPath($row['record_pid'], '', 0, 0);
724  $markerArray['element'] = $element;
725  $markerArray['headlink'] = htmlspecialchars($row['link_title']);
726  $markerArray['linktarget'] = htmlspecialchars($hookObj->getBrokenUrl($row));
727  $response = unserialize($row['url_response']);
728  if ($response['valid']) {
729  $linkMessage = '<span class="valid">' . htmlspecialchars($languageService->getLL('list.msg.ok')) . '</span>';
730  } else {
731  $linkMessage = '<span class="error">'
732  . nl2br(
733  // Encode for output
734  htmlspecialchars(
735  $hookObj->getErrorMessage($response['errorParams']),
736  ENT_QUOTES,
737  'UTF-8',
738  false
739  )
740  )
741  . '</span>';
742  }
743  $markerArray['linkmessage'] = $linkMessage;
744 
745  $lastRunDate = date(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $row['last_check']);
746  $lastRunTime = date(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'], $row['last_check']);
747  $markerArray['lastcheck'] = htmlspecialchars(sprintf($languageService->getLL('list.msg.lastRun'), $lastRunDate, $lastRunTime));
748 
749  // Return the table html code as string
750  return $this->templateService->substituteMarkerArray($brokenLinksItemTemplate, $markerArray, '###|###', true, true);
751  }
752 
760  protected function ‪getCheckOptions(array $brokenLinkOverView, $prefix = 'report')
761  {
762  $languageService = $this->‪getLanguageService();
763  $markerArray = [];
764  if (!empty($prefix)) {
765  $additionalAttr = ' class="' . $prefix . '"';
766  } else {
767  $additionalAttr = ' class="refresh"';
768  }
769  $checkOptionsTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###CHECKOPTIONS_SECTION###');
770  $hookSectionTemplate = $this->templateService->getSubpart($checkOptionsTemplate, '###HOOK_SECTION###');
771  $markerArray['statistics_header'] = '<h3>' . htmlspecialchars($languageService->getLL('report.statistics.header')) . '</h3>';
772  $markerArray['total_count_label'] = ‪BackendUtility::wrapInHelp('linkvalidator', 'checkboxes', $languageService->getLL('overviews.nbtotal'));
773  $markerArray['total_count'] = $brokenLinkOverView['brokenlinkCount'] ?: '0';
774 
775  $linktypes = GeneralUtility::trimExplode(',', $this->modTS['linktypes'], true);
776  $hookSectionContent = '';
777  if (is_array($linktypes)) {
778  if (
779  !empty(‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])
780  && is_array(‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])
781  ) {
782  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $type => $value) {
783  if (in_array($type, $linktypes)) {
784  $hookSectionMarker = [
785  'count' => $brokenLinkOverView[$type] ?: '0',
786  ];
787 
788  $translation = $languageService->getLL('hooks.' . $type) ?: $type;
789 
790  $checked = $this->checkOpt[$prefix][$type] ? 'checked="checked"' : '';
791 
792  $hookSectionMarker['option'] = '<input type="checkbox"' . $additionalAttr
793  . ' id="' . $prefix . '_SET_' . $type
794  . '" name="' . $prefix . '_SET[' . $type . ']" value="1"'
795  . ' ' . $checked . '/>' . '<label for="'
796  . $prefix . '_SET_' . $type . '">&nbsp;' . htmlspecialchars($translation) . '</label>';
797 
798  $hookSectionContent .= $this->templateService->substituteMarkerArray(
799  $hookSectionTemplate,
800  $hookSectionMarker,
801  '###|###',
802  true,
803  true
804  );
805  }
806  }
807  }
808  }
809  $checkOptionsTemplate = $this->templateService->substituteSubpart(
810  $checkOptionsTemplate,
811  '###HOOK_SECTION###',
812  $hookSectionContent
813  );
814 
815  // set this to signal that $prefix_SET variables should be used
816  $checkOptionsTemplate .= '<input type="hidden" name="' . $prefix . '_values" value="1">';
817 
818  return $this->templateService->substituteMarkerArray($checkOptionsTemplate, $markerArray, '###|###', true, true);
819  }
820 
826  protected function ‪getDocHeaderButtons()
827  {
828  return [
829  'csh' => ‪BackendUtility::cshItem('_MOD_web_func', ''),
830  'shortcut' => $this->‪getShortcutButton(),
831  'save' => ''
832  ];
833  }
834 
840  protected function ‪getShortcutButton()
841  {
842  $result = '';
843  if ($this->‪getBackendUser()->mayMakeShortcut()) {
844  $result = $this->doc->makeShortcutIcon('', 'function', 'web_info');
845  }
846  return $result;
847  }
848 
855  protected function ‪getTemplateMarkers()
856  {
857  $languageService = $this->‪getLanguageService();
858  return [
859  'FUNC_TITLE' => $languageService->getLL('report.func.title'),
860  'CHECKOPTIONS_TITLE' => $languageService->getLL('report.statistics.header'),
861  'FUNC_MENU' => $this->‪getLevelSelector('report'),
862  'CONTENT' => ‪$this->content,
863  'CHECKOPTIONS' => $this->checkOptionsHtml['report'],
864  'ID' => '<input type="hidden" name="id" value="' . $this->id . '" />',
865  'REFRESH' => '<input type="submit" class="btn btn-default t3js-update-button" name="refreshLinkList" id="refreshLinkList" value="'
866  . htmlspecialchars($languageService->getLL('label_refresh'))
867  . '" data-notification-message="'
868  . htmlspecialchars($languageService->getLL('label_refresh-link-list')) . '" />',
869  'UPDATE' => '',
870  ];
871  }
872 
879  protected function ‪getTemplateMarkersCheck()
880  {
881  $languageService = $this->‪getLanguageService();
882  return [
883  'FUNC_TITLE' => $languageService->getLL('checklinks.func.title'),
884  'CHECKOPTIONS_TITLE' => $languageService->getLL('checklinks.statistics.header'),
885  'FUNC_MENU' => $this->‪getLevelSelector('check'),
886  'CONTENT' => '',
887  'CHECKOPTIONS' => $this->checkOptionsHtml['check'],
888  'ID' => '<input type="hidden" name="id" value="' . $this->id . '" />',
889  'REFRESH' => '',
890  'UPDATE' => '<input type="submit" class="btn btn-default t3js-update-button" name="updateLinkList" id="updateLinkList" value="'
891  . htmlspecialchars($languageService->getLL('label_update'))
892  . '" data-notification-message="'
893  . htmlspecialchars($languageService->getLL('label_update-link-list'))
894  . '"/>',
895  ];
896  }
897 
903  protected function ‪isCurrentUserAdmin()
904  {
905  return $this->‪getBackendUser()->‪isAdmin();
906  }
907 
913  public function ‪checkExtObj()
914  {
915  if (is_array($this->extClassConf) && $this->extClassConf['name']) {
916  $this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']);
917  $this->extObj->init($this->pObj, $this->extClassConf);
918  // Re-write:
919  $this->pObj->MOD_SETTINGS = ‪BackendUtility::getModuleData($this->pObj->MOD_MENU, GeneralUtility::_GP('SET'), 'web_info');
920  }
921  }
922 
928  protected function ‪extObjContent()
929  {
930  if (is_object($this->extObj)) {
931  return $this->extObj->main();
932  }
933  }
934 
938  protected function ‪getLanguageService(): ‪LanguageService
939  {
940  return ‪$GLOBALS['LANG'];
941  }
942 
946  protected function ‪getBackendUser(): ‪BackendUserAuthentication
947  {
948  return ‪$GLOBALS['BE_USER'];
949  }
950 
954  protected function ‪getPageRenderer(): ‪PageRenderer
955  {
956  return GeneralUtility::makeInstance(PageRenderer::class);
957  }
958 
964  protected function ‪addPageTranslationsToPageList(string $theList, string $permsClause): string
965  {
966  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
967  $queryBuilder->getRestrictions()
968  ->removeAll()
969  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
970 
971  $result = $queryBuilder
972  ->select('uid', 'title', 'hidden')
973  ->from('pages')
974  ->where(
975  $queryBuilder->expr()->eq(
976  'l10n_parent',
977  $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)
978  ),
980  )
981  ->execute();
982 
983  while ($row = $result->fetch()) {
984  if ($row['hidden'] === 0 || $this->modTS['checkhidden']) {
985  $theList .= ',' . $row['uid'];
986  }
987  }
988 
989  return $theList;
990  }
991 }
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:29
‪TYPO3\CMS\Info\Controller\InfoModuleController
Definition: InfoModuleController.php:42
‪TYPO3\CMS\Core\Localization\LanguageService\includeLLFile
‪mixed includeLLFile($fileRef, $setGlobal=true, $mergeLocalOntoDefault=false)
Definition: LanguageService.php:260
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineLanguageLabelFile
‪addInlineLanguageLabelFile($fileRef, $selectionPrefix='', $stripFromSelectionName='')
Definition: PageRenderer.php:1678
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getPagePermsClause
‪string getPagePermsClause($perms)
Definition: BackendUserAuthentication.php:523
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:25
‪TYPO3
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isAdmin
‪bool isAdmin()
Definition: BackendUserAuthentication.php:294
‪TYPO3\CMS\Backend\Utility\BackendUtility\cshItem
‪static string cshItem($table, $field, $_='', $wrap='')
Definition: BackendUtility.php:2565
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:31
‪$fields
‪$fields
Definition: pages.php:4
‪TYPO3\CMS\Backend\Utility\BackendUtility\wrapInHelp
‪static string wrapInHelp($table, $field, $text='', array $overloadHelpText=[])
Definition: BackendUtility.php:2519
‪TYPO3\CMS\Backend\Template\ModuleTemplate
Definition: ModuleTemplate.php:40
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:23
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:35
‪TYPO3\CMS\Core\Database\Query\QueryHelper
Definition: QueryHelper.php:30
‪TYPO3\CMS\Backend\Template\DocumentTemplate
Definition: DocumentTemplate.php:48
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\pushModuleData
‪pushModuleData($module, $data, $noSave=0)
Definition: AbstractUserAuthentication.php:1213
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordTitle
‪static string getRecordTitle($table, $row, $prep=false, $forceResult=true)
Definition: BackendUtility.php:1811
‪TYPO3\CMS\Backend\Utility\BackendUtility\getModuleData
‪static array getModuleData( $MOD_MENU, $CHANGED_SETTINGS, $modName, $type='', $dontValidateList='', $setDefaultList='')
Definition: BackendUtility.php:3259
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:45
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:32
‪TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait
Definition: PublicMethodDeprecationTrait.php:68
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:130
‪TYPO3\CMS\Core\Messaging\AbstractMessage\OK
‪const OK
Definition: AbstractMessage.php:27
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:31
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:22
‪TYPO3\CMS\Core\Database\Query\QueryHelper\stripLogicalOperatorPrefix
‪static string stripLogicalOperatorPrefix(string $constraint)
Definition: QueryHelper.php:163
‪TYPO3\CMS\Backend\Utility\BackendUtility\getPagesTSconfig
‪static array getPagesTSconfig($id, $rootLine=null, $returnPartArray=false)
Definition: BackendUtility.php:864
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait
Definition: PublicPropertyDeprecationTrait.php:66
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Linkvalidator\Report
Definition: LinkValidatorReport.php:2
‪TYPO3\CMS\Core\Service\MarkerBasedTemplateService
Definition: MarkerBasedTemplateService.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordPath
‪static mixed getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
Definition: BackendUtility.php:572
‪TYPO3\CMS\Core\Messaging\FlashMessageService
Definition: FlashMessageService.php:25
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:29
‪TYPO3\CMS\Backend\Utility\BackendUtility\readPageAccess
‪static array bool readPageAccess($id, $perms_clause)
Definition: BackendUtility.php:635