81972cf529c808ca2061b650cc7e699d98cf7af0
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / ContentElement / ElementInformationController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller\ContentElement;
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\Backend\Utility\IconUtility;
19 use TYPO3\CMS\Core\Resource\Folder;
20 use TYPO3\CMS\Core\Resource\ProcessedFile;
21 use TYPO3\CMS\Core\Resource\ResourceFactory;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23
24 /**
25 * Script Class for showing information about an item.
26 *
27 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
28 */
29 class ElementInformationController {
30
31 /**
32 * Record table name
33 *
34 * @var string
35 */
36 public $table;
37
38 /**
39 * Record uid
40 *
41 * @var int
42 */
43 public $uid;
44
45 /**
46 * @var string
47 */
48 protected $permsClause;
49
50 /**
51 * @var bool
52 */
53 public $access = FALSE;
54
55 /**
56 * Which type of element:
57 * - "file"
58 * - "db"
59 *
60 * @var string
61 */
62 public $type = '';
63
64 /**
65 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
66 */
67 public $doc;
68
69 /**
70 * @var string
71 */
72 protected $content = '';
73
74 /**
75 * For type "db": Set to page record of the parent page of the item set
76 * (if type="db")
77 *
78 * @var array
79 */
80 public $pageInfo;
81
82 /**
83 * Database records identified by table/uid
84 *
85 * @var array
86 */
87 protected $row;
88
89 /**
90 * @var \TYPO3\CMS\Core\Resource\File
91 */
92 protected $fileObject;
93
94 /**
95 * @var Folder
96 */
97 protected $folderObject;
98
99 /**
100 * The HTML title tag
101 *
102 * @var string
103 */
104 protected $titleTag;
105
106 /**
107 * Constructor
108 */
109 public function __construct() {
110 $GLOBALS['BACK_PATH'] = '';
111 $GLOBALS['SOBE'] = $this;
112
113 $this->init();
114 }
115
116 /**
117 * Determines if table/uid point to database record or file and
118 * if user has access to view information
119 *
120 * @return void
121 */
122 public function init() {
123 $this->table = GeneralUtility::_GET('table');
124 $this->uid = GeneralUtility::_GET('uid');
125
126 $this->permsClause = $this->getBackendUser()->getPagePermsClause(1);
127 $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
128 $this->doc->divClass = 'container';
129
130 if (isset($GLOBALS['TCA'][$this->table])) {
131 $this->initDatabaseRecord();
132 } elseif ($this->table == '_FILE' || $this->table == '_FOLDER' || $this->table == 'sys_file') {
133 $this->initFileOrFolderRecord();
134 }
135 }
136
137 /**
138 * Init database records (table)
139 */
140 protected function initDatabaseRecord() {
141 $this->type = 'db';
142 $this->uid = (int)$this->uid;
143
144 // Check permissions and uid value:
145 if ($this->uid && $this->getBackendUser()->check('tables_select', $this->table)) {
146 if ((string)$this->table == 'pages') {
147 $this->pageInfo = BackendUtility::readPageAccess($this->uid, $this->permsClause);
148 $this->access = is_array($this->pageInfo) ? 1 : 0;
149 $this->row = $this->pageInfo;
150 } else {
151 $this->row = BackendUtility::getRecordWSOL($this->table, $this->uid);
152 if ($this->row) {
153 $this->pageInfo = BackendUtility::readPageAccess($this->row['pid'], $this->permsClause);
154 $this->access = is_array($this->pageInfo) ? 1 : 0;
155 }
156 }
157 /** @var $treatData \TYPO3\CMS\Backend\Form\DataPreprocessor */
158 $treatData = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Form\DataPreprocessor::class);
159 $treatData->renderRecord($this->table, $this->uid, 0, $this->row);
160 }
161 }
162
163 /**
164 * Init file/folder parameters
165 */
166 protected function initFileOrFolderRecord() {
167 $fileOrFolderObject = ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->uid);
168
169 if ($fileOrFolderObject instanceof Folder) {
170 $this->folderObject = $fileOrFolderObject;
171 $this->access = $this->folderObject->checkActionPermission('read');
172 $this->type = 'folder';
173 } else {
174 $this->fileObject = $fileOrFolderObject;
175 $this->access = $this->fileObject->checkActionPermission('read');
176 $this->type = 'file';
177 $this->table = 'sys_file';
178
179 try {
180 $this->row = BackendUtility::getRecordWSOL($this->table, $fileOrFolderObject->getUid());
181 } catch (\Exception $e) {
182 $this->row = array();
183 }
184 }
185 }
186
187 /**
188 * @return void
189 */
190 public function main() {
191 if (!$this->access) {
192 return;
193 }
194
195 // render type by user func
196 $typeRendered = FALSE;
197 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/show_item.php']['typeRendering'])) {
198 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/show_item.php']['typeRendering'] as $classRef) {
199 $typeRenderObj = GeneralUtility::getUserObj($classRef);
200 // @todo should have an interface
201 if (is_object($typeRenderObj) && method_exists($typeRenderObj, 'isValid') && method_exists($typeRenderObj, 'render')) {
202 if ($typeRenderObj->isValid($this->type, $this)) {
203 $this->content .= $typeRenderObj->render($this->type, $this);
204 $typeRendered = TRUE;
205 break;
206 }
207 }
208 }
209 }
210
211 if (!$typeRendered) {
212 $this->content .= $this->renderPageTitle();
213 $this->content .= $this->renderPreview();
214 $this->content .= $this->renderPropertiesAsTable();
215 $this->content .= $this->renderReferences();
216 $this->content .= $this->renderBackButton();
217 }
218 }
219
220 /**
221 * Render page title with icon, table title and record title
222 *
223 * @return string
224 */
225 protected function renderPageTitle() {
226 if ($this->type === 'folder') {
227 $table = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_common.xlf:folder');
228 $title = $this->doc->getResourceHeader($this->folderObject, array(' ', ''), FALSE);
229 } elseif ($this->type === 'file') {
230 $table = $this->getLanguageService()->sL($GLOBALS['TCA'][$this->table]['ctrl']['title']);
231 $title = $this->doc->getResourceHeader($this->fileObject, array(' ', ''), FALSE);
232 } else {
233 $table = $this->getLanguageService()->sL($GLOBALS['TCA'][$this->table]['ctrl']['title']);
234 $title = $this->doc->getHeader($this->table, $this->row, $this->pageInfo['_thePath'], 1, array(' ', ''), FALSE);
235 }
236 // Set HTML title tag
237 $this->titleTag = $table . ': ' . strip_tags(BackendUtility::getRecordTitle($this->table, $this->row));
238 return '<h1>' .
239 ($table ? '<small>' . $table . '</small><br />' : '') .
240 $title .
241 '</h1>';
242 }
243
244 /**
245 * Render preview for current record
246 *
247 * @return string
248 */
249 protected function renderPreview() {
250 // Perhaps @todo in future: Also display preview for records - without fileObject
251 if (!$this->fileObject) {
252 return '';
253 }
254
255 $previewTag = '';
256 $downloadLink = '';
257
258 // check if file is marked as missing
259 if ($this->fileObject->isMissing()) {
260 $flashMessage = \TYPO3\CMS\Core\Resource\Utility\BackendUtility::getFlashMessageForMissingFile($this->fileObject);
261 $previewTag .= $flashMessage->render();
262
263 } else {
264
265 /** @var \TYPO3\CMS\Core\Resource\Rendering\RendererRegistry $rendererRegistry */
266 $rendererRegistry = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Rendering\RendererRegistry::class);
267 $fileRenderer = $rendererRegistry->getRenderer($this->fileObject);
268 $fileExtension = $this->fileObject->getExtension();
269 $url = $this->fileObject->getPublicUrl(TRUE);
270
271 // Check if there is a FileRenderer
272 if ($fileRenderer !== NULL) {
273 $previewTag = $fileRenderer->render(
274 $this->fileObject,
275 '590m',
276 '400m',
277 array(),
278 TRUE
279 );
280
281 // else check if we can create an Image preview
282 } elseif (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileExtension)) {
283 $processedFile = $this->fileObject->process(
284 ProcessedFile::CONTEXT_IMAGEPREVIEW,
285 array(
286 'width' => '590m',
287 'height' => '400m'
288 )
289 );
290 // Create thumbnail image?
291 if ($processedFile) {
292 $thumbUrl = $processedFile->getPublicUrl(TRUE);
293 $previewTag .= '<img class="img-responsive img-thumbnail" src="' . $thumbUrl . '" ' .
294 'width="' . $processedFile->getProperty('width') . '" ' .
295 'height="' . $processedFile->getProperty('height') . '" ' .
296 'alt="' . htmlspecialchars(trim($this->fileObject->getName())) . '" ' .
297 'title="' . htmlspecialchars(trim($this->fileObject->getName())) . '" />';
298 }
299 }
300
301 // Download
302 if ($url) {
303 $downloadLink .= '
304 <a class="btn btn-primary" href="' . htmlspecialchars($url) . '" target="_blank">
305 ' . IconUtility::getSpriteIcon('actions-edit-download') . '
306 ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_common.xlf:download', TRUE) . '
307 </a>';
308 }
309 }
310
311 return ($previewTag ? '<p>' . $previewTag . '</p>' : '') .
312 ($downloadLink ? '<p>' . $downloadLink . '</p>' : '');
313 }
314
315 /**
316 * Render property array as html table
317 *
318 * @return string
319 */
320 protected function renderPropertiesAsTable() {
321 $tableRows = array();
322 $extraFields = array();
323
324 $lang = $this->getLanguageService();
325 if (in_array($this->type, array('folder', 'file'), TRUE)) {
326 if ($this->type === 'file') {
327 $extraFields['creation_date'] = $lang->sL('LLL:EXT:lang/locallang_general.xlf:LGL.creationDate', TRUE);
328 $extraFields['modification_date'] = $lang->sL('LLL:EXT:lang/locallang_general.xlf:LGL.timestamp', TRUE);
329 }
330 $extraFields['storage'] = $lang->sL('LLL:EXT:lang/locallang_tca.xlf:sys_file.storage', TRUE);
331 $extraFields['folder'] = $lang->sL('LLL:EXT:lang/locallang_common.xlf:folder', TRUE);
332 } else {
333 $extraFields['crdate'] = $lang->sL('LLL:EXT:lang/locallang_general.xlf:LGL.creationDate', TRUE);
334 $extraFields['cruser_id'] = $lang->sL('LLL:EXT:lang/locallang_general.xlf:LGL.creationUserId', TRUE);
335 $extraFields['tstamp'] = $lang->sL('LLL:EXT:lang/locallang_general.xlf:LGL.timestamp', TRUE);
336
337 // check if the special fields are defined in the TCA ctrl section of the table
338 foreach ($extraFields as $fieldName => $fieldLabel) {
339 if (isset($GLOBALS['TCA'][$this->table]['ctrl'][$fieldName])) {
340 $extraFields[$GLOBALS['TCA'][$this->table]['ctrl'][$fieldName]] = $fieldLabel;
341 } else {
342 unset($extraFields[$fieldName]);
343 }
344 }
345 }
346
347 foreach ($extraFields as $name => $fieldLabel) {
348 $rowValue = '';
349 if (!isset($this->row[$name])) {
350 $resourceObject = $this->fileObject ?: $this->folderObject;
351 if ($name === 'storage') {
352 $rowValue = $resourceObject->getStorage()->getName();
353 } elseif ($name === 'folder') {
354 $rowValue = $resourceObject->getParentFolder()->getReadablePath();
355 }
356 } elseif (in_array($name, array('creation_date', 'modification_date'), TRUE)) {
357 $rowValue = BackendUtility::datetime($this->row[$name]);
358 } else {
359 $rowValue = BackendUtility::getProcessedValueExtra($this->table, $name, $this->row[$name]);
360 }
361 // show the backend username who created the issue
362 if ($name === 'cruser_id' && $rowValue) {
363 $userTemp = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('username, realName', 'be_users', 'uid = ' . (int)$rowValue);
364 if ($userTemp['username'] !== '') {
365 $rowValue = $userTemp['username'];
366 if ($userTemp['realName'] !== '') {
367 $rowValue .= ' - ' . $userTemp['realName'];
368 }
369 }
370 }
371 $tableRows[] = '
372 <tr>
373 <th>' . rtrim($fieldLabel, ':') . '</th>
374 <td>' . htmlspecialchars($rowValue) . '</td>
375 </tr>';
376 }
377
378 // Traverse the list of fields to display for the record:
379 $fieldList = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$this->table]['interface']['showRecordFieldList'], TRUE);
380 foreach ($fieldList as $name) {
381 $name = trim($name);
382 $uid = $this->row['uid'];
383
384 if (!isset($GLOBALS['TCA'][$this->table]['columns'][$name])) {
385 continue;
386 }
387
388 // Storage is already handled above
389 if ($this->type === 'file' && $name === 'storage') {
390 continue;
391 }
392
393 $isExcluded = !(!$GLOBALS['TCA'][$this->table]['columns'][$name]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', $this->table . ':' . $name));
394 if ($isExcluded) {
395 continue;
396 }
397
398 $itemValue = BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, 0, FALSE, $uid);
399 $itemLabel = $lang->sL(BackendUtility::getItemLabel($this->table, $name), TRUE);
400 $tableRows[] = '
401 <tr>
402 <th>' . $itemLabel . '</th>
403 <td>' . htmlspecialchars($itemValue) . '</td>
404 </tr>';
405 }
406
407 return '
408 <div class="table-fit table-fit-wrap">
409 <table class="table table-striped table-hover">
410 ' . implode('', $tableRows) . '
411 </table>
412 </div>';
413 }
414
415 /**
416 * Render references section (references from and references to current record)
417 *
418 * @return string
419 */
420 protected function renderReferences() {
421 $content = '';
422
423 switch ($this->type) {
424 case 'db': {
425 $references = $this->makeRef($this->table, $this->row['uid']);
426 if (!empty($references)) {
427 $content .= $this->doc->section($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.referencesToThisItem'), $references);
428 }
429
430 $referencesFrom = $this->makeRefFrom($this->table, $this->row['uid']);
431 if (!empty($referencesFrom)) {
432 $content .= $this->doc->section($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.referencesFromThisItem'), $referencesFrom);
433 }
434 break;
435 }
436
437 case 'file': {
438 if ($this->fileObject && $this->fileObject->isIndexed()) {
439 $references = $this->makeRef('_FILE', $this->fileObject);
440
441 if (!empty($references)) {
442 $header = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.referencesToThisItem');
443 $content .= $this->doc->section($header, $references);
444 }
445 }
446 break;
447 }
448 }
449
450 return $content;
451 }
452
453 /**
454 * Render a back button, if a returnUrl was provided
455 *
456 * @return string
457 */
458 protected function renderBackButton() {
459 $backLink = '';
460 $returnUrl = GeneralUtility::_GET('returnUrl');
461 if ($returnUrl) {
462 $backLink .= '
463 <a class="btn btn-primary" href="' . htmlspecialchars($returnUrl) . '>
464 ' . IconUtility::getSpriteIcon('actions-view-go-back') . '
465 ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_common.xlf:back', TRUE) . '
466 </a>';
467 }
468 return $backLink;
469 }
470
471 /**
472 * Renders file properties as html table
473 *
474 * @param array $fieldList
475 * @return string
476 */
477 protected function renderFileInformationAsTable($fieldList) {
478 $tableRows = array();
479 foreach ($fieldList as $name) {
480 if (!isset($GLOBALS['TCA'][$this->table]['columns'][$name])) {
481 continue;
482 }
483 $isExcluded = !(!$GLOBALS['TCA'][$this->table]['columns'][$name]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', $this->table . ':' . $name));
484 if ($isExcluded) {
485 continue;
486 }
487 $uid = $this->row['uid'];
488 $itemValue = BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, 0, FALSE, $uid);
489 $itemLabel = $this->getLanguageService()->sL(BackendUtility::getItemLabel($this->table, $name), TRUE);
490 $tableRows[] = '
491 <tr>
492 <th>' . $itemLabel . '</th>
493 <td>' . htmlspecialchars($itemValue) . '</td>
494 </tr>';
495 }
496
497 if (!$tableRows) {
498 return '';
499 }
500
501 return '
502 <div class="table-fit table-fit-wrap">
503 <table class="table table-striped table-hover">
504 ' . implode('', $tableRows) . '
505 </table>
506 </div>';
507 }
508
509 /**
510 * End page and print content
511 *
512 * @return void
513 */
514 public function printContent() {
515 echo $this->doc->startPage($this->titleTag) .
516 $this->doc->insertStylesAndJS($this->content) .
517 $this->doc->endPage();
518 }
519
520 /**
521 * Get field name for specified table/column name
522 *
523 * @param string $tableName Table name
524 * @param string $fieldName Column name
525 * @return string label
526 */
527 public function getLabelForTableColumn($tableName, $fieldName) {
528 if ($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label'] !== NULL) {
529 $field = $this->getLanguageService()->sL($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label']);
530 if (trim($field) === '') {
531 $field = $fieldName;
532 }
533 } else {
534 $field = $fieldName;
535 }
536 return $field;
537 }
538
539 /**
540 * Returns the rendered record actions
541 *
542 * @param string $table
543 * @param int $uid
544 * @return string
545 */
546 protected function getRecordActions($table, $uid) {
547 if ($table === '' || $uid < 0) {
548 return '';
549 }
550
551 // Edit button
552 $editOnClick = BackendUtility::editOnClick('&edit[' . $table . '][' . $uid . ']=edit');
553 $pageActionIcons = '
554 <a class="btn btn-default btn-sm" href="#" onclick="' . htmlspecialchars($editOnClick) . '">
555 ' . IconUtility::getSpriteIcon('actions-document-open') . '
556 </a>';
557
558 // History button
559 $historyOnClick = 'window.location.href=' .
560 GeneralUtility::quoteJSvalue(
561 BackendUtility::getModuleUrl(
562 'record_history',
563 array(
564 'element' => $table . ':' . $uid,
565 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
566 )
567 )
568 ) . '; return false;';
569 $pageActionIcons .= '
570 <a class="btn btn-default btn-sm" href="#" onclick="' . htmlspecialchars($historyOnClick) . '">
571 ' . IconUtility::getSpriteIcon('actions-document-history-open') . '
572 </a>';
573
574 if ($table === 'pages') {
575 // Recordlist button
576 $url = BackendUtility::getModuleUrl('web_list', array('id' => $uid, 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')));
577 $pageActionIcons .= '
578 <a class="btn btn-default btn-sm" href="' . htmlspecialchars($url) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.showList') . '">
579 ' . IconUtility::getSpriteIcon('actions-system-list-open') . '
580 </a>';
581
582 // View page button
583 $viewOnClick = BackendUtility::viewOnClick($uid, '', BackendUtility::BEgetRootLine($uid));
584 $pageActionIcons .= '
585 <a class="btn btn-default btn-sm" href="#" onclick="' . htmlspecialchars($viewOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', TRUE) . '">
586 ' . IconUtility::getSpriteIcon('actions-document-view') . '
587 </a>';
588 }
589
590 return '
591 <div class="btn-group" role="group">
592 ' . $pageActionIcons . '
593 </div>';
594 }
595
596 /**
597 * Make reference display
598 *
599 * @param string $table Table name
600 * @param string|\TYPO3\CMS\Core\Resource\File $ref Filename or uid
601 * @return string HTML
602 */
603 protected function makeRef($table, $ref) {
604 $lang = $this->getLanguageService();
605 // Files reside in sys_file table
606 if ($table === '_FILE') {
607 $selectTable = 'sys_file';
608 $selectUid = $ref->getUid();
609 } else {
610 $selectTable = $table;
611 $selectUid = $ref;
612 }
613 $rows = $this->getDatabaseConnection()->exec_SELECTgetRows(
614 '*',
615 'sys_refindex',
616 'ref_table=' . $this->getDatabaseConnection()->fullQuoteStr($selectTable, 'sys_refindex') . ' AND ref_uid=' . (int)$selectUid . ' AND deleted=0'
617 );
618
619 // Compile information for title tag:
620 $infoData = array();
621 $infoDataHeader = '';
622 if (count($rows)) {
623 $infoDataHeader = '
624 <tr>
625 <th class="col-icon"></th>
626 <th class="col-title">' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.title') . '</th>
627 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.table') . '</th>
628 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.uid') . '</th>
629 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.field') . '</th>
630 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.flexpointer') . '</th>
631 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.softrefKey') . '</th>
632 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.sorting') . '</th>
633 <th class="col-control"></th>
634 </tr>';
635 }
636 foreach ($rows as $row) {
637 if ($row['tablename'] === 'sys_file_reference') {
638 $row = $this->transformFileReferenceToRecordReference($row);
639 if ($row['tablename'] === NULL || $row['recuid'] === NULL) {
640 return '';
641 }
642 }
643 $record = BackendUtility::getRecord($row['tablename'], $row['recuid']);
644 if ($record) {
645 $parentRecord = BackendUtility::getRecord('pages', $record['pid']);
646 $parentRecordTitle = is_array($parentRecord)
647 ? BackendUtility::getRecordTitle('pages', $parentRecord)
648 : '';
649 $icon = IconUtility::getSpriteIconForRecord($row['tablename'], $record);
650 $actions = $this->getRecordActions($row['tablename'], $row['recuid']);
651 $editOnClick = BackendUtility::editOnClick('&edit[' . $row['tablename'] . '][' . $row['recuid'] . ']=edit');
652 $infoData[] = '
653 <tr>
654 <td class="col-icon">
655 <a href="#" onclick="' . htmlspecialchars($editOnClick) . '" title="id=' . $record['uid'] . '">
656 ' . $icon . '
657 </a>
658 </td>
659 <td class="col-title">
660 <a href="#" onclick="' . htmlspecialchars($editOnClick) . '" title="id=' . $record['uid'] . '" >
661 ' . BackendUtility::getRecordTitle($row['tablename'], $record, TRUE) . '
662 </a>
663 </td>
664 <td>' . $lang->sL($GLOBALS['TCA'][$row['tablename']]['ctrl']['title'], TRUE) . '</td>
665 <td>
666 <span title="' . $lang->sL('LLL:EXT:lang/locallang_common.xlf:page') . ': '
667 . htmlspecialchars($parentRecordTitle) . ' (uid=' . $record['pid'] . ')">
668 ' . $record['uid'] . '
669 </span>
670 </td>
671 <td>' . htmlspecialchars($this->getLabelForTableColumn($row['tablename'], $row['field'])) . '</td>
672 <td>' . htmlspecialchars($row['flexpointer']) . '</td>
673 <td>' . htmlspecialchars($row['softref_key']) . '</td>
674 <td>' . htmlspecialchars($row['sorting']) . '</td>
675 <td class="col-control">' . $actions . '</td>
676 </tr>';
677 } else {
678 $infoData[] = '
679 <tr>
680 <td class="col-icon"></td>
681 <td class="col-title">' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.missing_record') . ' (uid=' . $row['recuid'] . ')</td>
682 <td>' . htmlspecialchars($lang->sL($GLOBALS['TCA'][$row['tablename']]['ctrl']['title']) ?: $row['tablename']) . '</td>
683 <td></td>
684 <td>' . htmlspecialchars($this->getLabelForTableColumn($row['tablename'], $row['field'])) . '</td>
685 <td>' . htmlspecialchars($row['flexpointer']) . '</td>
686 <td>' . htmlspecialchars($row['softref_key']) . '</td>
687 <td>' . htmlspecialchars($row['sorting']) . '</td>
688 <td class="col-control"></td>
689 </tr>';
690 }
691 }
692 $referenceLine = '';
693 if (count($infoData)) {
694 $referenceLine = '
695 <div class="table-fit">
696 <table class="table table-striped table-hover">
697 <thead>' . $infoDataHeader . '</thead>
698 <tbody>' . implode('', $infoData) . '</tbody>
699 </table>
700 </div>';
701 }
702 return $referenceLine;
703 }
704
705 /**
706 * Make reference display (what this elements points to)
707 *
708 * @param string $table Table name
709 * @param string $ref Filename or uid
710 * @return string HTML
711 */
712 protected function makeRefFrom($table, $ref) {
713 $lang = $this->getLanguageService();
714 $rows = $this->getDatabaseConnection()->exec_SELECTgetRows(
715 '*',
716 'sys_refindex',
717 'tablename=' . $this->getDatabaseConnection()->fullQuoteStr($table, 'sys_refindex') . ' AND recuid=' . (int)$ref
718 );
719
720 // Compile information for title tag:
721 $infoData = array();
722 $infoDataHeader = '';
723 if (count($rows)) {
724 $infoDataHeader = '
725 <tr>
726 <th class="col-icon"></th>
727 <th class="col-title">' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.title') . '</th>
728 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.table') . '</th>
729 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.uid') . '</th>
730 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.field') . '</th>
731 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.flexpointer') . '</th>
732 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.softrefKey') . '</th>
733 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.sorting') . '</th>
734 <th>' . $lang->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.refString') . '</th>
735 <th class="col-control"></th>
736 </tr>';
737 }
738 foreach ($rows as $row) {
739 $record = BackendUtility::getRecord($row['ref_table'], $row['ref_uid']);
740 $icon = IconUtility::getSpriteIconForRecord($row['tablename'], $record);
741 $actions = $this->getRecordActions($row['ref_table'], $row['ref_uid']);
742 $editOnClick = BackendUtility::editOnClick('&edit[' . $row['ref_table'] . '][' . $row['ref_uid'] . ']=edit');
743 $infoData[] = '
744 <tr>
745 <td class="col-icon">
746 <a href="#" onclick="' . htmlspecialchars($editOnClick) . '" title="id=' . $record['uid'] . '">
747 ' . $icon . '
748 </a>
749 </td>
750 <td class="col-title">
751 <a href="#" onclick="' . htmlspecialchars($editOnClick) . '" title="id=' . $record['uid'] . '" >
752 ' . BackendUtility::getRecordTitle($row['ref_table'], $record, TRUE) . '
753 </a>
754 </td>
755 <td>' . $lang->sL($GLOBALS['TCA'][$row['ref_table']]['ctrl']['title'], TRUE) . '</td>
756 <td>' . htmlspecialchars($row['ref_uid']) . '</td>
757 <td>' . htmlspecialchars($this->getLabelForTableColumn($table, $row['field'])) . '</td>
758 <td>' . htmlspecialchars($row['flexpointer']) . '</td>
759 <td>' . htmlspecialchars($row['softref_key']) . '</td>
760 <td>' . htmlspecialchars($row['sorting']) . '</td>
761 <td>' . htmlspecialchars($row['ref_string']) . '</td>
762 <td class="col-control">' . $actions . '</td>
763 </tr>';
764 }
765
766 if (empty($infoData)) {
767 return '';
768 }
769
770 return '
771 <div class="table-fit">
772 <table class="table table-striped table-hover">
773 <thead>' . $infoDataHeader . '</thead>
774 <tbody>' . implode('', $infoData) . '</tbody>
775 </table>
776 </div>';
777 }
778
779 /**
780 * Convert FAL file reference (sys_file_reference) to reference index (sys_refindex) table format
781 *
782 * @param array $referenceRecord
783 * @return array
784 */
785 protected function transformFileReferenceToRecordReference(array $referenceRecord) {
786 $fileReference = $this->getDatabaseConnection()->exec_SELECTgetSingleRow(
787 '*',
788 'sys_file_reference',
789 'uid=' . (int)$referenceRecord['recuid']
790 );
791 return array(
792 'recuid' => $fileReference['uid_foreign'],
793 'tablename' => $fileReference['tablenames'],
794 'field' => $fileReference['fieldname'],
795 'flexpointer' => '',
796 'softref_key' => '',
797 'sorting' => $fileReference['sorting_foreign']
798 );
799 }
800
801 /**
802 * Returns LanguageService
803 *
804 * @return \TYPO3\CMS\Lang\LanguageService
805 */
806 protected function getLanguageService() {
807 return $GLOBALS['LANG'];
808 }
809
810 /**
811 * Returns the current BE user.
812 *
813 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
814 */
815 protected function getBackendUser() {
816 return $GLOBALS['BE_USER'];
817 }
818
819 /**
820 * Returns the database connection
821 *
822 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
823 */
824 protected function getDatabaseConnection() {
825 return $GLOBALS['TYPO3_DB'];
826 }
827
828 }