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