/** * send response (save uploaded file, resize if required) * @access public * */ public function sendResponse() { $iErrorNumber = QFINDER_CONNECTOR_ERROR_NONE; $_config =& QFinder_Connector_Core_Factory::getInstance("Core_Config"); $oRegistry =& QFinder_Connector_Core_Factory::getInstance("Core_Registry"); $oRegistry->set("FileUpload_fileName", "unknown file"); $uploadedFile = array_shift($_FILES); if (!isset($uploadedFile['name'])) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_INVALID); } $sUnsafeFileName = QFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding(QFinder_Connector_Utils_Misc::mbBasename($uploadedFile['name'])); $sFileName = QFinder_Connector_Utils_FileSystem::secureFileName($sUnsafeFileName); if ($sFileName != $sUnsafeFileName) { $iErrorNumber = QFINDER_CONNECTOR_ERROR_UPLOADED_INVALID_NAME_RENAMED; } $oRegistry->set("FileUpload_fileName", $sFileName); $this->checkConnector(); $this->checkRequest(); if (!$this->_currentFolder->checkAcl(QFINDER_CONNECTOR_ACL_FILE_UPLOAD)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UNAUTHORIZED); } $_resourceTypeConfig = $this->_currentFolder->getResourceTypeConfig(); if (!QFinder_Connector_Utils_FileSystem::checkFileName($sFileName) || $_resourceTypeConfig->checkIsHiddenFile($sFileName)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_NAME); } $resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); if (!$resourceTypeInfo->checkExtension($sFileName)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); } $oRegistry->set("FileUpload_fileName", $sFileName); $oRegistry->set("FileUpload_url", $this->_currentFolder->getUrl()); $maxSize = $resourceTypeInfo->getMaxSize(); if (!$_config->checkSizeAfterScaling() && $maxSize && $uploadedFile['size'] > $maxSize) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_TOO_BIG); } $htmlExtensions = $_config->getHtmlExtensions(); $sExtension = QFinder_Connector_Utils_FileSystem::getExtension($sFileName); if ($htmlExtensions && !QFinder_Connector_Utils_Misc::inArrayCaseInsensitive($sExtension, $htmlExtensions) && ($detectHtml = QFinder_Connector_Utils_FileSystem::detectHtml($uploadedFile['tmp_name'])) === true) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_WRONG_HTML_FILE); } $secureImageUploads = $_config->getSecureImageUploads(); if ($secureImageUploads && ($isImageValid = QFinder_Connector_Utils_FileSystem::isImageValid($uploadedFile['tmp_name'], $sExtension)) === false) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_CORRUPT); } switch ($uploadedFile['error']) { case UPLOAD_ERR_OK: break; case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_TOO_BIG); break; case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_NO_FILE: $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_CORRUPT); break; case UPLOAD_ERR_NO_TMP_DIR: $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_NO_TMP_DIR); break; case UPLOAD_ERR_CANT_WRITE: $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_ACCESS_DENIED); break; case UPLOAD_ERR_EXTENSION: $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_ACCESS_DENIED); break; } $sServerDir = $this->_currentFolder->getServerPath(); while (true) { $sFilePath = QFinder_Connector_Utils_FileSystem::combinePaths($sServerDir, $sFileName); if (file_exists($sFilePath)) { $sFileName = QFinder_Connector_Utils_FileSystem::autoRename($sServerDir, $sFileName); $oRegistry->set("FileUpload_fileName", $sFileName); $iErrorNumber = QFINDER_CONNECTOR_ERROR_UPLOADED_FILE_RENAMED; } else { if (false === move_uploaded_file($uploadedFile['tmp_name'], $sFilePath)) { $iErrorNumber = QFINDER_CONNECTOR_ERROR_ACCESS_DENIED; } else { if (isset($detectHtml) && $detectHtml === -1 && QFinder_Connector_Utils_FileSystem::detectHtml($sFilePath) === true) { @unlink($sFilePath); $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_WRONG_HTML_FILE); } else { if (isset($isImageValid) && $isImageValid === -1 && QFinder_Connector_Utils_FileSystem::isImageValid($sFilePath, $sExtension) === false) { @unlink($sFilePath); $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_CORRUPT); } } } if (is_file($sFilePath) && ($perms = $_config->getChmodFiles())) { $oldumask = umask(0); chmod($sFilePath, $perms); umask($oldumask); } break; } } if (!$_config->checkSizeAfterScaling()) { $this->_errorHandler->throwError($iErrorNumber, true, false); } //resize image if required require_once QFINDER_CONNECTOR_LIB_DIR . "/CommandHandler/Thumbnail.php"; $_imagesConfig = $_config->getImagesConfig(); if ($_imagesConfig->getMaxWidth() > 0 && $_imagesConfig->getMaxHeight() > 0 && $_imagesConfig->getQuality() > 0) { QFinder_Connector_CommandHandler_Thumbnail::createThumb($sFilePath, $sFilePath, $_imagesConfig->getMaxWidth(), $_imagesConfig->getMaxHeight(), $_imagesConfig->getQuality(), true); } if ($_config->checkSizeAfterScaling()) { //check file size after scaling, attempt to delete if too big clearstatcache(); if ($maxSize && filesize($sFilePath) > $maxSize) { @unlink($sFilePath); $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UPLOADED_TOO_BIG); } else { $this->_errorHandler->throwError($iErrorNumber, true, false); } } QFinder_Connector_Core_Hooks::run('AfterFileUpload', array(&$this->_currentFolder, &$uploadedFile, &$sFilePath)); }
/** * handle request and build XML * @access protected * */ function buildXml() { if (empty($_POST['QFinderCommand']) || $_POST['QFinderCommand'] != 'true') { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_REQUEST); } $this->checkConnector(); $this->checkRequest(); //resizing to 1x1 is almost equal to deleting a file, that's why FILE_DELETE permissions are required if (!$this->_currentFolder->checkAcl(QFINDER_CONNECTOR_ACL_FILE_DELETE) || !$this->_currentFolder->checkAcl(QFINDER_CONNECTOR_ACL_FILE_UPLOAD)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_UNAUTHORIZED); } $_config =& QFinder_Connector_Core_Factory::getInstance("Core_Config"); $resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); if (!isset($_POST["fileName"])) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_NAME); } $fileName = QFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($_POST["fileName"]); if (!QFinder_Connector_Utils_FileSystem::checkFileName($fileName) || $resourceTypeInfo->checkIsHiddenFile($fileName)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_REQUEST); } if (!$resourceTypeInfo->checkExtension($fileName, false)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_REQUEST); } $filePath = QFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $fileName); if (!file_exists($filePath) || !is_file($filePath)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); } $newWidth = trim($_POST['width']); $newHeight = trim($_POST['height']); $quality = 80; $resizeOriginal = !empty($_POST['width']) && !empty($_POST['height']); if ($resizeOriginal) { if (!preg_match("/^\\d+\$/", $newWidth) || !preg_match("/^\\d+\$/", $newHeight) || !preg_match("/^\\d+\$/", $newWidth)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_REQUEST); } if (!isset($_POST["newFileName"])) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_NAME); } $newFileName = QFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($_POST["newFileName"]); if (!$resourceTypeInfo->checkExtension($newFileName)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); } if (!QFinder_Connector_Utils_FileSystem::checkFileName($newFileName) || $resourceTypeInfo->checkIsHiddenFile($newFileName)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_NAME); } $newFilePath = QFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $newFileName); if (!is_writable(dirname($newFilePath))) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_ACCESS_DENIED); } if ($_POST['overwrite'] != "1" && file_exists($newFilePath)) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_ALREADY_EXIST); } $_imagesConfig = $_config->getImagesConfig(); $maxWidth = $_imagesConfig->getMaxWidth(); $maxHeight = $_imagesConfig->getMaxHeight(); // Shouldn't happen as the JavaScript validation should not allow this. if ($maxWidth > 0 && $newWidth > $maxWidth || $maxHeight > 0 && $newHeight > $maxHeight) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_INVALID_REQUEST); } } require_once QFINDER_CONNECTOR_LIB_DIR . "/CommandHandler/Thumbnail.php"; if ($resizeOriginal) { $result = QFinder_Connector_CommandHandler_Thumbnail::createThumb($filePath, $newFilePath, $newWidth, $newHeight, $quality, false); if (!$result) { $this->_errorHandler->throwError(QFINDER_CONNECTOR_ERROR_ACCESS_DENIED); } } $config = $this->getConfig(); $nameWithoutExt = preg_replace("/^(.+)\\_\\d+x\\d+\$/", "\$1", QFinder_Connector_Utils_FileSystem::getFileNameWithoutExtension($fileName)); $extension = QFinder_Connector_Utils_FileSystem::getExtension($fileName); foreach (array('small', 'medium', 'large') as $size) { if (!empty($_POST[$size]) && $_POST[$size] == '1') { $thumbName = $nameWithoutExt . "_" . $size . "." . $extension; $newFilePath = QFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $thumbName); if (!empty($config[$size . 'Thumb'])) { if (preg_match("/^(\\d+)x(\\d+)\$/", $config[$size . 'Thumb'], $matches)) { QFinder_Connector_CommandHandler_Thumbnail::createThumb($filePath, $newFilePath, $matches[1], $matches[2], $quality, true); } } } } }
/** * Create thumbnail * * @param string $sourceFile * @param string $targetFile * @param int $maxWidth * @param int $maxHeight * @param boolean $preserverAspectRatio * @param boolean $bmpSupported * @return boolean * @static * @access public */ public static function createThumb($sourceFile, $targetFile, $maxWidth, $maxHeight, $quality, $preserverAspectRatio, $bmpSupported = false) { $sourceImageAttr = @getimagesize($sourceFile); if ($sourceImageAttr === false) { return false; } $sourceImageWidth = isset($sourceImageAttr[0]) ? $sourceImageAttr[0] : 0; $sourceImageHeight = isset($sourceImageAttr[1]) ? $sourceImageAttr[1] : 0; $sourceImageMime = isset($sourceImageAttr["mime"]) ? $sourceImageAttr["mime"] : ""; $sourceImageBits = isset($sourceImageAttr["bits"]) ? $sourceImageAttr["bits"] : 8; $sourceImageChannels = isset($sourceImageAttr["channels"]) ? $sourceImageAttr["channels"] : 3; if (!$sourceImageWidth || !$sourceImageHeight || !$sourceImageMime) { return false; } $iFinalWidth = $maxWidth == 0 ? $sourceImageWidth : $maxWidth; $iFinalHeight = $maxHeight == 0 ? $sourceImageHeight : $maxHeight; if ($sourceImageWidth <= $iFinalWidth && $sourceImageHeight <= $iFinalHeight) { if ($sourceFile != $targetFile) { copy($sourceFile, $targetFile); } return true; } if ($preserverAspectRatio) { // Gets the best size for aspect ratio resampling $oSize = QFinder_Connector_CommandHandler_Thumbnail::GetAspectRatioSize($iFinalWidth, $iFinalHeight, $sourceImageWidth, $sourceImageHeight); } else { $oSize = array('Width' => $iFinalWidth, 'Height' => $iFinalHeight); } QFinder_Connector_Utils_Misc::setMemoryForImage($sourceImageWidth, $sourceImageHeight, $sourceImageBits, $sourceImageChannels); switch ($sourceImageAttr['mime']) { case 'image/gif': if (@imagetypes() & IMG_GIF) { $oImage = @imagecreatefromgif($sourceFile); } else { $ermsg = 'GIF images are not supported'; } break; case 'image/jpeg': if (@imagetypes() & IMG_JPG) { $oImage = @imagecreatefromjpeg($sourceFile); } else { $ermsg = 'JPEG images are not supported'; } break; case 'image/png': if (@imagetypes() & IMG_PNG) { $oImage = @imagecreatefrompng($sourceFile); } else { $ermsg = 'PNG images are not supported'; } break; case 'image/wbmp': if (@imagetypes() & IMG_WBMP) { $oImage = @imagecreatefromwbmp($sourceFile); } else { $ermsg = 'WBMP images are not supported'; } break; case 'image/bmp': /* * This is sad that PHP doesn't support bitmaps. * Anyway, we will use our custom function at least to display thumbnails. * We'll not resize images this way (if $sourceFile === $targetFile), * because user defined imagecreatefrombmp and imagecreatebmp are horribly slow */ if ($bmpSupported && @imagetypes() & IMG_JPG && $sourceFile != $targetFile) { $oImage = QFinder_Connector_Utils_Misc::imageCreateFromBmp($sourceFile); } else { $ermsg = 'BMP/JPG images are not supported'; } break; default: $ermsg = $sourceImageAttr['mime'] . ' images are not supported'; break; } if (isset($ermsg) || false === $oImage) { return false; } $oThumbImage = imagecreatetruecolor($oSize["Width"], $oSize["Height"]); if ($sourceImageAttr['mime'] == 'image/png') { $bg = imagecolorallocatealpha($oThumbImage, 255, 255, 255, 127); // (PHP 4 >= 4.3.2, PHP 5) imagefill($oThumbImage, 0, 0, $bg); imagealphablending($oThumbImage, false); imagesavealpha($oThumbImage, true); } //imagecopyresampled($oThumbImage, $oImage, 0, 0, 0, 0, $oSize["Width"], $oSize["Height"], $sourceImageWidth, $sourceImageHeight); QFinder_Connector_Utils_Misc::fastImageCopyResampled($oThumbImage, $oImage, 0, 0, 0, 0, $oSize["Width"], $oSize["Height"], $sourceImageWidth, $sourceImageHeight, (int) max(floor($quality / 20), 6)); switch ($sourceImageAttr['mime']) { case 'image/gif': imagegif($oThumbImage, $targetFile); break; case 'image/jpeg': case 'image/bmp': imagejpeg($oThumbImage, $targetFile, $quality); break; case 'image/png': imagepng($oThumbImage, $targetFile); break; case 'image/wbmp': imagewbmp($oThumbImage, $targetFile); break; } $_config =& QFinder_Connector_Core_Factory::getInstance("Core_Config"); if (file_exists($targetFile) && ($perms = $_config->getChmodFiles())) { $oldUmask = umask(0); chmod($targetFile, $perms); umask($oldUmask); } imageDestroy($oImage); imageDestroy($oThumbImage); return true; }