* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * SwfUploadComponent - A CakePHP Component to use with SWFUpload * Thanks to Eelco Wiersma for the original explanation on handling * uploads from SWFUpload in CakePHP. Also, thanks to gwoo for guidance * and help refactoring for performance optimization and readability. * @author James Revillini http://james.revillini.com * @version 0.1.4 */ /** * @package SwfUploadComponent * @subpackage controllers.components */ class SwfUploadComponent extends Object { /* component configuration */ var $name = 'SwfUploadComponent'; /** * Array that stores the information from your $_FILES * This is passed in the upload() * */ var $data = array(); /* You may change the ffg variables based on your needs */ // file and path configuration var $uploadpath; /** * Tells if we will overwrite the file * */ var $overwrite = false; /** * how to create the filename * default: filename.ext fielaname(1).ext * full: abcdef.ext * partial: abcdef_filename.ext * * @var unknown_type */ var $filenameType = 'default'; /** * set the number of characters the random_word function will generate * */ var $random_word_length = 8; /** * This array stores all allowed mime types, a mime type * determines the type of file. * * The specified mime types below should be safe for uploads, * however the compressed formats could be a touch unsafe. */ var $allowedMime = array( 'img' => array( 'image/jpeg', // images 'image/pjpeg', 'image/png', 'image/gif', 'image/tiff', 'image/x-tiff' ), 'pdf' => array( 'application/pdf', // pdf 'application/x-pdf', 'application/acrobat', 'text/pdf', 'text/x-pdf' ), 'text' => array( 'text/plain' // text ), 'word' => array( 'application/msword', // word ), 'ppt' => array( 'application/mspowerpoint', // powerpoint 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint', ), 'xls' => array( 'application/x-msexcel', // excel 'application/excel', 'application/x-excel', ), 'zip' => array( 'application/x-compressed', // compressed files 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip', 'application/x-tar', 'application/x-compressed', 'application/x-gzip', 'application/x-gzip', 'multipart/x-gzip' ) ); /* No need to configure the ffg variables */ var $errorCode = null; var $errorMessage = null; var $filename=null; /** * Contructor function * @param Object &$controller pointer to calling controller */ /*function startup(&$controller) { } */ /** * Uploads a file to location * @return boolean true if upload was successful, false otherwise. */ function upload($file, $allowedMimeType=null) { // pass the array to our data holder $this->data = $file; $ok = false; if ($this->validate($allowedMimeType)) { $this->filename = $file['name']; $ok = $this->write(); } if (!$ok) { header("HTTP/1.0 500 Internal Server Error"); //this should tell SWFUpload what's up $this->setError(); //this should tell standard form what's up } return ($ok); } /** * finds a unique name for the file for the current directory * @param array an array of filenames which exist in the desired upload directory * @return string a unique filename for the file */ function findUniqueFilename($existing_files = null) { // append a digit to the end of the name $filenumber = 0; $filesuffix = ''; $fileparts = explode('.', $this->filename); $fileext = '.' . array_pop($fileparts); $filebase = implode('.', $fileparts); if (is_array($existing_files)) { do { $newfile = $filebase . $filesuffix . $fileext; $filenumber++; $filesuffix = '(' . $filenumber . ')'; } while (in_array($newfile, $existing_files)); } return $newfile; } /** * finds a unique name by random characters * * @param string $type type of process to follow, either partial or full renaming */ function findRandomFilename($type) { $notexist = true; $filename = explode('.', $this->filename); switch ($type) { case 'partial': while ($notexist) { $name = $this->random_word($this->random_word_length) . '_' . $filename[0] . '.' . $filename[1]; if (!file_exists($this->uploadpath . $name)) $notexist = false; } break; default: while ($notexist) { $name = $this->random_word($this->random_word_length) . $filename[1]; if (!file_exists($this->uploadpath . $name)) $notexist = false; } break; } return $name; } /** * moves the file to the desired location from the temp directory * @return boolean true if the file was successfully moved from the temporary directory to the desired destination on the filesystem */ function write() { // Include libraries if (!class_exists('Folder')) { uses ('folder'); } $moved = false; $folder = new Folder($this->uploadpath, true, 0755); if (!$folder) { $this->setError(1500, 'File system save failed.', 'Could not create requested directory: ' . $this->uploadpath); } else { if (!$this->overwrite) { $contents = $folder->ls(); //get directory contents if ($this->filenameType == 'default') { $this->filename = $this->findUniqueFilename($contents[1]); //pass the file list as an array } else { $type = explode('-', $this->filenameType); $this->filename = $this->findRandomFilename($type); } } if (!($moved = move_uploaded_file($this->data['tmp_name'], $this->uploadpath . $this->filename))) { $this->setError(1000, 'File system save failed.'); } } return $moved; } /** * validates the post data and checks receipt of the upload * * @param $file array content of $_FILES[yourfield] * @param $allowedMimeType array eg array(img, text).. leave null if no mime type validation is required * @return boolean true if post data is valid and file has been properly uploaded, false if not */ function validate($allowedMimeType=null) { $upload_error = $this->data['error']; $got_data = (is_uploaded_file($this->data['tmp_name'])); $err = false; if ($upload_error) { $this->setError(2500, 'Validation failed.', $this->getUploadErrorMessage($upload_error)); return false; } /* mime checking */ if (is_array($allowedMimeType)) { foreach ($allowedMimeType as $mimeType) { if(!in_array($this->data['type'], $this->allowedMime[$mimeType])) { $err = true; } } if ($err) { $this->setError(2000, 'The file uploaded is of an illegal mime type.'); return false; } } return !$upload_error && $got_data; } /** * parses file upload error code into human-readable phrase. * @param int $err PHP file upload error constant. * @return string human-readable phrase to explain issue. */ function getUploadErrorMessage($err) { $msg = null; switch ($err) { case UPLOAD_ERR_OK: break; case UPLOAD_ERR_INI_SIZE: $msg = ('The uploaded file exceeds the upload_max_filesize directive ('.ini_get('upload_max_filesize').') in php.ini.'); break; case UPLOAD_ERR_FORM_SIZE: $msg = ('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.'); break; case UPLOAD_ERR_PARTIAL: $msg = ('The file was only partially uploaded.'); break; case UPLOAD_ERR_NO_FILE: $msg = ('No file was uploaded.'); break; case UPLOAD_ERR_NO_TMP_DIR: $msg = ('The remote server has no temporary folder for file uploads.'); break; case UPLOAD_ERR_CANT_WRITE: $msg = ('Failed to write file to disk.'); break; default: $msg = ('Unknown File Error. Check php.ini settings.'); } return $msg; } /** * sets an error code which can be referenced if failure is detected by controller. * note: the amount of info stored in message depends on debug level. * @param int $code a unique error number for the message and debug info * @param string $message a simple message that you would show the user * @param string $debug any specific debug info to include when debug mode > 1 * @return bool true unless an error occurs */ function setError($code = 1, $message = 'An unknown error occured.', $debug = '') { $this->errorCode = $code; $this->errorMessage = $message; if (DEBUG) { $this->errorMessage .= $debug; } return true; } /** * Generates random characters * * @param int $length * @return string */ function random_word($length=8) { $i = 0; $char = ""; for($a=1;$a<=$length;$a++){ $val = ($a<=4)?rand (65,90):rand (48,57); $char .= chr($val); } return $char; } /** * Works best in single file upload * * @return bool */ function deleteRecentUpload() { return unlink($this->uploadpath . $this->filename); } } ?>