From 0a279c25a6f74fe6cf7f2ad4378550beee74c35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Sch=C3=B6lzel?= Date: Mon, 30 Dec 2024 17:13:38 +0100 Subject: [PATCH] [BUGFIX] MIME Type Filter --- Classes/Common/Helper.php | 41 +++++++++++++++-------- Classes/Controller/PageViewController.php | 5 +-- Classes/Controller/ToolboxController.php | 4 +-- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Classes/Common/Helper.php b/Classes/Common/Helper.php index d1f182944..82441e0fc 100644 --- a/Classes/Common/Helper.php +++ b/Classes/Common/Helper.php @@ -26,6 +26,7 @@ use TYPO3\CMS\Core\Messaging\FlashMessageService; use TYPO3\CMS\Core\Messaging\FlashMessageQueue; use TYPO3\CMS\Core\Resource\MimeTypeCollection; +use TYPO3\CMS\Core\Resource\MimeTypeDetector; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; @@ -945,26 +946,29 @@ private static function getLocalConfigurationByPath(string $path) } /** - * Filters a file based on its mimetype categories. + * Filters a file based on its mimetype. * * This method checks if the provided file array contains a specified mimetype key and - * verifies if the mimetype belongs to any of the specified categories or matches any of the additional custom mimetypes. + * verifies if the mimetype belongs to any of the allowed mimetypes or matches any of the additional custom mimetypes. * - * @param mixed $file The file array to filter - * @param array $categories The MIME type categories to filter by (e.g., ['audio'], ['video'] or ['image', 'application']) + * @param string $fileUrl Url to the file + * @param array $allowedCategories The allowed MIME type categories to filter by (e.g., ['audio'], ['video'] or ['image', 'application']) * @param array $dlfMimeTypes The custom DLF mimetype keys IIIF, IIP or ZOOMIFY to check against (default is an empty array) - * @param string $mimeTypeKey The key used to access the mimetype in the file array (default is 'mimetype') * - * @return bool True if the file mimetype belongs to any of the specified categories or matches any custom mimetypes, false otherwise + * @return bool True if the file mimetype belongs to any of the allowed mimetypes or matches any custom dlf mimetypes, false otherwise */ - public static function filterFilesByMimeType($file, array $categories, array $dlfMimeTypes = [], string $mimeTypeKey = 'mimetype'): bool + public static function filterFilesByMimeType(string $fileUrl, array $allowedCategories, array $dlfMimeTypes = []): bool { + if (empty($allowedCategories) && empty($dlfMimeTypes)) { + return false; + } + // Retrieves MIME types from the TYPO3 Core MimeTypeCollection $mimeTypeCollection = GeneralUtility::makeInstance(MimeTypeCollection::class); - $mimeTypes = array_filter( + $allowedMimeTypes = array_filter( $mimeTypeCollection->getMimeTypes(), - function ($mimeType) use ($categories) { - foreach ($categories as $category) { + function ($mimeType) use ($allowedCategories) { + foreach ($allowedCategories as $category) { if (strpos($mimeType, $category . '/') === 0) { return true; } @@ -979,13 +983,22 @@ function ($mimeType) use ($categories) { 'IIP' => 'application/vnd.netfpx', 'ZOOMIFY' => 'application/vnd.kitodo.zoomify' ]; - - // Filter custom MIME types based on provided keys + // Filter custom dlf MIME types based on provided keys $filteredDlfMimeTypes = array_intersect_key($dlfMimeTypeArray, array_flip($dlfMimeTypes)); - if (is_array($file) && isset($file[$mimeTypeKey])) { - return in_array($file[$mimeTypeKey], $mimeTypes) || in_array($file[$mimeTypeKey], $filteredDlfMimeTypes); + // Filter file based on its MIME type + if (!empty($fileUrl)) { + $fileExtension = pathinfo($fileUrl, PATHINFO_EXTENSION); + $assumedMimeTypesOfFile = GeneralUtility::makeInstance(MimeTypeDetector::class)->getMimeTypesForFileExtension($fileExtension); + $mergedMimeTypes = array_merge($filteredDlfMimeTypes, $allowedMimeTypes); + + foreach ($assumedMimeTypesOfFile as $mimeType) { + if (in_array($mimeType, $mergedMimeTypes, true)) { + return true; + } + } } + return false; } } diff --git a/Classes/Controller/PageViewController.php b/Classes/Controller/PageViewController.php index 1dd6bd808..2ea39139d 100644 --- a/Classes/Controller/PageViewController.php +++ b/Classes/Controller/PageViewController.php @@ -636,13 +636,14 @@ protected function getImage(int $page, MetsDocument $specificDoc = null): array foreach ($fileGrpsImages as $fileGrpImages) { // Get file info for the specific page and file group $file = $this->fetchFileInfo($page, $fileGrpImages, $specificDoc); - if ($file && Helper::filterFilesByMimeType($file, ['image', 'application'], ['IIIF', 'IIP', 'ZOOMIFY'], 'mimeType')) { + + if ($file && Helper::filterFilesByMimeType($file['location'], ['image'], ['IIIF', 'IIP', 'ZOOMIFY'])) { $image['url'] = $file['location']; $image['mimetype'] = $file['mimeType']; // Only deliver static images via the internal PageViewProxy. // (For IIP and IIIF, the viewer needs to build and access a separate metadata URL, see `getMetadataURL` in `OLSources.js`.) - if ($this->settings['useInternalProxy'] && !Helper::filterFilesByMimeType($file, ['application'], ['IIIF', 'IIP', 'ZOOMIFY'], 'mimeType')) { + if ($this->settings['useInternalProxy'] && !Helper::filterFilesByMimeType($file['location'], ['application'], ['IIIF', 'IIP', 'ZOOMIFY'])) { $this->configureProxyUrl($image['url']); } break; diff --git a/Classes/Controller/ToolboxController.php b/Classes/Controller/ToolboxController.php index cb93c6d62..a3a68bd40 100644 --- a/Classes/Controller/ToolboxController.php +++ b/Classes/Controller/ToolboxController.php @@ -295,13 +295,13 @@ private function renderImageDownloadTool(): void $imageArray = []; // Get left or single page download. $image = $this->getImage($page); - if (Helper::filterFilesByMimeType($image, ['image'])) { + if (Helper::filterFilesByMimeType($image['url'], ['image'])) { $imageArray[0] = $image; } if ($this->requestData['double'] == 1) { $image = $this->getImage($page + 1); - if (Helper::filterFilesByMimeType($image, ['image'])) { + if (Helper::filterFilesByMimeType($image['url'], ['image'])) { $imageArray[1] = $image; } }