checkFileWriteAccessForFileMetaData($existingFileMetadataRecord) ? 1 : 0; } return $accessAllowed; } /** * Hook that determines whether a user has access to modify a table. * We "abuse" it here to actually check if access is allowed to sys_file_metadata. * * @param bool $accessAllowed Whether the user has access to modify a table * @param string $table The name of the table to be modified */ public function checkModifyAccessList(&$accessAllowed, $table, DataHandler $parent): void { if ($table !== 'sys_file_metadata') { return; } foreach (($parent->cmdmap['sys_file_metadata'] ?? []) as $id => $command) { $fileMetadataRecord = (array)BackendUtility::getRecord('sys_file_metadata', (int)$id); $accessAllowed = $this->checkFileWriteAccessForFileMetaData($fileMetadataRecord); if (!$accessAllowed) { // If for any item in the array, access is not allowed, we deny the whole operation break; } } if (isset($parent->datamap[$table])) { foreach ($parent->datamap[$table] as $id => $data) { $recordAccessAllowed = false; if (!str_contains((string)$id, 'NEW')) { $fileMetadataRecord = BackendUtility::getRecord('sys_file_metadata', (int)$id); if ($fileMetadataRecord !== null) { if ($parent->isImporting && empty($fileMetadataRecord['file'])) { // When importing the record was added with an empty file relation as first step $recordAccessAllowed = true; } else { $recordAccessAllowed = $this->checkFileWriteAccessForFileMetaData($fileMetadataRecord); } } } else { // For new records record access is allowed $recordAccessAllowed = true; } if (isset($data['file'])) { if ($parent->isImporting && empty($data['file'])) { // When importing the record will be created with an empty file relation as first step $dataAccessAllowed = true; } elseif (empty($data['file'])) { $dataAccessAllowed = false; } else { $dataAccessAllowed = $this->checkFileWriteAccessForFileMetaData($data); } } else { $dataAccessAllowed = true; } if (!$recordAccessAllowed || !$dataAccessAllowed) { // If for any item in the array, access is not allowed, we deny the whole operation $accessAllowed = false; break; } } } } /** * Deny access to the edit form. This is not mandatory, but better to show this right away that access is denied. */ #[AsEventListener('evaluate-file-meta-data-edit-form-access')] public function isAllowedToShowEditForm(ModifyEditFormUserAccessEvent $event): void { if (!$event->doesUserHaveAccess() || $event->getTableName() !== 'sys_file_metadata' || $event->getCommand() !== 'edit') { return; } $this->checkFileWriteAccessForFileMetaData( (array)BackendUtility::getRecord('sys_file_metadata', (int)($event->getDatabaseRow()['uid'] ?? 0)) ) ? $event->allowUserAccess() : $event->denyUserAccess(); } /** * Checks write access to the file belonging to a metadata entry */ protected function checkFileWriteAccessForFileMetaData(array $fileMetadataRecord): bool { if (empty($fileMetadataRecord['file'])) { return false; } $file = $fileMetadataRecord['file']; if (str_contains($file, 'sys_file_')) { // The file relation could be written as sys_file_[uid], strip this off before checking access rights $file = substr($file, strlen('sys_file_')); } $fileObject = $this->resourceFactory->getFileObject((int)$file); return $fileObject->checkActionPermission('editMeta'); } }