1a4bdfc6c755ade3ce5cac754c5201d7dcd78d66
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / ContentElement / ElementInformationController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller\ContentElement;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 1999-2013 Kasper Skårhøj (kasperYYYY@typo3.com)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 use TYPO3\CMS\Backend\Utility\BackendUtility;
31 use TYPO3\CMS\Backend\Utility\IconUtility;
32 use TYPO3\CMS\Core\Resource\ProcessedFile;
33 use TYPO3\CMS\Core\Utility\GeneralUtility;
34
35 /**
36 * Script Class for showing information about an item.
37 *
38 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
39 */
40 class ElementInformationController {
41
42 /**
43 * Record table name
44 *
45 * @var string
46 */
47 public $table;
48
49 /**
50 * Record uid
51 *
52 * @var int
53 */
54 public $uid;
55
56 /**
57 * @var string
58 */
59 protected $permsClause;
60
61 /**
62 * @var boolean
63 */
64 public $access = FALSE;
65
66 /**
67 * Which type of element:
68 * - "file"
69 * - "db"
70 *
71 * @var string
72 */
73 public $type = '';
74
75 /**
76 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
77 */
78 public $doc;
79
80 /**
81 * @var string
82 */
83 protected $content = '';
84
85 /**
86 * For type "db": Set to page record of the parent page of the item set
87 * (if type="db")
88 *
89 * @var array
90 * @todo Define visibility
91 */
92 public $pageinfo;
93
94 /**
95 * Database records identified by table/uid
96 *
97 * @var array
98 */
99 protected $row;
100
101 /**
102 * @var \TYPO3\CMS\Core\Resource\File
103 */
104 protected $fileObject;
105
106 /**
107 * @var \TYPO3\CMS\Core\Resource\Folder
108 */
109 protected $folderObject;
110
111 /**
112 * Constructor
113 */
114 public function __construct() {
115 $GLOBALS['BACK_PATH'] = '';
116 $GLOBALS['SOBE'] = $this;
117
118 $this->init();
119 }
120
121 /**
122 * Determines if table/uid point to database record or file and
123 * if user has access to view information
124 *
125 * @return void
126 */
127 public function init() {
128 $this->table = GeneralUtility::_GET('table');
129 $this->uid = GeneralUtility::_GET('uid');
130
131 $this->perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
132 $this->doc = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
133
134 if (isset($GLOBALS['TCA'][$this->table])) {
135 $this->initDatabaseRecord();
136 } elseif ($this->table == '_FILE' || $this->table == '_FOLDER' || $this->table == 'sys_file') {
137 $this->initFileOrFolderRecord();
138 }
139 }
140
141 /**
142 * Init database records (table)
143 */
144 protected function initDatabaseRecord() {
145 $this->type = 'db';
146 $this->uid = intval($this->uid);
147
148 // Check permissions and uid value:
149 if ($this->uid && $GLOBALS['BE_USER']->check('tables_select', $this->table)) {
150 if ((string) $this->table == 'pages') {
151 $this->pageinfo = BackendUtility::readPageAccess($this->uid, $this->perms_clause);
152 $this->access = is_array($this->pageinfo) ? 1 : 0;
153 $this->row = $this->pageinfo;
154 } else {
155 $this->row = BackendUtility::getRecordWSOL($this->table, $this->uid);
156 if ($this->row) {
157 $this->pageinfo = BackendUtility::readPageAccess($this->row['pid'], $this->perms_clause);
158 $this->access = is_array($this->pageinfo) ? 1 : 0;
159 }
160 }
161 /** @var $treatData \TYPO3\CMS\Backend\Form\DataPreprocessor */
162 $treatData = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\DataPreprocessor');
163 $treatData->renderRecord($this->table, $this->uid, 0, $this->row);
164 }
165 }
166
167 /**
168 * Init file/folder parameters
169 */
170 protected function initFileOrFolderRecord() {
171 $fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->
172 retrieveFileOrFolderObject($this->uid);
173
174 if ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\Folder) {
175 $this->folderObject = $fileOrFolderObject;
176 $this->access = $this->folderObject->checkActionPermission('read');
177 $this->type = 'folder';
178 } else {
179 $this->fileObject = $fileOrFolderObject;
180 $this->access = $this->fileObject->checkActionPermission('read');
181 $this->type = 'file';
182 $this->table = 'sys_file';
183
184 try {
185 $this->row = BackendUtility::getRecordWSOL($this->table, $this->fileObject->getUid());
186 } catch (\Exception $e) {
187 $this->row = array();
188 }
189 }
190 }
191
192 /**
193 * @return void
194 */
195 public function main() {
196 if (!$this->access) {
197 return;
198 }
199
200 // render type by user func
201 $typeRendered = FALSE;
202 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/show_item.php']['typeRendering'])) {
203 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/show_item.php']['typeRendering'] as $classRef) {
204 $typeRenderObj = GeneralUtility::getUserObj($classRef);
205 // @TODO should have an interface
206 if (is_object($typeRenderObj) && method_exists($typeRenderObj, 'isValid') && method_exists($typeRenderObj, 'render')) {
207 if ($typeRenderObj->isValid($this->type, $this)) {
208 $this->content .= $typeRenderObj->render($this->type, $this);
209 $typeRendered = TRUE;
210 break;
211 }
212 }
213 }
214 }
215
216 if (!$typeRendered) {
217 $this->content .= $this->renderPageTitle();
218 $this->content .= $this->renderPreview();
219 $this->content .= $this->renderPropertiesAsTable();
220 $this->content .= $this->renderReferences();
221 }
222 }
223
224 /**
225 * Render page title with icon, table title and record title
226 *
227 * @return string
228 */
229 protected function renderPageTitle() {
230 if ($this->type === 'folder') {
231 $title = IconUtility::getSpriteIcon('apps-filetree-folder-default') . ' ' .
232 $this->folderObject->getName();
233 } else {
234 $table = $GLOBALS['LANG']->sL($GLOBALS['TCA'][$this->table]['ctrl']['title']);
235 $title = $this->doc->getHeader($this->table, $this->row, $this->pageinfo['_thePath'], 1, array(' ', ''));
236 }
237
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 $fileExtension = $this->fileObject->getExtension();
256 if (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileExtension)) {
257 $thumbUrl = $this->fileObject->process(
258 ProcessedFile::CONTEXT_IMAGEPREVIEW,
259 array(
260 'width' => '400m',
261 'height' => '400m'
262 )
263 )->getPublicUrl(TRUE);
264 }
265
266 // Create thumbnail image?
267 if ($thumbUrl) {
268 $imageTag = '<img src="' . $thumbUrl . '" ' .
269 'alt="' . htmlspecialchars(trim($this->fileObject->getName())) . '" ' .
270 'title="' . htmlspecialchars(trim($this->fileObject->getName())) . '" />';
271 }
272
273 // Display download link?
274 if ($this->fileObject->getPublicUrl()) {
275 $downloadLink = '<a href="../' . $this->fileObject->getPublicUrl() . '" target="_blank">' .
276 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:download', 1) .
277 '</a>';
278 }
279
280 return ($imageTag ? '<p>' . $imageTag . '</p>' : '') .
281 ($downloadLink ? '<p>' . $downloadLink . '</p>' : '');
282 }
283
284 /**
285 * Render property array as html table
286 *
287 * @return string
288 */
289 protected function renderPropertiesAsTable() {
290 $tableRows = array();
291
292 if ($this->type !== 'folder') {
293 $extraFields = array(
294 'crdate' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xlf:LGL.creationDate', 1),
295 'cruser_id' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xlf:LGL.creationUserId', 1),
296 'tstamp' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xlf:LGL.timestamp', 1)
297 );
298 }
299
300 foreach ($extraFields as $name => $value) {
301 $rowValue = BackendUtility::getProcessedValueExtra($this->table, $name, $this->row[$name]);
302 if ($name === 'cruser_id' && $rowValue) {
303 $userTemp = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('username, realName', 'be_users', 'uid = ' . intval($rowValue));
304 if ($userTemp[0]['username'] !== '') {
305 $rowValue = $userTemp[0]['username'];
306 if ($userTemp[0]['realName'] !== '') {
307 $rowValue .= ' - ' . $userTemp[0]['realName'];
308 }
309 }
310 }
311 $tableRows[] = '
312 <tr>
313 <td class="t3-col-header">' . rtrim($value, ':') . '</td>
314 <td>' . htmlspecialchars($rowValue) . '</td>
315 </tr>';
316 }
317
318 // Traverse the list of fields to display for the record:
319 $fieldList = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$this->table]['interface']['showRecordFieldList'], TRUE);
320 foreach ($fieldList as $name) {
321 $name = trim($name);
322 $uid = $this->row['uid'];
323
324 if (!isset($GLOBALS['TCA'][$this->table]['columns'][$name])) {
325 continue;
326 }
327
328 $isExcluded = !(!$GLOBALS['TCA'][$this->table]['columns'][$name]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $this->table . ':' . $name));
329 if ($isExcluded) {
330 continue;
331 }
332
333 $itemValue = BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, 0, FALSE, $uid);
334 $itemLabel = $GLOBALS['LANG']->sL(BackendUtility::getItemLabel($this->table, $name), 1);
335 $tableRows[] = '
336 <tr>
337 <td class="t3-col-header">' . $itemLabel . '</td>
338 <td>' . htmlspecialchars($itemValue) . '</td>
339 </tr>';
340 }
341
342 return '<table id="typo3-showitem" class="t3-table-info">' .
343 implode('', $tableRows) .
344 '</table>';
345 }
346
347 /*
348 * Render references section (references from and references to current record)
349 *
350 * @return string
351 */
352 protected function renderReferences() {
353 $content = '';
354
355 switch ($this->type) {
356 case 'db': {
357 $references = $this->makeRef($this->table, $this->row['uid']);
358 if (!empty($references)) {
359 $content .= $this->doc->section($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.referencesToThisItem'), $references);
360 }
361
362 $referencesFrom = $this->makeRefFrom($this->table, $this->row['uid']);
363 if (!empty($referencesFrom)) {
364 $content .= $this->doc->section($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.referencesFromThisItem'), $referencesFrom);
365 }
366 break;
367 }
368
369 case 'file': {
370 if ($this->fileObject && $this->fileObject->isIndexed()) {
371 $references = $this->makeRef('_FILE', $this->fileObject);
372
373 if (!empty($references)) {
374 $header = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.referencesToThisItem');
375 $content .= $this->doc->section($header, $references);
376 }
377 }
378 break;
379 }
380 }
381
382 return $content;
383 }
384
385 /**
386 * Renders file properties as html table
387 *
388 * @param array $fieldList
389 * @return string
390 */
391 protected function renderFileInformationAsTable($fieldList) {
392 $tableRows = array();
393 foreach ($fieldList as $name) {
394 if (!isset($GLOBALS['TCA'][$this->table]['columns'][$name])) {
395 continue;
396 }
397 $isExcluded = !(!$GLOBALS['TCA'][$this->table]['columns'][$name]['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $this->table . ':' . $name));
398 if ($isExcluded) {
399 continue;
400 }
401 $uid = $this->row['uid'];
402 $itemValue = BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, 0, FALSE, $uid);
403 $itemLabel = $GLOBALS['LANG']->sL(BackendUtility::getItemLabel($this->table, $name), 1);
404 $tableRows[] = '
405 <tr>
406 <td class="t3-col-header">' . $itemLabel . '</td>
407 <td>' . htmlspecialchars($itemValue) . '</td>
408 </tr>';
409 }
410
411 if (!$tableRows) {
412 return '';
413 }
414
415 return '<table id="typo3-showitem" class="t3-table-info">' .
416 implode('', $tableRows) .
417 '</table>';
418 }
419
420 /**
421 * End page and print content
422 *
423 * @return void
424 */
425 public function printContent() {
426 echo $this->doc->startPage('') .
427 $this->doc->insertStylesAndJS($this->content) .
428 $this->doc->endPage();
429 }
430
431 /**
432 * Get field name for specified table/column name
433 *
434 * @param string $tableName Table name
435 * @param string $fieldName Column name
436 * @return string label
437 */
438 public function getLabelForTableColumn($tableName, $fieldName) {
439 if ($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label'] !== NULL) {
440 $field = $GLOBALS['LANG']->sL($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label']);
441 if (trim($field) === '') {
442 $field = $fieldName;
443 }
444 } else {
445 $field = $fieldName;
446 }
447 return $field;
448 }
449
450 /**
451 * Returns the rendered record actions
452 *
453 * @param string $table
454 * @param integer $uid
455 * @return string
456 */
457 protected function getRecordActions($table, $uid) {
458 if ($table === '' || $uid < 0) {
459 return '';
460 }
461
462 $editOnClick = BackendUtility::editOnClick('&edit[' . $table . '][' . $uid . ']=edit', $GLOBALS['BACK_PATH']);
463 $icon = IconUtility::getSpriteIcon('actions-document-open');
464 $pageActionIcons = '<a href="#" onclick="' . htmlspecialchars($editOnClick) . '">' . $icon . '</a>';
465 $historyOnClick = 'window.location.href=\'show_rechis.php?element=' . $table . '%3A' .
466 $uid . '&returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI')) . '\'; return false;';
467
468 $icon = IconUtility::getSpriteIcon('actions-document-history-open');
469 $pageActionIcons .= '<a href="#" onclick="' . $historyOnClick . '">' . $icon . '</a>';
470 if ($table === 'pages') {
471 $pageActionIcons .= $this->doc->viewPageIcon($uid, '');
472 }
473 return $pageActionIcons;
474 }
475
476 /**
477 * Make reference display
478 *
479 * @param string $table Table name
480 * @param string|\TYPO3\CMS\Core\Resource\File $ref Filename or uid
481 * @return string HTML
482 */
483 protected function makeRef($table, $ref) {
484 // Files reside in sys_file table
485 if ($table === '_FILE') {
486 $selectTable = 'sys_file';
487 $selectUid = $ref->getUid();
488 } else {
489 $selectTable = $table;
490 $selectUid = $ref;
491 }
492 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
493 '*',
494 'sys_refindex',
495 'ref_table=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($selectTable, 'sys_refindex') . ' AND ref_uid=' . intval($selectUid) . ' AND deleted=0'
496 );
497
498 // Compile information for title tag:
499 $infoData = array();
500 if (count($rows)) {
501 $infoDataHeader = '<tr class="t3-row-header">' . '<td>&nbsp;</td>' . '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.table') . '</td>' . '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.title') . '</td>' . '<td>[uid]</td>' . '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.field') . '</td>' . '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.flexpointer') . '</td>' . '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.softrefKey') . '</td>' . '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.sorting') . '</td>' . '</tr>';
502 }
503 foreach ($rows as $row) {
504 if ($row['tablename'] === 'sys_file_reference') {
505 $row = $this->transformFileReferenceToRecordReference($row);
506 }
507 $record = BackendUtility::getRecord($row['tablename'], $row['recuid']);
508 $parentRecord = BackendUtility::getRecord('pages', $record['pid']);
509 $actions = $this->getRecordActions($row['tablename'], $row['recuid']);
510 $infoData[] = '<tr class="db_list_normal">' .
511 '<td style="white-space:nowrap;">' . $actions . '</td>' .
512 '<td>' . $GLOBALS['LANG']->sL($GLOBALS['TCA'][$row['tablename']]['ctrl']['title'], TRUE) . '</td>' .
513 '<td>' . BackendUtility::getRecordTitle($row['tablename'], $record, TRUE) . '</td>' .
514 '<td><span title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:page') . ': ' .
515 htmlspecialchars(BackendUtility::getRecordTitle('pages', $parentRecord)) . ' (uid=' . $record['pid'] . ')">' .
516 $record['uid'] . '</span></td>' .
517 '<td>' . htmlspecialchars($this->getLabelForTableColumn($row['tablename'], $row['field'])) . '</td>' .
518 '<td>' . htmlspecialchars($row['flexpointer']) . '</td>' . '<td>' . htmlspecialchars($row['softref_key']) . '</td>' .
519 '<td>' . htmlspecialchars($row['sorting']) . '</td>' .
520 '</tr>';
521 }
522 $referenceLine = '';
523 if (count($infoData)) {
524 $referenceLine = '<table border="0" cellpadding="0" cellspacing="0" class="typo3-dblist">' .
525 '<thead>' . $infoDataHeader . '</thead>' .
526 '<tbody>' .
527 implode('', $infoData) .
528 '</tbody></table>';
529 }
530 return $referenceLine;
531 }
532
533 /**
534 * Make reference display (what this elements points to)
535 *
536 * @param string $table Table name
537 * @param string $ref Filename or uid
538 * @return string HTML
539 */
540 protected function makeRefFrom($table, $ref) {
541 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
542 '*',
543 'sys_refindex',
544 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($table, 'sys_refindex') . ' AND recuid=' . intval($ref)
545 );
546
547 // Compile information for title tag:
548 $infoData = array();
549 if (count($rows)) {
550 $infoData[] = '<tr class="t3-row-header">' .
551 '<td>&nbsp;</td>' .
552 '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.field') . '</td>' .
553 '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.flexpointer') . '</td>' .
554 '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.softrefKey') . '</td>' .
555 '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.sorting') . '</td>' .
556 '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.refTable') . '</td>' .
557 '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.refUid') . '</td>' .
558 '<td>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:show_item.php.refString') . '</td>' .
559 '</tr>';
560 }
561 foreach ($rows as $row) {
562 $actions = $this->getRecordActions($row['ref_table'], $row['ref_uid']);
563 $infoData[] = '<tr>' .
564 '<td style="white-space:nowrap;">' . $actions . '</td>' .
565 '<td>' . htmlspecialchars($this->getLabelForTableColumn($table, $row['field'])) . '</td>' .
566 '<td>' . htmlspecialchars($row['flexpointer']) . '</td>' .
567 '<td>' . htmlspecialchars($row['softref_key']) . '</td>' .
568 '<td>' . htmlspecialchars($row['sorting']) . '</td>' .
569 '<td>' . $GLOBALS['LANG']->sL($GLOBALS['TCA'][$row['ref_table']]['ctrl']['title'], TRUE) . '</td>' .
570 '<td>' . htmlspecialchars($row['ref_uid']) . '</td>' .
571 '<td>' . htmlspecialchars($row['ref_string']) . '</td>' .
572 '</tr>';
573 }
574
575 if (empty($infoData)) {
576 return;
577 }
578
579 return '<table border="0" cellpadding="0" cellspacing="0" class="typo3-dblist">' .
580 implode('', $infoData) .
581 '</table>';
582 }
583
584 /**
585 * Convert FAL file reference (sys_file_reference) to reference index (sys_refindex) table format
586 *
587 * @param array $referenceRecord
588 * @return array
589 */
590 protected function transformFileReferenceToRecordReference(array $referenceRecord) {
591 $fileReference = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
592 '*',
593 'sys_file_reference',
594 'uid=' . (int)$referenceRecord['recuid']
595 );
596 return array(
597 'recuid' => $fileReference['uid_foreign'],
598 'tablename' => $fileReference['tablenames'],
599 'field' => $fileReference['fieldname'],
600 'flexpointer' => '',
601 'softref_key' => '',
602 'sorting' => $fileReference['sorting_foreign']
603 );
604 }
605
606 }
607
608 ?>