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