/** * Update index entry * * @param File $fileObject * @return void */ public function updateIndexEntry(File $fileObject) { $updatedInformation = $this->gatherFileInformationArray($fileObject->getIdentifier()); $fileObject->updateProperties($updatedInformation); $this->getFileIndexRepository()->update($fileObject); $this->extractRequiredMetaData($fileObject); }
/** * Render a thumbnail of a media * * @throws MissingTcaConfigurationException * @return string */ public function create() { if (empty($this->file)) { throw new MissingTcaConfigurationException('Missing File object. Forgotten to set a file?', 1355933144); } // Default class name $className = 'Fab\\Media\\Thumbnail\\FallBackThumbnailProcessor'; if (File::FILETYPE_IMAGE == $this->file->getType()) { $className = 'Fab\\Media\\Thumbnail\\ImageThumbnailProcessor'; } elseif (File::FILETYPE_AUDIO == $this->file->getType()) { $className = 'Fab\\Media\\Thumbnail\\AudioThumbnailProcessor'; } elseif (File::FILETYPE_VIDEO == $this->file->getType()) { $className = 'Fab\\Media\\Thumbnail\\VideoThumbnailProcessor'; } elseif (File::FILETYPE_APPLICATION == $this->file->getType() || File::FILETYPE_TEXT == $this->file->getType()) { $className = 'Fab\\Media\\Thumbnail\\ApplicationThumbnailProcessor'; } /** @var $processorInstance \Fab\Media\Thumbnail\ThumbnailProcessorInterface */ $processorInstance = GeneralUtility::makeInstance($className); $thumbnail = ''; if ($this->file->exists()) { $thumbnail = $processorInstance->setThumbnailService($this)->create(); } else { $logger = Logger::getInstance($this); $logger->warning(sprintf('Resource not found for File uid "%s" at %s', $this->file->getUid(), $this->file->getIdentifier())); } return $thumbnail; }
/** * Renders a HTML Block with file information * * @param File $file * @return string */ protected function renderFileInformationContent(File $file = null) { /** @var LanguageService $lang */ $lang = $GLOBALS['LANG']; if ($file !== null) { $processedFile = $file->process(ProcessedFile::CONTEXT_IMAGEPREVIEW, ['width' => 150, 'height' => 150]); $previewImage = $processedFile->getPublicUrl(true); $content = ''; if ($file->isMissing()) { $content .= '<span class="label label-danger label-space-right">' . htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:warning.file_missing')) . '</span>'; } if ($previewImage) { $content .= '<img src="' . htmlspecialchars($previewImage) . '" ' . 'width="' . $processedFile->getProperty('width') . '" ' . 'height="' . $processedFile->getProperty('height') . '" ' . 'alt="" class="t3-tceforms-sysfile-imagepreview" />'; } $content .= '<strong>' . htmlspecialchars($file->getName()) . '</strong>'; $content .= ' (' . htmlspecialchars(GeneralUtility::formatSize($file->getSize())) . 'bytes)<br />'; $content .= BackendUtility::getProcessedValue('sys_file', 'type', $file->getType()) . ' (' . $file->getMimeType() . ')<br />'; $content .= htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_misc.xlf:fileMetaDataLocation')) . ': '; $content .= htmlspecialchars($file->getStorage()->getName()) . ' - ' . htmlspecialchars($file->getIdentifier()) . '<br />'; $content .= '<br />'; } else { $content = '<h2>' . htmlspecialchars($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_misc.xlf:fileMetaErrorInvalidRecord')) . '</h2>'; } return $content; }
/** * get the identifier of the file * if there is no processed file in the file system (as the original file did not have to be modified e.g. * when the original image is in the boundaries of the maxW/maxH stuff) * then just return the identifier of the original file * * @return string */ public function getIdentifier() { if ($this->identifier) { return $this->identifier; } else { return $this->originalFile->getIdentifier(); } }
/** * Initialize * * @throws \TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException */ protected function init() { // Initialize GPvars: $this->target = GeneralUtility::_GP('target'); $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl')); // Cleaning and checking target if ($this->target) { $this->fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->target); } if (!$this->fileOrFolderObject) { $title = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_mod_file_list.xlf:paramError', TRUE); $message = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_mod_file_list.xlf:targetNoDir', TRUE); throw new \RuntimeException($title . ': ' . $message, 1294586844); } if ($this->fileOrFolderObject->getStorage()->getUid() === 0) { throw new \TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException('You are not allowed to access files outside your storages', 1375889840); } // If a folder should be renamed, AND the returnURL should go to the old directory name, the redirect is forced // so the redirect will NOT end in a error message // this case only happens if you select the folder itself in the foldertree and then use the clickmenu to // rename the folder if ($this->fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\Folder) { $parsedUrl = parse_url($this->returnUrl); $queryParts = GeneralUtility::explodeUrl2Array(urldecode($parsedUrl['query'])); if ($queryParts['id'] === $this->fileOrFolderObject->getCombinedIdentifier()) { $this->returnUrl = str_replace(urlencode($queryParts['id']), urlencode($this->fileOrFolderObject->getStorage()->getRootLevelFolder()->getCombinedIdentifier()), $this->returnUrl); } } // Setting icon and title $icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('apps-filetree-root'); $this->title = $icon . htmlspecialchars($this->fileOrFolderObject->getStorage()->getName()) . ': ' . htmlspecialchars($this->fileOrFolderObject->getIdentifier()); // Setting template object $this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class); $this->doc->setModuleTemplate('EXT:backend/Resources/Private/Templates/file_rename.html'); $this->doc->backPath = $GLOBALS['BACK_PATH']; $this->doc->JScode = $this->doc->wrapScriptTags(' function backToList() { // top.goToModule("file_list"); } '); }
/** * Creates the edit control section * * @param File|Folder $fileOrFolderObject Array with information about the file/directory for which to make the edit control section for the listing. * @return string HTML-table */ public function makeEdit($fileOrFolderObject) { $cells = array(); $fullIdentifier = $fileOrFolderObject->getCombinedIdentifier(); // Edit file content (if editable) if ($fileOrFolderObject instanceof File && $fileOrFolderObject->checkActionPermission('write') && GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'], $fileOrFolderObject->getExtension())) { $url = BackendUtility::getModuleUrl('file_edit', array('target' => $fullIdentifier)); $editOnClick = 'top.content.list_frame.location.href=' . GeneralUtility::quoteJSvalue($url) . '+\'&returnUrl=\'+top.rawurlencode(top.content.list_frame.document.location.pathname+top.content.list_frame.document.location.search);return false;'; $cells['edit'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($editOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.editcontent') . '">' . IconUtility::getSpriteIcon('actions-page-open') . '</a>'; } else { $cells['edit'] = $this->spaceIcon; } if ($fileOrFolderObject instanceof File) { $fileUrl = $fileOrFolderObject->getPublicUrl(TRUE); if ($fileUrl) { $aOnClick = 'return top.openUrlInWindow(' . GeneralUtility::quoteJSvalue($fileUrl) . ', \'WebFile\');'; $cells['view'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($aOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.view') . '">' . IconUtility::getSpriteIcon('actions-document-view') . '</a>'; } else { $cells['view'] = $this->spaceIcon; } } else { $cells['view'] = $this->spaceIcon; } // rename the file if ($fileOrFolderObject->checkActionPermission('rename')) { $url = BackendUtility::getModuleUrl('file_rename', array('target' => $fullIdentifier)); $renameOnClick = 'top.content.list_frame.location.href = ' . GeneralUtility::quoteJSvalue($url) . '+\'&returnUrl=\'+top.rawurlencode(top.content.list_frame.document.location.pathname+top.content.list_frame.document.location.search);return false;'; $cells['rename'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($renameOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.rename') . '">' . IconUtility::getSpriteIcon('actions-edit-rename') . '</a>'; } else { $cells['rename'] = $this->spaceIcon; } if ($fileOrFolderObject->checkActionPermission('read')) { $infoOnClick = ''; if ($fileOrFolderObject instanceof Folder) { $infoOnClick = 'top.launchView( \'_FOLDER\', ' . GeneralUtility::quoteJSvalue($fullIdentifier) . ');return false;'; } elseif ($fileOrFolderObject instanceof File) { $infoOnClick = 'top.launchView( \'_FILE\', ' . GeneralUtility::quoteJSvalue($fullIdentifier) . ');return false;'; } $cells['info'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($infoOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.info') . '">' . IconUtility::getSpriteIcon('status-dialog-information') . '</a>'; } else { $cells['info'] = $this->spaceIcon; } // delete the file if ($fileOrFolderObject->checkActionPermission('delete')) { $identifier = $fileOrFolderObject->getIdentifier(); if ($fileOrFolderObject instanceof Folder) { $referenceCountText = BackendUtility::referenceCount('_FILE', $identifier, ' (There are %s reference(s) to this folder!)'); } else { $referenceCountText = BackendUtility::referenceCount('sys_file', $fileOrFolderObject->getUid(), ' (There are %s reference(s) to this file!)'); } if ($this->getBackendUser()->jsConfirmation(JsConfirmation::DELETE)) { $confirmationCheck = 'confirm(' . GeneralUtility::quoteJSvalue(sprintf($this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:mess.delete'), $fileOrFolderObject->getName()) . $referenceCountText) . ')'; } else { $confirmationCheck = '1 == 1'; } $removeOnClick = 'if (' . $confirmationCheck . ') { top.content.list_frame.location.href=' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('tce_file') . '&file[delete][0][data]=' . rawurlencode($fileOrFolderObject->getCombinedIdentifier()) . '&vC=' . $this->getBackendUser()->veriCode() . BackendUtility::getUrlToken('tceAction') . '&redirect=') . '+top.rawurlencode(top.content.list_frame.document.location.pathname+top.content.list_frame.document.location.search);};'; $cells['delete'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($removeOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:cm.delete') . '">' . IconUtility::getSpriteIcon('actions-edit-delete') . '</a>'; } else { $cells['delete'] = $this->spaceIcon; } // Hook for manipulating edit icons. if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['fileList']['editIconsHook'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['fileList']['editIconsHook'] as $classData) { $hookObject = GeneralUtility::getUserObj($classData); if (!$hookObject instanceof FileListEditIconHookInterface) { throw new \UnexpectedValueException('$hookObject must implement interface \\TYPO3\\CMS\\Filelist\\FileListEditIconHookInterface', 1235225797); } $hookObject->manipulateEditIcons($cells, $this); } } // Compile items into a DIV-element: return '<div class="btn-group">' . implode('', $cells) . '</div>'; }
/** * @return bool */ public function usesOriginalFile() { return $this->identifier == null || $this->identifier === $this->originalFile->getIdentifier(); }
/** * Returns an index record of a file, or FALSE if the file is not indexed. * * @TODO : throw an exception if nothing found, for consistent handling as in AbstractRepository? * @param \TYPO3\CMS\Core\Resource\File $fileObject * @return bool|array */ public function getFileIndexRecord(\TYPO3\CMS\Core\Resource\File $fileObject) { $storageUid = $fileObject->getStorage()->getUid(); $identifier = $fileObject->getIdentifier(); $row = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', $this->table, sprintf('storage=%u AND identifier=%s', $storageUid, $GLOBALS['TYPO3_DB']->fullQuoteStr($identifier, $this->table))); if (!is_array($row)) { return FALSE; } else { return $row; } }
/** * Returns the identifier of the underlying original file * * @return string */ public function getIdentifier() { return $this->originalFile->getIdentifier(); }
/** * Checks the index status of a file and returns FALSE if the file is not * indexed, the uid otherwise. * * @param File $fileObject * @return boolean|integer * @deprecated since TYPO3 6.2, will be removed two versions later - use FileIndexRepository::isIndexed */ public function getFileIndexStatus(File $fileObject) { GeneralUtility::logDeprecatedFunction(); $storageUid = $fileObject->getStorage()->getUid(); $identifier = $fileObject->getIdentifier(); $row = $this->getFileIndexRepository()->findOneByStorageUidAndIdentifier($storageUid, $identifier); return is_array($row) ? $row['uid'] : FALSE; }
/** * get the file data as array * * @param \TYPO3\CMS\Core\Resource\File $resourceObject * * @return array */ protected function getFileData($resourceObject) { $fileData = array('identifier' => $resourceObject->getIdentifier(), 'modDate' => $resourceObject->_getPropertyRaw('modification_date'), 'extension' => $resourceObject->getExtension()); return $fileData; }
/** * Getter function to return the the file's corresponding hashed subfolder * of the processed folder * * @param File $file * @param Folder $rootProcessingFolder * @return Folder * @throws Exception\InsufficientFolderWritePermissionsException */ protected function getNestedProcessingFolder(File $file, Folder $rootProcessingFolder) { $processingFolder = $rootProcessingFolder; $nestedFolderNames = $this->getNamesForNestedProcessingFolder($file->getIdentifier(), self::PROCESSING_FOLDER_LEVELS); try { foreach ($nestedFolderNames as $folderName) { if ($processingFolder->hasFolder($folderName)) { $processingFolder = $processingFolder->getSubfolder($folderName); } else { $currentEvaluatePermissions = $processingFolder->getStorage()->getEvaluatePermissions(); $processingFolder->getStorage()->setEvaluatePermissions(false); $processingFolder = $processingFolder->createFolder($folderName); $processingFolder->getStorage()->setEvaluatePermissions($currentEvaluatePermissions); } } } catch (Exception\FolderDoesNotExistException $e) { } return $processingFolder; }
/** * Handle file upload for an existing file. * * @param File $file * @return string */ public function updateAction(File $file) { $uploadedFile = $this->handleUpload(); if (!is_object($uploadedFile)) { return htmlspecialchars(json_encode($uploadedFile), ENT_NOQUOTES); } /** @var $file File */ $targetFolder = $file->getStorage()->getFolder(dirname($file->getIdentifier())); try { $storage = $file->getStorage(); $storage->replaceFile($file, $uploadedFile->getFileWithAbsolutePath()); // Run the indexer for extracting metadata. $this->getMediaIndexer($file->getStorage())->updateIndex($file)->extractMetadata($file); // Clear cache on pages holding a reference to this file. $this->getCacheService()->clearCache($file); $response = array('success' => TRUE, 'uid' => $file->getUid(), 'name' => $file->getName(), 'thumbnail' => $this->getThumbnailService($file)->create(), 'fileInfo' => $this->getMetadataViewHelper()->render($file)); } catch (UploadException $e) { $response = array('error' => 'The upload has failed, no uploaded file found!'); } catch (InsufficientUserPermissionsException $e) { $response = array('error' => 'You are not allowed to upload files!'); } catch (UploadSizeException $e) { $response = array('error' => vsprintf('The uploaded file "%s" exceeds the size-limit', array($uploadedFile->getName()))); } catch (InsufficientFolderWritePermissionsException $e) { $response = array('error' => vsprintf('Destination path "%s" was not within your mount points!', array($targetFolder->getIdentifier()))); } catch (IllegalFileExtensionException $e) { $response = array('error' => vsprintf('Extension of file name "%s" is not allowed in "%s"!', array($uploadedFile->getName(), $targetFolder->getIdentifier()))); } catch (ExistingTargetFileNameException $e) { $response = array('error' => vsprintf('No unique filename available in "%s"!', array($targetFolder->getIdentifier()))); } catch (\RuntimeException $e) { $response = array('error' => vsprintf('Uploaded file could not be moved! Write-permission problem in "%s"?', array($targetFolder->getIdentifier()))); } // to pass data through iframe you will need to encode all html tags header("Content-Type: text/plain"); return htmlspecialchars(json_encode($response), ENT_NOQUOTES); }
/** * Creates the edit control section * * @param File|Folder $fileOrFolderObject Array with information about the file/directory for which to make the edit control section for the listing. * @return string HTML-table */ public function makeEdit($fileOrFolderObject) { $cells = []; $fullIdentifier = $fileOrFolderObject->getCombinedIdentifier(); // Edit file content (if editable) if ($fileOrFolderObject instanceof File && $fileOrFolderObject->checkActionPermission('write') && GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'], $fileOrFolderObject->getExtension())) { $url = BackendUtility::getModuleUrl('file_edit', ['target' => $fullIdentifier]); $editOnClick = 'top.list_frame.location.href=' . GeneralUtility::quoteJSvalue($url) . '+\'&returnUrl=\'+top.rawurlencode(top.list_frame.document.location.pathname+top.list_frame.document.location.search);return false;'; $cells['edit'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($editOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.editcontent') . '">' . $this->iconFactory->getIcon('actions-page-open', Icon::SIZE_SMALL)->render() . '</a>'; } else { $cells['edit'] = $this->spaceIcon; } if ($fileOrFolderObject instanceof File) { $fileUrl = $fileOrFolderObject->getPublicUrl(true); if ($fileUrl) { $aOnClick = 'return top.openUrlInWindow(' . GeneralUtility::quoteJSvalue($fileUrl) . ', \'WebFile\');'; $cells['view'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($aOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.view') . '">' . $this->iconFactory->getIcon('actions-document-view', Icon::SIZE_SMALL)->render() . '</a>'; } else { $cells['view'] = $this->spaceIcon; } } else { $cells['view'] = $this->spaceIcon; } // replace file if ($fileOrFolderObject instanceof File && $fileOrFolderObject->checkActionPermission('replace')) { $url = BackendUtility::getModuleUrl('file_replace', ['target' => $fullIdentifier, 'uid' => $fileOrFolderObject->getUid()]); $replaceOnClick = 'top.list_frame.location.href = ' . GeneralUtility::quoteJSvalue($url) . '+\'&returnUrl=\'+top.rawurlencode(top.list_frame.document.location.pathname+top.list_frame.document.location.search);return false;'; $cells['replace'] = '<a href="#" class="btn btn-default" onclick="' . $replaceOnClick . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.replace') . '">' . $this->iconFactory->getIcon('actions-edit-replace', Icon::SIZE_SMALL)->render() . '</a>'; } // rename the file if ($fileOrFolderObject->checkActionPermission('rename')) { $url = BackendUtility::getModuleUrl('file_rename', ['target' => $fullIdentifier]); $renameOnClick = 'top.list_frame.location.href = ' . GeneralUtility::quoteJSvalue($url) . '+\'&returnUrl=\'+top.rawurlencode(top.list_frame.document.location.pathname+top.list_frame.document.location.search);return false;'; $cells['rename'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($renameOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.rename') . '">' . $this->iconFactory->getIcon('actions-edit-rename', Icon::SIZE_SMALL)->render() . '</a>'; } else { $cells['rename'] = $this->spaceIcon; } if ($fileOrFolderObject->checkActionPermission('read')) { $infoOnClick = ''; if ($fileOrFolderObject instanceof Folder) { $infoOnClick = 'top.launchView( \'_FOLDER\', ' . GeneralUtility::quoteJSvalue($fullIdentifier) . ');return false;'; } elseif ($fileOrFolderObject instanceof File) { $infoOnClick = 'top.launchView( \'_FILE\', ' . GeneralUtility::quoteJSvalue($fullIdentifier) . ');return false;'; } $cells['info'] = '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($infoOnClick) . '" title="' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.info') . '">' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . '</a>'; } else { $cells['info'] = $this->spaceIcon; } // delete the file if ($fileOrFolderObject->checkActionPermission('delete')) { $identifier = $fileOrFolderObject->getIdentifier(); if ($fileOrFolderObject instanceof Folder) { $referenceCountText = BackendUtility::referenceCount('_FILE', $identifier, ' ' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.referencesToFolder')); $deleteType = 'delete_folder'; } else { $referenceCountText = BackendUtility::referenceCount('sys_file', $fileOrFolderObject->getUid(), ' ' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.referencesToFile')); $deleteType = 'delete_file'; } if ($this->getBackendUser()->jsConfirmation(JsConfirmation::DELETE)) { $confirmationCheck = '1'; } else { $confirmationCheck = '0'; } $deleteUrl = BackendUtility::getModuleUrl('tce_file'); $confirmationMessage = sprintf($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:mess.delete'), $fileOrFolderObject->getName()) . $referenceCountText; $title = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.delete'); $cells['delete'] = '<a href="#" class="btn btn-default t3js-filelist-delete" data-content="' . htmlspecialchars($confirmationMessage) . '" data-check="' . $confirmationCheck . '" data-delete-url="' . htmlspecialchars($deleteUrl) . '" data-title="' . htmlspecialchars($title) . '" data-identifier="' . htmlspecialchars($fileOrFolderObject->getCombinedIdentifier()) . '" data-veri-code="' . $this->getBackendUser()->veriCode() . '" data-delete-type="' . $deleteType . '" title="' . htmlspecialchars($title) . '">' . $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() . '</a>'; } else { $cells['delete'] = $this->spaceIcon; } // Hook for manipulating edit icons. if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['fileList']['editIconsHook'])) { $cells['__fileOrFolderObject'] = $fileOrFolderObject; foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['fileList']['editIconsHook'] as $classData) { $hookObject = GeneralUtility::getUserObj($classData); if (!$hookObject instanceof FileListEditIconHookInterface) { throw new \UnexpectedValueException($classData . ' must implement interface ' . FileListEditIconHookInterface::class, 1235225797); } $hookObject->manipulateEditIcons($cells, $this); } unset($cells['__fileOrFolderObject']); } // Compile items into a DIV-element: return '<div class="btn-group">' . implode('', $cells) . '</div>'; }