2 namespace TYPO3\CMS\Linkvalidator\Report;
143 $this->
getLanguageService()->includeLLFile(
'EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf');
146 if (isset($this->pObj->id)) {
148 $this->modTS = $this->modTS[
'properties'];
152 if (!empty($update)) {
156 $this->pObj->handleExternalFunctionValue();
157 if (isset($this->searchLevel)) {
160 $this->searchLevel = $this->pObj->MOD_SETTINGS[
'searchlevel'];
162 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXTCONF'][
'linkvalidator'][
'checkLinks'])) {
163 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXTCONF'][
'linkvalidator'][
'checkLinks'] as $linkType => $value) {
165 if (strpos($this->modTS[
'linktypes'], $linkType) !==
false) {
166 $this->availableOptions[$linkType] = 1;
169 if ($this->pObj->MOD_SETTINGS[$linkType] && empty($set) || $set[$linkType]) {
170 $this->checkOpt[$linkType] = 1;
171 $this->pObj->MOD_SETTINGS[$linkType] = 1;
173 $this->pObj->MOD_SETTINGS[$linkType] = 0;
174 unset($this->checkOpt[$linkType]);
178 $this->
getBackendUser()->pushModuleData(
'web_info', $this->pObj->MOD_SETTINGS);
186 if ($this->modTS[
'showCheckLinkTab'] == 1) {
187 $this->updateListHtml =
'<input class="btn btn-default" type="submit" name="updateLinkList" id="updateLinkList" value="' . $this->
getLanguageService()->getLL(
'label_update') .
'"/>';
189 $this->refreshListHtml =
'<input class="btn btn-default" type="submit" name="refreshLinkList" id="refreshLinkList" value="' . $this->
getLanguageService()->getLL(
'label_refresh') .
'"/>';
193 $brokenLinkOverView = $this->linkAnalyzer->getLinkCounts($this->pObj->id);
195 $this->checkOptionsHtmlCheck = $this->
getCheckOptions($brokenLinkOverView,
'check');
199 if ($this->pObj->id) {
204 return '<div id="linkvalidator-modfuncreport">' . $pageTile . $this->createTabs() .
'</div>';
212 protected function createTabs()
217 'content' => $this->
flush(
true)
221 if ((
bool)$this->modTS[
'showCheckLinkTab']) {
222 $menuItems[1] = array(
224 'content' => $this->
flush()
231 return $moduleTemplate->getDynamicTabMenu($menuItems,
'report-linkvalidator');
241 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXTCONF'][
'linkvalidator'][
'checkLinks'])) {
242 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXTCONF'][
'linkvalidator'][
'checkLinks'] as $linkType => $classRef) {
248 $this->doc->setModuleTemplate(
'EXT:linkvalidator/Resources/Private/Templates/mod_template.html');
251 if ($this->pObj->id && is_array($this->pageRecord) || !$this->pObj->id && $this->
isCurrentUserAdmin()) {
252 $this->isAccessibleForCurrentUser =
true;
255 $this->doc->addStyleSheet(
'module',
'sysext/linkvalidator/Resources/Public/Css/styles.css');
257 $this->
getPageRenderer()->loadRequireJsModule(
'TYPO3/CMS/Linkvalidator/Linkvalidator');
263 $this->isAccessibleForCurrentUser =
false;
274 $searchFields = array();
276 foreach ($this->modTS[
'searchFields.'] as $table => $fieldList) {
278 foreach ($fields as $field) {
279 if (!$searchFields || !is_array($searchFields[$table]) || array_search($field, $searchFields[$table]) ===
false) {
280 $searchFields[$table][] = $field;
284 $rootLineHidden = $this->linkAnalyzer->getRootLineIsHidden($this->pObj->pageinfo);
285 if (!$rootLineHidden || $this->modTS[
'checkhidden'] == 1) {
287 $pageList = $this->linkAnalyzer->extGetTreeList(
291 $this->getBackendUser()->getPagePermsClause(1),
292 $this->modTS[
'checkhidden']
294 if ($this->pObj->pageinfo[
'hidden'] == 0 || $this->modTS[
'checkhidden']) {
295 $pageList .= $this->pObj->id;
298 $this->linkAnalyzer->init($searchFields, $pageList, $this->modTS);
302 if (!empty($update)) {
303 $this->linkAnalyzer->getLinkStatistics($this->checkOpt, $this->modTS[
'checkhidden']);
313 protected function render()
315 if ($this->isAccessibleForCurrentUser) {
326 $this->content .= $message->render();
336 protected function flush($form =
false)
338 return $this->doc->moduleBody(
355 0 => $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.depth_0'),
356 1 => $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.depth_1'),
357 2 => $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.depth_2'),
358 3 => $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.depth_3'),
359 4 => $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.depth_4'),
360 999 => $this->
getLanguageService()->sL(
'LLL:EXT:lang/locallang_core.xlf:labels.depth_infi')
363 $options[] =
'<option value="' . $optionValue .
'"' . ($optionValue === (int)$this->searchLevel ?
' selected="selected"' :
'') .
'>' . htmlspecialchars($optionLabel) .
'</option>';
365 return '<select name="search_levels" class="form-control">' . implode(
'', $options) .
'</select>';
375 $brokenLinkItems =
'';
376 $brokenLinksTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate,
'###NOBROKENLINKS_CONTENT###');
378 if (is_array($this->checkOpt)) {
379 $keyOpt = array_keys($this->checkOpt);
385 $rootLineHidden = $this->linkAnalyzer->getRootLineIsHidden($this->pObj->pageinfo);
386 if (!$rootLineHidden || (
bool)$this->modTS[
'checkhidden']) {
387 $pageList = $this->linkAnalyzer->extGetTreeList(
391 $this->getBackendUser()->getPagePermsClause(1),
392 $this->modTS[
'checkhidden']
395 $pageList .= $this->pObj->id;
399 'tx_linkvalidator_link',
400 'record_pid IN (' . $pageList .
') AND link_type IN (\'' . implode(
'\',\
'', $keyOpt) .
'\')
',
402 'record_uid ASC, uid ASC
'
404 if (!empty($records)) {
405 // Display table with broken links
406 $brokenLinksTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###BROKENLINKS_CONTENT###
');
407 $brokenLinksItemTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###BROKENLINKS_ITEM###
');
409 // Table rows containing the broken links
411 foreach ($records as $record) {
412 $items[] = $this->renderTableRow($record['table_name
'], $record, $brokenLinksItemTemplate);
414 $brokenLinkItems = implode(LF, $items);
416 $brokenLinksMarker = $this->getNoBrokenLinkMessage($brokenLinksMarker);
419 $brokenLinksMarker = $this->getNoBrokenLinkMessage($brokenLinksMarker);
421 $brokenLinksTemplate = $this->templateService->substituteMarkerArray(
422 $brokenLinksTemplate,
423 $brokenLinksMarker, '###|###
',
426 return $this->templateService->substituteSubpart($brokenLinksTemplate, '###BROKENLINKS_ITEM
', $brokenLinkItems);
435 protected function getNoBrokenLinkMessage(array $brokenLinksMarker)
437 $brokenLinksMarker['LIST_HEADER
'] = '<h3>
' . $this->getLanguageService()->getLL('list.header
', true) . '</h3>
';
439 $message = GeneralUtility::makeInstance(
441 $this->getLanguageService()->getLL('list.no.broken.links
'),
442 $this->getLanguageService()->getLL('list.no.broken.links.title
'),
445 $brokenLinksMarker['NO_BROKEN_LINKS
'] = $message->render();
446 return $brokenLinksMarker;
454 protected function startTable()
457 $makerTableHead = array(
458 'tablehead_path
' => $this->getLanguageService()->getLL('list.tableHead.path
'),
459 'tablehead_element
' => $this->getLanguageService()->getLL('list.tableHead.element
'),
460 'tablehead_headlink
' => $this->getLanguageService()->getLL('list.tableHead.headlink
'),
461 'tablehead_linktarget
' => $this->getLanguageService()->getLL('list.tableHead.linktarget
'),
462 'tablehead_linkmessage
' => $this->getLanguageService()->getLL('list.tableHead.linkmessage
'),
463 'tablehead_lastcheck
' => $this->getLanguageService()->getLL('list.tableHead.lastCheck
'),
466 // Add CSH to the header of each column
467 foreach ($makerTableHead as $column => $label) {
468 $makerTableHead[$column] = BackendUtility::wrapInHelp('linkvalidator
', $column, $label);
470 // Add section header
471 $makerTableHead['list_header
'] = '<h3>
' . $this->getLanguageService()->getLL('list.header
', true) . '</h3>
';
472 return $makerTableHead;
483 protected function renderTableRow($table, array $row, $brokenLinksItemTemplate)
485 $markerArray = array();
487 // Restore the linktype object
488 $hookObj = $this->hookObjectsArr[$row['link_type
']];
490 // Construct link to edit the content element
491 $requestUri = GeneralUtility::getIndpEnv('REQUEST_URI
') .
492 '&
id=
' . $this->pObj->id .
493 '&search_levels=
' . $this->searchLevel;
494 $url = BackendUtility::getModuleUrl('record_edit
', [
497 $row['record_uid
'] => 'edit
'
500 'returnUrl
' => $requestUri
502 $actionLink = '<a href=
"' . htmlspecialchars($url);
503 $actionLink .= '" title=
"' . $this->getLanguageService()->getLL('list.edit') . '">
';
504 $actionLink .= $this->iconFactory->getIcon('actions-document-open
', Icon::SIZE_SMALL)->render();
505 $actionLink .= '</a>
';
506 $elementHeadline = $row['headline
'];
507 if (empty($elementHeadline)) {
508 $elementHeadline = '<i>
' . $this->getLanguageService()->getLL('list.no.headline
') . '</i>
';
510 // Get the language label for the field from TCA
511 if ($GLOBALS['TCA
'][$table]['columns
'][$row['field
']]['label
']) {
512 $fieldName = $this->getLanguageService()->sL($GLOBALS['TCA
'][$table]['columns
'][$row['field
']]['label
']);
513 // Crop colon from end if present
514 if (substr($fieldName, '-1
', '1
') === ':
') {
515 $fieldName = substr($fieldName, '0
', strlen($fieldName) - 1);
518 // Fallback, if there is no label
519 $fieldName = !empty($fieldName) ? $fieldName : $row['field
'];
521 $element = '<span title=
"' . htmlspecialchars($table . ':' . $row['record_uid']) . '">
' . $this->iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>
';
522 $element .= $elementHeadline;
523 $element .= ' ' . sprintf($this->getLanguageService()->getLL('list.field
'), $fieldName);
524 $markerArray['actionlink
'] = $actionLink;
525 $markerArray['path'] = BackendUtility::getRecordPath($row['record_pid
'], '', 0, 0);
526 $markerArray['element
'] = $element;
527 $markerArray['headlink
'] = $row['link_title
'];
528 $markerArray['linktarget
'] = $hookObj->getBrokenUrl($row);
529 $response = unserialize($row['url_response
']);
530 if ($response['valid
']) {
531 $linkMessage = '<span
class=
"valid">
' . $this->getLanguageService()->getLL('list.msg.ok
') . '</span>
';
533 $linkMessage = '<span
class=
"error">
' . $hookObj->getErrorMessage($response['errorParams
']) . '</span>
';
535 $markerArray['linkmessage
'] = $linkMessage;
537 $lastRunDate = date($GLOBALS['TYPO3_CONF_VARS
']['SYS
']['ddmmyy
'], $row['last_check
']);
538 $lastRunTime = date($GLOBALS['TYPO3_CONF_VARS
']['SYS
']['hhmm
'], $row['last_check
']);
539 $markerArray['lastcheck
'] = sprintf($this->getLanguageService()->getLL('list.msg.lastRun
'), $lastRunDate, $lastRunTime);
541 // Return the table html code as string
542 return $this->templateService->substituteMarkerArray($brokenLinksItemTemplate, $markerArray, '###|###
', true, true);
552 protected function getCheckOptions(array $brokenLinkOverView, $prefix = '')
554 $markerArray = array();
555 if (!empty($prefix)) {
556 $additionalAttr = ' class=
"' . $prefix . '"';
558 $additionalAttr = ' class=
"refresh"';
560 $checkOptionsTemplate = $this->templateService->getSubpart($this->doc->moduleTemplate, '###CHECKOPTIONS_SECTION###
');
561 $hookSectionTemplate = $this->templateService->getSubpart($checkOptionsTemplate, '###HOOK_SECTION###
');
562 $markerArray['statistics_header
'] = '<h3>
' . $this->getLanguageService()->getLL('report.statistics.header
', true) . '</h3>
';
563 $markerArray['total_count_label
'] = BackendUtility::wrapInHelp('linkvalidator
', 'checkboxes
', $this->getLanguageService()->getLL('overviews.nbtotal
'));
564 $markerArray['total_count
'] = $brokenLinkOverView['brokenlinkCount
'] ?: '0
';
566 $linktypes = GeneralUtility::trimExplode(',
', $this->modTS['linktypes
'], true);
567 $hookSectionContent = '';
568 if (is_array($linktypes)) {
570 !empty($GLOBALS['TYPO3_CONF_VARS
']['EXTCONF
']['linkvalidator
']['checkLinks
'])
571 && is_array($GLOBALS['TYPO3_CONF_VARS
']['EXTCONF
']['linkvalidator
']['checkLinks
'])
573 foreach ($GLOBALS['TYPO3_CONF_VARS
']['EXTCONF
']['linkvalidator
']['checkLinks
'] as $type => $value) {
574 if (in_array($type, $linktypes)) {
575 $hookSectionMarker = array(
576 'count
' => $brokenLinkOverView[$type] ?: '0
',
579 $translation = $this->getLanguageService()->getLL('hooks.
' . $type) ?: $type;
580 $hookSectionMarker['option
'] = '<input type=
"checkbox"' . $additionalAttr . ' id=
"' . $prefix . 'SET_' . $type . '" name=
"' . $prefix
581 . 'SET[' . $type . ']" value=
"1"' . ($this->pObj->MOD_SETTINGS[$type] ? ' checked=
"checked"' : '') . '/>
' . '<label
for=
"'
582 . $prefix . 'SET_' . $type . '">
' . htmlspecialchars($translation) . '</label>
';
584 $hookSectionContent .= $this->templateService->substituteMarkerArray(
585 $hookSectionTemplate,
586 $hookSectionMarker, '###|###
',
594 $checkOptionsTemplate = $this->templateService->substituteSubpart(
595 $checkOptionsTemplate,
596 '###HOOK_SECTION###
',
599 return $this->templateService->substituteMarkerArray($checkOptionsTemplate, $markerArray, '###|###
', true, true);
607 protected function getDocHeaderButtons()
610 'csh
' => BackendUtility::cshItem('_MOD_web_func
', ''),
611 'shortcut
' => $this->getShortcutButton(),
621 protected function getShortcutButton()
624 if ($this->getBackendUser()->mayMakeShortcut()) {
625 $result = $this->doc->makeShortcutIcon('', 'function', $this->pObj->MCONF['name
']);
635 protected function getTemplateMarkers()
638 'FUNC_TITLE
' => $this->getLanguageService()->getLL('report.func.title
'),
639 'CHECKOPTIONS_TITLE
' => $this->getLanguageService()->getLL('report.statistics.header
'),
640 'FUNC_MENU
' => $this->getLevelSelector(),
641 'CONTENT
' => $this->content,
642 'CHECKOPTIONS
' => $this->checkOptionsHtml,
643 'ID
' => '<input type=
"hidden" name=
"id" value=
"' . $this->pObj->id . '" />
',
644 'REFRESH
' => '<input type=
"submit" class=
"btn btn-default" name=
"refreshLinkList" id=
"refreshLinkList" value=
"' . $this->getLanguageService()->getLL('label_refresh') . '" />
',
654 protected function getTemplateMarkersCheck()
657 'FUNC_TITLE
' => $this->getLanguageService()->getLL('checklinks.func.title
'),
658 'CHECKOPTIONS_TITLE
' => $this->getLanguageService()->getLL('checklinks.statistics.header
'),
659 'FUNC_MENU
' => $this->getLevelSelector(),
661 'CHECKOPTIONS
' => $this->checkOptionsHtmlCheck,
662 'ID
' => '<input type=
"hidden" name=
"id" value=
"' . $this->pObj->id . '" />
',
664 'UPDATE
' => '<input type=
"submit" class=
"btn btn-default" name=
"updateLinkList" id=
"updateLinkList" value=
"' . $this->getLanguageService()->getLL('label_update') . '"/>
',
673 protected function isCurrentUserAdmin()
675 return $this->getBackendUser()->isAdmin();
683 protected function getLanguageService()
685 return $GLOBALS['LANG
'];
693 protected function getBackendUser()
695 return $GLOBALS['BE_USER
'];
701 protected function getDatabaseConnection()
703 return $GLOBALS['TYPO3_DB
'];