‪TYPO3CMS  ‪main
ElementInformationController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
31 use TYPO3\CMS\Backend\Utility\BackendUtility;
36 use TYPO3\CMS\Core\Imaging\IconSize;
46 
52 #[Controller]
54 {
58  protected string ‪$type = 'db';
59 
60  protected array ‪$row = [];
61  protected ?string ‪$table = null;
62  protected ?‪File ‪$fileObject = null;
63  protected ?‪Folder ‪$folderObject = null;
64 
65  public function ‪__construct(
66  protected readonly ‪IconFactory $iconFactory,
67  protected readonly ‪UriBuilder $uriBuilder,
68  protected readonly ‪ModuleTemplateFactory $moduleTemplateFactory,
69  protected readonly ‪ResourceFactory $resourceFactory,
70  private readonly ‪FormDataCompiler $formDataCompiler,
71  ) {
72  }
73 
78  public function ‪mainAction(ServerRequestInterface $request): ResponseInterface
79  {
80  $backendUser = $this->‪getBackendUser();
81  $view = $this->moduleTemplateFactory->create($request);
82  $view->getDocHeaderComponent()->disable();
83  $queryParams = $request->getQueryParams();
84  $this->table = $queryParams['table'] ?? null;
85  ‪$uid = $queryParams['uid'] ?? '';
86  $permsClause = $backendUser->getPagePermsClause(‪Permission::PAGE_SHOW);
87  // Determines if table/uid point to database record or file and if user has access to view information
88  $accessAllowed = false;
89  if (isset(‪$GLOBALS['TCA'][$this->table])) {
90  ‪$uid = (int)‪$uid;
91  // Check permissions and uid value:
92  if (‪$uid && $backendUser->check('tables_select', $this->table)) {
93  if ((string)$this->table === 'pages') {
94  $this->row = BackendUtility::readPageAccess(‪$uid, $permsClause) ?: [];
95  $accessAllowed = $this->row !== [];
96  } else {
97  $this->row = BackendUtility::getRecordWSOL($this->table, ‪$uid);
98  if ($this->row) {
99  if (isset($this->row['_ORIG_uid'])) {
100  // Make $uid the uid of the versioned record, while $this->row['uid'] is live record uid
101  ‪$uid = (int)$this->row['_ORIG_uid'];
102  }
103  $pageInfo = BackendUtility::readPageAccess((int)$this->row['pid'], $permsClause) ?: [];
104  $accessAllowed = $pageInfo !== [];
105  }
106  }
107  }
108  } elseif ($this->table === '_FILE' || $this->table === '_FOLDER' || $this->table === 'sys_file') {
109  $fileOrFolderObject = $this->resourceFactory->retrieveFileOrFolderObject(‪$uid);
110  if ($fileOrFolderObject instanceof ‪Folder) {
111  $this->folderObject = $fileOrFolderObject;
112  $accessAllowed = $this->folderObject->checkActionPermission('read');
113  $this->type = 'folder';
114  } elseif ($fileOrFolderObject instanceof ‪File) {
115  $this->fileObject = $fileOrFolderObject;
116  $accessAllowed = $this->fileObject->checkActionPermission('read');
117  $this->type = 'file';
118  $this->table = 'sys_file';
119  $this->row = BackendUtility::getRecordWSOL($this->table, $fileOrFolderObject->getUid());
120  }
121  }
122 
123  // Rendering of the output via fluid
124  $view->assign('accessAllowed', $accessAllowed);
125  $view->assign('hookContent', '');
126  if (!$accessAllowed) {
127  return $view->renderResponse('ContentElement/ElementInformation');
128  }
129 
130  // render type by user func
131  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/show_item.php']['typeRendering'] ?? [] as $className) {
132  $typeRenderObj = GeneralUtility::makeInstance($className);
133  if (is_object($typeRenderObj) && method_exists($typeRenderObj, 'isValid') && method_exists($typeRenderObj, 'render')) {
134  if ($typeRenderObj->isValid($this->type, $this)) {
135  $view->assign('hookContent', $typeRenderObj->render($this->type, $this));
136  return $view->renderResponse('ContentElement/ElementInformation');
137  }
138  }
139  }
140 
141  $pageTitle = $this->‪getPageTitle();
142  $view->setTitle($pageTitle['table'] . ': ' . $pageTitle['title']);
143  $view->assignMultiple($pageTitle);
144  $view->assignMultiple($this->‪getPreview($request));
145  $view->assignMultiple($this->‪getPropertiesForTable($request));
146  $view->assignMultiple($this->‪getReferences($request, ‪$uid));
147  $view->assign('returnUrl', GeneralUtility::sanitizeLocalUrl($request->getQueryParams()['returnUrl'] ?? ''));
148  $view->assign('maxTitleLength', $this->‪getBackendUser()->uc['titleLen'] ?? 20);
149 
150  return $view->renderResponse('ContentElement/ElementInformation');
151  }
152 
156  protected function ‪getPageTitle(): array
157  {
158  $pageTitle = [
159  'title' => BackendUtility::getRecordTitle($this->table, $this->row),
160  ];
161  if ($this->type === 'folder') {
162  $pageTitle['title'] = htmlspecialchars($this->folderObject->getName());
163  $pageTitle['table'] = $this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:folder');
164  $pageTitle['icon'] = $this->iconFactory->getIconForResource($this->folderObject, IconSize::SMALL)->render();
165  } elseif ($this->type === 'file') {
166  $pageTitle['table'] = $this->‪getLanguageService()->sL(‪$GLOBALS['TCA'][$this->table]['ctrl']['title']);
167  $pageTitle['icon'] = $this->iconFactory->getIconForResource($this->fileObject, IconSize::SMALL)->render();
168  } else {
169  $pageTitle['table'] = $this->‪getLanguageService()->sL(‪$GLOBALS['TCA'][$this->table]['ctrl']['title']);
170  $pageTitle['icon'] = $this->iconFactory->getIconForRecord($this->table, $this->row, IconSize::SMALL);
171  }
172  return $pageTitle;
173  }
174 
178  protected function ‪getPreview(ServerRequestInterface $request): array
179  {
180  $preview = [];
181  // Perhaps @todo in future: Also display preview for records - without fileObject
182  if (!$this->fileObject) {
183  return $preview;
184  }
185 
186  // check if file is marked as missing
187  if ($this->fileObject->isMissing()) {
188  $preview['missingFile'] = $this->fileObject->getName();
189  } else {
190  ‪$rendererRegistry = GeneralUtility::makeInstance(RendererRegistry::class);
191  $fileRenderer = ‪$rendererRegistry->getRenderer($this->fileObject);
192  $preview['url'] = $this->fileObject->getPublicUrl() ?? '';
193 
194  // Add "edit metadata" button
195  $preview['editMetadataUrl'] = '';
196  if (($metaDataUid = $this->fileObject->getProperties()['metadata_uid'] ?? false)
197  && $this->fileObject->isIndexed()
198  && $this->fileObject->checkActionPermission('editMeta')
199  && $this->getBackendUser()->check('tables_modify', 'sys_file_metadata')
200  ) {
201  $urlParameters = [
202  'edit' => [
203  'sys_file_metadata' => [
204  $metaDataUid => 'edit',
205  ],
206  ],
207  'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(),
208  ];
209  $preview['editMetadataUrl'] = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
210  }
211 
212  $width = min(590, $this->fileObject->getMetaData()['width'] ?? 590) . 'm';
213  $height = min(400, $this->fileObject->getMetaData()['height'] ?? 400) . 'm';
214 
215  // Check if there is a FileRenderer
216  if ($fileRenderer !== null) {
217  $preview['fileRenderer'] = $fileRenderer->render($this->fileObject, $width, $height);
218  // else check if we can create an Image preview
219  } elseif ($this->fileObject->isImage()) {
220  $preview['fileObject'] = ‪$this->fileObject;
221  $preview['width'] = $width;
222  $preview['height'] = $height;
223  }
224  }
225  return $preview;
226  }
227 
231  protected function ‪getPropertiesForTable(ServerRequestInterface $request): array
232  {
233  $lang = $this->‪getLanguageService();
234  $propertiesForTable = [];
235  $propertiesForTable['extraFields'] = $this->‪getExtraFields();
236 
237  // Traverse the list of fields to display for the record:
238  $fieldList = $this->‪getFieldList($request, $this->table, (int)($this->row['uid'] ?? 0));
239 
240  foreach ($fieldList as $name) {
241  $name = trim($name);
242  ‪$uid = $this->row['uid'] ?? 0;
243 
244  if (!isset(‪$GLOBALS['TCA'][$this->table]['columns'][$name])) {
245  continue;
246  }
247 
248  // @todo Add meaningful information for mfa field. For the time being we don't display anything at all.
249  if ($this->type === 'db' && $name === 'mfa' && in_array($this->table, ['be_users', 'fe_users'], true)) {
250  continue;
251  }
252 
253  // not a real field -> skip
254  if ($this->type === 'file' && $name === 'fileinfo') {
255  continue;
256  }
257 
258  // Field does not exist (e.g. having type=none) -> skip
259  if (!array_key_exists($name, $this->row)) {
260  continue;
261  }
262 
263  $isExcluded = !(!(‪$GLOBALS['TCA'][‪$this->table]['columns'][$name]['exclude'] ?? false) || $this->‪getBackendUser()->check('non_exclude_fields', $this->table . ':' . $name));
264  if ($isExcluded) {
265  continue;
266  }
267  $label = $lang->sL(BackendUtility::getItemLabel($this->table, $name));
268  $label = $label ?: $name;
269 
270  $propertiesForTable['fields'][] = [
271  'fieldValue' => BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, false, false, ‪$uid),
272  'fieldLabel' => htmlspecialchars($label),
273  ];
274  }
275 
276  // additional information for folders and files
277  if ($this->folderObject instanceof ‪Folder || $this->fileObject instanceof ‪File) {
278  // storage
279  if ($this->folderObject instanceof ‪Folder) {
280  $propertiesForTable['fields']['storage'] = [
281  'fieldValue' => $this->folderObject->getStorage()->getName(),
282  'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file.storage')),
283  ];
284  }
285 
286  // folder
287  $resourceObject = $this->fileObject ?: ‪$this->folderObject;
288  $parentFolder = $resourceObject->‪getParentFolder();
289  $propertiesForTable['fields']['folder'] = [
290  'fieldValue' => $parentFolder instanceof ‪Folder ? $parentFolder->‪getReadablePath() : '',
291  'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:folder')),
292  ];
293 
294  if ($this->fileObject instanceof ‪File) {
295  // show file dimensions for images
296  if ($this->fileObject->getType() === ‪AbstractFile::FILETYPE_IMAGE) {
297  $propertiesForTable['fields']['width'] = [
298  'fieldValue' => $this->fileObject->getProperty('width') . 'px',
299  'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.width')),
300  ];
301  $propertiesForTable['fields']['height'] = [
302  'fieldValue' => $this->fileObject->getProperty('height') . 'px',
303  'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.height')),
304  ];
305  }
306 
307  // file size
308  $propertiesForTable['fields']['size'] = [
309  'fieldValue' => GeneralUtility::formatSize((int)$this->fileObject->getProperty('size'), htmlspecialchars($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:byteSizeUnits'))),
310  'fieldLabel' => $lang->sL(BackendUtility::getItemLabel($this->table, 'size')),
311  ];
312 
313  // show the metadata of a file as well
314  ‪$table = 'sys_file_metadata';
315  $metaDataRepository = GeneralUtility::makeInstance(MetaDataRepository::class);
317  $metaData = $metaDataRepository->findByFileUid($this->row['uid'] ?? 0);
318 
319  // If there is no metadata record, skip it
320  if ($metaData !== []) {
321  $allowedFields = $this->‪getFieldList($request, ‪$table, (int)$metaData['uid']);
322 
323  foreach ($metaData as $name => $value) {
324  if (in_array($name, $allowedFields, true)) {
325  if (!isset(‪$GLOBALS['TCA'][‪$table]['columns'][$name])) {
326  continue;
327  }
328 
329  $isExcluded = !(!(‪$GLOBALS['TCA'][‪$table]['columns'][$name]['exclude'] ?? false) || $this->‪getBackendUser()->check('non_exclude_fields', $table . ':' . $name));
330  if ($isExcluded) {
331  continue;
332  }
333 
334  $label = $lang->sL(BackendUtility::getItemLabel(‪$table, $name));
335  $label = $label ?: $name;
336 
337  $propertiesForTable['fields'][] = [
338  'fieldValue' => BackendUtility::getProcessedValue(‪$table, $name, $metaData[$name], 0, false, false, (int)$metaData['uid']),
339  'fieldLabel' => htmlspecialchars($label),
340  ];
341  }
342  }
343  }
344  }
345  }
346 
347  return $propertiesForTable;
348  }
349 
353  protected function ‪getFieldList(ServerRequestInterface $request, string ‪$table, int ‪$uid): array
354  {
355  $formDataCompilerInput = [
356  'request' => $request,
357  'command' => 'edit',
358  'tableName' => ‪$table,
359  'vanillaUid' => ‪$uid,
360  ];
361  try {
362  $result = $this->formDataCompiler->compile($formDataCompilerInput, GeneralUtility::makeInstance(TcaDatabaseRecord::class));
363  $fieldList = array_unique(array_values($result['columnsToProcess']));
364 
365  $ctrlKeysOfUnneededFields = ['origUid', 'transOrigPointerField', 'transOrigDiffSourceField'];
366  foreach ($ctrlKeysOfUnneededFields as $field) {
367  if (isset(‪$GLOBALS['TCA'][‪$table]['ctrl'][$field]) && ($key = array_search(‪$GLOBALS['TCA'][‪$table]['ctrl'][$field], $fieldList, true)) !== false) {
368  unset($fieldList[$key]);
369  }
370  }
371  } catch (\‪Exception $exception) {
372  $fieldList = [];
373  }
374 
375  $searchFields = GeneralUtility::trimExplode(',', (‪$GLOBALS['TCA'][‪$table]['ctrl']['searchFields'] ?? ''));
376 
377  return array_unique(array_merge($fieldList, $searchFields));
378  }
379 
383  protected function ‪getExtraFields(): array
384  {
385  $lang = $this->‪getLanguageService();
386  $keyLabelPair = [];
387  if (in_array($this->type, ['folder', 'file'], true)) {
388  if ($this->type === 'file') {
389  $keyLabelPair['uid'] = [
390  'value' => (int)$this->row['uid'],
391  ];
392  $keyLabelPair['creation_date'] = [
393  'value' => BackendUtility::datetime($this->row['creation_date']),
394  'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationDate')),
395  'isDatetime' => true,
396  ];
397  $keyLabelPair['modification_date'] = [
398  'value' => BackendUtility::datetime($this->row['modification_date']),
399  'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.timestamp')),
400  'isDatetime' => true,
401  ];
402  }
403  } else {
404  $keyLabelPair['uid'] = [
405  'value' => BackendUtility::getProcessedValueExtra($this->table, 'uid', $this->row['uid']),
406  'fieldLabel' => rtrim(htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.uid')), ':'),
407  ];
408  foreach (['crdate' => 'creationDate', 'tstamp' => 'timestamp'] as $field => $label) {
409  if (isset(‪$GLOBALS['TCA'][$this->table]['ctrl'][$field])) {
410  $keyLabelPair[$field] = [
411  'value' => BackendUtility::datetime($this->row[‪$GLOBALS['TCA'][$this->table]['ctrl'][$field]]),
412  'fieldLabel' => rtrim(htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.' . $label)), ':'),
413  'isDatetime' => true,
414  ];
415  }
416  }
417  // Show the user who created the record
418  $recordHistory = GeneralUtility::makeInstance(RecordHistory::class);
419  $ownerInformation = $recordHistory->getCreationInformationForRecord($this->type, $this->row);
420  $ownerUid = (int)(is_array($ownerInformation) && $ownerInformation['actiontype'] === 'BE' ? $ownerInformation['userid'] : 0);
421  if ($ownerUid) {
422  $creatorRecord = BackendUtility::getRecord('be_users', $ownerUid);
423  if ($creatorRecord) {
424  $avatar = GeneralUtility::makeInstance(Avatar::class);
425  $creatorRecord['icon'] = $avatar->render($creatorRecord);
426  $rowValue = $creatorRecord;
427  $keyLabelPair['creatorRecord'] = [
428  'value' => $rowValue,
429  'fieldLabel' => rtrim(htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationUserId')), ':'),
430  ];
431  }
432  }
433  }
434  return $keyLabelPair;
435  }
436 
440  protected function ‪getReferences(ServerRequestInterface $request, int|string ‪$uid): array
441  {
442  $references = [];
443  switch ($this->type) {
444  case 'db': {
445  $references['refLines'] = $this->‪makeRef($this->table, ‪$uid, $request);
446  $references['refFromLines'] = $this->‪makeRefFrom($this->table, ‪$uid, $request);
447  break;
448  }
449  case 'file': {
450  if ($this->fileObject && $this->fileObject->isIndexed()) {
451  $references['refLines'] = $this->‪makeRef('_FILE', $this->fileObject, $request);
452  }
453  break;
454  }
455  }
456  return $references;
457  }
458 
466  protected function ‪getLabelForTableColumn($tableName, $fieldName): string
467  {
468  if ((‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label'] ?? null) !== null) {
469  $field = $this->‪getLanguageService()->sL(‪$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label']);
470  if (trim($field) === '') {
471  $field = $fieldName;
472  }
473  } else {
474  $field = $fieldName;
475  }
476  return $field;
477  }
478 
486  protected function ‪getRecordActions(‪$table, ‪$uid, ServerRequestInterface $request): array
487  {
488  if (‪$table === '' || ‪$uid < 0) {
489  return [];
490  }
491 
492  $actions = [];
493  // Edit button
494  $urlParameters = [
495  'edit' => [
496  ‪$table => [
497  ‪$uid => 'edit',
498  ],
499  ],
500  'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(),
501  ];
502  $actions['recordEditUrl'] = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
503 
504  // History button
505  $urlParameters = [
506  'element' => ‪$table . ':' . ‪$uid,
507  'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(),
508  ];
509  $actions['recordHistoryUrl'] = (string)$this->uriBuilder->buildUriFromRoute('record_history', $urlParameters);
510 
511  if (‪$table === 'pages') {
512  // Recordlist button
513  $actions['webListUrl'] = (string)$this->uriBuilder->buildUriFromRoute('web_list', ['id' => ‪$uid, 'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri()]);
514 
515  $previewUriBuilder = ‪PreviewUriBuilder::create((int)‪$uid)
516  ->withRootLine(BackendUtility::BEgetRootLine(‪$uid));
517  // View page button
518  $actions['previewUrlAttributes'] = $previewUriBuilder->serializeDispatcherAttributes();
519  }
520 
521  return $actions;
522  }
523 
531  protected function ‪makeRef(‪$table, $ref, ServerRequestInterface $request): array
532  {
533  $refLines = [];
534  $lang = $this->‪getLanguageService();
535  // Files reside in sys_file table
536  if ($table === '_FILE') {
537  $selectTable = 'sys_file';
538  $selectUid = $ref->getUid();
539  } else {
540  $selectTable = ‪$table;
541  $selectUid = $ref;
542  }
543  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
544  ->getQueryBuilderForTable('sys_refindex');
545 
546  $predicates = [
547  $queryBuilder->expr()->eq(
548  'ref_table',
549  $queryBuilder->createNamedParameter($selectTable)
550  ),
551  $queryBuilder->expr()->eq(
552  'ref_uid',
553  $queryBuilder->createNamedParameter($selectUid, ‪Connection::PARAM_INT)
554  ),
555  ];
556 
557  $backendUser = $this->‪getBackendUser();
558  if (!$backendUser->isAdmin()) {
559  $allowedSelectTables = GeneralUtility::trimExplode(',', $backendUser->groupData['tables_select']);
560  $predicates[] = $queryBuilder->expr()->in(
561  'tablename',
562  $queryBuilder->createNamedParameter($allowedSelectTables, Connection::PARAM_STR_ARRAY)
563  );
564  }
565 
566  $rows = $queryBuilder
567  ->select('*')
568  ->from('sys_refindex')
569  ->where(...$predicates)
570  ->executeQuery()
571  ->fetchAllAssociative();
572 
573  // Compile information for title tag:
574  foreach ($rows as ‪$row) {
575  if (‪$row['tablename'] === 'sys_file_reference') {
577  if (‪$row === null) {
578  return [];
579  }
580  }
581 
582  $line = [];
583  ‪$record = BackendUtility::getRecordWSOL(‪$row['tablename'], ‪$row['recuid']);
584  if (‪$record) {
585  if (!$this->‪canAccessPage($row['tablename'], ‪$record)) {
586  continue;
587  }
588  $parentRecord = BackendUtility::getRecord('pages', ‪$record['pid']);
589  $parentRecordTitle = is_array($parentRecord)
590  ? BackendUtility::getRecordTitle('pages', $parentRecord)
591  : '';
592  $urlParameters = [
593  'edit' => [
594  ‪$row['tablename'] => [
595  ‪$row['recuid'] => 'edit',
596  ],
597  ],
598  'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(),
599  ];
600  ‪$url = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
601  $line['url'] = ‪$url;
602  $line['icon'] = $this->iconFactory->getIconForRecord(‪$row['tablename'], ‪$record, IconSize::SMALL)->render();
603  $line['row'] = ‪$row;
604  $line['record'] = ‪$record;
605  $line['recordTitle'] = BackendUtility::getRecordTitle(‪$row['tablename'], ‪$record, false, true);
606  $line['parentRecord'] = $parentRecord;
607  $line['parentRecordTitle'] = $parentRecordTitle;
608  $line['title'] = $lang->sL(‪$GLOBALS['TCA'][‪$row['tablename']]['ctrl']['title']);
609  $line['labelForTableColumn'] = $this->‪getLabelForTableColumn($row['tablename'], ‪$row['field']);
610  $line['path'] = BackendUtility::getRecordPath(‪$record['pid'], '', 0, 0);
611  $line['actions'] = $this->‪getRecordActions($row['tablename'], ‪$row['recuid'], $request);
612  } else {
613  $line['row'] = ‪$row;
614  $line['title'] = $lang->sL(‪$GLOBALS['TCA'][‪$row['tablename']]['ctrl']['title'] ?? '') ?: ‪$row['tablename'];
615  $line['labelForTableColumn'] = $this->‪getLabelForTableColumn($row['tablename'], ‪$row['field']);
616  }
617  $refLines[] = $line;
618  }
619  return $refLines;
620  }
621 
628  protected function ‪makeRefFrom(‪$table, $ref, ServerRequestInterface $request): array
629  {
630  $refFromLines = [];
631  $lang = $this->‪getLanguageService();
632 
633  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
634  ->getQueryBuilderForTable('sys_refindex');
635 
636  $predicates = [
637  $queryBuilder->expr()->eq(
638  'tablename',
639  $queryBuilder->createNamedParameter(‪$table)
640  ),
641  $queryBuilder->expr()->eq(
642  'recuid',
643  $queryBuilder->createNamedParameter($ref, ‪Connection::PARAM_INT)
644  ),
645  ];
646 
647  $backendUser = $this->‪getBackendUser();
648  if (!$backendUser->isAdmin()) {
649  $allowedSelectTables = GeneralUtility::trimExplode(',', $backendUser->groupData['tables_select']);
650  $predicates[] = $queryBuilder->expr()->in(
651  'ref_table',
652  $queryBuilder->createNamedParameter($allowedSelectTables, Connection::PARAM_STR_ARRAY)
653  );
654  }
655 
656  $rows = $queryBuilder
657  ->select('*')
658  ->from('sys_refindex')
659  ->where(...$predicates)
660  ->executeQuery()
661  ->fetchAllAssociative();
662 
663  // Compile information for title tag:
664  foreach ($rows as ‪$row) {
665  $line = [];
666  ‪$record = BackendUtility::getRecordWSOL(‪$row['ref_table'], ‪$row['ref_uid']);
667  if (‪$record) {
668  if (!$this->‪canAccessPage($row['ref_table'], ‪$record)) {
669  continue;
670  }
671  $urlParameters = [
672  'edit' => [
673  ‪$row['ref_table'] => [
674  ‪$row['ref_uid'] => 'edit',
675  ],
676  ],
677  'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(),
678  ];
679  ‪$url = (string)$this->uriBuilder->buildUriFromRoute('record_edit', $urlParameters);
680  $line['url'] = ‪$url;
681  $line['icon'] = $this->iconFactory->getIconForRecord(‪$row['tablename'], ‪$record, IconSize::SMALL)->render();
682  $line['row'] = ‪$row;
683  $line['record'] = ‪$record;
684  $line['recordTitle'] = BackendUtility::getRecordTitle(‪$row['ref_table'], ‪$record, false, true);
685  $line['title'] = $lang->sL(‪$GLOBALS['TCA'][‪$row['ref_table']]['ctrl']['title'] ?? '');
686  $line['labelForTableColumn'] = $this->‪getLabelForTableColumn($table, ‪$row['field']);
687  $line['path'] = BackendUtility::getRecordPath(‪$record['pid'], '', 0, 0);
688  $line['actions'] = $this->‪getRecordActions($row['ref_table'], ‪$row['ref_uid'], $request);
689  } else {
690  $line['row'] = ‪$row;
691  $line['title'] = $lang->sL(‪$GLOBALS['TCA'][‪$row['ref_table']]['ctrl']['title'] ?? '');
692  $line['labelForTableColumn'] = $this->‪getLabelForTableColumn($table, ‪$row['field']);
693  }
694  $refFromLines[] = $line;
695  }
696  return $refFromLines;
697  }
698 
702  protected function ‪transformFileReferenceToRecordReference(array $referenceRecord): ?array
703  {
704  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
705  ->getQueryBuilderForTable('sys_file_reference');
706  $queryBuilder->getRestrictions()->removeAll();
707  $fileReference = $queryBuilder
708  ->select('*')
709  ->from('sys_file_reference')
710  ->where(
711  $queryBuilder->expr()->eq(
712  'uid',
713  $queryBuilder->createNamedParameter($referenceRecord['recuid'], ‪Connection::PARAM_INT)
714  )
715  )
716  ->executeQuery()
717  ->fetchAssociative();
718 
719  return $fileReference ? [
720  'recuid' => $fileReference['uid_foreign'],
721  'tablename' => $fileReference['tablenames'],
722  'field' => $fileReference['fieldname'],
723  'flexpointer' => '',
724  'softref_key' => '',
725  'sorting' => $fileReference['sorting_foreign'],
726  ] : null;
727  }
728 
733  protected function ‪canAccessPage(string $tableName, array ‪$record): bool
734  {
735  $recordPid = (int)($tableName === 'pages' ? ‪$record['uid'] : ‪$record['pid']);
736  return $this->‪getBackendUser()->isInWebMount($tableName === 'pages' ? ‪$record : ‪$record['pid'])
737  || $recordPid === 0 && !empty(‪$GLOBALS['TCA'][$tableName]['ctrl']['security']['ignoreRootLevelRestriction']);
738  }
739 
741  {
742  return ‪$GLOBALS['LANG'];
743  }
744 
746  {
747  return ‪$GLOBALS['BE_USER'];
748  }
749 }
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository
Definition: MetaDataRepository.php:39
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getLanguageService
‪getLanguageService()
Definition: ElementInformationController.php:740
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getPropertiesForTable
‪getPropertiesForTable(ServerRequestInterface $request)
Definition: ElementInformationController.php:231
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:46
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\$row
‪array $row
Definition: ElementInformationController.php:60
‪TYPO3\CMS\Backend\Template\ModuleTemplateFactory
Definition: ModuleTemplateFactory.php:33
‪TYPO3\CMS\Backend\Backend\Avatar\Avatar
Definition: Avatar.php:35
‪TYPO3\CMS\Backend\Exception
Definition: Exception.php:24
‪TYPO3\CMS\Backend\Controller\ContentElement
Definition: ElementHistoryController.php:18
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getBackendUser
‪getBackendUser()
Definition: ElementInformationController.php:745
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\canAccessPage
‪canAccessPage(string $tableName, array $record)
Definition: ElementInformationController.php:733
‪TYPO3\CMS\Backend\Attribute\Controller
Definition: Controller.php:25
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getExtraFields
‪getExtraFields()
Definition: ElementInformationController.php:383
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController
Definition: ElementInformationController.php:54
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getPageTitle
‪getPageTitle()
Definition: ElementInformationController.php:156
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getLabelForTableColumn
‪string getLabelForTableColumn($tableName, $fieldName)
Definition: ElementInformationController.php:466
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getReferences
‪getReferences(ServerRequestInterface $request, int|string $uid)
Definition: ElementInformationController.php:440
‪TYPO3\CMS\Core\Resource\AbstractFile\FILETYPE_IMAGE
‪const FILETYPE_IMAGE
Definition: AbstractFile.php:81
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\makeRef
‪makeRef($table, $ref, ServerRequestInterface $request)
Definition: ElementInformationController.php:531
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Core\Resource\Folder\getParentFolder
‪getParentFolder()
Definition: Folder.php:511
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\$table
‪string $table
Definition: ElementInformationController.php:61
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\makeRefFrom
‪makeRefFrom($table, $ref, ServerRequestInterface $request)
Definition: ElementInformationController.php:628
‪TYPO3\CMS\Core\Resource\AbstractFile
Definition: AbstractFile.php:28
‪TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException
Definition: RouteNotFoundException.php:22
‪TYPO3\CMS\Backend\History\RecordHistory
Definition: RecordHistory.php:32
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder\create
‪static static create(int $pageId)
Definition: PreviewUriBuilder.php:65
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:26
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\$fileObject
‪File $fileObject
Definition: ElementInformationController.php:62
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:64
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\$type
‪string $type
Definition: ElementInformationController.php:58
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\__construct
‪__construct(protected readonly IconFactory $iconFactory, protected readonly UriBuilder $uriBuilder, protected readonly ModuleTemplateFactory $moduleTemplateFactory, protected readonly ResourceFactory $resourceFactory, private readonly FormDataCompiler $formDataCompiler,)
Definition: ElementInformationController.php:65
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\mainAction
‪mainAction(ServerRequestInterface $request)
Definition: ElementInformationController.php:78
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:35
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getFieldList
‪getFieldList(ServerRequestInterface $request, string $table, int $uid)
Definition: ElementInformationController.php:353
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getPreview
‪getPreview(ServerRequestInterface $request)
Definition: ElementInformationController.php:178
‪TYPO3\CMS\Webhooks\Message\$url
‪identifier readonly UriInterface $url
Definition: LoginErrorOccurredMessage.php:36
‪TYPO3\CMS\Core\Resource\Folder\getReadablePath
‪string getReadablePath($rootId=null)
Definition: Folder.php:100
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder
Definition: PreviewUriBuilder.php:44
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\$folderObject
‪Folder $folderObject
Definition: ElementInformationController.php:63
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:51
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Backend\Form\FormDataCompiler
Definition: FormDataCompiler.php:26
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\transformFileReferenceToRecordReference
‪transformFileReferenceToRecordReference(array $referenceRecord)
Definition: ElementInformationController.php:702
‪TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord
Definition: TcaDatabaseRecord.php:25
‪$rendererRegistry
‪$rendererRegistry
Definition: ext_localconf.php:41
‪TYPO3\CMS\Backend\Controller\ContentElement\ElementInformationController\getRecordActions
‪getRecordActions($table, $uid, ServerRequestInterface $request)
Definition: ElementInformationController.php:486
‪TYPO3\CMS\Core\Resource\Rendering\RendererRegistry
Definition: RendererRegistry.php:26