Browse Source

Add Validation::uploadedFile()

Add a simple wraper function for the various file validation methods.
This method makes it easier to wrap up the various file validators into
one method.

Refs #4456
mark_story 11 years ago
parent
commit
34717345af
2 changed files with 115 additions and 0 deletions
  1. 42 0
      src/Validation/Validation.php
  2. 73 0
      tests/TestCase/Validation/ValidationTest.php

+ 42 - 0
src/Validation/Validation.php

@@ -951,6 +951,48 @@ class Validation {
 	}
 
 /**
+ * Validate an uploaded file.
+ *
+ * Helps join `uploadError`, `fileSize` and `mimeType` into
+ * one higher level validation method.
+ *
+ * ### Options
+ *
+ * - `types` - A list of valid mime types. If empty all types
+ *   will be accepted. The `type` will not be looked at, instead
+ *   the file type will be checked with ext/finfo.
+ * - `minSize` - The minimum file size. Defaults to not checking.
+ * - `maxSize` - The maximum file size. Defaults to not checking.
+ *
+ * @param array $file The uploaded file data from PHP.
+ * @param array $options An array of options for the validation.
+ * @return bool
+ */
+	public static function uploadedFile($file, $options = []) {
+		$options += ['minSize' => null, 'maxSize' => null, 'types' => null];
+		if (!is_array($file)) {
+			return false;
+		}
+		$keys = ['name', 'tmp_name', 'error', 'type', 'size'];
+		if (array_keys($file) != $keys) {
+			return false;
+		}
+		if (!static::uploadError($file)) {
+			return false;
+		}
+		if (isset($options['minSize']) && !static::fileSize($file, '>=', $options['minSize'])) {
+			return false;
+		}
+		if (isset($options['maxSize']) && !static::fileSize($file, '<=', $options['maxSize'])) {
+			return false;
+		}
+		if (isset($options['types']) && !static::mimeType($file, $options['types'])) {
+			return false;
+		}
+		return true;
+	}
+
+/**
  * Lazily populate the IP address patterns used for validations
  *
  * @return void

+ 73 - 0
tests/TestCase/Validation/ValidationTest.php

@@ -2342,4 +2342,77 @@ class ValidationTest extends TestCase {
 		$this->assertFalse(Validation::fileSize(array('tmp_name' => $image), '>', '1KB'));
 	}
 
+/**
+ * Test uploaded file validation.
+ *
+ * @return void
+ */
+	public function testUploadedFileErrorCode() {
+		$this->assertFalse(Validation::uploadedFile('derp'));
+		$invalid = [
+			'name' => 'testing'
+		];
+		$this->assertFalse(Validation::uploadedFile($invalid));
+
+		$file = [
+			'name' => 'cake.power.gif',
+			'tmp_name' => TEST_APP . 'webroot/img/cake.power.gif',
+			'error' => UPLOAD_ERR_OK,
+			'type' => 'image/gif',
+			'size' => 201
+		];
+		$this->assertTrue(Validation::uploadedFile($file));
+
+		$file['error'] = UPLOAD_ERR_NO_FILE;
+		$this->assertFalse(Validation::uploadedFile($file), 'Error upload should fail.');
+	}
+
+/**
+ * Test uploaded file validation.
+ *
+ * @return void
+ */
+	public function testUploadedFileMimeType() {
+		$file = [
+			'name' => 'cake.power.gif',
+			'tmp_name' => TEST_APP . 'webroot/img/cake.power.gif',
+			'error' => UPLOAD_ERR_OK,
+			'type' => 'text/plain',
+			'size' => 201
+		];
+		$options = [
+			'types' => ['text/plain']
+		];
+		$this->assertFalse(Validation::uploadedFile($file, $options), 'Incorrect mimetype.');
+
+		$options = [
+			'types' => ['image/gif', 'image/png']
+		];
+		$this->assertTrue(Validation::uploadedFile($file, $options));
+	}
+
+/**
+ * Test uploaded file validation.
+ *
+ * @return void
+ */
+	public function testUploadedFileSize() {
+		$file = [
+			'name' => 'cake.power.gif',
+			'tmp_name' => TEST_APP . 'webroot/img/cake.power.gif',
+			'error' => UPLOAD_ERR_OK,
+			'type' => 'text/plain',
+			'size' => 201
+		];
+		$options = [
+			'minSize' => 500
+		];
+		$this->assertFalse(Validation::uploadedFile($file, $options), 'Too small');
+
+		$options = [
+			'maxSize' => 100
+		];
+		$this->assertFalse(Validation::uploadedFile($file, $options), 'Too big');
+	}
+
 }