[FEATURE] Provide TSConfig to link checkers
[Packages/TYPO3.CMS.git] / typo3 / sysext / linkvalidator / Classes / Report / LinkValidatorReport.php
1 <?php
2 namespace TYPO3\CMS\Linkvalidator\Report;
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 TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Messaging\FlashMessage;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21 /**
22 * Module 'Linkvalidator' for the 'linkvalidator' extension
23 *
24 * @author Michael Miousse <michael.miousse@infoglobe.ca>
25 * @author Jochen Rieger <j.rieger@connecta.ag>
26 */
27 class LinkValidatorReport extends \TYPO3\CMS\Backend\Module\AbstractFunctionModule {
28
29 /**
30 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
31 */
32 public $doc;
33
34 /**
35 * @var string
36 */
37 protected $relativePath;
38
39 /**
40 * Information about the current page record
41 *
42 * @var array
43 */
44 protected $pageRecord = array();
45
46 /**
47 * Information, if the module is accessible for the current user or not
48 *
49 * @var bool
50 */
51 protected $isAccessibleForCurrentUser = FALSE;
52
53 /**
54 * Depth for the recursive traversal of pages for the link validation
55 *
56 * @var int
57 */
58 protected $searchLevel;
59
60 /**
61 * Link validation class
62 *
63 * @var \TYPO3\CMS\Linkvalidator\LinkAnalyzer
64 */
65 protected $processor;
66
67 /**
68 * TSconfig of the current module
69 *
70 * @var array
71 */
72 protected $modTS = array();
73
74 /**
75 * List of available link types to check defined in the TSconfig
76 *
77 * @var array
78 */
79 protected $availableOptions = array();
80
81 /**
82 * List of link types currently chosen in the statistics table
83 * Used to show broken links of these types only
84 *
85 * @var array
86 */
87 protected $checkOpt = array();
88
89 /**
90 * Html for the button "Check Links"
91 *
92 * @var string
93 */
94 protected $updateListHtml;
95
96 /**
97 * Html for the button "Refresh Display"
98 *
99 * @var string
100 */
101 protected $refreshListHtml;
102
103 /**
104 * Html for the statistics table with the checkboxes of the link types
105 * and the numbers of broken links for report tab
106 *
107 * @var string
108 */
109 protected $checkOptHtml;
110
111 /**
112 * Html for the statistics table with the checkboxes of the link types
113 * and the numbers of broken links for check links tab
114 *
115 * @var string
116 */
117 protected $checkOptHtmlCheck;
118
119 /**
120 * Complete content (html) to be displayed
121 *
122 * @var string
123 */
124 protected $content;
125
126 /**
127 * @var \TYPO3\CMS\Core\Page\PageRenderer
128 */
129 protected $pageRenderer;
130
131 /**
132 * @var \TYPO3\CMS\Linkvalidator\Linktype\LinktypeInterface[]
133 */
134 protected $hookObjectsArr = array();
135
136 /**
137 * @var string $checkAllHtml
138 */
139 protected $checkAllHtml = '';
140
141 /**
142 * Main method of modfuncreport
143 *
144 * @return string Module content
145 */
146 public function main() {
147 $GLOBALS['LANG']->includeLLFile('EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf');
148 $this->searchLevel = GeneralUtility::_GP('search_levels');
149 if (isset($this->pObj->id)) {
150 $this->modTS = BackendUtility::getModTSconfig($this->pObj->id, 'mod.linkvalidator');
151 $this->modTS = $this->modTS['properties'];
152 }
153 $update = GeneralUtility::_GP('updateLinkList');
154 $prefix = '';
155 if (!empty($update)) {
156 $prefix = 'check';
157 }
158 $set = GeneralUtility::_GP($prefix . 'SET');
159 $this->pObj->handleExternalFunctionValue();
160 if (isset($this->searchLevel)) {
161 $this->pObj->MOD_SETTINGS['searchlevel'] = $this->searchLevel;
162 } else {
163 $this->searchLevel = $this->pObj->MOD_SETTINGS['searchlevel'];
164 }
165 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
166 foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $linkType => $value) {
167 // Compile list of all available types. Used for checking with button "Check Links".
168 if (strpos($this->modTS['linktypes'], $linkType) !== FALSE) {
169 $this->availableOptions[$linkType] = 1;
170 }
171 // Compile list of types currently selected by the checkboxes
172 if ($this->pObj->MOD_SETTINGS[$linkType] && empty($set) || $set[$linkType]) {
173 $this->checkOpt[$linkType] = 1;
174 $this->pObj->MOD_SETTINGS[$linkType] = 1;
175 } else {
176 $this->pObj->MOD_SETTINGS[$linkType] = 0;
177 unset($this->checkOpt[$linkType]);
178 }
179 }
180 }
181 $GLOBALS['BE_USER']->pushModuleData('web_info', $this->pObj->MOD_SETTINGS);
182 $this->initialize();
183
184 // Localization
185 $this->pageRenderer->addInlineLanguageLabelFile(
186 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('linkvalidator', 'Resources/Private/Language/Module/locallang.xlf')
187 );
188 $this->pageRenderer->addJsInlineCode('linkvalidator', 'function toggleActionButton(prefix) {
189 var buttonDisable = true;
190 Ext.select(\'.\' + prefix ,false).each(function(checkBox,i){
191 checkDom = checkBox.dom;
192 if (checkDom.checked){
193 buttonDisable = false;
194 }
195
196 });
197 if (prefix == \'check\'){
198 checkSub = document.getElementById(\'updateLinkList\');
199 } else {
200 checkSub = document.getElementById(\'refreshLinkList\');
201 }
202 checkSub.disabled = buttonDisable;
203 }');
204 // Add JS
205 $this->pageRenderer->addJsFile($this->doc->backPath . 'js/extjs/ux/Ext.ux.FitToParent.js');
206 $this->pageRenderer->addJsFile($this->doc->backPath . 'sysext/backend/Resources/Public/JavaScript/flashmessages.js');
207 $this->pageRenderer->addJsFile($this->doc->backPath . 'sysext/backend/Resources/Public/JavaScript/iframepanel.js');
208 if ($this->modTS['showCheckLinkTab'] == 1) {
209 $this->updateListHtml = '<input type="submit" name="updateLinkList" id="updateLinkList" value="' . $GLOBALS['LANG']->getLL('label_update') . '"/>';
210 }
211 $this->refreshListHtml = '<input type="submit" name="refreshLinkList" id="refreshLinkList" value="' . $GLOBALS['LANG']->getLL('label_refresh') . '"/>';
212 $this->processor = GeneralUtility::makeInstance(\TYPO3\CMS\Linkvalidator\LinkAnalyzer::class);
213 $this->updateBrokenLinks();
214 $brokenLinkOverView = $this->processor->getLinkCounts($this->pObj->id);
215 $this->checkOptHtml = $this->getCheckOptions($brokenLinkOverView);
216 $this->checkOptHtmlCheck = $this->getCheckOptions($brokenLinkOverView, 'check');
217 $this->createTabs();
218 return '<div id="linkvalidator-modfuncreport"></div>';
219 }
220
221 /**
222 * Create TabPanel to split the report and the checkLink functions
223 *
224 * @return void
225 */
226 protected function createTabs() {
227 $panelCheck = '';
228 if ($this->modTS['showCheckLinkTab'] == 1) {
229 $panelCheck = ',
230 {
231 title: TYPO3.l10n.localize(\'CheckLink\'),
232 html: ' . json_encode($this->flush()) . ',
233 }';
234 }
235 $this->render();
236 $js = 'var panel = new Ext.TabPanel( {
237 renderTo: \'linkvalidator-modfuncreport\',
238 id: \'linkvalidator-main\',
239 plain: true,
240 activeTab: 0,
241 bodyStyle: \'padding:10px;\',
242 items : [
243 {
244 autoHeight: true,
245 title: TYPO3.l10n.localize(\'Report\'),
246 html: ' . json_encode($this->flush(TRUE)) . '
247 }' . $panelCheck . '
248 ]
249
250 });
251 ';
252 $this->pageRenderer->addExtOnReadyCode($js);
253 }
254
255 /**
256 * Initializes the menu array internally
257 *
258 * @return array Module menu
259 */
260 public function modMenu() {
261 $modMenu = array(
262 'checkAllLink' => 0
263 );
264 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
265 foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $linkType => $value) {
266 $modMenu[$linkType] = 1;
267 }
268 }
269 return $modMenu;
270 }
271
272 /**
273 * Initializes the Module
274 *
275 * @return void
276 */
277 protected function initialize() {
278 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
279 foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $linkType => $classRef) {
280 $this->hookObjectsArr[$linkType] = GeneralUtility::getUserObj($classRef);
281 }
282 }
283 $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
284 $this->doc->backPath = $GLOBALS['BACK_PATH'];
285 $this->doc->setModuleTemplate(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('linkvalidator') . 'Resources/Private/Templates/mod_template.html');
286 $this->relativePath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('linkvalidator');
287 $this->pageRecord = BackendUtility::readPageAccess($this->pObj->id, $GLOBALS['BE_USER']->getPagePermsClause(1));
288 $this->pageRenderer = $this->doc->getPageRenderer();
289 $this->isAccessibleForCurrentUser = FALSE;
290 if ($this->pObj->id && is_array($this->pageRecord) || !$this->pObj->id && $this->isCurrentUserAdmin()) {
291 $this->isAccessibleForCurrentUser = TRUE;
292 }
293 $this->loadHeaderData();
294 // Don't access in workspace
295 if ($GLOBALS['BE_USER']->workspace !== 0) {
296 $this->isAccessibleForCurrentUser = FALSE;
297 }
298 }
299
300 /**
301 * Updates the table of stored broken links
302 *
303 * @return void
304 */
305 protected function updateBrokenLinks() {
306 $searchFields = array();
307 // Get the searchFields from TypoScript
308 foreach ($this->modTS['searchFields.'] as $table => $fieldList) {
309 $fields = GeneralUtility::trimExplode(',', $fieldList);
310 foreach ($fields as $field) {
311 if (!$searchFields || !is_array($searchFields[$table]) || array_search($field, $searchFields[$table]) == FALSE) {
312 $searchFields[$table][] = $field;
313 }
314 }
315 }
316 $rootLineHidden = $this->processor->getRootLineIsHidden($this->pObj->pageinfo);
317 if (!$rootLineHidden || $this->modTS['checkhidden'] == 1) {
318 // Get children pages
319 $pageList = $this->processor->extGetTreeList($this->pObj->id, $this->searchLevel, 0, $GLOBALS['BE_USER']->getPagePermsClause(1), $this->modTS['checkhidden']);
320 if ($this->pObj->pageinfo['hidden'] == 0 || $this->modTS['checkhidden'] == 1) {
321 $pageList .= $this->pObj->id;
322 }
323 $this->processor->init($searchFields, $pageList, $this->modTS);
324 // Check if button press
325 $update = GeneralUtility::_GP('updateLinkList');
326 if (!empty($update)) {
327 $this->processor->getLinkStatistics($this->checkOpt, $this->modTS['checkhidden']);
328 }
329 }
330 }
331
332 /**
333 * Renders the content of the module
334 *
335 * @return void
336 */
337 protected function render() {
338 if ($this->isAccessibleForCurrentUser) {
339 $this->content = $this->renderBrokenLinksTable();
340 } else {
341 // If no access or if ID == zero
342 /** @var FlashMessage $message */
343 $message = GeneralUtility::makeInstance(
344 FlashMessage::class,
345 $GLOBALS['LANG']->getLL('no.access'),
346 $GLOBALS['LANG']->getLL('no.access.title'),
347 FlashMessage::ERROR
348 );
349 $this->content .= $message->render();
350 }
351 }
352
353 /**
354 * Flushes the rendered content to the browser
355 *
356 * @param bool $form
357 * @return string $content
358 */
359 protected function flush($form = FALSE) {
360 $content = $this->doc->moduleBody(
361 $this->pageRecord,
362 $this->getDocHeaderButtons(),
363 $form ? $this->getTemplateMarkers() : $this->getTemplateMarkersCheck()
364 );
365 return $content;
366 }
367
368 /**
369 * Builds the selector for the level of pages to search
370 *
371 * @return string Html code of that selector
372 */
373 protected function getLevelSelector() {
374 // Build level selector
375 $opt = array();
376 $parts = array(
377 0 => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_0'),
378 1 => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_1'),
379 2 => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_2'),
380 3 => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_3'),
381 999 => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_infi')
382 );
383 foreach ($parts as $kv => $label) {
384 $opt[] = '<option value="' . $kv . '"' . ($kv == (int)$this->searchLevel ? ' selected="selected"' : '') . '>' . htmlspecialchars($label) . '</option>';
385 }
386 $lMenu = '<select name="search_levels">' . implode('', $opt) . '</select>';
387 return $lMenu;
388 }
389
390 /**
391 * Displays the table of broken links or a note if there were no broken links
392 *
393 * @return string Content of the table or of the note
394 */
395 protected function renderBrokenLinksTable() {
396 $items = ($brokenLinksMarker = array());
397 $brokenLinkItems = '';
398 $brokenLinksTemplate = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($this->doc->moduleTemplate, '###NOBROKENLINKS_CONTENT###');
399 $keyOpt = array();
400 if (is_array($this->checkOpt)) {
401 $keyOpt = array_keys($this->checkOpt);
402 }
403 $rootLineHidden = $this->processor->getRootLineIsHidden($this->pObj->pageinfo);
404 if (!$rootLineHidden || $this->modTS['checkhidden'] == 1) {
405 $pageList = $this->processor->extGetTreeList(
406 $this->pObj->id,
407 $this->searchLevel,
408 0,
409 $GLOBALS['BE_USER']->getPagePermsClause(1),
410 $this->modTS['checkhidden']
411 );
412 // Always add the current page, because we are just displaying the results
413 $pageList .= $this->pObj->id;
414 if (($res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
415 '*',
416 'tx_linkvalidator_link',
417 'record_pid in (' . $pageList . ') and link_type in (\'' . implode('\',\'', $keyOpt) . '\')',
418 '',
419 'record_uid ASC, uid ASC')
420 )) {
421 // Display table with broken links
422 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res) > 0) {
423 $brokenLinksTemplate = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($this->doc->moduleTemplate, '###BROKENLINKS_CONTENT###');
424 $brokenLinksItemTemplate = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($this->doc->moduleTemplate, '###BROKENLINKS_ITEM###');
425 // Table header
426 $brokenLinksMarker = $this->startTable();
427 // Table rows containing the broken links
428 while (($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) !== FALSE) {
429 $items[] = $this->renderTableRow($row['table_name'], $row, $brokenLinksItemTemplate);
430 }
431 $brokenLinkItems = implode(chr(10), $items);
432 } else {
433 $brokenLinksMarker = $this->getNoBrokenLinkMessage($brokenLinksMarker);
434 }
435 $GLOBALS['TYPO3_DB']->sql_free_result($res);
436 }
437 } else {
438 $brokenLinksMarker = $this->getNoBrokenLinkMessage($brokenLinksMarker);
439 }
440 $brokenLinksTemplate = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray(
441 $brokenLinksTemplate,
442 $brokenLinksMarker, '###|###',
443 TRUE
444 );
445 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($brokenLinksTemplate, '###BROKENLINKS_ITEM', $brokenLinkItems);
446 return $content;
447 }
448
449 /**
450 * Replace $brokenLinksMarker['NO_BROKEN_LINKS] with localized flashmessage
451 *
452 * @param array $brokenLinksMarker
453 * @return array $brokenLinksMarker['NO_BROKEN_LINKS] replaced with flashmessage
454 */
455 protected function getNoBrokenLinkMessage(array $brokenLinksMarker) {
456 $brokenLinksMarker['LIST_HEADER'] = $this->doc->sectionHeader($GLOBALS['LANG']->getLL('list.header'));
457 /** @var $message FlashMessage */
458 $message = GeneralUtility::makeInstance(
459 FlashMessage::class,
460 $GLOBALS['LANG']->getLL('list.no.broken.links'),
461 $GLOBALS['LANG']->getLL('list.no.broken.links.title'),
462 FlashMessage::OK
463 );
464 $brokenLinksMarker['NO_BROKEN_LINKS'] = $message->render();
465 return $brokenLinksMarker;
466 }
467
468 /**
469 * Displays the table header of the table with the broken links
470 *
471 * @return string Code of content
472 */
473 protected function startTable() {
474 // Listing head
475 $makerTableHead = array();
476 $makerTableHead['tablehead_path'] = $GLOBALS['LANG']->getLL('list.tableHead.path');
477 $makerTableHead['tablehead_element'] = $GLOBALS['LANG']->getLL('list.tableHead.element');
478 $makerTableHead['tablehead_headlink'] = $GLOBALS['LANG']->getLL('list.tableHead.headlink');
479 $makerTableHead['tablehead_linktarget'] = $GLOBALS['LANG']->getLL('list.tableHead.linktarget');
480 $makerTableHead['tablehead_linkmessage'] = $GLOBALS['LANG']->getLL('list.tableHead.linkmessage');
481 $makerTableHead['tablehead_lastcheck'] = $GLOBALS['LANG']->getLL('list.tableHead.lastCheck');
482 // Add CSH to the header of each column
483 foreach ($makerTableHead as $column => $label) {
484 $label = BackendUtility::wrapInHelp('linkvalidator', $column, $label);
485 $makerTableHead[$column] = $label;
486 }
487 // Add section header
488 $makerTableHead['list_header'] = $this->doc->sectionHeader($GLOBALS['LANG']->getLL('list.header'));
489 return $makerTableHead;
490 }
491
492 /**
493 * Displays one line of the broken links table
494 *
495 * @param string $table Name of database table
496 * @param array $row Record row to be processed
497 * @param array $brokenLinksItemTemplate Markup of the template to be used
498 * @return string HTML of the rendered row
499 */
500 protected function renderTableRow($table, array $row, $brokenLinksItemTemplate) {
501 $markerArray = array();
502 $fieldName = '';
503 // Restore the linktype object
504 $hookObj = $this->hookObjectsArr[$row['link_type']];
505 $brokenUrl = $hookObj->getBrokenUrl($row);
506 // Construct link to edit the content element
507 $params = '&edit[' . $table . '][' . $row['record_uid'] . ']=edit';
508 $requestUri = GeneralUtility::getIndpEnv('REQUEST_URI') .
509 '?id=' . $this->pObj->id .
510 '&search_levels=' . $this->searchLevel;
511 $actionLink = '<a href="#" onclick="';
512 $actionLink .= BackendUtility::editOnClick(
513 $params,
514 $GLOBALS['BACK_PATH'],
515 $requestUri
516 );
517 $actionLink .= '" title="' . $GLOBALS['LANG']->getLL('list.edit') . '">';
518 $actionLink .= \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-open');
519 $actionLink .= '</a>';
520 $elementHeadline = $row['headline'];
521 if (empty($elementHeadline)) {
522 $elementHeadline = '<i>' . $GLOBALS['LANG']->getLL('list.no.headline') . '</i>';
523 }
524 // Get the language label for the field from TCA
525 if ($GLOBALS['TCA'][$table]['columns'][$row['field']]['label']) {
526 $fieldName = $GLOBALS['TCA'][$table]['columns'][$row['field']]['label'];
527 $fieldName = $GLOBALS['LANG']->sL($fieldName);
528 // Crop colon from end if present
529 if (substr($fieldName, '-1', '1') === ':') {
530 $fieldName = substr($fieldName, '0', strlen($fieldName) - 1);
531 }
532 }
533 // Fallback, if there is no label
534 $fieldName = !empty($fieldName) ? $fieldName : $row['field'];
535 // column "Element"
536 $element = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord(
537 $table,
538 $row,
539 array('title' => $table . ':' . $row['record_uid'])
540 );
541 $element .= $elementHeadline;
542 $element .= ' ' . sprintf($GLOBALS['LANG']->getLL('list.field'), $fieldName);
543 $markerArray['actionlink'] = $actionLink;
544 $markerArray['path'] = BackendUtility::getRecordPath($row['record_pid'], '', 0, 0);
545 $markerArray['element'] = $element;
546 $markerArray['headlink'] = $row['link_title'];
547 $markerArray['linktarget'] = $brokenUrl;
548 $response = unserialize($row['url_response']);
549 if ($response['valid']) {
550 $linkMessage = '<span style="color: green;">' . $GLOBALS['LANG']->getLL('list.msg.ok') . '</span>';
551 } else {
552 $linkMessage = '<span style="color: red;">' . $hookObj->getErrorMessage($response['errorParams']) . '</span>';
553 }
554 $markerArray['linkmessage'] = $linkMessage;
555 $lastRunDate = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $row['last_check']);
556 $lastRunTime = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'], $row['last_check']);
557 $message = sprintf($GLOBALS['LANG']->getLL('list.msg.lastRun'), $lastRunDate, $lastRunTime);
558 $markerArray['lastcheck'] = $message;
559 // Return the table html code as string
560 return \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($brokenLinksItemTemplate, $markerArray, '###|###', TRUE, TRUE);
561 }
562
563 /**
564 * Builds the checkboxes out of the hooks array
565 *
566 * @param array $brokenLinkOverView Array of broken links information
567 * @param string $prefix
568 * @return string code content
569 */
570 protected function getCheckOptions(array $brokenLinkOverView, $prefix = '') {
571 $markerArray = array();
572 $additionalAttr = '';
573 if (!empty($prefix)) {
574 $additionalAttr = ' onclick="toggleActionButton(\'' . $prefix . '\');" class="' . $prefix . '" ';
575 } else {
576 $additionalAttr = ' onclick="toggleActionButton(\'refresh\');" class="refresh" ';
577 }
578 $checkOptionsTemplate = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($this->doc->moduleTemplate, '###CHECKOPTIONS_SECTION###');
579 $hookSectionTemplate = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($checkOptionsTemplate, '###HOOK_SECTION###');
580 $markerArray['statistics_header'] = $this->doc->sectionHeader($GLOBALS['LANG']->getLL('report.statistics.header'));
581 $totalCountLabel = $GLOBALS['LANG']->getLL('overviews.nbtotal');
582 $totalCountLabel = BackendUtility::wrapInHelp('linkvalidator', 'checkboxes', $totalCountLabel);
583 $markerArray['total_count_label'] = $totalCountLabel;
584 if (empty($brokenLinkOverView['brokenlinkCount'])) {
585 $markerArray['total_count'] = '0';
586 } else {
587 $markerArray['total_count'] = $brokenLinkOverView['brokenlinkCount'];
588 }
589 $linktypes = GeneralUtility::trimExplode(',', $this->modTS['linktypes'], TRUE);
590 $hookSectionContent = '';
591 if (is_array($linktypes)) {
592 if (!empty($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])
593 && is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
594 foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $type => $value) {
595 if (in_array($type, $linktypes)) {
596 $hookSectionMarker = array();
597 if (empty($brokenLinkOverView[$type])) {
598 $hookSectionMarker['count'] = '0';
599 } else {
600 $hookSectionMarker['count'] = $brokenLinkOverView[$type];
601 }
602 $translation = $GLOBALS['LANG']->getLL('hooks.' . $type);
603 $translation = $translation ? $translation : $type;
604 $option = '<input type="checkbox" ' . $additionalAttr . ' id="' . $prefix . 'SET_' . $type . '" name="' . $prefix . 'SET[' . $type . ']" value="1"' . ($this->pObj->MOD_SETTINGS[$type] ? ' checked="checked"' : '') . '/>' . '<label for="' . $prefix . 'SET[' . $type . ']">' . htmlspecialchars($translation) . '</label>';
605 $hookSectionMarker['option'] = $option;
606 $hookSectionContent .= \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray(
607 $hookSectionTemplate,
608 $hookSectionMarker, '###|###',
609 TRUE,
610 TRUE
611 );
612 }
613 }
614 }
615 }
616 $checkOptionsTemplate = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart(
617 $checkOptionsTemplate,
618 '###HOOK_SECTION###', $hookSectionContent
619 );
620 return \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($checkOptionsTemplate, $markerArray, '###|###', TRUE, TRUE);
621 }
622
623 /**
624 * Loads data in the HTML head section (e.g. JavaScript or stylesheet information)
625 *
626 * @return void
627 */
628 protected function loadHeaderData() {
629 $this->doc->addStyleSheet('linkvalidator', $this->relativePath . 'Resources/Public/Css/linkvalidator.css', 'linkvalidator');
630 $this->pageRenderer->addJsFile($this->doc->backPath . 'js/extjs/ux/Ext.ux.FitToParent.js');
631 }
632
633 /**
634 * Gets the buttons that shall be rendered in the docHeader
635 *
636 * @return array Available buttons for the docHeader
637 */
638 protected function getDocHeaderButtons() {
639 $buttons = array(
640 'csh' => BackendUtility::cshItem('_MOD_web_func', ''),
641 'shortcut' => $this->getShortcutButton(),
642 'save' => ''
643 );
644 return $buttons;
645 }
646
647 /**
648 * Gets the button to set a new shortcut in the backend (if current user is allowed to).
649 *
650 * @return string HTML representation of the shortcut button
651 */
652 protected function getShortcutButton() {
653 $result = '';
654 if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
655 $result = $this->doc->makeShortcutIcon('', 'function', $this->MCONF['name']);
656 }
657 return $result;
658 }
659
660 /**
661 * Gets the filled markers that are used in the HTML template
662 *
663 * @return array The filled marker array
664 */
665 protected function getTemplateMarkers() {
666 $markers = array(
667 'FUNC_TITLE' => $GLOBALS['LANG']->getLL('report.func.title'),
668 'CHECKOPTIONS_TITLE' => $GLOBALS['LANG']->getLL('report.statistics.header'),
669 'FUNC_MENU' => $this->getLevelSelector(),
670 'CONTENT' => $this->content,
671 'CHECKALLLINK' => $this->checkAllHtml,
672 'CHECKOPTIONS' => $this->checkOptHtml,
673 'ID' => '<input type="hidden" name="id" value="' . $this->pObj->id . '" />',
674 'REFRESH' => $this->refreshListHtml,
675 'UPDATE' => ''
676 );
677 return $markers;
678 }
679
680 /**
681 * Gets the filled markers that are used in the HTML template
682 *
683 * @return array The filled marker array
684 */
685 protected function getTemplateMarkersCheck() {
686 $markers = array(
687 'FUNC_TITLE' => $GLOBALS['LANG']->getLL('checklinks.func.title'),
688 'CHECKOPTIONS_TITLE' => $GLOBALS['LANG']->getLL('checklinks.statistics.header'),
689 'FUNC_MENU' => $this->getLevelSelector(),
690 'CONTENT' => '',
691 'CHECKALLLINK' => $this->checkAllHtml,
692 'CHECKOPTIONS' => $this->checkOptHtmlCheck,
693 'ID' => '<input type="hidden" name="id" value="' . $this->pObj->id . '" />',
694 'REFRESH' => '',
695 'UPDATE' => $this->updateListHtml
696 );
697 return $markers;
698 }
699
700 /**
701 * Determines whether the current user is an admin
702 *
703 * @return bool Whether the current user is admin
704 */
705 protected function isCurrentUserAdmin() {
706 return (bool)$GLOBALS['BE_USER']->user['admin'];
707 }
708
709 }