diff --git a/typo3/sysext/backend/Classes/Controller/ContentElement/ElementInformationController.php b/typo3/sysext/backend/Classes/Controller/ContentElement/ElementInformationController.php index 7ca3b597ad9d3b1b33307c0f21f1a1a59b72ef4f..57b7b29efe39927081e22b8fcf75cbab7a4299a6 100644 --- a/typo3/sysext/backend/Classes/Controller/ContentElement/ElementInformationController.php +++ b/typo3/sysext/backend/Classes/Controller/ContentElement/ElementInformationController.php @@ -35,6 +35,7 @@ use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Resource\AbstractFile; use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Resource\Folder; +use TYPO3\CMS\Core\Resource\Index\MetaDataRepository; use TYPO3\CMS\Core\Resource\Rendering\RendererRegistry; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Type\Bitmask\Permission; @@ -342,89 +343,130 @@ class ElementInformationController */ protected function getPropertiesForTable(): array { - $propertiesForTable = []; $lang = $this->getLanguageService(); + $propertiesForTable = []; + $propertiesForTable['extraFields'] = $this->getExtraFields(); - $extraFields = [ - 'uid' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.uid')) - ]; + // Traverse the list of fields to display for the record: + $fieldList = $this->getFieldList($this->table, (int)$this->row['uid']); - if (in_array($this->type, ['folder', 'file'], true)) { - if ($this->type === 'file') { - $extraFields['creation_date'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationDate')); - $extraFields['modification_date'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.timestamp')); - if ($this->fileObject->getType() === AbstractFile::FILETYPE_IMAGE) { - $extraFields['width'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.width')); - $extraFields['height'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.height')); - } + foreach ($fieldList as $name) { + $name = trim($name); + $uid = $this->row['uid']; + + if (!isset($GLOBALS['TCA'][$this->table]['columns'][$name])) { + continue; } - $extraFields['storage'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file.storage')); - $extraFields['folder'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:folder')); - } else { - $extraFields['crdate'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationDate')); - $extraFields['cruser_id'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationUserId')); - $extraFields['tstamp'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.timestamp')); - - // check if the special fields are defined in the TCA ctrl section of the table - foreach ($extraFields as $fieldName => $fieldLabel) { - if (isset($GLOBALS['TCA'][$this->table]['ctrl'][$fieldName])) { - $extraFields[$GLOBALS['TCA'][$this->table]['ctrl'][$fieldName]] = $fieldLabel; - } elseif ($fieldName !== 'uid') { - unset($extraFields[$fieldName]); - } + + // not a real field -> skip + if ($this->type === 'file' && $name === 'fileinfo') { + continue; } + + $isExcluded = !(!$GLOBALS['TCA'][$this->table]['columns'][$name]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', $this->table . ':' . $name)); + if ($isExcluded) { + continue; + } + $label = $lang->sL(BackendUtility::getItemLabel($this->table, $name)); + $label = $label ?: $name; + + $propertiesForTable['fields'][] = [ + 'fieldValue' => BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, 0, false, $uid), + 'fieldLabel' => htmlspecialchars($label) + ]; } - foreach ($extraFields as $name => $fieldLabel) { - $rowValue = ''; - $thisRow = []; - if (!isset($this->row[$name])) { - $resourceObject = $this->fileObject ?: $this->folderObject; - if ($name === 'storage') { - $rowValue = $resourceObject->getStorage()->getName(); - } elseif ($name === 'folder') { - $rowValue = $resourceObject->getParentFolder()->getReadablePath(); - } elseif ($name === 'width') { - $rowValue = $this->fileObject->getProperty('width') . 'px'; - } elseif ($name === 'height') { - $rowValue = $this->fileObject->getProperty('height') . 'px'; - } - } elseif ($name === 'creation_date' || $name === 'modification_date' || $name === 'tstamp' || $name === 'crdate') { - $rowValue = BackendUtility::datetime($this->row[$name]); - } else { - $rowValue = BackendUtility::getProcessedValueExtra($this->table, $name, $this->row[$name]); + // additional information for folders and files + if ($this->folderObject instanceof Folder || $this->fileObject instanceof File) { + // storage + if ($this->folderObject instanceof Folder) { + $propertiesForTable['fields']['storage'] = [ + 'fieldValue' => $this->folderObject->getStorage()->getName(), + 'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file.storage')) + ]; } - $thisRow['value'] = $rowValue; - $thisRow['fieldLabel'] = rtrim($fieldLabel, ':'); - // show the backend username who created the issue - if ($name === 'cruser_id' && $rowValue) { - $creatorRecord = BackendUtility::getRecord('be_users', $rowValue); - if ($creatorRecord) { - /** @var Avatar $avatar */ - $avatar = GeneralUtility::makeInstance(Avatar::class); - $creatorRecord['icon'] = $avatar->render($creatorRecord); - $thisRow['creatorRecord'] = $creatorRecord; - $thisRow['value'] = ''; + + // folder + $resourceObject = $this->fileObject ?: $this->folderObject; + $propertiesForTable['fields']['folder'] = [ + 'fieldValue' => $resourceObject->getParentFolder()->getReadablePath(), + 'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:folder')) + ]; + + if ($this->fileObject instanceof File) { + // show file dimensions for images + if ($this->fileObject->getType() === AbstractFile::FILETYPE_IMAGE) { + $propertiesForTable['fields']['width'] = [ + 'fieldValue' => $this->fileObject->getProperty('width') . 'px', + 'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.width')) + ]; + $propertiesForTable['fields']['height'] = [ + 'fieldValue' => $this->fileObject->getProperty('height') . 'px', + 'fieldLabel' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.height')) + ]; + } + + // file size + $propertiesForTable['fields']['size'] = [ + 'fieldValue' => GeneralUtility::formatSize((int)$this->fileObject->getProperty('size'), htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:byteSizeUnits'))), + 'fieldLabel' => $lang->sL(BackendUtility::getItemLabel($this->table, 'size')) + ]; + + // show the metadata of a file as well + $table = 'sys_file_metadata'; + $metaDataRepository = GeneralUtility::makeInstance(MetaDataRepository::class); + $metaData = $metaDataRepository->findByFileUid($this->row['uid']); + $allowedFields = $this->getFieldList($table, (int)$metaData['uid']); + + foreach ($metaData as $name => $value) { + if (in_array($name, $allowedFields, true)) { + if (!isset($GLOBALS['TCA'][$table]['columns'][$name])) { + continue; + } + + $isExcluded = !(!$GLOBALS['TCA'][$table]['columns'][$name]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', $table . ':' . $name)); + if ($isExcluded) { + continue; + } + + $label = $lang->sL(BackendUtility::getItemLabel($table, $name)); + $label = $label ?: $name; + + $propertiesForTable['fields'][] = [ + 'fieldValue' => BackendUtility::getProcessedValue($table, $name, $metaData[$name], 0, 0, false, $metaData['uid']), + 'fieldLabel' => htmlspecialchars($label) + ]; + } } } - $propertiesForTable['extraFields'][$name] = $thisRow; } - // Traverse the list of fields to display for the record: + return $propertiesForTable; + } + + /** + * Get the list of fields that should be shown for the given table + * + * @param string $table + * @param int $uid + * @return array + */ + protected function getFieldList(string $table, int $uid): array + { $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class); $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup); $formDataCompilerInput = [ 'command' => 'edit', - 'tableName' => $this->table, - 'vanillaUid' => (int)$this->row['uid'], + 'tableName' => $table, + 'vanillaUid' => $uid, ]; try { $result = $formDataCompiler->compile($formDataCompilerInput); $fieldList = array_unique(array_values($result['columnsToProcess'])); - $ctrlKeysOfUneededFields = ['origUid', 'transOrigPointerField', 'transOrigDiffSourceField']; - foreach ($ctrlKeysOfUneededFields as $field) { - if (($key = array_search($GLOBALS['TCA'][$this->table]['ctrl'][$field], $fieldList)) !== false) { + $ctrlKeysOfUnneededFields = ['origUid', 'transOrigPointerField', 'transOrigDiffSourceField']; + foreach ($ctrlKeysOfUnneededFields as $field) { + if (($key = array_search($GLOBALS['TCA'][$table]['ctrl'][$field], $fieldList, true)) !== false) { unset($fieldList[$key]); } } @@ -432,37 +474,67 @@ class ElementInformationController $fieldList = []; } - foreach ($fieldList as $name) { - $thisRow = []; - $name = trim($name); - $uid = $this->row['uid']; + $searchFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['ctrl']['searchFields']); - if (!isset($GLOBALS['TCA'][$this->table]['columns'][$name])) { - continue; - } + return array_unique(array_merge($fieldList, $searchFields)); + } - // Storage is already handled above - if ($this->type === 'file' && $name === 'storage') { - continue; - } + /** + * Get the extra fields (uid, timestamps, creator) for the table + * + * @return array + */ + protected function getExtraFields(): array + { + $lang = $this->getLanguageService(); + $keyLabelPair = []; + $extraFields = [ + 'uid' => htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.uid')) + ]; - // format file size as bytes/kilobytes/megabytes - if ($this->type === 'file' && $name === 'size') { - $this->row[$name] = GeneralUtility::formatSize($this->row[$name], htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:byteSizeUnits'))); + if (in_array($this->type, ['folder', 'file'], true)) { + if ($this->type === 'file') { + $extraFields['creation_date'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.creationDate')); + $extraFields['modification_date'] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.timestamp')); } - - $isExcluded = !(!$GLOBALS['TCA'][$this->table]['columns'][$name]['exclude'] || $this->getBackendUser()->check('non_exclude_fields', $this->table . ':' . $name)); - if ($isExcluded) { - continue; + } else { + foreach (['crdate' => 'creationDate', 'tstamp' => 'timestamp', 'cruser_id' => 'creationUserId'] as $field => $label) { + if (isset($GLOBALS['TCA'][$this->table]['ctrl'][$field])) { + $extraFields[$GLOBALS['TCA'][$this->table]['ctrl'][$field]] = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.' . $label)); + } } - $label = $lang->sL(BackendUtility::getItemLabel($this->table, $name)); - $label = $label ?: $name; + } - $thisRow['fieldValue'] = BackendUtility::getProcessedValue($this->table, $name, $this->row[$name], 0, 0, false, $uid); - $thisRow['fieldLabel'] = htmlspecialchars($label); - $propertiesForTable['fields'][] = $thisRow; + foreach ($extraFields as $name => $fieldLabel) { + if (in_array($name, ['creation_date', 'modification_date', 'tstamp', 'crdate'], true)) { + $rowValue = BackendUtility::datetime($this->row[$name]); + $keyLabelPair[$name] = [ + 'value' => $rowValue, + 'fieldLabel' => rtrim($fieldLabel, ':'), + 'isDatetime' => true, + ]; + } else { + $rowValue = BackendUtility::getProcessedValueExtra($this->table, $name, $this->row[$name]); + + // show the backend username who created the issue + if ($name === 'cruser_id' && $rowValue) { + $creatorRecord = BackendUtility::getRecord('be_users', $rowValue); + if ($creatorRecord) { + /** @var Avatar $avatar */ + $avatar = GeneralUtility::makeInstance(Avatar::class); + $creatorRecord['icon'] = $avatar->render($creatorRecord); + $name = 'creatorRecord'; + $rowValue = $creatorRecord; + } + } + $keyLabelPair[$name] = [ + 'value' => $rowValue, + 'fieldLabel' => rtrim($fieldLabel, ':'), + ]; + } } - return $propertiesForTable; + + return $keyLabelPair; } /** diff --git a/typo3/sysext/backend/Resources/Private/Templates/ContentElement/ElementInformation.html b/typo3/sysext/backend/Resources/Private/Templates/ContentElement/ElementInformation.html index f23df6224b07c8dec48ed95d152430cbcab4b8d0..fe2264e1d48eff38ddfb0b0f0df807c2c7bace2a 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ContentElement/ElementInformation.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ContentElement/ElementInformation.html @@ -18,29 +18,25 @@ <div class="card-content"> <div class="row"> - <f:if condition="{extraFields.crdate}"> - <div class="col-md-6"> - <strong>{extraFields.crdate.fieldLabel}</strong><br> - {extraFields.crdate.value} - </div> - </f:if> - <f:if condition="{extraFields.tstamp}"> - <div class="col-md-6"> - <strong>{extraFields.tstamp.fieldLabel}</strong><br> - {extraFields.tstamp.value} - </div> - </f:if> + <f:for each="{extraFields}" as="extraField"> + <f:if condition="{extraField.isDatetime}"> + <div class="col-md-6"> + <strong>{extraField.fieldLabel}</strong><br> + {extraField.value} + </div> + </f:if> + </f:for> </div> - <f:if condition="{extraFields.cruser_id.creatorRecord}"> + <f:if condition="{extraFields.creatorRecord}"> <div class="row"> <div class="col-md-12"> <div class="media"> <div class="media-left"> - {extraFields.cruser_id.creatorRecord.icon -> f:format.raw()} + {extraFields.creatorRecord.value.icon -> f:format.raw()} </div> <div class="media-body"> - <strong>{extraFields.cruser_id.creatorRecord.username}</strong><br> - {extraFields.cruser_id.creatorRecord.realName} + <strong>{extraFields.creatorRecord.value.username}</strong><br> + {extraFields.creatorRecord.value.realName} </div> </div> </div>