<?php
namespace gnomephp\input;
class UploadField{
protected $fileArray=array();
protected $rules=array();
protected $messages = array();
public $requiered = false;
public function __construct($fileArray){
$this->fileArray = $fileArray;
}
/**
* Validation rule.
* Maximum size of file (in kilo bytes).
* @param string $message
*/
public function maxSize($kilo_bytes, $message = null) {
$message = ( empty ($message) ) ? 'The file size must not exceed '.$kilo_bytes.' KB' : $message;
$this->addValidaitonRule(__FUNCTION__, function(UploadField $self) use ($kilo_bytes) {
return $kilo_bytes >= $self->getSize()/1024 ? TRUE : FALSE;
}, $message);
return $this;
}
/**
* Validation rule.
* Minimum size of file. (in kilo bytes).
* @param string $message
*/
public function minSize($kilo_bytes, $message = null) {
$message = ( empty ($message) ) ? 'The file size must not be less then '.$kilo_bytes.' KB' : $message;
$this->addValidaitonRule(__FUNCTION__, function(UploadField $self) use ($kilo_bytes) {
return $kilo_bytes <= $self->getSize()/1024 ? TRUE : FALSE;
}, $message);
return $this;
}
/**
* Validation rule.
* Regexp match the filename.
* @param string $message
*/
public function regexpMatch($pattern, $message = null) {
$message = ( empty ($message) ) ? 'The file name is illegal. Please justify the filename before uploading.' : $message;
$this->addValidaitonRule(__FUNCTION__, function(UploadField $self) use ($pattern) {
return preg_match($pattern, $self->getName()) ? TRUE : FALSE;
}, $message);
return $this;
}
/**
* Validation rule.
* File is required to upload.
* @param string $message
*/
public function requiered($message = null) {
$message = ( empty ($message) ) ? 'It is required to upload a file.' : $message;
$this->addValidaitonRule(__FUNCTION__, function(UploadField $self) {
$self->requiered = true;
return $self->getName() != '' && $self->getTmpName() != '' ? TRUE : FALSE;
}, $message);
return $this;
}
/**
* Validation rule.
* Validates only if certain file extension is given.
* Provide array or a simple string.
* @param string $message
*/
public function validFileType($file_extensions, $message = null) {
$message = ( empty ($message) ) ? 'We do not allow that type of file extension. Allowed file extensions is:'.(is_array($file_extensions) ? implode(' ', $file_extensions) : $file_extensions) : $message;
$this->addValidaitonRule(__FUNCTION__, function(UploadField $self) use ($file_extensions) {
if (!is_array($file_extensions) && $self->getType() != $file_extensions)return false;
if (is_array($file_extensions)){
if (!in_array($self->getType(), $file_extensions))return false;
}
return true;
}, $message);
return $this;
}
/**
* Validates rules of file upload if any.
* @throws UploadFieldValidException
*/
protected function validate(){
$errors = array();
// Skip if empty and is not requiered.
if ($this->isEmpty() && !$this->requiered)return $this;
// try each rule function
foreach ($this->rules as $rule => $function) {
if (is_callable($function)) {
if ($function($this) === FALSE) {
$errors[] = $this->messages[$rule];
}
}
}
if (count($errors) > 0){
throw new UploadFieldValidException($errors);
}
return $this;
}
/**
*
* Uploads file to $path, and optionaly set a custom filename.
* If any validation rules is applied and fails, UploadFieldValidException is thrown.
* If any errors regarding upload failure UploadException will be thrown.
*
* Returns null if not uploaded ( file was not required in validation rules and was not uploaded ).
* @param string $path
* @param bool $filename
* @throws UploadException
* @throws UploadFieldValidException
*/
public function upload($path, $filename=null){
// Validate.
$this->validate();
// If is empty now, we don't upload.
if ($this->isEmpty())return null;
// Throw internal error messages if any this is before it's uploaded to the real location.
if ($this->getError() !== UPLOAD_ERR_OK)throw new UploadException($this->getError());
if ($filename === null)$filename = basename($this->getName());
if (!$filename && strstr($filename,'..'))throw new UploadException(UploadException::DOTDOT_FAILURE);
// Generate target path.
$len = strlen($path);
$target_path = $path . (substr($path, $len-1, $len)=='/' || substr($path, $len-1, $len) == '\\' ? '' : DIRECTORY_SEPARATOR) . $filename;
if(move_uploaded_file($this->getTmpName(), $target_path)){
// OK
}else{
throw new UploadException(UploadException::MOVE_UPLOAD_FAILURE);
}
return $this;
}
public function isEmpty(){
return $this->getName() == '' && $this->getTmpName() == '';
}
/**
* Gets the name of the file.
*/
public function getName(){
return $this->fileArray['name'];
}
/**
* Gets the temporary name of the file stored on the server.
*/
public function getTmpName(){
return $this->fileArray['tmp_name'];
}
/**
* Gets the size of the file.
*/
public function getSize(){
return $this->fileArray['size'];
}
/**
* Gets the filetype of the file.
*/
public function getType(){
return $this->fileArray['type'];
}
/**
* Gets the error code if any.
*/
public function getError(){
return $this->fileArray['error'];
}
/**
* addValidaitonRule
* @param string $rule
* @param closure $function
* @param string $message
*/
public function addValidaitonRule($rule, $function, $message='') {
if (is_callable($function)) {
$this->rules[$rule] = $function;
if (!empty($message)) {
$this->messages[$rule] = $message;
}
}
return $this;
}
}