Permalink
Browse files

Add extra validations

Finalize exceptions

Finalize SplFileInfo
  • Loading branch information...
codeguy committed Sep 11, 2012
1 parent c8b7d15 commit 96bf777658333de1da776b27a1eaa05523a216f1
View
@@ -8,14 +8,11 @@
stopOnFailure="false"
syntaxCheck="false"
bootstrap="tests/bootstrap.php">
- <!-- Tests -->
<testsuites>
<testsuite name="Upload Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
-
- <!-- Code Coverage -->
<filter>
<whitelist>
<directory>./src/Upload/</directory>
View
@@ -44,26 +44,59 @@
*/
class File extends \SplFileInfo
{
+ /********************************************************************************
+ * Static Properties
+ *******************************************************************************/
+
/**
- * The file's storage delegate
+ * Upload error code messages
+ * @var array
+ */
+ protected static $errorCodeMessages = array(
+ 1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
+ 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
+ 3 => 'The uploaded file was only partially uploaded',
+ 4 => 'No file was uploaded',
+ 6 => 'Missing a temporary folder',
+ 7 => 'Failed to write file to disk',
+ 8 => 'A PHP extension stopped the file upload'
+ );
+
+ /**
+ * Lookup hash to convert file units to bytes
+ * @var array
+ */
+ protected static $units = array(
+ 'b' => 1,
+ 'k' => 1024,
+ 'm' => 1048576,
+ 'g' => 1073741824
+ );
+
+ /********************************************************************************
+ * Instance Properties
+ *******************************************************************************/
+
+ /**
+ * Storage delegate
* @var \Upload\Storage\Base
*/
protected $storage;
/**
- * Array of validations
+ * Validations
* @var array[\Upload\Validation\Base]
*/
protected $validations;
/**
- * Array of validation errors
+ * Validation errors
* @var array
*/
protected $errors;
/**
- * Original file name provided by client
+ * Original file name provided by client (for internal use only)
* @var string
*/
protected $originalName;
@@ -86,11 +119,19 @@ class File extends \SplFileInfo
*/
protected $mimetype;
+ /**
+ * Upload error code (for internal use only)
+ * @var int
+ * @link http://www.php.net/manual/en/features.file-upload.errors.php
+ */
+ protected $errorCode;
+
/**
* Constructor
- * @param string $key The file's key in $_FILES superglobal
- * @param \Upload\Storage\Base $storage The method with which to store file
- * @throws \InvalidArgumentException If $_FILES key does not exist
+ * @param string $key The file's key in $_FILES superglobal
+ * @param \Upload\Storage\Base $storage The method with which to store file
+ * @throws \Upload\Exception\UploadException If file uploads are disabled in the php.ini file
+ * @throws \InvalidArgumentException If $_FILES key does not exist
*/
public function __construct($key, \Upload\Storage\Base $storage)
{
@@ -101,6 +142,7 @@ public function __construct($key, \Upload\Storage\Base $storage)
$this->validations = array();
$this->errors = array();
$this->originalName = $_FILES[$key]['name'];
+ $this->errorCode = $_FILES[$key]['error'];
parent::__construct($_FILES[$key]['tmp_name']);
}
@@ -203,6 +245,17 @@ public function getValidations()
*/
public function validate()
{
+ // Validate is uploaded OK
+ if ($this->isOk() === false) {
+ $this->errors[] = self::$errorCodeMessages[$this->errorCode];
+ }
+
+ // Validate is uploaded file
+ if ($this->isUploadedFile() === false) {
+ $this->errors[] = 'The uploaded file was not sent with a POST request';
+ }
+
+ // User validations
foreach ($this->validations as $validation) {
if ($validation->validate($this) === false) {
$this->errors[] = $validation->getMessage();
@@ -250,4 +303,51 @@ public function upload()
return $this->storage->upload($this);
}
+
+ /********************************************************************************
+ * Helpers
+ *******************************************************************************/
+
+ /**
+ * Is this file uploaded with a POST request?
+ *
+ * This is a separate method so that it can be stubbed in unit tests to avoid
+ * the hard dependency on the `is_uploaded_file` function.
+ *
+ * @return bool
+ */
+ public function isUploadedFile()
+ {
+ return is_uploaded_file($this->getPathname());
+ }
+
+ /**
+ * Is this file OK?
+ *
+ * This method inspects the upload error code to see if the upload was
+ * successful or if it failed for a variety of reasons.
+ *
+ * @link http://www.php.net/manual/en/features.file-upload.errors.php
+ * @return bool
+ */
+ public function isOk()
+ {
+ return ($this->errorCode === UPLOAD_ERR_OK);
+ }
+
+ /**
+ * Convert human readable file size (e.g. "10K" or "3M") into bytes
+ * @param string $input
+ * @return int
+ */
+ public static function humanReadableToBytes($input)
+ {
+ $number = (int)$input;
+ $unit = strtolower(substr($input, -1));
+ if (isset(self::$units[$unit])) {
+ $number = $number * self::$units[$unit];
+ }
+
+ return $number;
+ }
}
@@ -41,7 +41,7 @@
* @since 1.0.0
* @package Upload
*/
-class FileSize extends \Upload\Validation\Base
+class Size extends \Upload\Validation\Base
{
/**
* Minimum acceptable file size (bytes)
@@ -55,16 +55,6 @@ class FileSize extends \Upload\Validation\Base
*/
protected $maxSize;
- /**
- * Bytes per unit lookup table
- * @var array
- */
- protected $units = array(
- 'B' => 1,
- 'KB' => 1024,
- 'MB' => 1048576
- );
-
/**
* Error message
* @var string
@@ -79,12 +69,12 @@ class FileSize extends \Upload\Validation\Base
public function __construct($maxSize, $minSize = 0)
{
if (is_string($maxSize)) {
- $maxSize = $this->humanReadableToBytes($maxSize);
+ $maxSize = \Upload\File::humanReadableToBytes($maxSize);
}
$this->maxSize = $maxSize;
if (is_string($minSize)) {
- $minSize = $this->humanReadableToBytes($minSize);
+ $minSize = \Upload\File::humanReadableToBytes($minSize);
}
$this->minSize = $minSize;
}
@@ -111,19 +101,4 @@ public function validate(\Upload\File $file)
return $isValid;
}
-
- /**
- * Convert human readble file size into bytes
- * @param text $input Human readable filesize (e.g. "1MB")
- * @return int
- */
- protected function humanReadableToBytes($input)
- {
- preg_match('#(\d+)\s*(B|KB|MB)#', $input, $parts);
- $number = (int)$parts[1];
- $unit = $parts[2];
- $bytesPerUnit = $this->units[$unit];
-
- return $number * $bytesPerUnit;
- }
}
Oops, something went wrong.

0 comments on commit 96bf777

Please sign in to comment.