<?php
/**
* Filename.......: fileupload.class.php
* Version........: 1.3
* Project........: Simple Fileupload
* Copyright......: 2006, Fransjo Leihitu, http://www.leihitu.nl
*/
/*
* CHANGELOG
*
* 1.3 : 15-09-2006
* - added error msg
*
* 1.2 : 27-07-2006
* - Added check on chmod
* - added example with error check
*
*/
/*
TODO:
* check filesize
* check on Windows (ieeuw)
* MIME-types?
*/
/*
Usage and examples:
1) The basic with error check
$myFileUpload = new FileUpload($_FILES["my_file"],"my_target_path/");
if(!$myFileUpload->upload())
{
print "<pre>";
print_r($myFileUpload->getErrors());
print "</pre>";
}
2) Generate a uniq filename
$myFileUpload = new FileUpload($_FILES["my_file"],"my_target_path/");
$myFileUpload->useUniqFilename();
$myFileUpload->upload();
3) Only allow .jpg files
$myFileUpload = new FileUpload($_FILES["my_file"],"my_target_path/");
$myFileUpload->addExtension("jpg");
$myFileUpload->upload();
4) Only allow .jpg files and generate a uniq filename
$myFileUpload = new FileUpload($_FILES["my_file"],"my_target_path/");
$myFileUpload->addExtension("jpg");
$myFileUpload->useUniqFilename();
$myFileUpload->upload();
5) Only allow .jpg and .gif files
$myFileUpload = new FileUpload($_FILES["my_file"],"my_target_path/");
$myExtension=array();
$myExtension[]="jpg";
$myExtension[]="gif";
$myFileUpload-addExtensions($myExtension);
$myFileUpload->upload();
6) Allow all files except .php files
$myFileUpload = new FileUpload($_FILES["my_file"],"my_target_path/");
$myFileUpload->excludeExtension("php");
$myFileUpload->upload();
7) Only allow .jpg files and save the file to a filename you want
$myFileUpload = new FileUpload($_FILES["my_file"],"my_target_path/");
$myFileUpload->addExtension("jpg");
$myFileUpload->upload("my_picture.jpg");
PS when the file already exists on the server, the file will be deleted!
*/
class FileUpLoad
{
/**
* Target path where the file needs to be saves
* @var string
*/
var $targetPath;
/**
* If set true, an hash (md5) will be created to generate a filename
*
* @var boolean
*/
var $uniq_Filename;
/**
* If set true all white spaces will be removed
*
* Default: false;
*
* @var boolean
*/
var $strip_Spaces;
/**
* The $_FILES array, wich hold the array with information about the uploaded file
*
* Default: true;
*
* @var array
*/
var $fileArray;
/**
* Array wich holds all allowed extensions
* @var array
*/
var $allowedExtensions;
/**
* Array wich holds all excluded extensions
*
* @var array
*/
var $excludeExtensions;
/**
* When $uniq_Filename is false, the script uses the name that was submitted.
* When the file exists on the server, the existing file is deleted
*
* Default: true;
*
* @var boolean
*/
var $deleteDuplicateTargetFile;
/**
* Array wich holds all errors
*
* @var array
*/
var $errors;
/**
* Convert filename to lowercase
*
* Default: true;
*
*
* @var boolean
*/
var $useLowerCaseFileName;
/**
* Constructor.
*
* Sets up the object.
*
* @param $fileArray - The $_FILES array
* @param $targetPath - Path to save the file
*
* @access public
*/
function FileUpLoad($fileArray=null,$targetPath="")
{
$this->fileArray=null;
if(isSet($fileArray))
{
if($fileArray!=null)
{
$this->fileArray=$fileArray;
}
}
$this->targetPath="";
if(isSet($targetPath))
{
if(is_dir($targetPath))
{
$this->setTargetPath($targetPath);
}
}
$this->uniq_Filename=false;
$this->strip_Spaces=false;
$this->allowedExtensions=array();
$this->excludeExtensions=array();
$this->deleteDuplicateTargetFile=true;
$this->errors=array();
$this->useLowerCaseFileName=true;
$this->addDefaultExcludeExtensions();
}
function clear()
{
}
/**
* onlyImages()
*
* Sets jpg/jpeg/gif as allowed extension.
*
*
* @param $extension - Array with extra extensions
*
* @access public
*/
function onlyImages($extension=null)
{
if($extension!=null && count($extension)>0)
{
$count=count($extension);
for($i=0;$i<$count;$i++)
{
$this->addExtension($extension[$i]);
}
} else {
$this->addExtension("jpg");
$this->addExtension("jpeg");
$this->addExtension("gif");
}
}
/**
* dontUseLowerCaseFileName()
*
* Don't convert the filename to lowercase
*
*/
function dontUseLowerCaseFileName()
{
$this->useLowerCaseFileName=false;
}
/**
* excludeExtensions()
*
* Exclude a list of extensions
*
*
* @param $ex - Array with extensions to be excluded
*
* @access public
*/
function excludeExtensions($ex=null)
{
if($ex!=null)
{
$count=count($ex);
for($i=0;$i<$count;$i++)
{
$this->excludeExtension($ex[$i]);
}
}
}
/**
* excludeExtension()
*
* Exclude an extension
*
*
* @param $ex - String with an extension to be excluded
*
* @access public
*
* @return default: false, on success: true
*/
function excludeExtension($ex="")
{
if(isSet($ex))
{
$ex=strip_tags(stripslashes($ex));
$ex=strtolower(trim(str_replace(" ","",$ex)));
$ex=strtolower(trim(str_replace(".","",$ex)));
if($ex!="")
{
if(!isSet($this->excludeExtensions[$ex]))
{
$this->excludeExtensions[$ex]=$ex;
if(isSet($this->allowedExtensions[$ex]))
{
unset($this->allowedExtensions[$ex]);
}
return true;
}
}
}
return false;
}
/**
* addExtensions()
*
* Allow a list of extensions
*
*
* @param $ex - Array with extensions that are allowed
*
* @access public
*
* @return default: false, on success: true
*/
function addExtensions($ex=null)
{
if($ex!=null)
{
$count=count($ex);
for($i=0;$i<$count;$i++)
{
$this->addExtension($ex[$i]);
}
}
}
/**
* addExtension()
*
* Allow an extension
*
*
* @param $ex - String with an extension that is allowed
*
* @access public
*
* @return default: false, on success: true
*/
function addExtension($ex="")
{
if(isSet($ex))
{
$ex=strip_tags(stripslashes($ex));
$ex=strtolower(trim(str_replace(" ","",$ex)));
$ex=strtolower(trim(str_replace(".","",$ex)));
if($ex!="")
{
if(!isSet($this->allowedExtensions[$ex]))
{
$this->allowedExtensions[$ex]=$ex;
if(isSet($this->excludeExtensions[$ex]))
{
unset($this->excludeExtensions[$ex]);
}
return true;
}
}
}
return false;
}
/**
* stripSpaces()
*
* Strip white spaces
*
*/
function stripSpaces()
{
$this->strip_Spaces=true;
}
/**
* useUniqFilename()
*
* Filename will be generated with MD5
*
*/
function useUniqFilename()
{
$this->uniq_Filename=true;
}
/**
* setTargetPath()
*
* Set the target path where the file needs to be saves
*
*
* @param $path - String with the path
*
* @access public
*
* @return default: false, on success: true
*/
function setTargetPath($path="")
{
if(isSet($path))
{
$path=trim(strip_tags(stripslashes($path)));
if($path!="")
{
if(is_dir($path))
{
$this->targetPath=$path;
return true;
}
}
}
return false;
}
/**
* getFileExtension()
*
* Fet the file extension
*
*
* @param $filename - String with the filename
*
* @access public
*
* @return default: false, on success: the file extension
*/
function getFileExtension($filename="")
{
if(isSet($filename))
{
$filename=trim(strip_tags(stripslashes($filename)));
if($filename!="")
{
$dummyArray=split("[/.]",$filename);
$count=count($dummyArray);
if($count>0)
{
return strtolower($dummyArray[$count-1]);
}
}
}
return false;
}
/**
* addDefaultExcludeExtensions()
*
* Set some default exclude extensions
*
*
* @access public
*
*/
function addDefaultExcludeExtensions()
{
$this->excludeExtension("php");
$this->excludeExtension("asp");
$this->excludeExtension("cfm");
$this->excludeExtension("pl");
$this->excludeExtension("rb");
$this->excludeExtension("cgi");
$this->excludeExtension("jsp");
$this->excludeExtension("aspx");
}
/**
* upload()
*
* Upload the file
*
*
* @param $newFileName - If you just want to upload the file and give it the name you want
you can use this String
*
* @access public
*
* @return default: false, on success: the filename that was saved on the server
*/
function upload($newFileName="")
{
if($this->fileArray!=null)
{
if($this->targetPath!="")
{
if(isSet($this->fileArray["tmp_name"]))
{
// was the file uploaded?
if(is_uploaded_file($this->fileArray['tmp_name']))
{
// is there a name?
if(isSet($this->fileArray['name']))
{
$filename=$this->fileArray['name'];
// convert filename to lowercase?
if($this->useLowerCaseFileName==true)
{
$filename=strtolower($filename);
}
// get the extension
$extension=$this->getFileExtension($filename);
// check if the extension is not on the black list
if(!isSet($this->excludeExtensions[$extension]))
{
/*
* At this point the extension is almost safe.
* Now it neets to check if the extension is allowed
*
* This might be strange, but there are 3 ways to accept extensions:
*
* 1) ALL extensions are allowed
* 2) ALL extensions are allowed except some extensions (the exclude list)
* 3) ALL extensions are NOT allowed except some extenstions (the allow list)
*/
$doUpload=true;
$countAllowedExtensions=count($this->allowedExtensions);
if($countAllowedExtensions>0)
{
if(!isSet($this->allowedExtensions[$extension]))
{
$doUpload=false;
$this->addError("." . $extension . " files are not allowed!",1009);
}
}
// ok we can continue
if($doUpload==true)
{
// check if there was an filename given by the user
if(trim($newFileName)!="")
{
$filename=trim($newFileName);
// we don't need to generate a uniq filename
$this->uniq_Filename=false;
// and if the filename already exists, just delete it
$this->deleteDuplicateTargetFile=true;
}
// strip white spaced?
if($this->strip_Spaces==true) $filename=str_replace(" ","",$filename);
// setup the target path
$destination=$this->targetPath . "/" . $filename;
$destination=str_replace("//","/",$destination);
// do we need a uniq filename?
if($this->uniq_Filename==true)
{
$goAhead=false;
while($goAhead==false)
{
/*
* This loop will generate a new filename with the extension from the original file
* and checks if the file_already exists.
* If the file exists, a new filename will be generated
*/
$filename= md5(uniqid(rand(), true)) . "." . $extension;
$destination=$this->targetPath . "/" . $filename;
$destination=str_replace("//","/",$destination);
if(!is_file($destination)) $goAhead=true;
}
} else {
// so we don't need a uniq filename.
// check if a duplicate filename needs to be deleted
if($this->deleteDuplicateTargetFile==true)
{
if(is_file($destination))
{
unlink($destination);
}
}
}
// check is the target file already exists
if(!is_file($destination))
{
// try to move the tmp file to the destination file
if(move_uploaded_file($this->fileArray['tmp_name'], $destination))
{
// chmod the file
if(chmod($destination,0666))
{
// return the filename
return $filename;
} else {
$this->addError("Cannot chmod the file",1001);
}
} else {
$this->addError("Cannot move the file",1002);
}
} else {
$this->addError($filename . " already exists",1002);
}
}
} else {
$this->addError("." . $extension . " files are not allowed!",1003);
}
} else {
$this->addError("No filename",1004);
}
} else {
$error_str="";
switch ($this->fileArray["error"])
{
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_INI_SIZE:
$error_str="The uploaded file exceeds the upload_max_filesize directive (". ini_get("upload_max_filesize"). ") in php.ini.";
break;
case UPLOAD_ERR_FORM_SIZE:
$error_str="The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.";
break;
case UPLOAD_ERR_PARTIAL:
$error_str="The uploaded file was only partially uploaded.";
break;
case UPLOAD_ERR_NO_FILE:
$error_str="No file was uploaded.";
break;
case UPLOAD_ERR_NO_TMP_DIR:
$error_str="Missing a temporary folder.";
break;
case UPLOAD_ERR_CANT_WRITE:
$error_str="Failed to write file to disk";
break;
default:
$error_str="Unknown File Error";
}
$this->addError("File was not uploaded : " . $error_str,1005);
}
} else {
$this->addError("No file to upload",1006);
}
} else {
$this->addError("No targetpath",1007);
}
} else {
$this->addError("No filearray to upload",1008);
}
return false;
}
/**
* addError()
*
* Upload the file
*
*
* @param $error - String with the error
*
* @access public
*
*/
function addError($error="",$error_nr=0)
{
if(isSet($error))
{
if(trim($error)!="")
{
$errorPayload=array();
$errorPayload["error_nr"]=$error_nr;
$errorPayload["error_message"]=trim($error);
$this->errors[]=$errorPayload;
}
}
}
/**
* hasErrors()
*
* check if the error array is empty
*
*
* @access public
*
* @return default: false (no errors), otherwise true (has errors)
*/
function hasErrors()
{
$count=count($this->errors);
if($count>0) return true;
return false;
}
/**
* getErrors()
*
* returns the error(s)
*
*
* @access public
*
* @return default: false (no errors), otherwise array with error(s)
*/
function getErrors()
{
if($this->hasErrors())
{
return $this->errors;
} else {
return false;
}
}
}
/*
* Fransjo says:
*
* $1.3 : Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
* $1.2 : SELECT * FROM IQ ..... 0 row(s) affected.
* $1.1 : GOD is real, unless declared INT.
* $1.0 : It's life, but not as we know it.
*
*/
?>