From c53d8d026021f97075fb2f4940ba22793c38fb6e Mon Sep 17 00:00:00 2001 From: davehauenstein Date: Wed, 15 Apr 2009 22:06:42 +0000 Subject: added toolbar; functionality includes refresh button to get back to original page, print article, email a link to the article with a personal note git-svn-id: http://arc90labs-readability.googlecode.com/svn/trunk@31 d4e419ec-0920-11de-bbfd-a7c1bc4c261e --- lib/Zend/Validate/File/Count.php | 275 +++++++++++++++++++ lib/Zend/Validate/File/Crc32.php | 179 ++++++++++++ lib/Zend/Validate/File/ExcludeExtension.php | 94 +++++++ lib/Zend/Validate/File/ExcludeMimeType.php | 91 +++++++ lib/Zend/Validate/File/Exists.php | 203 ++++++++++++++ lib/Zend/Validate/File/Extension.php | 234 ++++++++++++++++ lib/Zend/Validate/File/FilesSize.php | 163 +++++++++++ lib/Zend/Validate/File/Hash.php | 195 ++++++++++++++ lib/Zend/Validate/File/ImageSize.php | 370 +++++++++++++++++++++++++ lib/Zend/Validate/File/IsCompressed.php | 133 +++++++++ lib/Zend/Validate/File/IsImage.php | 137 ++++++++++ lib/Zend/Validate/File/Md5.php | 183 +++++++++++++ lib/Zend/Validate/File/MimeType.php | 283 +++++++++++++++++++ lib/Zend/Validate/File/NotExists.php | 84 ++++++ lib/Zend/Validate/File/Sha1.php | 181 +++++++++++++ lib/Zend/Validate/File/Size.php | 404 ++++++++++++++++++++++++++++ lib/Zend/Validate/File/Upload.php | 234 ++++++++++++++++ 17 files changed, 3443 insertions(+) create mode 100644 lib/Zend/Validate/File/Count.php create mode 100644 lib/Zend/Validate/File/Crc32.php create mode 100644 lib/Zend/Validate/File/ExcludeExtension.php create mode 100644 lib/Zend/Validate/File/ExcludeMimeType.php create mode 100644 lib/Zend/Validate/File/Exists.php create mode 100644 lib/Zend/Validate/File/Extension.php create mode 100644 lib/Zend/Validate/File/FilesSize.php create mode 100644 lib/Zend/Validate/File/Hash.php create mode 100644 lib/Zend/Validate/File/ImageSize.php create mode 100644 lib/Zend/Validate/File/IsCompressed.php create mode 100644 lib/Zend/Validate/File/IsImage.php create mode 100644 lib/Zend/Validate/File/Md5.php create mode 100644 lib/Zend/Validate/File/MimeType.php create mode 100644 lib/Zend/Validate/File/NotExists.php create mode 100644 lib/Zend/Validate/File/Sha1.php create mode 100644 lib/Zend/Validate/File/Size.php create mode 100644 lib/Zend/Validate/File/Upload.php (limited to 'lib/Zend/Validate/File') diff --git a/lib/Zend/Validate/File/Count.php b/lib/Zend/Validate/File/Count.php new file mode 100644 index 0000000..97667ab --- /dev/null +++ b/lib/Zend/Validate/File/Count.php @@ -0,0 +1,275 @@ + "Too much files, maximum '%max%' are allowed but '%count%' are given", + self::TOO_LESS => "Too less files, minimum '%min%' are expected but '%count%' are given" + ); + + /** + * @var array Error message template variables + */ + protected $_messageVariables = array( + 'min' => '_min', + 'max' => '_max', + 'count' => '_count' + ); + + /** + * Minimum file count + * + * If null, there is no minimum file count + * + * @var integer + */ + protected $_min; + + /** + * Maximum file count + * + * If null, there is no maximum file count + * + * @var integer|null + */ + protected $_max; + + /** + * Actual filecount + * + * @var integer + */ + protected $_count; + + /** + * Internal file array + * @var array + */ + protected $_files; + + /** + * Sets validator options + * + * Min limits the file count, when used with max=null it is the maximum file count + * It also accepts an array with the keys 'min' and 'max' + * + * If $options is a integer, it will be used as maximum file count + * As Array is accepts the following keys: + * 'min': Minimum filecount + * 'max': Maximum filecount + * + * @param integer|array $options Options for the adapter + * @param integer $max (Deprecated) Maximum value (implies $options is the minimum) + * @return void + */ + public function __construct($options) + { + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } elseif (is_string($options) || is_numeric($options)) { + $options = array('max' => $options); + } elseif (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + if (1 < func_num_args()) { + trigger_error('Multiple arguments are deprecated in favor of an array of named arguments', E_USER_NOTICE); + $options['min'] = func_get_arg(0); + $options['max'] = func_get_arg(1); + } + + if (isset($options['min'])) { + $this->setMin($options); + } + + if (isset($options['max'])) { + $this->setMax($options); + } + } + + /** + * Returns the minimum file count + * + * @return integer + */ + public function getMin() + { + return $this->_min; + } + + /** + * Sets the minimum file count + * + * @param integer|array $min The minimum file count + * @return Zend_Validate_File_Count Provides a fluent interface + * @throws Zend_Validate_Exception When min is greater than max + */ + public function setMin($min) + { + if (is_array($min) and isset($min['min'])) { + $min = $min['min']; + } + + if (!is_string($min) and !is_numeric($min)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + $min = (integer) $min; + if (($this->_max !== null) && ($min > $this->_max)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum file count, but $min >" + . " {$this->_max}"); + } + + $this->_min = $min; + return $this; + } + + /** + * Returns the maximum file count + * + * @return integer + */ + public function getMax() + { + return $this->_max; + } + + /** + * Sets the maximum file count + * + * @param integer|array $max The maximum file count + * @return Zend_Validate_StringLength Provides a fluent interface + * @throws Zend_Validate_Exception When max is smaller than min + */ + public function setMax($max) + { + if (is_array($max) and isset($max['max'])) { + $max = $max['max']; + } + + if (!is_string($max) and !is_numeric($max)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + $max = (integer) $max; + if (($this->_min !== null) && ($max < $this->_min)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum file count, but " + . "$max < {$this->_min}"); + } + + $this->_max = $max; + return $this; + } + + /** + * Adds a file for validation + * + * @param string|array $file + */ + public function addFile($file) + { + if (is_string($file)) { + $file = array($file); + } + + if (is_array($file)) { + foreach ($file as $name) { + if (!isset($this->_files[$name])) { + $this->_files[$name] = $name; + } + } + } + + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the file count of all checked files is at least min and + * not bigger than max (when max is not null). Attention: When checking with set min you + * must give all files with the first call, otherwise you will get an false. + * + * @param string|array $value Filenames to check for count + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + $this->addFile($value); + $this->_count = count($this->_files); + if (($this->_max !== null) && ($this->_count > $this->_max)) { + return $this->_throw($file, self::TOO_MUCH); + } + + if (($this->_min !== null) && ($this->_count < $this->_min)) { + return $this->_throw($file, self::TOO_LESS); + } + + return true; + } + + /** + * Throws an error of the given type + * + * @param string $file + * @param string $errorType + * @return false + */ + protected function _throw($file, $errorType) + { + if ($file !== null) { + $this->_value = $file['name']; + } + + $this->_error($errorType); + return false; + } +} diff --git a/lib/Zend/Validate/File/Crc32.php b/lib/Zend/Validate/File/Crc32.php new file mode 100644 index 0000000..47ace9d --- /dev/null +++ b/lib/Zend/Validate/File/Crc32.php @@ -0,0 +1,179 @@ + "The file '%value%' does not match the given crc32 hashes", + self::NOT_DETECTED => "There was no crc32 hash detected for the given file", + self::NOT_FOUND => "The file '%value%' could not be found" + ); + + /** + * Hash of the file + * + * @var string + */ + protected $_hash; + + /** + * Sets validator options + * + * @param string|array $options + * @return void + */ + public function __construct($options) + { + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } elseif (is_scalar($options)) { + $options = array('hash1' => $options); + } elseif (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception('Invalid options to validator provided'); + } + + $this->setCrc32($options); + } + + /** + * Returns all set crc32 hashes + * + * @return array + */ + public function getCrc32() + { + return $this->getHash(); + } + + /** + * Sets the crc32 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function setHash($options) + { + if (!is_array($options)) { + $options = array($options); + } + + $options['algorithm'] = 'crc32'; + parent::setHash($options); + return $this; + } + + /** + * Sets the crc32 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function setCrc32($options) + { + $this->setHash($options); + return $this; + } + + /** + * Adds the crc32 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function addHash($options) + { + if (!is_array($options)) { + $options = array($options); + } + + $options['algorithm'] = 'crc32'; + parent::addHash($options); + return $this; + } + + /** + * Adds the crc32 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function addCrc32($options) + { + $this->addHash($options); + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the given file confirms the set hash + * + * @param string $value Filename to check for hash + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_FOUND); + } + + $hashes = array_unique(array_keys($this->_hash)); + $filehash = hash_file('crc32', $value); + if ($filehash === false) { + return $this->_throw($file, self::NOT_DETECTED); + } + + foreach($hashes as $hash) { + if ($filehash === $hash) { + return true; + } + } + + return $this->_throw($file, self::DOES_NOT_MATCH); + } +} \ No newline at end of file diff --git a/lib/Zend/Validate/File/ExcludeExtension.php b/lib/Zend/Validate/File/ExcludeExtension.php new file mode 100644 index 0000000..2a442ab --- /dev/null +++ b/lib/Zend/Validate/File/ExcludeExtension.php @@ -0,0 +1,94 @@ + "The file '%value%' has a false extension", + self::NOT_FOUND => "The file '%value%' was not found" + ); + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the fileextension of $value is not included in the + * set extension list + * + * @param string $value Real file to check for extension + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_FOUND); + } + + if ($file !== null) { + $info['extension'] = substr($file['name'], strrpos($file['name'], '.') + 1); + } else { + $info = pathinfo($value); + } + + $extensions = $this->getExtension(); + + if ($this->_case and (!in_array($info['extension'], $extensions))) { + return true; + } else if (!$this->_case) { + $found = false; + foreach ($extensions as $extension) { + if (strtolower($extension) == strtolower($info['extension'])) { + $found = true; + } + } + + if (!$found) { + return true; + } + } + + return $this->_throw($file, self::FALSE_EXTENSION); + } +} diff --git a/lib/Zend/Validate/File/ExcludeMimeType.php b/lib/Zend/Validate/File/ExcludeMimeType.php new file mode 100644 index 0000000..d69dc06 --- /dev/null +++ b/lib/Zend/Validate/File/ExcludeMimeType.php @@ -0,0 +1,91 @@ +_throw($file, self::NOT_READABLE); + } + + if ($file !== null) { + if (class_exists('finfo', false) && defined('MAGIC')) { + $mime = new finfo(FILEINFO_MIME); + $this->_type = $mime->file($value); + unset($mime); + } elseif (function_exists('mime_content_type') && ini_get('mime_magic.magicfile')) { + $this->_type = mime_content_type($value); + } else { + $this->_type = $file['type']; + } + } + + if (empty($this->_type)) { + return $this->_throw($file, self::NOT_DETECTED); + } + + $mimetype = $this->getMimeType(true); + if (in_array($this->_type, $mimetype)) { + return $this->_throw($file, self::FALSE_TYPE); + } + + $types = explode('/', $this->_type); + $types = array_merge($types, explode('-', $this->_type)); + foreach($mimetype as $mime) { + if (in_array($mime, $types)) { + return $this->_throw($file, self::FALSE_TYPE); + } + } + + return true; + } +} diff --git a/lib/Zend/Validate/File/Exists.php b/lib/Zend/Validate/File/Exists.php new file mode 100644 index 0000000..cf509aa --- /dev/null +++ b/lib/Zend/Validate/File/Exists.php @@ -0,0 +1,203 @@ + "The file '%value%' does not exist" + ); + + /** + * Internal list of directories + * @var string + */ + protected $_directory = ''; + + /** + * @var array Error message template variables + */ + protected $_messageVariables = array( + 'directory' => '_directory' + ); + + /** + * Sets validator options + * + * @param string|array $directory + * @return void + */ + public function __construct($directory = array()) + { + if ($directory instanceof Zend_Config) { + $directory = $directory->toArray(); + } else if (is_string($directory)) { + $directory = explode(',', $directory); + } else if (!is_array($directory)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + $this->setDirectory($directory); + } + + /** + * Returns the set file directories which are checked + * + * @param boolean $asArray Returns the values as array, when false an concated string is returned + * @return string + */ + public function getDirectory($asArray = false) + { + $asArray = (bool) $asArray; + $directory = (string) $this->_directory; + if ($asArray) { + $directory = explode(',', $directory); + } + + return $directory; + } + + /** + * Sets the file directory which will be checked + * + * @param string|array $directory The directories to validate + * @return Zend_Validate_File_Extension Provides a fluent interface + */ + public function setDirectory($directory) + { + $this->_directory = null; + $this->addDirectory($directory); + return $this; + } + + /** + * Adds the file directory which will be checked + * + * @param string|array $directory The directory to add for validation + * @return Zend_Validate_File_Extension Provides a fluent interface + */ + public function addDirectory($directory) + { + $directories = $this->getDirectory(true); + + if (is_string($directory)) { + $directory = explode(',', $directory); + } else if (!is_array($directory)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + foreach ($directory as $content) { + if (empty($content) || !is_string($content)) { + continue; + } + + $directories[] = trim($content); + } + $directories = array_unique($directories); + + // Sanity check to ensure no empty values + foreach ($directories as $key => $dir) { + if (empty($dir)) { + unset($directories[$key]); + } + } + + $this->_directory = implode(',', $directories); + + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the file already exists in the set directories + * + * @param string $value Real file to check for existance + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + $directories = $this->getDirectory(true); + if (($file !== null) and (!empty($file['destination']))) { + $directories[] = $file['destination']; + } else if (!isset($file['name'])) { + $file['name'] = $value; + } + + $check = false; + foreach ($directories as $directory) { + if (empty($directory)) { + continue; + } + + $check = true; + if (!file_exists($directory . DIRECTORY_SEPARATOR . $file['name'])) { + return $this->_throw($file, self::DOES_NOT_EXIST); + } + } + + if (!$check) { + return $this->_throw($file, self::DOES_NOT_EXIST); + } + + return true; + } + + /** + * Throws an error of the given type + * + * @param string $file + * @param string $errorType + * @return false + */ + protected function _throw($file, $errorType) + { + if ($file !== null) { + $this->_value = $file['name']; + } + + $this->_error($errorType); + return false; + } +} diff --git a/lib/Zend/Validate/File/Extension.php b/lib/Zend/Validate/File/Extension.php new file mode 100644 index 0000000..49411b3 --- /dev/null +++ b/lib/Zend/Validate/File/Extension.php @@ -0,0 +1,234 @@ + "The file '%value%' has a false extension", + self::NOT_FOUND => "The file '%value%' was not found" + ); + + /** + * Internal list of extensions + * @var string + */ + protected $_extension = ''; + + /** + * Validate case sensitive + * + * @var boolean + */ + protected $_case = false; + + /** + * @var array Error message template variables + */ + protected $_messageVariables = array( + 'extension' => '_extension' + ); + + /** + * Sets validator options + * + * @param string|array $extension + * @param boolean $case If true validation is done case sensitive + * @return void + */ + public function __construct($options) + { + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } + + if (1 < func_num_args()) { + trigger_error('Multiple arguments to constructor are deprecated in favor of options array', E_USER_NOTICE); + $case = func_get_arg(1); + $this->setCase($case); + } + + if (is_array($options) and isset($options['case'])) { + $this->setCase($options['case']); + unset($options['case']); + } + + $this->setExtension($options); + } + + /** + * Returns the case option + * + * @return boolean + */ + public function getCase() + { + return $this->_case; + } + + /** + * Sets the case to use + * + * @param boolean $case + * @return Zend_Validate_File_Extension Provides a fluent interface + */ + public function setCase($case) + { + $this->_case = (boolean) $case; + return $this; + } + + /** + * Returns the set file extension + * + * @return array + */ + public function getExtension() + { + $extension = explode(',', $this->_extension); + + return $extension; + } + + /** + * Sets the file extensions + * + * @param string|array $extension The extensions to validate + * @return Zend_Validate_File_Extension Provides a fluent interface + */ + public function setExtension($extension) + { + $this->_extension = null; + $this->addExtension($extension); + return $this; + } + + /** + * Adds the file extensions + * + * @param string|array $extension The extensions to add for validation + * @return Zend_Validate_File_Extension Provides a fluent interface + */ + public function addExtension($extension) + { + $extensions = $this->getExtension(); + if (is_string($extension)) { + $extension = explode(',', $extension); + } + + foreach ($extension as $content) { + if (empty($content) || !is_string($content)) { + continue; + } + + $extensions[] = trim($content); + } + $extensions = array_unique($extensions); + + // Sanity check to ensure no empty values + foreach ($extensions as $key => $ext) { + if (empty($ext)) { + unset($extensions[$key]); + } + } + + $this->_extension = implode(',', $extensions); + + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the fileextension of $value is included in the + * set extension list + * + * @param string $value Real file to check for extension + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_FOUND); + } + + if ($file !== null) { + $info['extension'] = substr($file['name'], strrpos($file['name'], '.') + 1); + } else { + $info = pathinfo($value); + } + + $extensions = $this->getExtension(); + + if ($this->_case && (in_array($info['extension'], $extensions))) { + return true; + } else if (!$this->getCase()) { + foreach ($extensions as $extension) { + if (strtolower($extension) == strtolower($info['extension'])) { + return true; + } + } + } + + return $this->_throw($file, self::FALSE_EXTENSION); + } + + /** + * Throws an error of the given type + * + * @param string $file + * @param string $errorType + * @return false + */ + protected function _throw($file, $errorType) + { + if (null !== $file) { + $this->_value = $file['name']; + } + + $this->_error($errorType); + return false; + } +} diff --git a/lib/Zend/Validate/File/FilesSize.php b/lib/Zend/Validate/File/FilesSize.php new file mode 100644 index 0000000..ea8d085 --- /dev/null +++ b/lib/Zend/Validate/File/FilesSize.php @@ -0,0 +1,163 @@ + "All files in sum should have a maximum size of '%max%' but '%size%' were detected", + self::TOO_SMALL => "All files in sum should have a minimum size of '%min%' but '%size%' were detected", + self::NOT_READABLE => "One or more files can not be read" + ); + + /** + * Internal file array + * + * @var array + */ + protected $_files; + + /** + * Sets validator options + * + * Min limits the used diskspace for all files, when used with max=null it is the maximum filesize + * It also accepts an array with the keys 'min' and 'max' + * + * @param integer|array $min Minimum diskspace for all files + * @param integer $max Maximum diskspace for all files (deprecated) + * @param boolean $bytestring Use bytestring or real size ? (deprecated) + * @return void + */ + public function __construct($options) + { + $this->_files = array(); + $this->_setSize(0); + + if (1 < func_num_args()) { + trigger_error('Multiple constructor options are deprecated in favor of a single options array', E_USER_NOTICE); + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } elseif (is_scalar($options)) { + $options = array('min' => $options); + } elseif (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception('Invalid options to validator provided'); + } + + $argv = func_get_args(); + array_shift($argv); + $options['max'] = array_shift($argv); + if (!empty($argv)) { + $options['bytestring'] = array_shift($argv); + } + } + + parent::__construct($options); + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the disk usage of all files is at least min and + * not bigger than max (when max is not null). + * + * @param string|array $value Real file to check for size + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + require_once 'Zend/Loader.php'; + if (is_string($value)) { + $value = array($value); + } + + $min = $this->getMin(true); + $max = $this->getMax(true); + $size = $this->_getSize(); + foreach ($value as $files) { + // Is file readable ? + if (!Zend_Loader::isReadable($files)) { + $this->_throw($file, self::NOT_READABLE); + continue; + } + + if (!isset($this->_files[$files])) { + $this->_files[$files] = $files; + } else { + // file already counted... do not count twice + continue; + } + + // limited to 2GB files + $size += @filesize($files); + $this->_setSize($size); + if (($max !== null) && ($max < $size)) { + if ($this->useByteString()) { + $this->setMax($this->_toByteString($max)); + $this->_throw($file, self::TOO_BIG); + $this->setMax($max); + } else { + $this->_throw($file, self::TOO_BIG); + } + } + } + + // Check that aggregate files are >= minimum size + if (($min !== null) && ($size < $min)) { + if ($this->useByteString()) { + $this->setMin($this->_toByteString($min)); + $this->_throw($file, self::TOO_SMALL); + $this->setMin($min); + } else { + $this->_throw($file, self::TOO_SMALL); + } + } + + if (count($this->_messages) > 0) { + return false; + } + + return true; + } +} diff --git a/lib/Zend/Validate/File/Hash.php b/lib/Zend/Validate/File/Hash.php new file mode 100644 index 0000000..1702593 --- /dev/null +++ b/lib/Zend/Validate/File/Hash.php @@ -0,0 +1,195 @@ + "The file '%value%' does not match the given hashes", + self::NOT_DETECTED => "There was no hash detected for the given file", + self::NOT_FOUND => "The file '%value%' could not be found" + ); + + /** + * Hash of the file + * + * @var string + */ + protected $_hash; + + /** + * Sets validator options + * + * @param string|array $options + * @return void + */ + public function __construct($options) + { + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } elseif (is_scalar($options)) { + $options = array('hash1' => $options); + } elseif (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception('Invalid options to validator provided'); + } + + if (1 < func_num_args()) { + trigger_error('Multiple constructor options are deprecated in favor of a single options array', E_USER_NOTICE); + $options['algorithm'] = func_get_arg(1); + } + + $this->setHash($options); + } + + /** + * Returns the set hash values as array, the hash as key and the algorithm the value + * + * @return array + */ + public function getHash() + { + return $this->_hash; + } + + /** + * Sets the hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function setHash($options) + { + $this->_hash = null; + $this->addHash($options); + + return $this; + } + + /** + * Adds the hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function addHash($options) + { + if (is_string($options)) { + $options = array($options); + } else if (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("False parameter given"); + } + + $known = hash_algos(); + if (!isset($options['algorithm'])) { + $algorithm = 'crc32'; + } else { + $algorithm = $options['algorithm']; + unset($options['algorithm']); + } + + if (!in_array($algorithm, $known)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("Unknown algorithm '{$algorithm}'"); + } + + foreach ($options as $value) { + $this->_hash[$value] = $algorithm; + } + + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the given file confirms the set hash + * + * @param string $value Filename to check for hash + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_FOUND); + } + + $algos = array_unique(array_values($this->_hash)); + $hashes = array_unique(array_keys($this->_hash)); + foreach ($algos as $algorithm) { + $filehash = hash_file($algorithm, $value); + if ($filehash === false) { + return $this->_throw($file, self::NOT_DETECTED); + } + + foreach($hashes as $hash) { + if ($filehash === $hash) { + return true; + } + } + } + + return $this->_throw($file, self::DOES_NOT_MATCH); + } + + /** + * Throws an error of the given type + * + * @param string $file + * @param string $errorType + * @return false + */ + protected function _throw($file, $errorType) + { + if ($file !== null) { + $this->_value = $file['name']; + } + + $this->_error($errorType); + return false; + } +} diff --git a/lib/Zend/Validate/File/ImageSize.php b/lib/Zend/Validate/File/ImageSize.php new file mode 100644 index 0000000..ada8bd3 --- /dev/null +++ b/lib/Zend/Validate/File/ImageSize.php @@ -0,0 +1,370 @@ + "Maximum allowed width for image '%value%' should be '%maxwidth%' but '%width%' detected", + self::WIDTH_TOO_SMALL => "Minimum expected width for image '%value%' should be '%minwidth%' but '%width%' detected", + self::HEIGHT_TOO_BIG => "Maximum allowed height for image '%value%' should be '%maxheight%' but '%height%' detected", + self::HEIGHT_TOO_SMALL => "Minimum expected height for image '%value%' should be '%minheight%' but '%height%' detected", + self::NOT_DETECTED => "The size of image '%value%' could not be detected", + self::NOT_READABLE => "The image '%value%' can not be read" + ); + + /** + * @var array Error message template variables + */ + protected $_messageVariables = array( + 'minwidth' => '_minwidth', + 'maxwidth' => '_maxwidth', + 'minheight' => '_minheight', + 'maxheight' => '_maxheight', + 'width' => '_width', + 'height' => '_height' + ); + + /** + * Minimum image width + * + * @var integer + */ + protected $_minwidth; + + /** + * Maximum image width + * + * @var integer + */ + protected $_maxwidth; + + /** + * Minimum image height + * + * @var integer + */ + protected $_minheight; + + /** + * Maximum image height + * + * @var integer + */ + protected $_maxheight; + + /** + * Detected width + * + * @var integer + */ + protected $_width; + + /** + * Detected height + * + * @var integer + */ + protected $_height; + + /** + * Sets validator options + * + * Accepts the following option keys: + * - minheight + * - minwidth + * - maxheight + * - maxwidth + * + * @param Zend_Config|array $options + * @return void + */ + public function __construct($options) + { + $minwidth = 0; + $minheight = 0; + $maxwidth = null; + $maxheight = null; + + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } elseif (1 < func_num_args()) { + trigger_error('Multiple constructor options are deprecated in favor of a single options array', E_USER_NOTICE); + if (!is_array($options)) { + $options = array('minwidth' => $options); + } + $argv = func_get_args(); + array_shift($argv); + $options['minheight'] = array_shift($argv); + if (!empty($argv)) { + $options['maxwidth'] = array_shift($argv); + if (!empty($argv)) { + $options['maxheight'] = array_shift($argv); + } + } + } else if (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + if (isset($options['minheight']) || isset($options['minwidth'])) { + $this->setImageMin($options); + } + + if (isset($options['maxheight']) || isset($options['maxwidth'])) { + $this->setImageMax($options); + } + } + + /** + * Returns the set minimum image sizes + * + * @return array + */ + public function getImageMin() + { + return array('minwidth' => $this->_minwidth, 'minheight' => $this->_minheight); + } + + /** + * Returns the set maximum image sizes + * + * @return array + */ + public function getImageMax() + { + return array('maxwidth' => $this->_maxwidth, 'maxheight' => $this->_maxheight); + } + + /** + * Returns the set image width sizes + * + * @return array + */ + public function getImageWidth() + { + return array('minwidth' => $this->_minwidth, 'maxwidth' => $this->_maxwidth); + } + + /** + * Returns the set image height sizes + * + * @return array + */ + public function getImageHeight() + { + return array('minheight' => $this->_minheight, 'maxheight' => $this->_maxheight); + } + + /** + * Sets the minimum image size + * + * @param array $options The minimum image dimensions + * @throws Zend_Validate_Exception When minwidth is greater than maxwidth + * @throws Zend_Validate_Exception When minheight is greater than maxheight + * @return Zend_Validate_File_ImageSize Provides a fluent interface + */ + public function setImageMin($options) + { + if (isset($options['minwidth'])) { + if (($this->_maxwidth !== null) and ($options['minwidth'] > $this->_maxwidth)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The minimum image width must be less than or equal to the " + . " maximum image width, but {$options['minwidth']} > {$this->_maxwidth}"); + } + } + + if (isset($options['maxheight'])) { + if (($this->_maxheight !== null) and ($options['minheight'] > $this->_maxheight)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The minimum image height must be less than or equal to the " + . " maximum image height, but {$options['minheight']} > {$this->_maxheight}"); + } + } + + if (isset($options['minwidth'])) { + $this->_minwidth = (int) $options['minwidth']; + } + + if (isset($options['minheight'])) { + $this->_minheight = (int) $options['minheight']; + } + + return $this; + } + + /** + * Sets the maximum image size + * + * @param array $options The maximum image dimensions + * @throws Zend_Validate_Exception When maxwidth is smaller than minwidth + * @throws Zend_Validate_Exception When maxheight is smaller than minheight + * @return Zend_Validate_StringLength Provides a fluent interface + */ + public function setImageMax($options) + { + if (isset($options['maxwidth'])) { + if (($this->_minwidth !== null) and ($options['maxwidth'] < $this->_minwidth)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The maximum image width must be greater than or equal to the " + . "minimum image width, but {$options['maxwidth']} < {$this->_minwidth}"); + } + } + + if (isset($options['maxheight'])) { + if (($this->_minheight !== null) and ($options['maxheight'] < $this->_minheight)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The maximum image height must be greater than or equal to the " + . "minimum image height, but {$options['maxheight']} < {$this->_minwidth}"); + } + } + + if (isset($options['maxwidth'])) { + $this->_maxwidth = (int) $options['maxwidth']; + } + + if (isset($options['maxheight'])) { + $this->_maxheight = (int) $options['maxheight']; + } + + return $this; + } + + /** + * Sets the mimimum and maximum image width + * + * @param array $options The image width dimensions + * @return Zend_Validate_File_ImageSize Provides a fluent interface + */ + public function setImageWidth($options) + { + $this->setImageMin($options); + $this->setImageMax($options); + + return $this; + } + + /** + * Sets the mimimum and maximum image height + * + * @param array $options The image height dimensions + * @return Zend_Validate_File_ImageSize Provides a fluent interface + */ + public function setImageHeight($options) + { + $this->setImageMin($options); + $this->setImageMax($options); + + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the imagesize of $value is at least min and + * not bigger than max + * + * @param string $value Real file to check for image size + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_READABLE); + } + + $size = @getimagesize($value); + $this->_setValue($file); + + if (empty($size) or ($size[0] === 0) or ($size[1] === 0)) { + return $this->_throw($file, self::NOT_DETECTED); + } + + $this->_width = $size[0]; + $this->_height = $size[1]; + if ($this->_width < $this->_minwidth) { + $this->_throw($file, self::WIDTH_TOO_SMALL); + } + + if (($this->_maxwidth !== null) and ($this->_maxwidth < $this->_width)) { + $this->_throw($file, self::WIDTH_TOO_BIG); + } + + if ($this->_height < $this->_minheight) { + $this->_throw($file, self::HEIGHT_TOO_SMALL); + } + + if (($this->_maxheight !== null) and ($this->_maxheight < $this->_height)) { + $this->_throw($file, self::HEIGHT_TOO_BIG); + } + + if (count($this->_messages) > 0) { + return false; + } + + return true; + } + + /** + * Throws an error of the given type + * + * @param string $file + * @param string $errorType + * @return false + */ + protected function _throw($file, $errorType) + { + if ($file !== null) { + $this->_value = $file['name']; + } + + $this->_error($errorType); + return false; + } +} diff --git a/lib/Zend/Validate/File/IsCompressed.php b/lib/Zend/Validate/File/IsCompressed.php new file mode 100644 index 0000000..050eb1c --- /dev/null +++ b/lib/Zend/Validate/File/IsCompressed.php @@ -0,0 +1,133 @@ + "The file '%value%' is not compressed, '%type%' detected", + self::NOT_DETECTED => "The mimetype of file '%value%' has not been detected", + self::NOT_READABLE => "The file '%value%' can not be read" + ); + + /** + * Sets validator options + * + * @param string|array $compression + * @return void + */ + public function __construct($mimetype = array()) + { + if (empty($mimetype)) { + $mimetype = array( + 'application/x-tar', + 'application/x-cpio', + 'application/x-debian-package', + 'application/x-archive', + 'application/x-arc', + 'application/x-arj', + 'application/x-lharc', + 'application/x-lha', + 'application/x-rar', + 'application/zip', + 'application/zoo', + 'application/x-eet', + 'application/x-java-pack200', + 'application/x-compress', + 'application/x-gzip', + 'application/x-bzip2' + ); + } + + $this->setMimeType($mimetype); + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the file is compression with the set compression types + * + * @param string $value Real file to check for compression + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_READABLE); + } + + if ($file !== null) { + if (class_exists('finfo', false) && defined('MAGIC')) { + $mime = new finfo(FILEINFO_MIME); + $this->_type = $mime->file($value); + unset($mime); + } elseif (function_exists('mime_content_type') && ini_get('mime_magic.magicfile')) { + $this->_type = mime_content_type($value); + } else { + $this->_type = $file['type']; + } + } + + if (empty($this->_type)) { + return $this->_throw($file, self::NOT_DETECTED); + } + + $compressions = $this->getMimeType(true); + if (in_array($this->_type, $compressions)) { + return true; + } + + $types = explode('/', $this->_type); + $types = array_merge($types, explode('-', $this->_type)); + foreach ($compressions as $mime) { + if (in_array($mime, $types)) { + return true; + } + } + + return $this->_throw($file, self::FALSE_TYPE); + } +} diff --git a/lib/Zend/Validate/File/IsImage.php b/lib/Zend/Validate/File/IsImage.php new file mode 100644 index 0000000..045c7fe --- /dev/null +++ b/lib/Zend/Validate/File/IsImage.php @@ -0,0 +1,137 @@ + "The file '%value%' is no image, '%type%' detected", + self::NOT_DETECTED => "The mimetype of file '%value%' has not been detected", + self::NOT_READABLE => "The file '%value%' can not be read" + ); + + /** + * Sets validator options + * + * @param string|array $mimetype + * @return void + */ + public function __construct($mimetype = array()) + { + if (empty($mimetype)) { + $mimetype = array( + 'image/x-quicktime', + 'image/jp2', + 'image/x-xpmi', + 'image/x-portable-bitmap', + 'image/x-portable-greymap', + 'image/x-portable-pixmap', + 'image/x-niff', + 'image/tiff', + 'image/png', + 'image/x-unknown', + 'image/gif', + 'image/x-ms-bmp', + 'application/dicom', + 'image/vnd.adobe.photoshop', + 'image/vnd.djvu', + 'image/x-cpi', + 'image/jpeg', + 'image/x-ico', + 'image/x-coreldraw', + 'image/svg+xml' + ); + } + + $this->setMimeType($mimetype); + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the file is compression with the set compression types + * + * @param string $value Real file to check for compression + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_READABLE); + } + + if ($file !== null) { + if (class_exists('finfo', false) && defined('MAGIC')) { + $mime = new finfo(FILEINFO_MIME); + $this->_type = $mime->file($value); + unset($mime); + } elseif (function_exists('mime_content_type') && ini_get('mime_magic.magicfile')) { + $this->_type = mime_content_type($value); + } else { + $this->_type = $file['type']; + } + } + + if (empty($this->_type)) { + return $this->_throw($file, self::NOT_DETECTED); + } + + $compressions = $this->getMimeType(true); + if (in_array($this->_type, $compressions)) { + return true; + } + + $types = explode('/', $this->_type); + $types = array_merge($types, explode('-', $this->_type)); + foreach($compressions as $mime) { + if (in_array($mime, $types)) { + return true; + } + } + + return $this->_throw($file, self::FALSE_TYPE); + } +} diff --git a/lib/Zend/Validate/File/Md5.php b/lib/Zend/Validate/File/Md5.php new file mode 100644 index 0000000..4b612d0 --- /dev/null +++ b/lib/Zend/Validate/File/Md5.php @@ -0,0 +1,183 @@ + "The file '%value%' does not match the given md5 hashes", + self::NOT_DETECTED => "There was no md5 hash detected for the given file", + self::NOT_FOUND => "The file '%value%' could not be found" + ); + + /** + * Hash of the file + * + * @var string + */ + protected $_hash; + + /** + * Sets validator options + * + * $hash is the hash we accept for the file $file + * + * @param string|array $options + * @return void + */ + public function __construct($options) + { + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } elseif (is_scalar($options)) { + $options = array('hash1' => $options); + } elseif (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception('Invalid options to validator provided'); + } + + $this->setMd5($options); + } + + /** + * Returns all set md5 hashes + * + * @return array + */ + public function getMd5() + { + return $this->getHash(); + } + + /** + * Sets the md5 hash for one or multiple files + * + * @param string|array $options + * @param string $algorithm (Deprecated) Algorithm to use, fixed to md5 + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function setHash($options) + { + if (!is_array($options)) { + $options = (array) $options; + } + + $options['algorithm'] = 'md5'; + parent::setHash($options); + return $this; + } + + /** + * Sets the md5 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function setMd5($options) + { + $this->setHash($options); + return $this; + } + + /** + * Adds the md5 hash for one or multiple files + * + * @param string|array $options + * @param string $algorithm (Depreciated) Algorithm to use, fixed to md5 + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function addHash($options) + { + if (!is_array($options)) { + $options = (array) $options; + } + + $options['algorithm'] = 'md5'; + parent::addHash($options); + return $this; + } + + /** + * Adds the md5 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function addMd5($options) + { + $this->addHash($options); + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the given file confirms the set hash + * + * @param string $value Filename to check for hash + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_FOUND); + } + + $hashes = array_unique(array_keys($this->_hash)); + $filehash = hash_file('md5', $value); + if ($filehash === false) { + return $this->_throw($file, self::NOT_DETECTED); + } + + foreach($hashes as $hash) { + if ($filehash === $hash) { + return true; + } + } + + return $this->_throw($file, self::DOES_NOT_MATCH); + } +} diff --git a/lib/Zend/Validate/File/MimeType.php b/lib/Zend/Validate/File/MimeType.php new file mode 100644 index 0000000..1605dad --- /dev/null +++ b/lib/Zend/Validate/File/MimeType.php @@ -0,0 +1,283 @@ + "The file '%value%' has a false mimetype of '%type%'", + self::NOT_DETECTED => "The mimetype of file '%value%' could not been detected", + self::NOT_READABLE => "The file '%value%' can not be read" + ); + + /** + * @var array + */ + protected $_messageVariables = array( + 'type' => '_type' + ); + + /** + * @var string + */ + protected $_type; + + /** + * Mimetypes + * + * If null, there is no mimetype + * + * @var string|null + */ + protected $_mimetype; + + /** + * Magicfile to use + * + * @var string|null + */ + protected $_magicfile; + + /** + * Sets validator options + * + * Mimetype to accept + * + * @param string|array $mimetype MimeType + * @return void + */ + public function __construct($mimetype) + { + if ($mimetype instanceof Zend_Config) { + $mimetype = $mimetype->toArray(); + } elseif (is_string($mimetype)) { + $mimetype = explode(',', $mimetype); + } elseif (!is_array($mimetype)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("Invalid options to validator provided"); + } + + if (isset($mimetype['magicfile'])) { + $this->setMagicFile($mimetype['magicfile']); + } + + $this->setMimeType($mimetype); + } + + /** + * Returna the actual set magicfile + * + * @return string + */ + public function getMagicFile() + { + return $this->_magicfile; + } + + /** + * Sets the magicfile to use + * if null, the MAGIC constant from php is used + * + * @param string $file + * @return Zend_Validate_File_MimeType Provides fluid interface + */ + public function setMagicFile($file) + { + if (empty($file)) { + $this->_magicfile = null; + } else if (!is_readable($file)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception('The given magicfile can not be read'); + } else { + $this->_magicfile = (string) $file; + } + + return $this; + } + + /** + * Returns the set mimetypes + * + * @param boolean $asArray Returns the values as array, when false an concated string is returned + * @return string|array + */ + public function getMimeType($asArray = false) + { + $asArray = (bool) $asArray; + $mimetype = (string) $this->_mimetype; + if ($asArray) { + $mimetype = explode(',', $mimetype); + } + + return $mimetype; + } + + /** + * Sets the mimetypes + * + * @param string|array $mimetype The mimetypes to validate + * @return Zend_Validate_File_Extension Provides a fluent interface + */ + public function setMimeType($mimetype) + { + $this->_mimetype = null; + $this->addMimeType($mimetype); + return $this; + } + + /** + * Adds the mimetypes + * + * @param string|array $mimetype The mimetypes to add for validation + * @return Zend_Validate_File_Extension Provides a fluent interface + */ + public function addMimeType($mimetype) + { + $mimetypes = $this->getMimeType(true); + + if (is_string($mimetype)) { + $mimetype = explode(',', $mimetype); + } elseif (!is_array($mimetype)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("Invalid options to validator provided"); + } + + if (isset($mimetype['magicfile'])) { + unset($mimetype['magicfile']); + } + + foreach ($mimetype as $content) { + if (empty($content) || !is_string($content)) { + continue; + } + $mimetypes[] = trim($content); + } + $mimetypes = array_unique($mimetypes); + + // Sanity check to ensure no empty values + foreach ($mimetypes as $key => $mt) { + if (empty($mt)) { + unset($mimetypes[$key]); + } + } + + $this->_mimetype = implode(',', $mimetypes); + + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if the mimetype of the file matches the given ones. Also parts + * of mimetypes can be checked. If you give for example "image" all image + * mime types will be accepted like "image/gif", "image/jpeg" and so on. + * + * @param string $value Real file to check for mimetype + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_READABLE); + } + + if ($file !== null) { + $mimefile = $this->getMagicFile(); + if (class_exists('finfo', false) && ((!empty($mimefile)) or (defined('MAGIC')))) { + if (!empty($mimefile)) { + $mime = new finfo(FILEINFO_MIME, $mimefile); + } else { + $mime = new finfo(FILEINFO_MIME); + } + + $this->_type = $mime->file($value); + unset($mime); + } elseif (function_exists('mime_content_type') && ini_get('mime_magic.magicfile')) { + $this->_type = mime_content_type($value); + } else { + $this->_type = $file['type']; + } + } + + if (empty($this->_type)) { + return $this->_throw($file, self::NOT_DETECTED); + } + + $mimetype = $this->getMimeType(true); + if (in_array($this->_type, $mimetype)) { + return true; + } + + $types = explode('/', $this->_type); + $types = array_merge($types, explode('-', $this->_type)); + foreach($mimetype as $mime) { + if (in_array($mime, $types)) { + return true; + } + } + + return $this->_throw($file, self::FALSE_TYPE); + } + + /** + * Throws an error of the given type + * + * @param string $file + * @param string $errorType + * @return false + */ + protected function _throw($file, $errorType) + { + if ($file !== null) { + $this->_value = $file['name']; + } + + $this->_error($errorType); + return false; + } +} diff --git a/lib/Zend/Validate/File/NotExists.php b/lib/Zend/Validate/File/NotExists.php new file mode 100644 index 0000000..8aeef9f --- /dev/null +++ b/lib/Zend/Validate/File/NotExists.php @@ -0,0 +1,84 @@ + "The file '%value%' does exist" + ); + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the file does not exist in the set destinations + * + * @param string $value Real file to check for + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + $directories = $this->getDirectory(true); + if (($file !== null) and (!empty($file['destination']))) { + $directories[] = $file['destination']; + } else if (!isset($file['name'])) { + $file['name'] = $value; + } + + foreach ($directories as $directory) { + if (empty($directory)) { + continue; + } + + $check = true; + if (file_exists($directory . DIRECTORY_SEPARATOR . $file['name'])) { + return $this->_throw($file, self::DOES_EXIST); + } + } + + if (!isset($check)) { + return $this->_throw($file, self::DOES_EXIST); + } + + return true; + } +} diff --git a/lib/Zend/Validate/File/Sha1.php b/lib/Zend/Validate/File/Sha1.php new file mode 100644 index 0000000..b02a837 --- /dev/null +++ b/lib/Zend/Validate/File/Sha1.php @@ -0,0 +1,181 @@ + "The file '%value%' does not match the given sha1 hashes", + self::NOT_DETECTED => "There was no sha1 hash detected for the given file", + self::NOT_FOUND => "The file '%value%' could not be found" + ); + + /** + * Hash of the file + * + * @var string + */ + protected $_hash; + + /** + * Sets validator options + * + * $hash is the hash we accept for the file $file + * + * @param string|array $options + * @return void + */ + public function __construct($options) + { + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } elseif (is_scalar($options)) { + $options = array('hash1' => $options); + } elseif (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception('Invalid options to validator provided'); + } + + $this->setHash($options); + } + + /** + * Returns all set sha1 hashes + * + * @return array + */ + public function getSha1() + { + return $this->getHash(); + } + + /** + * Sets the sha1 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function setHash($options) + { + if (!is_array($options)) { + $options = (array) $options; + } + + $options['algorithm'] = 'sha1'; + parent::setHash($options); + return $this; + } + + /** + * Sets the sha1 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function setSha1($options) + { + $this->setHash($options); + return $this; + } + + /** + * Adds the sha1 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function addHash($options) + { + if (!is_array($options)) { + $options = (array) $options; + } + + $options['algorithm'] = 'sha1'; + parent::addHash($options); + return $this; + } + + /** + * Adds the sha1 hash for one or multiple files + * + * @param string|array $options + * @return Zend_Validate_File_Hash Provides a fluent interface + */ + public function addSha1($options) + { + $this->addHash($options); + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the given file confirms the set hash + * + * @param string $value Filename to check for hash + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_FOUND); + } + + $hashes = array_unique(array_keys($this->_hash)); + $filehash = hash_file('sha1', $value); + if ($filehash === false) { + return $this->_throw($file, self::NOT_DETECTED); + } + + foreach ($hashes as $hash) { + if ($filehash === $hash) { + return true; + } + } + + return $this->_throw($file, self::DOES_NOT_MATCH); + } +} diff --git a/lib/Zend/Validate/File/Size.php b/lib/Zend/Validate/File/Size.php new file mode 100644 index 0000000..a52d499 --- /dev/null +++ b/lib/Zend/Validate/File/Size.php @@ -0,0 +1,404 @@ + "Maximum allowed size for file '%value%' is '%max%' but '%size%' detected", + self::TOO_SMALL => "Minimum expected size for file '%value%' is '%min%' but '%size%' detected", + self::NOT_FOUND => "The file '%value%' could not be found" + ); + + /** + * @var array Error message template variables + */ + protected $_messageVariables = array( + 'min' => '_min', + 'max' => '_max', + 'size' => '_size', + ); + + /** + * Minimum filesize + * @var integer + */ + protected $_min; + + /** + * Maximum filesize + * + * If null, there is no maximum filesize + * + * @var integer|null + */ + protected $_max; + + /** + * Detected size + * + * @var integer + */ + protected $_size; + + /** + * Use bytestring ? + * + * @var boolean + */ + protected $_useByteString = true; + + /** + * Sets validator options + * + * If $options is a integer, it will be used as maximum filesize + * As Array is accepts the following keys: + * 'min': Minimum filesize + * 'max': Maximum filesize + * 'bytestring': Use bytestring or real size for messages + * + * @param integer|array $options Options for the adapter + */ + public function __construct($options) + { + if ($options instanceof Zend_Config) { + $options = $options->toArray(); + } elseif (is_string($options) || is_numeric($options)) { + $options = array('max' => $options); + } elseif (!is_array($options)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + if (1 < func_num_args()) { + trigger_error('Multiple constructor options are deprecated in favor of a single options array', E_USER_NOTICE); + $argv = func_get_args(); + array_shift($argv); + $options['max'] = array_shift($argv); + if (!empty($argv)) { + $options['bytestring'] = array_shift($argv); + } + } + + if (isset($options['bytestring'])) { + $this->setUseByteString($options['bytestring']); + } + + if (isset($options['min'])) { + $this->setMin($options['min']); + } + + if (isset($options['max'])) { + $this->setMax($options['max']); + } + } + + /** + * Returns the minimum filesize + * + * @param boolean $byteString Use bytestring ? + * @return integer + */ + public function setUseByteString($byteString = true) + { + $this->_useByteString = (bool) $byteString; + return $this; + } + + /** + * Will bytestring be used? + * + * @return boolean + */ + public function useByteString() + { + return $this->_useByteString; + } + + /** + * Returns the minimum filesize + * + * @param bool $raw Whether or not to force return of the raw value (defaults off) + * @return integer|string + */ + public function getMin($raw = false) + { + $min = $this->_min; + if (!$raw && $this->useByteString()) { + $min = $this->_toByteString($min); + } + + return $min; + } + + /** + * Sets the minimum filesize + * + * @param integer $min The minimum filesize + * @throws Zend_Validate_Exception When min is greater than max + * @return Zend_Validate_File_Size Provides a fluent interface + */ + public function setMin($min) + { + if (!is_string($min) and !is_numeric($min)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + $min = (integer) $this->_fromByteString($min); + $max = $this->getMax(true); + if (($max !== null) && ($min > $max)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum filesize, but $min >" + . " $max"); + } + + $this->_min = $min; + return $this; + } + + /** + * Returns the maximum filesize + * + * @param bool $raw Whether or not to force return of the raw value (defaults off) + * @return integer|string + */ + public function getMax($raw = false) + { + $max = $this->_max; + if (!$raw && $this->useByteString()) { + $max = $this->_toByteString($max); + } + + return $max; + } + + /** + * Sets the maximum filesize + * + * @param integer $max The maximum filesize + * @throws Zend_Validate_Exception When max is smaller than min + * @return Zend_Validate_StringLength Provides a fluent interface + */ + public function setMax($max) + { + if (!is_string($max) && !is_numeric($max)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception ('Invalid options to validator provided'); + } + + $max = (integer) $this->_fromByteString($max); + $min = $this->getMin(true); + if (($min !== null) && ($max < $min)) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum filesize, but " + . "$max < $min"); + } + + $this->_max = $max; + return $this; + } + + /** + * Retrieve current detected file size + * + * @return int + */ + protected function _getSize() + { + return $this->_size; + } + + /** + * Set current size + * + * @param int $size + * @return Zend_Validate_File_Size + */ + protected function _setSize($size) + { + $this->_size = $size; + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the filesize of $value is at least min and + * not bigger than max (when max is not null). + * + * @param string $value Real file to check for size + * @param array $file File data from Zend_File_Transfer + * @return boolean + */ + public function isValid($value, $file = null) + { + // Is file readable ? + require_once 'Zend/Loader.php'; + if (!Zend_Loader::isReadable($value)) { + return $this->_throw($file, self::NOT_FOUND); + } + + // limited to 4GB files + $size = sprintf("%u", @filesize($value)); + + // Check to see if it's smaller than min size + $min = $this->getMin(true); + $max = $this->getMax(true); + if (($min !== null) && ($size < $min)) { + if ($this->useByteString()) { + $this->_min = $this->_toByteString($min); + $this->_size = $this->_toByteString($size); + $this->_throw($file, self::TOO_SMALL); + $this->_min = $min; + $this->_size = $size; + } else { + $this->_throw($file, self::TOO_SMALL); + } + } + + // Check to see if it's larger than max size + if (($max !== null) && ($max < $size)) { + if ($this->useByteString()) { + $this->_max = $this->_toByteString($max); + $this->_size = $this->_toByteString($size); + $this->_throw($file, self::TOO_BIG); + $this->_max = $max; + $this->_size = $size; + } else { + $this->_throw($file, self::TOO_BIG); + } + } + + if (count($this->_messages) > 0) { + return false; + } + + return true; + } + + /** + * Returns the formatted size + * + * @param integer $size + * @return string + */ + protected function _toByteString($size) + { + $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); + for ($i=0; $size >= 1024 && $i < 9; $i++) { + $size /= 1024; + } + + return round($size, 2) . $sizes[$i]; + } + + /** + * Returns the unformatted size + * + * @param string $size + * @return integer + */ + protected function _fromByteString($size) + { + if (is_numeric($size)) { + return (integer) $size; + } + + $type = trim(substr($size, -2, 1)); + + $value = substr($size, 0, -1); + if (!is_numeric($value)) { + $value = substr($value, 0, -1); + } + + switch (strtoupper($type)) { + case 'Y': + $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); + break; + case 'Z': + $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); + break; + case 'E': + $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024); + break; + case 'P': + $value *= (1024 * 1024 * 1024 * 1024 * 1024); + break; + case 'T': + $value *= (1024 * 1024 * 1024 * 1024); + break; + case 'G': + $value *= (1024 * 1024 * 1024); + break; + case 'M': + $value *= (1024 * 1024); + break; + case 'K': + $value *= 1024; + break; + default: + break; + } + + return $value; + } + + /** + * Throws an error of the given type + * + * @param string $file + * @param string $errorType + * @return false + */ + protected function _throw($file, $errorType) + { + if ($file !== null) { + $this->_value = $file['name']; + } + + $this->_error($errorType); + return false; + } +} diff --git a/lib/Zend/Validate/File/Upload.php b/lib/Zend/Validate/File/Upload.php new file mode 100644 index 0000000..ddeb328 --- /dev/null +++ b/lib/Zend/Validate/File/Upload.php @@ -0,0 +1,234 @@ + "The file '%value%' exceeds the defined ini size", + self::FORM_SIZE => "The file '%value%' exceeds the defined form size", + self::PARTIAL => "The file '%value%' was only partially uploaded", + self::NO_FILE => "The file '%value%' was not uploaded", + self::NO_TMP_DIR => "No temporary directory was found for the file '%value%'", + self::CANT_WRITE => "The file '%value%' can't be written", + self::EXTENSION => "The extension returned an error while uploading the file '%value%'", + self::ATTACK => "The file '%value%' was illegal uploaded, possible attack", + self::FILE_NOT_FOUND => "The file '%value%' was not found", + self::UNKNOWN => "Unknown error while uploading the file '%value%'" + ); + + /** + * Internal array of files + * @var array + */ + protected $_files = array(); + + /** + * Sets validator options + * + * The array $files must be given in syntax of Zend_File_Transfer to be checked + * If no files are given the $_FILES array will be used automatically. + * NOTE: This validator will only work with HTTP POST uploads! + * + * @param array $files Array of files in syntax of Zend_File_Transfer + * @return void + */ + public function __construct($files = array()) + { + $this->setFiles($files); + } + + /** + * Returns the array of set files + * + * @param string $files (Optional) The file to return in detail + * @return array + * @throws Zend_Validate_Exception If file is not found + */ + public function getFiles($file = null) + { + if ($file !== null) { + $return = array(); + foreach ($this->_files as $name => $content) { + if ($name === $file) { + $return[$file] = $this->_files[$name]; + } + + if ($content['name'] === $file) { + $return[$name] = $this->_files[$name]; + } + } + + if (count($return) === 0) { + require_once 'Zend/Validate/Exception.php'; + throw new Zend_Validate_Exception("The file '$file' was not found"); + } + + return $return; + } + + return $this->_files; + } + + /** + * Sets the minimum filesize + * + * @param array $files The files to check in syntax of Zend_File_Transfer + * @return Zend_Validate_File_Upload Provides a fluent interface + */ + public function setFiles($files = array()) + { + if (count($files) === 0) { + $this->_files = $_FILES; + } else { + $this->_files = $files; + } + return $this; + } + + /** + * Defined by Zend_Validate_Interface + * + * Returns true if and only if the file was uploaded without errors + * + * @param string $value Single file to check for upload errors, when giving null the $_FILES array + * from initialization will be used + * @return boolean + */ + public function isValid($value, $file = null) + { + if (array_key_exists($value, $this->_files)) { + $files[$value] = $this->_files[$value]; + } else { + foreach ($this->_files as $file => $content) { + if ($content['name'] === $value) { + $files[$file] = $this->_files[$file]; + } + + if ($content['tmp_name'] === $value) { + $files[$file] = $this->_files[$file]; + } + } + } + + if (empty($files)) { + return $this->_throw($file, self::FILE_NOT_FOUND); + } + + foreach ($files as $file => $content) { + $this->_value = $file; + switch($content['error']) { + case 0: + if (!is_uploaded_file($content['tmp_name'])) { + $this->_throw($file, self::ATTACK); + } + break; + + case 1: + $this->_throw($file, self::INI_SIZE); + break; + + case 2: + $this->_throw($file, self::FORM_SIZE); + break; + + case 3: + $this->_throw($file, self::PARTIAL); + break; + + case 4: + $this->_throw($file, self::NO_FILE); + break; + + case 6: + $this->_throw($file, self::NO_TMP_DIR); + break; + + case 7: + $this->_throw($file, self::CANT_WRITE); + break; + + case 8: + $this->_throw($file, self::EXTENSION); + break; + + default: + $this->_throw($file, self::UNKNOWN); + break; + } + } + + if (count($this->_messages) > 0) { + return false; + } else { + return true; + } + } + + /** + * Throws an error of the given type + * + * @param string $file + * @param string $errorType + * @return false + */ + protected function _throw($file, $errorType) + { + if ($file !== null) { + if (is_array($file) and !empty($file['name'])) { + $this->_value = $file['name']; + } + } + + $this->_error($errorType); + return false; + } +} -- cgit v1.2.3