/** * Create all the thumbnails for a picture. * * @param string $path Path to the file. This can be a virtual path or a absolute path. * @param string $fileNamePlain Plain file name without extension * @param string $fileExtension Extension of the file * @param \ImageManager $imageManager * * <code> * <?php * \Cx\Core_Modules\MediaBrowser\Model\FileSystem::createThumbnail( * 'files/', * 'Django, * 'jpg', * new ImageManager() // Please recycle the instance and don't create a new anonymous instance for each call. * // This is just a simple example. * ); * ?> * </code> * * @return array With all thumbnail types and if they were generated successfully. */ public static function createThumbnail($path, $fileNamePlain, $fileExtension, \ImageManager $imageManager, $generateThumbnailByRatio = false) { $success = array(); foreach (UploaderConfiguration::getInstance()->getThumbnails() as $thumbnail) { if (\Cx\Lib\FileSystem\FileSystem::exists(MediaSourceManager::getAbsolutePath($path) . $fileNamePlain . $thumbnail['value'] . '.' . $fileExtension)) { $success[$thumbnail['value']] = self::THUMBNAIL_GENERATOR_NEUTRAL; continue; } if ($imageManager->_createThumb(MediaSourceManager::getAbsolutePath($path) . '/', '', $fileNamePlain . '.' . $fileExtension, $thumbnail['size'], $thumbnail['quality'], $fileNamePlain . $thumbnail['value'] . '.' . $fileExtension, $generateThumbnailByRatio)) { $success[$thumbnail['value']] = self::THUMBNAIL_GENERATOR_SUCCESS; continue; } $success[$thumbnail['value']] = self::THUMBNAIL_GENERATOR_FAIL; } return $success; }
/** * Handle the calendar image upload * * @param string $id unique form id * * @return string image path */ function _handleUpload($fieldName, $id) { $tup = self::getTemporaryUploadPath($fieldName, $id); $tmpUploadDir = \Env::get('cx')->getWebsitePath() . $tup[1] . '/' . $tup[2] . '/'; //all the files uploaded are in here $depositionTarget = $this->uploadImgPath; //target folder $pic = ''; //move all files if (!\Cx\Lib\FileSystem\FileSystem::exists($tmpUploadDir)) { throw new \Exception("could not find temporary upload directory '{$tmpUploadDir}'"); } $h = opendir($tmpUploadDir); if ($h) { while (false !== ($f = readdir($h))) { // skip folders and thumbnails if ($f == '..' || $f == '.' || preg_match("/(?:\\.(?:thumb_thumbnail|thumb_medium|thumb_large)\\.[^.]+\$)|(?:\\.thumb)\$/i", $f)) { continue; } //do not overwrite existing files. $prefix = ''; while (file_exists($depositionTarget . $prefix . $f)) { if (empty($prefix)) { $prefix = 0; } $prefix++; } // move file try { $objFile = new \Cx\Lib\FileSystem\File($tmpUploadDir . $f); $fileInfo = pathinfo($tmpUploadDir . $f); $objFile->move($depositionTarget . $prefix . $f, false); $imageName = $prefix . $f; if (in_array($fileInfo['extension'], array('gif', 'jpg', 'jpeg', 'png'))) { $objImage = new \ImageManager(); $objImage->_createThumb($this->uploadImgPath, $this->uploadImgWebPath, $imageName, 180); } $pic = contrexx_input2raw($this->uploadImgWebPath . $imageName); // abort after one file has been fetched, as all event upload // fields do allow a single file only anyway break; } catch (\Cx\Lib\FileSystem\FileSystemException $e) { \DBG::msg($e->getMessage()); } } } return $pic; }
/** * Handles the upload request. * * @param array $conf * * @return array|bool */ static function handleRequest($conf = array()) { $cx = Cx::instanciate(); // 5 minutes execution time @set_time_limit(5 * 60); self::$_error = null; // start fresh $conf = self::$conf = array_merge(array('file_data_name' => 'file', 'tmp_dir' => $_SESSION->getTempPath(), 'target_dir' => 'images/content/', 'cleanup' => true, 'max_file_age' => 5 * 3600, 'chunk' => isset($_REQUEST['chunk']) ? intval($_REQUEST['chunk']) : 0, 'chunks' => isset($_REQUEST['chunks']) ? intval($_REQUEST['chunks']) : 0, 'fileName' => isset($_REQUEST['name']) ? $_REQUEST['name'] : false, 'allow_extensions' => false, 'delay' => 0, 'cb_sanitizeFileName' => array(__CLASS__, 'sanitizeFileName'), 'cb_check_file' => false), $conf); try { if (!$conf['fileName']) { if (!empty($_FILES)) { $conf['fileName'] = $_FILES[$conf['file_data_name']]['name']; } else { throw new UploaderException('', PLUPLOAD_INPUT_ERR); } } // Cleanup outdated temp files and folders if ($conf['cleanup']) { self::cleanup(); } // Fake network congestion if ($conf['delay']) { usleep($conf['delay']); } // callback function for sanitizie filename if (is_callable($conf['cb_sanitizeFileName'])) { $fileName = call_user_func($conf['cb_sanitizeFileName'], $conf['fileName']); } else { $fileName = $conf['fileName']; } // Check if file type is allowed if ($conf['allow_extensions']) { if (is_string($conf['allow_extensions'])) { $conf['allow_extensions'] = preg_split('{\\s*,\\s*}', $conf['allow_extensions']); } if (!in_array(strtolower(pathinfo($fileName, PATHINFO_EXTENSION)), $conf['allow_extensions'])) { throw new UploaderException('', PLUPLOAD_TYPE_ERR); } } $file_path = rtrim($conf['tmp_dir'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $fileName; $tmp_path = $file_path . ".part"; // Write file or chunk to appropriate temp location if ($conf['chunks']) { self::writeFileTo("{$file_path}.dir.part" . DIRECTORY_SEPARATOR . $conf['chunk']); // Check if all chunks already uploaded if ($conf['chunk'] == $conf['chunks'] - 1) { self::writeChunksToFile("{$file_path}.dir.part", $tmp_path); } } else { self::writeFileTo($tmp_path); } // Upload complete write a temp file to the final destination if (!$conf['chunks'] || $conf['chunk'] == $conf['chunks'] - 1) { if (is_callable($conf['cb_check_file']) && !call_user_func($conf['cb_check_file'], $tmp_path)) { @unlink($tmp_path); throw new UploaderException('', PLUPLOAD_SECURITY_ERR); } $new_path = $conf['target_dir'] . $fileName; \Cx\Lib\FileSystem\FileSystem::move($tmp_path, $new_path, true); $rootPath = $cx->getWebsitePath() . $conf['target_dir']; $rootPathFull = $cx->getWebsitePath() . $new_path; $filePathinfo = pathinfo($rootPathFull); $fileExtension = $filePathinfo['extension']; $fileNamePlain = $filePathinfo['filename']; $im = new \ImageManager(); if ($im->_isImage($rootPathFull)) { foreach (UploaderConfiguration::getInstance()->getThumbnails() as $thumbnail) { $im->_createThumb($rootPath, $conf['target_dir'], $fileName, $thumbnail['size'], $thumbnail['quality'], $fileNamePlain . $thumbnail['value'] . '.' . $fileExtension); } } return array('name' => $fileName, 'path' => $file_path, 'size' => filesize($file_path)); } // ok so far return true; } catch (UploaderException $ex) { self::$_error = $ex->getCode(); return array('error' => $ex->getCode()); } }
/** * Create all the thumbnails for a picture. * * @param string $path Path to the file. This can be a virtual path or a absolute path. * @param string $fileNamePlain Plain file name without extension * @param string $fileExtension Extension of the file * @param \ImageManager $imageManager * * <code> * <?php * \Cx\Core_Modules\MediaBrowser\Model\FileSystem::createThumbnail( * 'files/', * 'Django, * 'jpg', * new ImageManager() // Please recycle the instance and don't create a new anonymous instance for each call. * // This is just a simple example. * ); * ?> * </code> * * @param bool $generateThumbnailByRatio * @param bool $force Force creation of new Thumbnails. This overwrites any existing thumbnail. * * @return array Array with the relative paths to the thumbnails. */ public function createThumbnail($path, $fileNamePlain, $fileExtension, \ImageManager $imageManager, $generateThumbnailByRatio = false, $force = false) { $thumbnails = array(); foreach ($this->getThumbnails() as $thumbnail) { if ($force) { \Cx\Lib\FileSystem\FileSystem::delete_file(MediaSourceManager::getAbsolutePath($path) . '/' . $fileNamePlain . $thumbnail['value'] . '.' . $fileExtension); } elseif (\Cx\Lib\FileSystem\FileSystem::exists(MediaSourceManager::getAbsolutePath($path) . '/' . $fileNamePlain . $thumbnail['value'] . '.' . $fileExtension)) { $thumbnails[] = $fileNamePlain . $thumbnail['value'] . '.' . $fileExtension; continue; } if ($imageManager->_createThumb(MediaSourceManager::getAbsolutePath($path) . '/', '', $fileNamePlain . '.' . $fileExtension, $thumbnail['size'], $thumbnail['quality'], $fileNamePlain . $thumbnail['value'] . '.' . $fileExtension, $generateThumbnailByRatio)) { $thumbnails[] = $fileNamePlain . $thumbnail['value'] . '.' . $fileExtension; continue; } } return $thumbnails; }
public static function uploadFinished($tempPath, $tempWebPath, $data, $uploadId, $fileInfos) { global $objDatabase, $_ARRAYLANG, $_CONFIG; $originalNames = $fileInfos['originalFileNames']; $path = $data['path']; $webPath = $data['webPath']; $objCategory = Category::getCategory($data['category_id']); // check for sufficient permissions if ($objCategory->getAddFilesAccessId() && !\Permission::checkAccess($objCategory->getAddFilesAccessId(), 'dynamic', true) && $objCategory->getOwnerId() != \FWUser::getFWUserObject()->objUser->getId()) { return; } //we remember the names of the uploaded files here. they are stored in the session afterwards, //so we can later display them highlighted. $arrFiles = array(); //rename files, delete unwanted $arrFilesToRename = array(); //used to remember the files we need to rename $h = opendir($tempPath); while (false !== ($file = readdir($h))) { //skip . and .. if ($file == '.' || $file == '..') { continue; } //delete potentially malicious files if (!\FWValidator::is_file_ending_harmless($file)) { @unlink($tempPath . '/' . $file); continue; } $info = pathinfo($file); $cleanFile = \Cx\Lib\FileSystem\FileSystem::replaceCharacters($file); if ($cleanFile != $file) { rename($tempPath . '/' . $file, $tempPath . '/' . $cleanFile); $file = $cleanFile; } //check if file needs to be renamed $newName = ''; $suffix = ''; if (file_exists($path . '/' . $file)) { if (empty($_REQUEST['uploadForceOverwrite']) || !intval($_REQUEST['uploadForceOverwrite'] > 0)) { $suffix = '_' . time(); $newName = $info['filename'] . $suffix . '.' . $info['extension']; $arrFilesToRename[$file] = $newName; array_push($arrFiles, $newName); } } if (!isset($arrFilesToRename[$file])) { //file will keep this name - create thumb \ImageManager::_createThumb($tempPath . '/', $tempWebPath . '/', $file); } $objDownloads = new downloads(''); $objDownloads->addDownloadFromUpload($info['filename'], $info['extension'], $suffix, $objCategory, $objDownloads, $originalNames[$file]); } //rename files where needed foreach ($arrFilesToRename as $oldName => $newName) { rename($tempPath . '/' . $oldName, $tempPath . '/' . $newName); //file will keep this name - create thumb \ImageManager::_createThumb($tempPath . '/', $tempWebPath . '/', $newName); } //remeber the uploaded files $_SESSION['media_upload_files_' . $uploadId] = $arrFiles; /* unwanted files have been deleted, unallowed filenames corrected. we can now simply return the desired target path, as only valid files are present in $tempPath */ return array($path, $webPath); }
/** * Notifies the callback. Invoked on upload completion. */ public function notifyCallback() { //temporary path where files were uploaded $tempDir = '/upload_' . $this->uploadId; $tempPath = $_SESSION->getTempPath() . $tempDir; $tempWebPath = $_SESSION->getWebTempPath() . $tempDir; //we're going to call the callbck, so the data is not needed anymore //well... not quite sure. need it again in contact form. //TODO: code session cleanup properly if time. //$this->cleanupCallbackData(); $classFile = $this->callbackData[0]; //call the callback, get return code if ($classFile != null) { if (!file_exists($classFile)) { throw new UploaderException("Class file '{$classFile}' specified for callback does not exist!"); } require_once $this->callbackData[0]; } $originalFileNames = array(); if (isset($_SESSION['upload']['handlers'][$this->uploadId]['originalFileNames'])) { $originalFileNames = $_SESSION['upload']['handlers'][$this->uploadId]['originalFileNames']; } //various file infos are passed via this array $fileInfos = array('originalFileNames' => $originalFileNames); $response = null; //the response data. if (isset($_SESSION['upload']['handlers'][$this->uploadId]['response_data'])) { $response = UploadResponse::fromSession($_SESSION['upload']['handlers'][$this->uploadId]['response_data']); } else { $response = new UploadResponse(); } $ret = call_user_func(array($this->callbackData[1], $this->callbackData[2]), $tempPath, $tempWebPath, $this->getData(), $this->uploadId, $fileInfos, $response); //clean up session: we do no longer need the array with the original file names unset($_SESSION['upload']['handlers'][$this->uploadId]['originalFileNames']); //same goes for the data //if(isset($_SESSION['upload']['handlers'][$this->uploadId]['data'])) // TODO: unset this when closing the uploader dialog, but not before // unset($_SESSION['upload']['handlers'][$this->uploadId]['data']); if (\Cx\Lib\FileSystem\FileSystem::exists($tempWebPath)) { //the callback could have returned a path where he wants the files moved to // check that $ret[1] is not empty is VERY important!!! if (!is_null($ret) && !empty($ret[1])) { //we need to move the files //gather target information $path = pathinfo($ret[0]); $pathWeb = pathinfo($ret[1]); //make sure the target directory is writable \Cx\Lib\FileSystem\FileSystem::makeWritable($pathWeb['dirname'] . '/' . $path['basename']); //revert $path and $pathWeb to whole path instead of pathinfo path for copying $path = $path['dirname'] . '/' . $path['basename'] . '/'; $pathWeb = $pathWeb['dirname'] . '/' . $pathWeb['basename'] . '/'; //trailing slash needed for File-class calls $tempPath .= '/'; $tempWebPath .= '/'; //move everything uploaded to target dir $h = opendir($tempPath); $im = new \ImageManager(); while (false != ($f = readdir($h))) { //skip . and .. if ($f == '.' || $f == '..') { continue; } //TODO: if return value = 'error' => react \Cx\Lib\FileSystem\FileSystem::move($tempWebPath . $f, $pathWeb . $f, true); if ($im->_isImage($path . $f)) { $im->_createThumb($path, $pathWeb, $f); } $response->increaseUploadedFilesCount(); } closedir($h); } else { // TODO: what now???? } //delete the folder \Cx\Lib\FileSystem\FileSystem::delete_folder($tempWebPath, true); } else { // TODO: output error message to user that no files had been uploaded!!! } $response->uploadFinished(); $_SESSION['upload']['handlers'][$this->uploadId]['response_data'] = $response->toSessionValue(); }