From 6173dbd6417366784f7c4fb89a97e7394e0364aa Mon Sep 17 00:00:00 2001 From: Julian Egelstaff Date: Wed, 8 May 2024 00:57:48 -0300 Subject: [PATCH] Make thumbs for uploaded images, serve thumbs in img tags, serve images directly (#502) * Make thumbs for uploaded images, serve thumbs in img tags, serve images directly --- modules/formulize/class/fileUploadElement.php | 122 +++++++++++++++--- modules/formulize/download.php | 21 ++- 2 files changed, 121 insertions(+), 22 deletions(-) diff --git a/modules/formulize/class/fileUploadElement.php b/modules/formulize/class/fileUploadElement.php index 6a4a1ae32..78ec8f67e 100644 --- a/modules/formulize/class/fileUploadElement.php +++ b/modules/formulize/class/fileUploadElement.php @@ -434,7 +434,7 @@ function logMissingMimeType($extension, $mimeType, $map) { } /** - * Create an HTML img tag with the src set as the url for the image + * Create an HTML img tag with the src set as the url for the image. Creates a thumbnail version of the image if one does not exist already. * * @param string $url The URL used to access the image. * @param string $displayName Optional. The name of the file/image, for use in the title attribute. @@ -442,9 +442,107 @@ function logMissingMimeType($extension, $mimeType, $map) { * @return string Returns the HTML img tag referring to the image */ function createImageTag($url, $displayName='', $class='formulize-uploaded-image-thumbnail') { + $url = $this->getThumbnailUrl($url, $displayName); return ""; } + /** + * Return the URL for the thumbnail version of an image, and create the thumbnail if necessary + * + * @param string $url The URL used to access the image. + * @return string The URL of the thumbnail version of the image. Or the URL passed in if the URL is not for an image. + */ + function getThumbnailUrl($url) { + list($entry_id, $element_id, $fid) = $this->extractEntryIdAndElementIdFromUrl($url); + $data_handler = new formulizeDataHandler($fid); + $fileInfo = $data_handler->getElementValueInEntry($entry_id, $element_id); + $fileInfo = unserialize($fileInfo); + if(fileNameHasImageExtension($fileInfo['name'])) { + $dotPos = strrpos($fileInfo['name'], '.'); + $fileExtension = strtolower(substr($fileInfo['name'], $dotPos+1)); + $thumbFileName = substr_replace($fileInfo['name'], ".thumb.$fileExtension", $dotPos); + $path = XOOPS_ROOT_PATH."/uploads/formulize_".$fid."_".$entry_id."_".$element_id."/".$fileInfo['name']; + $thumbPath = XOOPS_ROOT_PATH."/uploads/formulize_".$fid."_".$entry_id."_".$element_id."/".$thumbFileName; + if(strstr($url, XOOPS_URL."/modules/formulize/download.php?element=")) { + $thumbUrl = $url . "&size=thumb"; + } else { + $thumbUrl = str_replace($fileInfo['name'], $thumbFileName, $url); + } + if(!file_exists($thumbPath)) { + $image = null; + switch($fileExtension) { + case 'gif': + $image = imagecreatefromgif($path); + break; + case 'png': + $image = imagecreatefrompng($path); + break; + case 'webp': + $image = imagecreatefromwebp($path); + break; + case 'jpg': + case 'jpeg': + $image = imagecreatefromjpeg($path); + break; + } + $exif = exif_read_data($path); + if ($image AND $exif AND isset($exif['Orientation'])) { + $orientation = $exif['Orientation']; + if ($orientation == 6 OR $orientation == 5) { $image = imagerotate($image, 270, 0); } + if ($orientation == 3 OR $orientation == 4) { $image = imagerotate($image, 180, 0); } + if ($orientation == 8 OR $orientation == 7) { $image = imagerotate($image, 90, 0); } + if ($orientation == 5 OR $orientation == 4 OR $orientation == 7) { imageflip($image, IMG_FLIP_HORIZONTAL); } + } + $image = imagescale($image, 200); + switch($fileExtension) { + case 'gif': + imagegif($image, $thumbPath); + break; + case 'png': + imagepng($image, $thumbPath); + break; + case 'webp': + imagewebp($image, $thumbPath); + break; + case 'jpg': + case 'jpeg': + imagejpeg($image, $thumbPath); + break; + } + } + $url = $thumbUrl; + } + return $url; + } + + /** + * Get the entryId and elementId and form Id from the URL for an image. Parsing depends on the kind of URL + * + * @param string $url The URL used to access the image. + * @return array An array of the entry Id and element Id and form Id + */ + function extractEntryIdAndElementIdFromUrl($url) { + if(strstr($url, XOOPS_URL."/modules/formulize/download.php?element=")) { + $urlParts = explode('?', $url); + $urlParams = explode('&', $urlParts[1]); + $elementIdParamParts = explode('=',$urlParams[0]); + $entryIdParamParts = explode('=',$urlParams[1]); + $elementId = $elementIdParamParts[1]; + $entryId = $entryIdParamParts[1]; + } else { + $metaData = str_replace(XOOPS_URL."/uploads/formulize_", "", $url); + $metaData = explode('/', $metaData); + $metaDataParts = explode('_',$metaData[0]); + $elementId = $metaDataParts[2]; + $entryId = $metaDataParts[1]; + } + $element_handler = xoops_getmodulehandler('elements', 'formulize'); + $fid = 0; + if($elementObject = $element_handler->get($elementId)) { + $fid = $elementObject->getVar('id_form'); + } + return array($entryId, $elementId, $fid); + } } /** @@ -460,21 +558,7 @@ function displayFileImage($entryOrDataset, $elementHandle, $dataSetKey=null, $lo $displayName = ""; $url = display($entryOrDataset, $elementHandle, $dataSetKey, $localId); $element_handler = xoops_getmodulehandler('fileUploadElement', 'formulize'); - // extract the element id and entry id from the url - if(strstr($url, XOOPS_URL."/modules/formulize/download.php?element=")) { - $urlParts = explode('?', $url); - $urlParams = explode('&', $urlParts[1]); - $elementIdParamParts = explode('=',$urlParams[0]); - $entryIdParamParts = explode('=',$urlParams[1]); - $elementId = $elementIdParamParts[1]; - $entryId = $entryIdParamParts[1]; - } else { - $metaData = str_replace(XOOPS_URL."/uploads/formulize_", "", $url); - $metaData = explode('/', $metaData); - $metaDataParts = explode('_',$metaData[0]); - $elementId = $metaDataParts[2]; - $entryId = $metaDataParts[1]; - } + list($entryId, $elementId, $fid) = $element_handler->extractEntryIdAndElementIdFromUrl($url); // lookup the name if($elementObject = $element_handler->get($elementId)) { $dataHandler = new formulizeDataHandler($elementObject->getVar('id_form')); @@ -484,14 +568,14 @@ function displayFileImage($entryOrDataset, $elementHandle, $dataSetKey=null, $lo $displayName = $element_handler->getFileDisplayName($name); } if(fileNameHasImageExtension($displayName)) { - return $element_handler->createImageTag($url, $displayName); + return $element_handler->createImageTag($url, $displayName); } - return $url; + return $url; } /** * Check if a filename has one of various common image file type extensions. - * + * * @param string $displayName The name of the file * @return boolean Return true or false depending if the file has a matching extension. If there is no displayName, return false. */ diff --git a/modules/formulize/download.php b/modules/formulize/download.php index 85e00ef25..8e2a77138 100644 --- a/modules/formulize/download.php +++ b/modules/formulize/download.php @@ -64,15 +64,30 @@ $fileInfo = $data_handler->getElementValueInEntry($entry_id, $elementObject); $fileInfo = unserialize($fileInfo); $filePath = XOOPS_ROOT_PATH."/uploads/formulize_".$fid."_".$entry_id."_".$element_id."/".$fileInfo['name']; + if(isset($_GET['size']) AND $_GET['size'] == 'thumb') { + $dotPos = strrpos($filePath, '.'); + $fileExtension = strtolower(substr($filePath, $dotPos+1)); + $thumbFilePath = substr_replace($filePath, ".thumb.$fileExtension", $dotPos); + if(file_exists($thumbFilePath)) { + $filePath = $thumbFilePath; + } + } + $fileDisplayName = $element_handler->getFileDisplayName($fileInfo['name']); if (file_exists($filePath)) { - header('Content-Description: File Transfer'); header('Content-Type: '.$fileInfo['type']); - header('Content-Disposition: attachment; filename="'.$element_handler->getFileDisplayName($fileInfo['name']).'"'); + if(fileNameHasImageExtension($fileDisplayName)) { + header('Content-Disposition: filename="'.$fileDisplayName.'"'); + header('Cache-Control: max-age=3600'); + header('Pragma: public'); + } else { + header('Content-Description: File Transfer'); + header('Content-Disposition: attachment; filename="'.$fileDisplayName.'"'); header('Content-Transfer-Encoding: binary'); + header('Content-Length: ' . $fileInfo['size']); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); - header('Content-Length: ' . $fileInfo['size']); + } readfile($filePath); exit; } else {