TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
ElementInformationController.php
Go to the documentation of this file.
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 Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
29 
34 {
40  public $table;
41 
47  public $uid;
48 
52  protected $permsClause;
53 
57  public $access = false;
58 
66  public $type = '';
67 
71  protected $moduleTemplate;
72 
79  public $pageInfo;
80 
86  protected $row;
87 
91  protected $fileObject;
92 
96  protected $folderObject;
97 
101  protected $iconFactory;
102 
106  public function __construct()
107  {
108  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
109  $GLOBALS['SOBE'] = $this;
110 
111  $this->init();
112  }
113 
120  public function init()
121  {
122  $this->table = GeneralUtility::_GET('table');
123  $this->uid = GeneralUtility::_GET('uid');
124 
125  $this->permsClause = $this->getBackendUser()->getPagePermsClause(1);
126  $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
127  $this->moduleTemplate->getDocHeaderComponent()->disable();
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 
139  protected function initDatabaseRecord()
140  {
141  $this->type = 'db';
142  $this->uid = (int)$this->uid;
143 
144  // Check permissions and uid value:
145  if ($this->uid && $this->getBackendUser()->check('tables_select', $this->table)) {
146  if ((string)$this->table == 'pages') {
147  $this->pageInfo = BackendUtility::readPageAccess($this->uid, $this->permsClause);
148  $this->access = is_array($this->pageInfo) ? 1 : 0;
149  $this->row = $this->pageInfo;
150  } else {
151  $this->row = BackendUtility::getRecordWSOL($this->table, $this->uid);
152  if ($this->row) {
153  $this->pageInfo = BackendUtility::readPageAccess($this->row['pid'], $this->permsClause);
154  $this->access = is_array($this->pageInfo) ? 1 : 0;
155  }
156  }
157  }
158  }
159 
163  protected function initFileOrFolderRecord()
164  {
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 = [];
181  }
182  }
183  }
184 
193  public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
194  {
195  $this->main();
196 
197  $response->getBody()->write($this->moduleTemplate->renderContent());
198  return $response;
199  }
200 
204  public function main()
205  {
206  if (!$this->access) {
207  return;
208  }
209 
210  $content = '';
211 
212  // render type by user func
213  $typeRendered = false;
214  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/show_item.php']['typeRendering'])) {
215  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/show_item.php']['typeRendering'] as $classRef) {
216  $typeRenderObj = GeneralUtility::getUserObj($classRef);
217  if (is_object($typeRenderObj) && method_exists($typeRenderObj, 'isValid') && method_exists($typeRenderObj, 'render')) {
218  if ($typeRenderObj->isValid($this->type, $this)) {
219  $content .= $typeRenderObj->render($this->type, $this);
220  $typeRendered = true;
221  break;
222  }
223  }
224  }
225  }
226 
227  if (!$typeRendered) {
228  // Rendering of the output via fluid
229  $view = GeneralUtility::makeInstance(StandaloneView::class);
230  $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
231  $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
232  $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
233  'EXT:backend/Resources/Private/Templates/ContentElement/ElementInformation.html'
234  ));
235  $view->assignMultiple($this->getPageTitle());
236  $view->assignMultiple($this->getPreview());
237  $view->assignMultiple($this->getPropertiesForTable());
238  $view->assignMultiple($this->getReferences());
239  $view->assignMultiple($this->getBackButton());
240  $content .= $view->render();
241  }
242  $this->moduleTemplate->setContent($content);
243  }
244 
250  protected function getPageTitle() : array
251  {
252  $pageTitle = [
253  'title' => strip_tags(BackendUtility::getRecordTitle($this->table, $this->row))
254  ];
255  if ($this->type === 'folder') {
256  $pageTitle['table'] = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:folder');
257  $pageTitle['icon'] = $this->iconFactory->getIconForResource($this->folderObject, Icon::SIZE_SMALL)->render();
258  } elseif ($this->type === 'file') {
259  $pageTitle['table'] = $this->getLanguageService()->sL($GLOBALS['TCA'][$this->table]['ctrl']['title']);
260  $pageTitle['icon'] = $this->iconFactory->getIconForResource($this->fileObject, Icon::SIZE_SMALL)->render();
261  } else {
262  $pageTitle['table'] = $this->getLanguageService()->sL($GLOBALS['TCA'][$this->table]['ctrl']['title']);
263  $pageTitle['icon'] = $this->iconFactory->getIconForRecord($this->table, $this->row, Icon::SIZE_SMALL);
264  }
265  $this->moduleTemplate->setTitle($pageTitle['table'] . ': ' . $pageTitle['title']);
266  return $pageTitle;
267  }
268 
274  protected function getPreview() : array
275  {
276  $preview = [];
277  // Perhaps @todo in future: Also display preview for records - without fileObject
278  if (!$this->fileObject) {
279  return $preview;
280  }
281 
282  // check if file is marked as missing
283  if ($this->fileObject->isMissing()) {
284  $preview['missingFile'] =$this->fileObject->getName();
285  } else {
287  $rendererRegistry = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Rendering\RendererRegistry::class);
288  $fileRenderer = $rendererRegistry->getRenderer($this->fileObject);
289  $fileExtension = $this->fileObject->getExtension();
290  $preview['url'] = $this->fileObject->getPublicUrl(true);
291 
292  $width = '590m';
293  $heigth = '400m';
294 
295  // Check if there is a FileRenderer
296  if ($fileRenderer !== null) {
297  $preview['fileRenderer'] = $fileRenderer->render(
298  $this->fileObject,
299  $width,
300  $heigth,
301  [],
302  true
303  );
304 
305  // else check if we can create an Image preview
306  } elseif (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileExtension)) {
307  $preview['fileObject'] = $this->fileObject;
308  $preview['width'] = $width;
309  $preview['heigth'] = $heigth;
310  }
311  }
312  return $preview;
313  }
314 
320  protected function getPropertiesForTable() : array
321  {
322  $propertiesForTable = [];
323  $extraFields = [];
324 
325  $lang = $this->getLanguageService();
326  if (in_array($this->type, ['folder', 'file'], true)) {
327  if ($this->type === 'file') {
328  $extraFields['creation_date'] = htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.creationDate'));
329  $extraFields['modification_date'] = htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.timestamp'));
330  }
331  $extraFields['storage'] = htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_tca.xlf:sys_file.storage'));
332  $extraFields['folder'] = htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:folder'));
333  } else {
334  $extraFields['crdate'] = htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.creationDate'));
335  $extraFields['cruser_id'] = htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.creationUserId'));
336  $extraFields['tstamp'] = htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.timestamp'));
337 
338  // check if the special fields are defined in the TCA ctrl section of the table
339  foreach ($extraFields as $fieldName => $fieldLabel) {
340  if (isset($GLOBALS['TCA'][$this->table]['ctrl'][$fieldName])) {
341  $extraFields[$GLOBALS['TCA'][$this->table]['ctrl'][$fieldName]] = $fieldLabel;
342  } else {
343  unset($extraFields[$fieldName]);
344  }
345  }
346  }
347 
348  foreach ($extraFields as $name => $fieldLabel) {
349  $rowValue = '';
350  $thisRow = [];
351  if (!isset($this->row[$name])) {
352  $resourceObject = $this->fileObject ?: $this->folderObject;
353  if ($name === 'storage') {
354  $rowValue = $resourceObject->getStorage()->getName();
355  } elseif ($name === 'folder') {
356  $rowValue = $resourceObject->getParentFolder()->getReadablePath();
357  }
358  } elseif (in_array($name, ['creation_date', 'modification_date'], true)) {
359  $rowValue = BackendUtility::datetime($this->row[$name]);
360  } else {
361  $rowValue = BackendUtility::getProcessedValueExtra($this->table, $name, $this->row[$name]);
362  }
363  $thisRow['value'] = $rowValue;
364  $thisRow['fieldLabel'] = rtrim($fieldLabel, ':');
365  // show the backend username who created the issue
366  if ($name === 'cruser_id' && $rowValue) {
367  $creatorRecord = BackendUtility::getRecord('be_users', $rowValue);
368  if ($creatorRecord) {
370  $avatar = GeneralUtility::makeInstance(Avatar::class);
371  $creatorRecord['icon'] = $avatar->render($creatorRecord);
372  $thisRow['creatorRecord'] = $creatorRecord;
373  $thisRow['value'] = '';
374  }
375  }
376  $propertiesForTable['extraFields'][] = $thisRow;
377  }
378 
379  // Traverse the list of fields to display for the record:
380  $fieldList = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$this->table]['interface']['showRecordFieldList'], true);
381  foreach ($fieldList as $name) {
382  $thisRow = [];
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  // format file size as bytes/kilobytes/megabytes
396  if ($this->type === 'file' && $name === 'size') {
397  $this->row[$name] = GeneralUtility::formatSize($this->row[$name], htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:byteSizeUnits')));
398  }
399 
400  $isExcluded = !(!$GLOBALS['TCA'][$this->table]['columns'][$name]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', $this->table . ':' . $name));
401  if ($isExcluded) {
402  continue;
403  }
404 
405  $thisRow['fieldValue'] = BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, 0, false, $uid);
406  $thisRow['fieldLabel'] = htmlspecialchars($lang->sL(BackendUtility::getItemLabel($this->table, $name)));
407  $propertiesForTable['fields'][] = $thisRow;
408  }
409  return $propertiesForTable;
410  }
411 
417  protected function getReferences() : array
418  {
419  $references = [];
420  switch ($this->type) {
421  case 'db': {
422  $references['refLines'] = $this->makeRef($this->table, $this->row['uid']);
423  $references['refFromLines'] = $this->makeRefFrom($this->table, $this->row['uid']);
424  break;
425  }
426 
427  case 'file': {
428  if ($this->fileObject && $this->fileObject->isIndexed()) {
429  $references['refLines'] = $this->makeRef('_FILE', $this->fileObject);
430  }
431  break;
432  }
433  }
434  return $references;
435  }
436 
442  protected function getBackButton() : array
443  {
444  return ['returnUrl' => GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GET('returnUrl'))];
445  }
446 
454  public function getLabelForTableColumn($tableName, $fieldName)
455  {
456  if ($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label'] !== null) {
457  $field = $this->getLanguageService()->sL($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label']);
458  if (trim($field) === '') {
459  $field = $fieldName;
460  }
461  } else {
462  $field = $fieldName;
463  }
464  return $field;
465  }
466 
474  protected function getRecordActions($table, $uid)
475  {
476  if ($table === '' || $uid < 0) {
477  return [];
478  }
479 
480  $actions = [];
481  // Edit button
482  $urlParameters = [
483  'edit' => [
484  $table => [
485  $uid => 'edit'
486  ]
487  ],
488  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
489  ];
490  $actions['recordEditUrl'] = BackendUtility::getModuleUrl('record_edit', $urlParameters);
491 
492  // History button
493  $urlParameters = [
494  'element' => $table . ':' . $uid,
495  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
496  ];
497  $actions['recordHistoryUrl'] = BackendUtility::getModuleUrl('record_history', $urlParameters);
498 
499  if ($table === 'pages') {
500  // Recordlist button
501  $actions['webListUrl'] = BackendUtility::getModuleUrl('web_list', ['id' => $uid, 'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]);
502 
503  // View page button
504  $actions['viewOnClick'] = BackendUtility::viewOnClick($uid, '', BackendUtility::BEgetRootLine($uid));
505  }
506 
507  return $actions;
508  }
509 
517  protected function makeRef($table, $ref)
518  {
519  $refLines = [];
520  $lang = $this->getLanguageService();
521  // Files reside in sys_file table
522  if ($table === '_FILE') {
523  $selectTable = 'sys_file';
524  $selectUid = $ref->getUid();
525  } else {
526  $selectTable = $table;
527  $selectUid = $ref;
528  }
530  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
531  ->getQueryBuilderForTable('sys_refindex');
532  $rows = $queryBuilder
533  ->select('*')
534  ->from('sys_refindex')
535  ->where(
536  $queryBuilder->expr()->eq(
537  'ref_table',
538  $queryBuilder->createNamedParameter($selectTable, \PDO::PARAM_STR)
539  ),
540  $queryBuilder->expr()->eq(
541  'ref_uid',
542  $queryBuilder->createNamedParameter($selectUid, \PDO::PARAM_INT)
543  ),
544  $queryBuilder->expr()->eq(
545  'deleted',
546  $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
547  )
548  )
549  ->execute()
550  ->fetchAll();
551 
552  // Compile information for title tag:
553  foreach ($rows as $row) {
554  if ($row['tablename'] === 'sys_file_reference') {
555  $row = $this->transformFileReferenceToRecordReference($row);
556  if ($row['tablename'] === null || $row['recuid'] === null) {
557  return;
558  }
559  }
560  $line = [];
561  $record = BackendUtility::getRecord($row['tablename'], $row['recuid']);
562  if ($record) {
563  $parentRecord = BackendUtility::getRecord('pages', $record['pid']);
564  $parentRecordTitle = is_array($parentRecord)
565  ? BackendUtility::getRecordTitle('pages', $parentRecord)
566  : '';
567  $urlParameters = [
568  'edit' => [
569  $row['tablename'] => [
570  $row['recuid'] => 'edit'
571  ]
572  ],
573  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
574  ];
575  $url = BackendUtility::getModuleUrl('record_edit', $urlParameters);
576  $line['url'] = $url;
577  $line['icon'] = $this->iconFactory->getIconForRecord($row['tablename'], $record, Icon::SIZE_SMALL)->render();
578  $line['row'] = $row;
579  $line['record'] = $record;
580  $line['recordTitle'] = BackendUtility::getRecordTitle($row['tablename'], $record, true);
581  $line['parentRecordTitle'] = $parentRecordTitle;
582  $line['title'] = $lang->sL($GLOBALS['TCA'][$row['tablename']]['ctrl']['title']);
583  $line['labelForTableColumn'] = $this->getLabelForTableColumn($row['tablename'], $row['field']);
584  $line['actions'] = $this->getRecordActions($row['tablename'], $row['recuid']);
585  } else {
586  $line['row'] = $row;
587  $line['title'] = $lang->sL($GLOBALS['TCA'][$row['tablename']]['ctrl']['title']) ?: $row['tablename'];
588  $line['labelForTableColumn'] = $this->getLabelForTableColumn($row['tablename'], $row['field']);
589  }
590  $refLines[] = $line;
591  }
592  return $refLines;
593  }
594 
602  protected function makeRefFrom($table, $ref) : array
603  {
604  $refFromLines = [];
605  $lang = $this->getLanguageService();
606 
608  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
609  ->getQueryBuilderForTable('sys_refindex');
610  $rows = $queryBuilder
611  ->select('*')
612  ->from('sys_refindex')
613  ->where(
614  $queryBuilder->expr()->eq(
615  'tablename',
616  $queryBuilder->createNamedParameter($table, \PDO::PARAM_STR)
617  ),
618  $queryBuilder->expr()->eq(
619  'recuid',
620  $queryBuilder->createNamedParameter($ref, \PDO::PARAM_INT)
621  )
622  )
623  ->execute()
624  ->fetchAll();
625 
626  // Compile information for title tag:
627  foreach ($rows as $row) {
628  $line = [];
629  $record = BackendUtility::getRecord($row['ref_table'], $row['ref_uid']);
630  if ($record) {
631  $urlParameters = [
632  'edit' => [
633  $row['ref_table'] => [
634  $row['ref_uid'] => 'edit'
635  ]
636  ],
637  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
638  ];
639  $url = BackendUtility::getModuleUrl('record_edit', $urlParameters);
640  $line['url'] = $url;
641  $line['icon'] = $this->iconFactory->getIconForRecord($row['tablename'], $record, Icon::SIZE_SMALL)->render();
642  $line['row'] = $row;
643  $line['record'] = $record;
644  $line['recordTitle'] = BackendUtility::getRecordTitle($row['ref_table'], $record, true);
645  $line['title'] = $lang->sL($GLOBALS['TCA'][$row['ref_table']]['ctrl']['title']);
646  $line['labelForTableColumn'] = $this->getLabelForTableColumn($table, $row['field']);
647  $line['actions'] = $this->getRecordActions($row['ref_table'], $row['ref_uid']);
648  } else {
649  $line['row'] = $row;
650  $line['title'] = $lang->sL($GLOBALS['TCA'][$row['ref_table']]['ctrl']['title']);
651  $line['labelForTableColumn'] = $this->getLabelForTableColumn($table, $row['field']);
652  }
653  $refFromLines[] = $line;
654  }
655  return $refFromLines;
656  }
657 
664  protected function transformFileReferenceToRecordReference(array $referenceRecord)
665  {
667  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
668  ->getQueryBuilderForTable('sys_file_reference');
669  $queryBuilder->getRestrictions()->removeAll();
670  $fileReference = $queryBuilder
671  ->select('*')
672  ->from('sys_file_reference')
673  ->where(
674  $queryBuilder->expr()->eq(
675  'uid',
676  $queryBuilder->createNamedParameter($referenceRecord['recuid'], \PDO::PARAM_INT)
677  )
678  )
679  ->execute()
680  ->fetch();
681 
682  return [
683  'recuid' => $fileReference['uid_foreign'],
684  'tablename' => $fileReference['tablenames'],
685  'field' => $fileReference['fieldname'],
686  'flexpointer' => '',
687  'softref_key' => '',
688  'sorting' => $fileReference['sorting_foreign']
689  ];
690  }
691 
697  protected function getLanguageService()
698  {
699  return $GLOBALS['LANG'];
700  }
701 
707  protected function getBackendUser()
708  {
709  return $GLOBALS['BE_USER'];
710  }
711 }
static getRecordWSOL($table, $uid, $fields= '*', $where= '', $useDeleteClause=true, $unsetMovePointers=false)
static getProcessedValueExtra($table, $fN, $fV, $fixed_lgd_chars=0, $uid=0, $forceResult=true, $pid=0)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
mainAction(ServerRequestInterface $request, ResponseInterface $response)
$rendererRegistry
static formatSize($sizeInBytes, $labels= '', $base=0)
static getRecordTitle($table, $row, $prep=false, $forceResult=true)
static viewOnClick($pageUid, $backPath= '', $rootLine=null, $anchorSection= '', $alternativeUrl= '', $additionalGetVars= '', $switchFocus=true)
static BEgetRootLine($uid, $clause= '', $workspaceOL=false)
static getRecord($table, $uid, $fields= '*', $where= '', $useDeleteClause=true)
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static makeInstance($className,...$constructorArguments)
static getFileAbsFileName($filename, $_=null, $_2=null)