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