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